Table of Contents
11라인의 파이선 코드로 설명하는 신경망
머신 러닝 공부할 때 가장 많이 도움이 된 코드입니다.
코드
X = np.array([ [0,0,1],[0,1,1],[1,0,1],[1,1,1] ])
y = np.array([[0,1,1,0]]).T
syn0 = 2*np.random.random((3,4)) - 1
syn1 = 2*np.random.random((4,1)) - 1
for j in range(60000):
l1 = 1/(1+np.exp(-(np.dot(X,syn0))))
l2 = 1/(1+np.exp(-(np.dot(l1,syn1))))
l2_delta = (y - l2)*(l2*(1-l2))
l1_delta = l2_delta.dot(syn1.T) * (l1 * (1-l1))
syn1 += l1.T.dot(l2_delta)
syn0 += X.T.dot(l1_delta)
단지 11줄의 코드로 머신러닝을 설명하고 있습니다.
심지어 공식도 없고 뭐도 없습니다.
라인 1-2
머신 러닝은 알고있는 입력값과 출력값을 기반으로 인공지능망(network) 을 학습시키고, 학습된 망(network) 을 이용해 새로운 입력값이 출력값을 생성하는 방식입니다.
import numpy as np
X = np.array([
[0,0,1],
[0,1,1],
[1,0,1],
[1,1,1]
])
y = np.array([
[0,1,1,0]
]).T
print(y)
위에서 4개의 입력값(X) 과 4개의 출력값(y) 이 있습니다.
입력값 [0,0,1]
에 대해 출력값 0
, 입력값 [0,1,1]
에 대해 출력값 1
등이 대응합니다.
라인 3-4
syn0 = 2*np.random.random((3,4)) - 1
syn1 = 2*np.random.random((4,1)) - 1
랜덤값으로 신경망을 초기화합니다.
X
와 y
사이에 -1 ~ 1
사이의 랜덤값으로 구성된 행렬을 배치합니다. 학습은 이 랜덤값을 적절한 값으로 교정해 나가는 과정입니다.
라인 5-7
for j in xrange(60000):
l1 = 1/(1+np.exp(-(np.dot(X,syn0))))
l2 = 1/(1+np.exp(-(np.dot(l1,syn1))))
위 내용을 함수를 생성해서 정리해 봅니다.
# sigmoid function
def nonlin(x,deriv=False):
if(deriv==True):
return x*(1-x)
return 1/(1+np.exp(-x))
for j in range(60000):
# forward propagation
l0 = X
l1 = nonlin(np.dot(l0,syn0))
l2 = nonlin(np.dot(l1,syn1))
X
를 첫번째 레이어 l0
에 대입합니다.
l0
을 syn0
과 도트연산 후 sigmoid
함수에 입력합니다.
다시, l1
을 syn1
과 도트연산 후 sigmoid
함수에 입력합니다.
라인 8-9
for j in range(60000):
# ......
l2_delta = (y - l2)*(l2*(1-l2))
l1_delta = l2_delta.dot(syn1.T) * (l1 * (1-l1))
위 내용도 다시 풀어 봅니다.
for j in range(60000):
# how much did we miss?
l2_error = y - l2
l2_delta = l2_error * nonlin(l2,True)
l1_delta = l2_delta.dot(syn1.T) * nonlin(l1,True)
y - l2
로 출력값과 계산값의 오차를 구합니다.
랜덤값으로 연산을 했으므로 당연히 오차가 발생합니다.
라인 10-11
위에서 구한 델타값을 이용해 신경망을 교정합니다.
for j in range(60000):
# ......
syn1 += l1.T.dot(l2_delta)
syn0 += X.T.dot(l1_delta)
테스트 하기
위의 신경망이 정상적으로 업데이트 되었는지 확인해 봅니다.
이미 알고있는 [1,1,1]
값을 이용해 0
이 출력되는지 확인해 봅니다.
아직 알지 못하는 [1,1,0]
값을 입력해 결과값을 예측해봅니다.
X_test = np.array([
[1,1,1],
[1,1,0]
])
l0 = X_test
l1 = nonlin(np.dot(l0,syn0))
l2 = nonlin(np.dot(l1,syn1))
print(l2)
[[0.00284545]
[0.99835627]]
정확히 0
이 아니라 0.00284545 이 출력됩니다.