ABC 부트캠프

[22일차] ABC 부트캠프 인공지능_4

ejis 2024. 8. 3. 18:00

일주일의 어려웠던 개념이 끝이 나고 이제 저에게 남은 건 복습뿐이네요.. 다들 화이팅입니다.


오늘 배운 개념

1. 신경망 (Neuron Network)
신경망은 인간의 뇌 구조를 모방한 기계 학습 모델로, 여러 개의 노드(뉴런)로 구성된 층을 통해 데이터를 처리합니다. 입력층, 은닉층, 출력층으로 구성되며, 각 층의 뉴런들은 서로 연결되어 있습니다. 신경망은 복잡한 패턴 인식과 예측 문제를 해결하는 데 유용합니다.

2. 전통적인 컴퓨터 vs 인공 신경망
전통적인 컴퓨터는 명시적인 규칙과 알고리즘을 기반으로 작동하며, 주어진 문제를 해결하는 데 필요한 모든 정보를 사전에 프로그래밍해야 합니다. 반면, 인공 신경망은 데이터에서 패턴을 학습하여 문제를 해결하며, 복잡한 문제에 대해 일반화할 수 있는 능력을 가지고 있습니다.

3. 기존의 컴퓨터 vs 인간의 두뇌
기존의 컴퓨터는 논리적이고 정량적인 연산을 신속하게 수행하지만, 인간의 두뇌는 직관적이고 비선형적인 사고를 통해 복잡한 문제를 해결하는 데 강점을 보입니다. 인간의 두뇌는 감정, 경험, 학습을 통해 지식을 쌓아가며, 이를 바탕으로 다양한 상황에 적응하는 능력이 있습니다.

4. 퍼셉트론 학습 알고리즘
퍼셉트론은 단일 뉴런으로 구성된 간단한 신경망입니다. 입력값과 가중치를 곱해 합산한 후, 활성화 함수를 적용하여 출력값을 결정합니다. 퍼셉트론 학습 알고리즘은 주어진 데이터로부터 가중치를 조정하여 올바른 출력을 생성하도록 학습하는 과정입니다.

5. sklearn으로 퍼셉트론 실습하기
sklearn은 Python에서 머신러닝을 구현할 수 있는 라이브러리로, 퍼셉트론 알고리즘을 쉽게 구현할 수 있는 기능을 제공합니다. sklearn의 Perceptron 클래스를 사용하여 데이터를 학습하고 예측할 수 있습니다.

6. MLP (다층 퍼셉트론)
MLP는 여러 개의 은닉층을 가진 신경망으로, 입력층과 출력층 사이에 여러 개의 층을 추가하여 복잡한 문제를 해결할 수 있습니다. 각 층의 뉴런들은 활성화 함수를 통해 비선형성을 추가하여 데이터의 복잡한 패턴을 학습합니다.

7. 일반적으로 많이 사용되는 활성화 함수
활성화 함수는 뉴런의 출력을 결정하는 함수로, 신경망의 성능에 큰 영향을 미칩니다. 일반적으로 사용되는 활성화 함수에는

시그모이드 함수: 0과 1 사이의 출력을 생성하여 이진 분류에 주로 사용됨.ReLU (Rectified Linear Unit): 입력값이 0보다 클 경우 그대로 출력하고, 0 이하는 0으로 반환하여 비선형성을 부여.Softmax: 다중 클래스 분류에서 사용되어 각 클래스의 확률을 출력.


8. 시그모이드 함수
시그모이드 함수는 다음과 같은 형태를 가집니다: ( f(x) = \frac{1}{1 + e^{-x}} ). 이 함수는 입력값을 0과 1 사이의 값으로 압축하여 이진 분류 문제에서 주로 사용됩니다. 그러나 기울기 소실 문제가 발생할 수 있어 깊은 신경망에서는 다른 활성화 함수를 사용하는 것이 일반적입니다.

9. 경사 하강법과 미니 배치
경사 하강법은 손실 함수를 최소화하기 위해 가중치를 업데이트하는 최적화 알고리즘입니다. 전체 데이터셋을 사용하여 가중치를 업데이트하는 "배치 경사 하강법"과, 데이터셋을 작은 배치로 나누어 각 배치에 대해 업데이트하는 "미니 배치 경사 하강법"이 있습니다. 미니 배치는 계산 효율성을 높이고, 노이즈를 추가하여 일반화 성능을 향상시킬 수 있습니다.

10. 2차원 그래디언트 시각화
2차원 그래디언트 시각화는 손실 함수의 기울기를 시각적으로 표현하여 최적화 과정에서의 경향성을 이해하는 데 도움을 줍니다. 일반적으로 등고선 그래프와 화살표를 사용하여 기울기가 큰 방향을 시각적으로 나타냅니다.

11. Adam
Adam(Adaptive Moment Estimation)은 경사 하강법을 기반으로 한 최적화 알고리즘으로, 각 파라미터의 기울기(1차 모멘트)와 기울기의 제곱(2차 모멘트)을 적응적으로 조정합니다. 이로 인해 학습 속도가 빨라지고, 안정성이 향상되며, 다양한 문제에서 효과적으로 작동합니다.

