Neural Networks in XOR problem
본 장에서는 Neural network을 약 20년간 암흑기에 빠지게한 XOR
문제에 대해서 다뤄 보겠다.
우선 직관적으로 Hiddlen Layer
를 통해서 XOR 문제를 해결 하는 방법을 알아보고
두 번째로 Backpropagation Algorithm을 이용해서 기계적으로 학습을 통해서 Weight 값을 알아내는 방법을 알아본다.
마지막으로 TensorFlow
를 통해서 이를 각각 구현해 보도록 한다.
XOR using NN
아래와 같은 weight들로 구성 되어져 있다고 가정 하자.
생각해 볼것은 여기서 주어진 wegiht들 이외에 XOR 문제를 풀수 있는 새로운 W
와 b
를 찾을 수 있을까?
그리고 Vectorazation
을 이용해서 좀 더 간소화 시킬 수 도 있다.
# Our hypothesis
K = tf.sigmoid(tf.matmul(X, W1) + b1)
hypothesis = tf.sigmoid(tf.matmul(K, W2) + b2)
Backpropagation
MIT AI Lab의 창시자 Marvin Minsky가 말했던
No one on earth had found a viable way to train MLPs good enough to learn such simple functions.
Forwarding 방식으로는 Derivation을 계산하기가 너무 어렵다.
따라서 제안된 방식이 Backpropagation
이다.
기본적으로 Back propagation은 미분학의 chain rule을 사용하는 방식이다.
여기서 chain rule
이란 아래의 미분 공식을 말한다.
함수 $f(g(x))$의 미분값은 아래의 방식으로 계산 할 수 있다.
$$\frac{\partial f}{\partial x}=\frac{\partial f}{\partial g}\frac{\partial g}{\partial x}$$
이제 아래와 같은 간단한 함수를 생각해 보자.
$$f=Wx+b, g=Wx, f=g+b$$
그리고 이것을 chain rule
을 통해서 모두 계산 할 수 있게 된다. 즉 결과 f에 미치는 각각의 term들의 영향을 계산할 수 있는 것이다.
- forward (w=-2, x=5, b=3)
- backward
이제 각각의 계산하면
w = -2
x = 5
b = 3
g = -10
f = -7
그리고 계산의 편의를 위해서 각각의 partial derivative
를 모두 계산해 보자.
$$\frac{\partial g}{\partial w}=x$$
$$\frac{\partial g}{\partial x}=w$$
$$\frac{\partial f}{\partial g}=1$$
$$\frac{\partial f}{\partial b}=1$$
이제 편미분 값을 이용해서 f에 미치는 영향을 각각 계산하면 아래와 같다.
위 값을 해석해보면 결국 1
이라는 것은 1:1
영향 관계를 나타내고5
는 5배
만큼 영향을 미친다는 것이다.
즉 b=3
에서 b=4
로 증가시킬 경우 f
의 값은 -6
이 된다. 즉 1
만큼 차이가 생긴다.
반대로 w
를 -3
으로 변경 시키면 f
는 -12
되므로 -5
만큼 값이 증가하게 된다. 5배
의 영향을 미치는 것을 알 수 있다.
이러한 방법을 이용해서 아무리 복잡해서 모두 계산 할 수 있다.
Neural network implementation
How can we learn W1, W2, B1, B2 from training data ?
구현 방법에 대해서 알아 보겠다.
지난번 logistic regression code에서 약간만 더 수정하면 된다.
W1 = tf.Variable(tf.random_uniform([2, 2], -1.0, 1.0))
W2 = tf.Variable(tf.random_uniform([2, 1], -1.0, 1.0))
b1 = tf.Variable(tf.zeros([2]), name="Bias1")
b2 = tf.Variable(tf.zeros([1]), name="Bias1")
# Our hypothesis
L2 = tf.sigmoid(tf.matmul(X, W1) + b1)
hypothesis = tf.sigmoid(tf.matmul(L2, W2) + b2)
위와 같이 구현하면 쉽게 두개의 layer가 존재하는 neural network을 구성한 것이 된다.
전체소스코드는 아래와 같다.
기본적으로 변경된 것은 아래와 같다.
1) hypothesis를 위와 같이 변경 했다.
2) 입력 데이터 형테를 변경 했다.
변경전
[[ 0, 0, 1, 1],
[ 0, 1, 0, 1]]
변경후
[[0, 0],
[0, 1],
[1, 0],
[1, 1]]
3) Learning rate과 interation을 조정했다. converge하는데 시간이 너무 오래 걸린다.
import tensorflow as tf
import numpy as np
xy = np.loadtxt('train.txt', unpack=True)
#x_data = xy[0:-1]
x_data = np.transpose(xy[0:-1])
#y_data = xy[-1]
y_data = np.reshape(xy[-1], (4, 1))
X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)
W1 = tf.Variable(tf.random_uniform([2, 2], -1.0, 1.0))
W2 = tf.Variable(tf.random_uniform([2, 1], -1.0, 1.0))
b1 = tf.Variable(tf.zeros([2]), name="Bias1")
b2 = tf.Variable(tf.zeros([1]), name="Bias1")
# Our hypothesis
L2 = tf.sigmoid(tf.matmul(X, W1) + b1)
hypothesis = tf.sigmoid(tf.matmul(L2, W2) + b2)
# Cost function
cost = -tf.reduce_mean(Y*tf.log(hypothesis) + (1-Y)*tf.log(1-hypothesis))
# Minimize
a = tf.Variable(0.1) # Learning rate, alpha
optimizer = tf.train.GradientDescentOptimizer(a)
train = optimizer.minimize(cost)
# Before starting, initialize the variables. We will `run` this first.
init = tf.initialize_all_variables()
# Launch the graph,
with tf.Session() as sess:
sess.run(init)
# Fit the line.
for step in xrange(10000):
sess.run(train, feed_dict={X:x_data, Y:y_data})
if step % 200 == 0:
print step, sess.run(cost, feed_dict={X:x_data, Y:y_data}), sess.run(W1), sess.run(W2)
# Test model
correct_prediction = tf.equal(tf.floor(hypothesis+0.5), Y)
# Calculate accuracy
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
print sess.run([hypothesis, tf.floor(hypothesis+0.5), correct_prediction, accuracy], feed_dict={X:x_data, Y:y_data})
print "Accuracy:", accuracy.eval({X:x_data, Y:y_data})
재치환 오류 계산 코드 설명
# Test model
correct_prediction = tf.equal(tf.floor(hypothesis+0.5), Y)
# Calculate accuracy
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
print sess.run([hypothesis, tf.floor(hypothesis+0.5), correct_prediction, accuracy], feed_dict={X:x_data, Y:y_data})
print "Accuracy:", accuracy.eval({X:x_data, Y:y_data})
tf.floor(hypothesis+0.5)
는 0~1 사이의 값을 나오게 한다.
그리고 Y
의 실제 값과 비교를 한다.
이러한 기능을 하는 함수 correct_prediction
를 디자인 한것이다.
accuracy
는 평균을 구하는 것이다.
[hypothesis, tf.floor(hypothesis+0.5), correct_prediction, accuracy],
feed_dict={X:x_data_testing, Y:y_data_testing}
print "Accuracy:", accuracy.eval({X:x_data_testing, Y:y_data_testing})
실행결과
9800 0.0402879 [[-6.13605404 -4.11170053]
[-6.11376047 -4.1088109 ]] [[-8.83549595]
[ 8.12334061]]
[array([[ 0.02604489],
[ 0.96690428],
[ 0.96695912],
[ 0.05478531]], dtype=float32), array([[ 0.],
[ 1.],
[ 1.],
[ 0.]], dtype=float32), array([[ True],
[ True],
[ True],
[ True]], dtype=bool), 1.0]
Accuracy: 1.0
cost가 0.04로 0에 근접하는 것을 알 수 있다.
'AI > TensorFlow, PyTorch, Keras, Scikit' 카테고리의 다른 글
Naive Bayes vs Neural network (2) | 2016.04.25 |
---|---|
Softmax Function (0) | 2016.04.19 |
Logistic Regression (0) | 2016.04.17 |
Linear regression with TensorFlow (0) | 2016.04.17 |
TensorFlow 개발환경 ( Eclipse + PyDev, Pycharm, Jupyter) (0) | 2015.11.17 |