환경 변수 설정하기
실제 값이 될 XOR 진리표는 다음과 같다.
먼저 두 개의 입력 값과 한 개의 타깃 값으로 먼저 설정하겠습니다. 실행 횟수, 학습률, 모멘텀 계수도 설정하겠습니다.
import random
import numpy as np
# 환경 변수 지정
# 입력값 및 타깃 값
data = [
[[0, 0], [0]],
[[0, 1], [1]],
[[1, 0], [1]],
[[1, 1], [0]]
]
# 실행 횟수(iterations), 학습률(lr), 모멘텀 계수(mo) 설정
iterations=5000
lr=0.1
mo=0.4
# 활성화 함수 - 1. 시그모이드
# 미분할 때와 아닐 때의 각각의 값
def sigmoid(x, derivative=False):
if (derivative == True):
return x * (1 - x)
return 1 / (1 + np.exp(-x))
# 활성화 함수 - 2. tanh
# tanh 함수의 미분은 1 - (활성화 함수 출력의 제곱)
def tanh(x, derivative=False):
if (derivative == True):
return 1 - x ** 2
return np.tanh(x)
# 가중치 배열 만드는 함수
def makeMatrix(i, j, fill=0.0):
mat = []
for i in range(i):
mat.append([fill] * j)
return mat
파이썬 코드로 실행하는 신경망
신경망을 실행하는 클래스는 초깃값의 지정, 업데이트 함수, 역전파 함수로 구성됩니다.
# 신경망의 실행
class NeuralNetwork:
# 초깃값의 지정
def __init__(self, num_x, num_yh, num_yo, bias=1):
# 입력값(num_x), 은닉층 초깃값(num_yh), 출력층 초깃값(num_yo), 바이어스
self.num_x = num_x + bias # 바이어스는 1로 지정(본문 참조)
self.num_yh = num_yh
self.num_yo = num_yo
# 활성화 함수 초깃값
self.activation_input = [1.0] * self.num_x
self.activation_hidden = [1.0] * self.num_yh
self.activation_out = [1.0] * self.num_yo
# 가중치 입력 초깃값
self.weight_in = makeMatrix(self.num_x, self.num_yh)
for i in range(self.num_x):
for j in range(self.num_yh):
self.weight_in[i][j] = random.random()
# 가중치 출력 초깃값
self.weight_out = makeMatrix(self.num_yh, self.num_yo)
for j in range(self.num_yh):
for k in range(self.num_yo):
self.weight_out[j][k] = random.random()
# 모멘텀 SGD를 위한 이전 가중치 초깃값
self.gradient_in = makeMatrix(self.num_x, self.num_yh)
self.gradient_out = makeMatrix(self.num_yh, self.num_yo)
# 업데이트 함수
def update(self, inputs):
# 입력 레이어의 활성화 함수
for i in range(self.num_x - 1):
self.activation_input[i] = inputs[i]
# 은닉층의 활성화 함수
for j in range(self.num_yh):
sum = 0.0
for i in range(self.num_x):
sum = sum + self.activation_input[i] * self.weight_in[i][j]
# 시그모이드와 tanh 중에서 활성화 함수 선택
self.activation_hidden[j] = tanh(sum, False)
# 출력층의 활성화 함수
for k in range(self.num_yo):
sum = 0.0
for j in range(self.num_yh):
sum = sum + self.activation_hidden[j] * self.weight_out[j][k]
# 시그모이드와 tanh 중에서 활성화 함수 선택
self.activation_out[k] = tanh(sum, False)
return self.activation_out[:]
# 역전파의 실행
def backPropagate(self, targets):
# 델타 출력 계산
output_deltas = [0.0] * self.num_yo
for k in range(self.num_yo):
error = targets[k] - self.activation_out[k]
# 시그모이드와 tanh 중에서 활성화 함수 선택, 미분 적용
output_deltas[k] = tanh(self.activation_out[k], True) * error
# 은닉 노드의 오차 함수
hidden_deltas = [0.0] * self.num_yh
for j in range(self.num_yh):
error = 0.0
for k in range(self.num_yo):
error = error + output_deltas[k] * self.weight_out[j][k]
# 시그모이드와 tanh 중에서 활성화 함수 선택, 미분 적용
hidden_deltas[j] = tanh(self.activation_hidden[j], True) * error
# 출력 가중치 업데이트
for j in range(self.num_yh):
for k in range(self.num_yo):
gradient = output_deltas[k] * self.activation_hidden[j]
v = mo * self.gradient_out[j][k] - lr * gradient
self.weight_out[j][k] += v
self.gradient_out[j][k] = gradient
# 입력 가중치 업데이트
for i in range(self.num_x):
for j in range(self.num_yh):
gradient = hidden_deltas[j] * self.activation_input[i]
v = mo*self.gradient_in[i][j] - lr * gradient
self.weight_in[i][j] += v
self.gradient_in[i][j] = gradient
# 오차의 계산(최소 제곱법)
error = 0.0
for k in range(len(targets)):
error = error + 0.5 * (targets[k] - self.activation_out[k]) ** 2
return error
# 학습 실행
def train(self, patterns):
for i in range(iterations):
error = 0.0
for p in patterns:
inputs = p[0]
targets = p[1]
self.update(inputs)
error = error + self.backPropagate(targets)
if i % 500 == 0:
print('error: %-.5f' % error)
# 결괏값 출력
def result(self, patterns):
for p in patterns:
print('Input: %s, Predict: %s' % (p[0], self.update(p[0])))
if __name__ == '__main__':
# 두 개의 입력 값, 두 개의 레이어, 하나의 출력 값을 갖도록 설정
n = NeuralNetwork(2, 2, 1)
# 학습 실행
n.train(data)
# 결괏값 출력
n.result(data)
# Reference: http://arctrix.com/nas/python/bpnn.py (Neil Schemenauer)
'이론 > 모두의 딥러닝' 카테고리의 다른 글
< 다섯째 마당 > 딥러닝 활용하기 (0) | 2023.02.17 |
---|---|
< 넷째 마당 > 딥러닝 기본기 다지기 (0) | 2023.02.15 |
< 심화 학습1 > 오차 역전파의 계산법 (0) | 2023.02.06 |
< 셋째 마당 > 딥러닝의 시작, 신경망 (1) | 2023.02.05 |
<둘째 마당> 예측 모델의 기본 원리 (0) | 2023.02.03 |