12. 텐서플로우의 구조
텐서플로우는 구글이 개발한 오픈소스 머신러닝 라이브러리로, 데이터 플로우 그래프를 기반으로 작동합니다. 텐서플로우의 구조는 다음과 같습니다:

텐서: 데이터의 기본 단위로, 다차원 배열을 표현합니다.
그래프: 연산을 노드로, 데이터 흐름을 엣지로 표현하여 복잡한 계산을 효율적으로 수행합니다.
세션: 그래프를 실행하는 환경을 제공하여, 텐서플로우에서 정의한 연산을 실행합니다.


from sklearn.linear_model import Perceptron
import numpy as np

# AND 게이트를 위한 샘플 데이터
# AND 게이트는 두 입력이 모두 1일 때만 1을 출력합니다.
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 0, 0, 1])  # 기대하는 출력

# 퍼셉트론 모델 초기화 (tol은 수렴 기준)
percept = Perceptron(tol=0.001, random_state=0)
percept.fit(X=X, y=y)  # 모델 학습
print("AND 게이트 예측:", percept.predict(X=X))  # 예측 결과 출력

# OR 게이트를 위한 샘플 데이터
# OR 게이트는 두 입력 중 하나라도 1이면 1을 출력합니다.
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 1, 1, 1])  # 기대하는 출력

percept = Perceptron(tol=0.001, random_state=0)  # 새로운 모델 초기화
percept.fit(X=X, y=y)  # 모델 학습
print("OR 게이트 예측:", percept.predict(X=X))  # 예측 결과 출력

# XOR 게이트를 위한 샘플 데이터
# XOR 게이트는 두 입력이 다를 때만 1을 출력합니다. 
# 이 경우, 퍼셉트론으로는 해결할 수 없는 비선형 문제입니다.
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 1, 1, 0])  # 기대하는 출력

percept = Perceptron(tol=0.001, random_state=0)  # 새로운 모델 초기화
percept.fit(X=X, y=y)  # 모델 학습

# XOR 게이트에 대한 예측 결과 출력
print("XOR 게이트 예측:", percept.predict(X=X))  # [0 0 0 0] -> 오류 발생
# 퍼셉트론은 XOR 문제를 해결할 수 없으므로 모든 출력이 0이 나옵니다.
  • AND 게이트 : 두 입력이 모두 1일 때만 1을 출력하는 논리 게이트입니다. 예측 결과는 올바르게 학습되어 기대한 대로 출력됩니다.
  • OR 게이트 : 두 입력 중 하나라도 1인 경우 1을 출력하는 논리 게이트입니다. 예측 결과 역시 기대한 대로 출력됩니다.
  • XOR 게이트 : 두 입력이 다를 때만 1을 출력하는 게이트로, 퍼셉트론으로는 해결할 수 없는 문제입니다. 퍼셉트론은 선형 분리 가능 문제에만 적용 가능하기 때문에, XOR 문제의 경우 모든 출력이 0으로 나와 오류가 발생합니다.

import numpy as np
import matplotlib.pyplot as plt
import pylab as pl

# 시그모이드 함수 정의
def sigmoid(x: float) -> float:
    """
    시그모이드 함수
    입력값 x에 대해 0과 1 사이의 값을 반환합니다.
    """
    return 1.0 / (1.0 + np.exp(-x))

'''
# x 값 범위를 -10.0에서 10.0까지 설정하고 0.1 간격으로 생성
X = np.arange(-10.0, 10.0, 0.1)
# 시그모이드 함수에 x 값을 적용하여 y 값을 계산
y = sigmoid(x=X)
plt.plot(X, y)
pl.show()
'''

'''
# -π에서 π까지 60개의 점을 생성하여 x 값을 정의
# x = np.linspace(-np.pi, np.pi, 60)
# x 값을 -100에서 100까지 100개의 점으로 생성
x = np.linspace(-100, 100, 100)  # x축 범위가 너무 넓어져서 직선처럼 보일 수 있습니다.
# tanh 함수를 적용하여 y 값을 계산
y = np.tanh(x)
plt.plot(x, y)
plt.show()
'''

# ReLU 함수 정의
def relu(x: float) -> int:
    """
    ReLU (Rectified Linear Unit) 함수
    입력값 x가 0보다 크면 x를 반환하고, 그렇지 않으면 0을 반환합니다.
    """
    return np.maximum(x, 0)  # 0보다 크면 자기 자신, 아니면 0을 반환

# x 값 범위를 -10.0에서 10.0까지 설정하고 0.1 간격으로 생성
x = np.arange(-10.0, 10.0, 0.1)
# ReLU 함수에 x 값을 적용하여 y 값을 계산
y = relu(x)
plt.plot(x, y)
plt.show()

케라스로 신경망을 작성하는 절차

import tensorflow as tf

# XOR 모델 정의
model = tf.keras.models.Sequential([], name="XOR_MODEL")

