ABC부트캠프 데이터 탐험가 과정

[22일차] ABC 부트캠프 인공신경망, MLP

hwibeenjeong 2024. 8. 2. 16:49

1. 인공 신경망

신경망: 생물학적인 신경망에서 영감을 받아서 만들어진 컴퓨팅 구조
  인간의 두뇌 컴퓨터
처리 소자의 개수 10의 10제곱개의 뉴런 10의 8제곱개의 트랜지스터
처리 소자의 속도 10의 제곱Hz 10의12제곱 Hz
학습 기능
계산 스타일 분산 병렬 처리 중앙집중식, 순차적 처리

단순한 필기체와 같은 이미지들은 식별이 쉽지만, 다채로운 색상의 그림은 식별하기 어렵다. 

 

2. MLP (Multi Layer Perceptron)

2-1. 퍼셉트론(Perceptron)

1957년 로젠 블라트가 고안한 인공신경망, 입력층에 임의의 벡터가 들어 오면, 서로 연결된 특징값과 가중치를 곱한 결과를 모두 더한다. 이렇게 얻은 값을 활성화 함수에 입력으로 넣고 계산한다. 활성화 함수의 출력이 퍼셉트론의 최종 출력이 되는데, 1 또는 -1이 된다.

 

2-2. 단층 퍼셉트론을 이용한 AND게이트, OR게이트 구현, 단층 퍼셉트론의 한계

from sklearn.linear_model import Perceptron
import numpy as np

# AND게이트 생성 
# 샘플 데이터 생성
X_and = np.array([[0,0], [0,1], [1,0], [1,1]])
y_and = np.array([0, 0, 0, 1])
# 이미 활성화함수, 단계함수가 포함되어 있기 때문에 따로 정의 안해줘도 됨

percept = Perceptron(tol=0.001, random_state = 0)
percept.fit(X = X_and, y = y_and)
print('AND: ', percept.predict(X_and))

# OR게이트 생성
#샘플 데이터 생성
X_or = np.array([[0,0], [0,1], [1,0], [1,1]])
y_or = np.array([0, 1, 1, 1])
# 이미 활성화함수, 단계함수가 포함되어 있기 때문에 따로 정의 안해줘도 됨

percept = Perceptron(tol=0.001, random_state = 0)
percept.fit(X = X_or, y = y_or)
print('O R: ', percept.predict(X_or))

# XOR게이트 생성
#샘플 데이터 생성
X_xor = np.array([[0,0], [0,1], [1,0], [1,1]])
y_xor = np.array([0, 1, 1, 0])
# 이미 활성화함수, 단계함수가 포함되어 있기 때문에 따로 정의 안해줘도 됨

percept = Perceptron(tol=0.001, random_state = 0)
percept.fit(X = X_xor, y = y_xor)
print('XOR: ', percept.predict(X_xor))

AND게이트와 OR게이트는 구현이 잘 되었지만, XOR게이트의 구현에는 한계가 발생했다. 한 개의 선형 함수로는 XOR게이트를 구현할 수 없는 한계점이 존재했다. 그렇기 때문에 다층 퍼셉트론을 고안해냈다.

 

 

2-3. 다층 퍼셉트론 (Multi Layer Perceptron)

입력층과 출력층 사이에 은닉층을 가지고 있는 퍼셉트론, 은닉층의 개수에 따라서 최적의 활성화 함수를 사용해야한다.

다층 퍼셉트론은 층마다 가중치에 대해 선형 방정식을 계산하기 때문에 층과 층 사이에서 선형으로 표현된 데이터를 비선형으로 바꿔주는 과정이 필요하다. 이 과정을 담당하는 것이 바로 활성화 함수이다.

1. Sigmoid 

# sigmoid 활성화 함수에 대한 정의
def sigmoid(x:float) -> float:
    return 1.0/(1.0 + np.exp(-x))

x = np.arange(-10.0, 10.0, 0.1)
y = sigmoid(x)
plt.plot(x, y)
plt.show()

다음과 같이 출력된다. Sigmoid함수를 이용하면 모든 값에 대해 0부터 1까지 사이의 값으로 바꾸어준다. 

 

2. tanH

