import numpy as np
# Neural network class를 기능을 추가하여 다시 정의하는 코드입니다.
# "def feed_forward(self, X):"부분을 추가로 정의한 것을 볼 수 있습니다.
class NeuralNetwork:
def __init__(self):
# 신경망의 구조를 결정합니다. 입력층 2 노드, 은닉층 3 노드, 출력층 1 노드
self.inputs = 2
self.hiddenNodes = 3
self.outputNodes = 1
# 가중치를 초기화 합니다.
# layer 1 가중치 (2x3)
self.w1 = np.random.randn(self.inputs,self.hiddenNodes)
# layer 2 가중치 (3x1)
self.w2 = np.random.randn(self.hiddenNodes, self.outputNodes)
def sigmoid(self, s):
return 1 / (1+np.exp(-s))
def feed_forward(self, X):
# 가중합 계산
self.hidden_sum = np.dot(X, self.w1)
# 활성화함수
self.activated_hidden = self.sigmoid(self.hidden_sum)
# 출력층에서 사용할 은닉층의 각 노드의 출력값을 가중합 합니다.
self.output_sum = np.dot(self.activated_hidden, self.w2)
# 출력층 활성화, 예측값을 출력합니다.
self.activated_output = self.sigmoid(self.output_sum)
return self.activated_output
# 예측을 수행해 봅시다.
nn = NeuralNetwork()
print(X[0])
output = nn.feed_forward(X[0])
print("예측값: ", output)
error = y[0] - output
# 모든 데이터를 예측해보고 에러값을 계산해 보겠습니다.
# print(X)
output_all = nn.feed_forward(X)
error_all = y - output_all
print(output_all)
print(error_all)
역전파
import numpy as np
# 음수 가중치를 가지는 활성화는 낮추고, 양수 가중치를 가지는 활성화는 높이고 싶습니다.
class NeuralNetwork:
def __init__(self):
# 신경망의 구조를 결정합니다. 입력층 2 노드, 은닉층 3 노드, 출력층 1 노드 / Bias 없음.
self.inputs = 2
self.hiddenNodes = 3
self.outputNodes = 1
# 가중치를 초기화 합니다.
# layer 1 가중치 (2x3)
self.w1 = np.random.randn(self.inputs,self.hiddenNodes)
# layer 2 가중치 (3x1)
self.w2 = np.random.randn(self.hiddenNodes, self.outputNodes)
def sigmoid(self, s):
return 1 / (1+np.exp(-s))
def sigmoidPrime(self, s):
sx = self.sigmoid(s)
return sx * (1-sx)
def feed_forward(self, X):
# 가중합 계산
self.hidden_sum = np.dot(X, self.w1)
# 활성화함수
self.activated_hidden = self.sigmoid(self.hidden_sum)
# 출력층에서 사용할 은닉층의 각 노드의 출력값을 가중합 합니다.
self.output_sum = np.dot(self.activated_hidden, self.w2)
# 출력층 활성화, 예측값을 출력합니다.
self.activated_output = self.sigmoid(self.output_sum)
return self.activated_output
def backward(self, X, y, o):
# 역전파 알고리즘
# 출력층의 손실값 (Error) 입니다.
self.o_error = y - o
# 출력층 활성화함수인 시그모이드 함수의 도함수를 사용합니다. (dE / dY * dY / dy) - Latter A
self.o_delta = self.o_error * self.sigmoidPrime(o)
# z2 error: 출력층의 가중치가 얼마나 에러에 기여했는지
self.z2_error = self.o_delta.dot(self.w2.T)
# z2 delta: 시그모이드 도함수를 z2 error에 적용합니다. (d_HiddenE / dY) * (dY / dy) - Latter
self.z2_delta = self.z2_error*self.sigmoidPrime(self.output_sum)
# w1를 업데이트 합니다.
self.w1 += X.T.dot(self.z2_delta) # X * dE/dY * dY/dy(=Y(1-Y))
# w2를 업데이트 합니다.
self.w2 += self.activated_hidden.T.dot(self.o_delta) # H1 * Y(1-Y) * (Y - o) # (Latter A)
def train(self, X,y):
o = self.feed_forward(X)
self.backward(X,y,o)