안녕하세요.
이번 포스팅에서는 우리가 딥러닝 이론에서 배웠던 XOR 문제를 텐서플로우로 해결해보도록 하겠습니다.
이론적인 부분은 아래 글에서 설명드렸기에, 코드에 대한 이야기를 주로 할 것 같습니다. 딥러닝에 대한 기본적인 이론이기에 잘 이해가 안되시는 분들은 아래 글을 참고해주세요.
* 해당 포스트의 모든 내용은 김성훈 교수님의 '모두를 위한 딥러닝'을 바탕으로 제작되었습니다.
관련한 상세 내용은 아래 링크를 참고해주세요.
1. XOR data set
먼저 XOR이 어떤건지 간단히 살펴보겠습니다.
XOR은 위에서 가운데에 있는 심볼로 나타냅니다. 그리고 우리에게 필요한 데이터, truth table은 그 오른쪽 표와 같이 나와있습니다. 두 개의 input이 입력되고, input값이 서로 같을 때는 0을 출력하고, input값이 서로 다를 때는 1을 출력합니다.
이것을 텐서플로우에서 데이터로 입력해본다면 아래와 같은 코드로 입력됩니다.
1 2 | x_data = np.array([[0,0], [0,1], [1,0], [1,1]], dtype=np.float32) y_data = np.array([[0], [1], [1], [0]], dtype=np.float32) | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import tensorflow as tf import numpy as np x_data = np.array([[0,0], [0,1], [1,0], [1,1]], dtype=np.float32) y_data = np.array([[0], [1], [1], [0]], dtype=np.float32) X = tf.placeholder(tf.float32) Y = tf.placeholder(tf.float32) W = tf.Variable(tf.random_normal([2,1]), name = "weight") b = tf.Variable(tf.random_normal([1]), name = "bias") # hypothesis: sigmoid(X * W + b) hypothesis = tf.sigmoid(tf.matmul(X, W) + b) # cost function / minimize cost cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) * tf.log(1 - hypothesis)) train = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost) # predicate / accuracy predicated = tf.cast(hypothesis > 0.5, dtype=tf.float32) accuracy = tf.reduce_mean(tf.cast(tf.equal(predicated, Y), dtype=tf.float32)) # with tf.Session() as sess: sess.run(tf.global_variables_initializer()) for step in range(10001): sess.run(train, feed_dict={X: x_data, Y: y_data}) if step%100 == 0: print(step, sess.run(cost, feed_dict={X: x_data, Y: y_data}), sess.run(W)) h, c, a = sess.run([hypothesis, predicated, accuracy], feed_dict={X: x_data, Y: y_data}) print("\nHypothesis: ",h,"\nCorrect: ",c,"\nAccuracy: ",a) | cs |
결과에서 무언가 이상함을 느끼셨나요?
Accuracy가 0.5라는 값으로 출력되었습니다.
하지만 이는 이상한 것이 아닙니다.
우리가 이론시간에서 알아보았듯이, 하나의 node로, 그래프에서 생각해본다면 linear한 직선하나로 XOR 문제를 푸는 것은 불가능 하다고 했었죠.
그래서 우리는 layer라는 개념을 통해 여러개의 모델을 사용하고 이를 연결하는 방법을 배웠습니다. 그럼 그러한 방법으로 다시 시도해보도록 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import tensorflow as tf import numpy as np x_data = np.array([[0,0], [0,1], [1,0], [1,1]], dtype=np.float32) y_data = np.array([[0], [1], [1], [0]], dtype=np.float32) X = tf.placeholder(tf.float32) Y = tf.placeholder(tf.float32) # W = tf.Variable(tf.random_normal([2,1]), name = "weight") # b = tf.Variable(tf.random_normal([1]), name = "bias") # hypothesis = tf.sigmoid(tf.matmul(X, W) + b) W1 = tf.Variable(tf.random_normal([2,2]), name="weight1") b1 = tf.Variable(tf.random_normal([2]), name="bias1") layer1 = tf.sigmoid(tf.matmul(X, W1) + b1) W2 = tf.Variable(tf.random_normal([2,1]), name="weight2") b2 = tf.Variable(tf.random_normal([1]), name="bias2") hypothesis = tf.sigmoid(tf.matmul(layer1, W2) + b2) # cost function / minimize cost cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) * tf.log(1 - hypothesis)) train = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost) # predicate / accuracy predicated = tf.cast(hypothesis > 0.5, dtype=tf.float32) accuracy = tf.reduce_mean(tf.cast(tf.equal(predicated, Y), dtype=tf.float32)) # with tf.Session() as sess: sess.run(tf.global_variables_initializer()) for step in range(10001): sess.run(train, feed_dict={X: x_data, Y: y_data}) if step%1000 == 0: print(step, sess.run(cost, feed_dict={X: x_data, Y: y_data}), sess.run([W1, W2])) h, c, a = sess.run([hypothesis, predicated, accuracy], feed_dict={X: x_data, Y: y_data}) print("\nHypothesis: ",h,"\nCorrect: ",c,"\nAccuracy: ",a) | cs |
처음에 나왔던 결과와 다르게, 모델이 제대로 훈련되어 Accuracy 값으로 1이 출력되었습니다.
위의 코드에서 빨간색 줄 그어져 있는 부분을 보겠습니다.
처음의 [2,2] 는 x의 입력이 2개이기 때문에 앞의 숫자 2가 나오고, 뒤의 숫자2는 임의로 출력을 2개로 한 것입니다.
그리고 b1에 있는 [2]는 W1에서 출력을 2로 했으므로 같이 맞춰주는 것입니다.
그리고 아래의 [2,1] 에서는 위에서 출력한 2개를 입력으로 받기 때문에 앞의 숫자2가 나오고, 우리가 최종적으로 출력하는 Y는 1개의 출력값을 가지므로 1, 한개로 출력하고 b2도 이와 함께 맞추어 준 것입니다.
즉, 이것을 그림으로 나타내면 아래와 같습니다.
그럼 다시 돌아와서, 우리가 보다 더 정확하게 예측할 수 있는 방법 중에 하나는, 위에 그림에서 두개의 모델 사이의 연결선을 증가시키는 방법입니다.
즉, 그림으로 생각하면 다음과 같이 되겠으며
코드로는 다음과 같이 구현이 되겠습니다.
그리고 이러한 변화를 결과로 확인해보면 다음과 같습니다.
모델을 보다 더 Wide 하기전과 비교해본다면, hypothsis의 작은 값은 더 작게, 큰 값은 더 크게 되는 것을 확인하실 수 있습니다.
예측율을 높이는 다른 방법은 layer를 더 깊게 만드는 것입니다.
코드로 보면 아래와 같이, 단순하게 layer를 총 4개 사용하였습니다.
그리고 그 결과는 역시, 처음보다 더 좋은 예측율을 보여줍니다.
'AI & BigData > 모두를 위한 딥러닝(정리)' 카테고리의 다른 글
딥러닝(DeepLearning) #4_ ReLU::Rectified Linear Unit (0) | 2018.04.19 |
---|---|
텐서플로우(Tensor Flow) #13_ TensorBoard 사용하기 (0) | 2018.04.19 |
딥러닝(DeepLearning) #3_ Backpropagation (0) | 2018.04.17 |
딥러닝(DeepLearning) #2_ XOR using Neural Nets(NN) (0) | 2018.04.12 |
텐서플로우(Tensor Flow) #11_ TensorFlow Manipulation (0) | 2018.04.11 |