# 첫 번째 Dense 레이어 추가: 2개의 유닛, 입력 형태는 2차원 (2,)
model.add(tf.keras.layers.Dense(units=2, input_shape=(2,),
                                activation='sigmoid', name='LAYER1'))

# 출력 레이어 추가: 1개의 유닛, 시그모이드 활성화 함수 사용
model.add(tf.keras.layers.Dense(units=1,
                                activation='sigmoid', name="OUTPUT"))

# 모델 요약 정보 출력: 각 레이어의 구성과 파라미터 수를 확인할 수 있음
model.summary()

# 모델 컴파일: SGD 옵티마이저와 MSE 손실 함수 사용
model.compile(optimizer='sgd', loss="mse")

# XOR 문제에 대한 입력 데이터 정의: 4개의 입력 조합
X = tf.constant([[0, 0], [0, 1], [1, 0], [1, 1]])
# XOR 문제에 대한 기대 출력 정의
y = tf.constant([0, 1, 1, 0])

# 모델 학습: 10,000 에포크 동안 학습
model.fit(X, y, epochs=10_000)

# 학습된 모델로 입력 데이터에 대한 예측 수행
print(model.predict(X))


import numpy as np
import time
from matplotlib import pyplot as plt

# 샘플 데이터 개수 설정
SAMPLE_NUMBER = 10_000  # 10,000개의 샘플 데이터를 생성

# 현재 시간을 시드로 사용하여 랜덤 시드 설정
np.random.seed(int(time.time()))

# -2.0과 0.5 사이의 균등 분포에서 랜덤 샘플 생성
Xs = np.random.uniform(low=-2.0, high=0.5, size=SAMPLE_NUMBER)

# 생성된 데이터를 무작위로 섞기
np.random.shuffle(Xs)
print(Xs[0:15])

# y = 2x^2 + 3x + 5 공식을 사용하여 출력 값 생성
ys = 2 * np.square(Xs) + 3 * Xs + 5

# Xs와 ys를 산점도로 시각화
plt.plot(Xs, ys, 'r.')  # 'r.'은 빨간 점을 의미
plt.show()

ys += 0.2 * np.random.randn(SAMPLE_NUMBER) # 출력 값에 노이즈 추가
plt.plot(Xs, ys, 'r.')
plt.show()

import tensorflow as tf

# Sequential 모델 생성
model = tf.keras.Sequential(name="MODEL")

# 입력 레이어 정의: 입력 형태는 1차원 (1,)
input = tf.keras.Input(shape=(1,))
model.add(input)  # 입력 레이어를 모델에 추가

# 첫 번째 Dense 레이어 추가: 16개의 유닛, ReLU 활성화 함수 사용
model.add(tf.keras.layers.Dense(units=16, activation='relu', name="LAYER1"))
model.add(tf.keras.layers.Dense(units=8, activation='relu', name="LAYER2"))
model.add(tf.keras.layers.Dense(units=4, activation='relu', name="LAYER3"))
# 출력 레이어 추가: 1개의 유닛, ReLU 활성화 함수 사용
model.add(tf.keras.layers.Dense(units=1, activation='relu', name="OUTPUT"))

# 모델 요약 정보 출력: 각 레이어의 구성과 파라미터 수를 확인할 수 있음
model.summary()

# 모델 컴파일: 평균 제곱 오차(MSE) 손실 함수와 Adam 옵티마이저 사용
model.compile(loss='mse', optimizer='adam')
from sklearn.model_selection import train_test_split

# 데이터를 학습 세트와 테스트 세트로 분할: 전체 데이터의 20%를 테스트 데이터로 사용
(X_train, X_test, y_train, y_test) = train_test_split(Xs, ys, test_size=0.2)

# 학습 데이터 시각화: 파란색 점으로 표시
plt.plot(X_train, y_train, 'b.', label="Train")

# 테스트 데이터 시각화: 빨간색 점으로 표시
plt.plot(X_test, y_test, 'r.', label="Test")

# 범례 추가: 각 데이터 세트를 식별할 수 있도록 범례 표시
plt.legend()
plt.show()

model.fit(X_train, y_train, epochs=500)

모델을 500 에포크 동안 훈련시킨다.

# 테스트 데이터에 대한 예측 수행
y_predict = model.predict(X_test)
print(y_predict)
print(y_test)

# 예측값과 실제값의 관계를 시각화: 빨간색 점으로 표시
plt.plot(y_predict, y_test, 'r.')
plt.show()


다른 분이 제 글을 읽으며 코드만 복붙 했다고 하시는데.. 코드에 주석을 한 줄마다 다 달아놔서 오히려 저는 그게 보기 더 편한 줄 알았는데.. 제가 처음에 테크노트 작성요령에 처음 보는 사람이어도 이해가 갈 수 있게 하겠다 했지만 그게 잘 안된 거 같아 반성하는 계기가 되었습니다.. 이번주 한 주도 고생하셨습니다! 감기 조심하세요..(저도 걸렸답니다.)

썸네일