x = np.linspace(-np.pi, np.pi, 60)
# 별도의 tanH 활성화 함수를 정의하지 않아도 numpy에서 지원하기 때문에 해당 함수 사용
y = np.tanh(x)

plt.plot(x, y)
plt.show()

tanH함수는 모든 값에 대해 -1부터 1 사이 값으로 표현한다. 

 

3. ReLU

# ReLU 활성화 함수 정의
def relu(x:float) -> int:
    return np.maximum(x, 0) # 0보다 크면 자기자신

x = np.arange(-10.0, 10.0, 0.1)
y = relu(x)
plt.plot(x, y)
plt.show()

ReLU함수는 0이하의 값은 모두 0으로 처리하고, 나머지 값에 대해서는 모두 자기 자신을 반환하도록 한다.

 

활성화 함수를 알아보았으니, 실제로 다층 퍼셉트론에서 학습하는 과정을 살펴보자.

우측 방향으로 진행이 되고, 입력층에서는 입력을 받고, 은닉층과 출력층에서 실질적으로 학습이 이루어진다. 모든 경우의 수를 따지기 때문에 

2-4. 텐서플로우 (TensorFlow)를 이용한 XOR게이트 구현

텐서플로우는 구글에서 제공하는 딥러닝 라이브러리 중 하나이다. 오픈소스로 제공해주며, Tensorflow2.0에 들어서면서 keras와 합쳐졌다. 그렇기 때문에 높은 호환성을 보인다. Tensorflow를 이용해 XOR게이트를 구현해보자.

import tensorflow as tf 

# 입력값과 출력값 설정
x = tf.constant([[0,0], [0,1], [1,0], [1,1]])
y = tf.constant([0, 1, 1, 0])

# Model 불러오기
model = tf.keras.models.Sequential([], name = 'XOR_Model')
# 은닉층 설정
model.add(tf.keras.layers.Dense(units=2, input_shape = (2,), activation = 'sigmoid', name = 'LAYER1'))
# 출력층 설정
model.add(tf.keras.layers.Dense(units=1,  activation = 'sigmoid', name = 'OUTPUT'))

# 모델에 대한 설명 요약
model.summary()
#모델의 학습률, 오차범위 방식 설정
model.compile(optimizer=tf.keras.optimizers.SGD(0.3), loss = 'mse')
# 입력값과 출력 값에 대한 학습 진행. 진행 횟수는 10,000
model.fit(x, y, epochs = 10_000)

# 결과 출력
print(model.predict(x))

이렇게 하면 높은 정확도를 가진 XOR게이트를 구현할 수 있다. 

위와 같이 출력이 되고, 높은 정확로 XOR게이트를 구현하였다.

 

3. MLP 예제 1

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Input

# 데이터 불러오기
df = pd.read_csv(filepath_or_buffer='./pima-indians-diabetes3.csv')
print(df.head())
print(df['diabetes'].value_counts())
print(df.describe())

# 히트맵 그리기
print(df.corr())
color_map = plt.cm.gist_heat # 그래프의 상관관계
plt.figure(figsize=(12,12))
sns.heatmap(df.corr(), linewidths=0.1, vmax=0.5,
             cmap = color_map, linecolor='white',
             annot=True)
plt.show()

df = pd.read_csv(filepath_or_buffer='./pima-indians-diabetes3.csv')
x = df.iloc[:, 0:8]
y = df.iloc[:, 8]


model = Sequential(name = 'PIMA_INDIANS') # 모델 생성
model.add(Input(shape = (8,))) # 입력층 설정
model.add(Dense(units = 12, activation = 'relu', name = 'LAYER1')) # 은닉층1 설정
model.add(Dense(units = 8, activation = 'relu', name = 'LAYER2')) # 은닉층2 설정
model.add(Dense(units = 1, activation = 'relu', name = 'OUTPUT')) # 출력층 설정

model.summary() # 모델 요약

model.compile(loss = 'binary_crossentropy', optimizer = 'adam', metrics =['accuracy'])
# 모델의 학습률, 오차범위 계산법 설정
model.fit(x, y, epochs = 1000) # 모델 학습
y_predict = model.predict(x) # 학습된 모델을 이용하여 x값 예측
print(y_predict)
print(y)

plt.plot(y_predict, y, 'b.') # 시각화
plt.show()