AND 로직 문제는 N=2 에 해당하는 즉 조도센서(Photocell)가 2개인 Rosenblatt의 퍼셉트론 문제로 귀착이 된다. 물론 더 이상 Rosenblatt의 웨이트 업데이트 방식을 적용할 필요는 없으며 Softmax 또는 Sigmoid 함수를 사용하여 머신 러닝이 가능하다.
AND 로직 문제는 OR 로직 문제에서와 마찬가지로 2개의 입력 센서를 가지는 Rosenblatt의 퍼셉트론에서 2개의 라벨을 “+1”과 “-1”이 아닌 “1”과 “0” 으로 학습하는 경우로 보면 될 것이다.
최소제곱법에 의한 학습결과 hypothesis의 3차원 그래픽 처리 결과에 따르면 학습 지점에서 주어진 출력 값과 계산된 hypothesis 값들이 분리선을 설정함에는 아무런 문제가 없으나 출력 값과의 차이가 25%로 의외로 큰 편이다.
AND 로직 문제도 Binary Classification 문제이므로 Softmax 와 Sigmoid 확률분포 함수 기법 모두 다 적용이 가능하므로 최소제곱법에서 학습에 의해 발생하는 갭을 줄여 보도록 하자.
다시 말하자면 Softmax 나 Sigmoid 계산법에서는 출력 값 y에 대한 아날로그적인 숫자 값이 직접 나오는 것이 아니라 각각의 y 값에 대해 부여한 라벨 값에 대한 확률 값이 출력된다. 하지만 y에 대한 아날로그적인 숫자 값이 각각 0.0 과 1.0임에 대하여 라벨 값도 “0”과 “1” 로 둔 사실을 유의하자.
Softmax 기법 적용을 위해서는 4개의 입력 데이터 세트를 변수명 x_data로 리스트 데이터화 하자.
x_data =[ [ 0, 0 ], [ 1, 0 ], [ 0, 1 ], [ 1, 1 ] ]
각각의 데이터에 대해 출력 값 y 를 라벨 값으로 택하고 “0”은 [ 1, 0 ] “1”은 [ 0, 1 ] 로 one hot code를 부여한다. learning rate = 0.1로 두고 steps 수를 2000회로 두고 학습 후에 hypothesis를 출력해 보자.
[[9.9980253e-01 1.9746594e-04]
[9.5087612e-01 4.9123954e-02]
[9.5087522e-01 4.9124796e-02]
[6.8901218e-02 9.3109882e-01]] [0 0 0 1]
즉 입력 데이타 [ 0, 0 ] 이 라벨 값 “0” 이 될 확률이 99.98% 라는 의미이며 [ 1, 1 ] 이 라벨 값 “1”이 될 확률은 93.1% 이다. 확률이긴 하지만 최소제곱법의 25% 에 비해 훨씬 정확하다고 볼 수 있다.
Sigmoid 함수를 사용할 경우에는 단지 softmax 명령을 sigmoid로 바꾸로 cost 함수를 sigmoid용으로 바꾸어 주면 되므로 결과만 검토하기로 하자.
[[0.99133533 0.00907968]
[0.8496383 0.152083 ]
[0.84796935 0.15418997]
[0.2159769 0.78110707]] [0 0 0 1]
즉 입력 데이타 [ 0, 0 ] 이 라벨 값 “0” 이 될 확률이 99.1% 라는 의미이며 [ 1, 1 ] 이 라벨 값 “1”이 될 확률은 78.1% 인데 Softmax 기법에 비해 확률이 훨씬 부정확함을 알 수 있다.
첨부된 2개의 파이선 코드를 실행해 보자. 단 session = tf.Session() 이하 영역에서 indentation 이 무너진 부분을 반드시 복구하여 실행하기 바란다.
#softmax_classifier_2data_And_logic_Rosenblatt_01.py
from matplotlib import pyplot as plt
import numpy as np
import tensorflow as tf
tf.set_random_seed(777) # for reproducibility
x_data = [[ 0, 0 ], [ 1, 0], [ 0, 1], [ 1, 1] ]
y_data = [ [1, 0], [1, 0], [1, 0],[0, 1] ]
X = tf.placeholder("float", [None, 2])
Y = tf.placeholder("float", [None, 2])
nb_classes = 2
W = tf.Variable(tf.random_normal([2, nb_classes]), name='weight')
b = tf.Variable(tf.random_normal([nb_classes]), name='bias')
#hypothesis = tf.nn.softmax(tf.matmul(X, W) + b)
hypothesis = tf.nn.softmax(tf.matmul(X, W) + b)
#cost/loss
cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(hypothesis), axis=1))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)
#Launch graph
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for step in range(2001):
sess.run(optimizer, 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}))
print('--------------')
#Testing & One-hot encoding
a = sess.run(hypothesis, feed_dict={X: [[ 0.0, 0.0 ]]})
print(a, sess.run(tf.argmax(a, 1)))
print('--------------')
all = sess.run(hypothesis, feed_dict={
X: [[ 0.0, 0.0 ],[ 1.0, 0.0], [ 0.0, 1.0 ], [ 1.0, 1.0 ]]})
print(all, sess.run(tf.argmax(all, 1)))
#logistic_classifier_2data_And_logic_Rosenblatt_01.py
from matplotlib import pyplot as plt
import numpy as np
import tensorflow as tf
tf.set_random_seed(777) # for reproducibility
x_data = [[ 0, 0 ], [ 1, 0], [ 0, 1], [ 1, 1] ]
y_data = [ [1, 0], [1, 0], [1, 0],[0, 1] ]
X = tf.placeholder("float", [None, 2])
Y = tf.placeholder("float", [None, 2])
nb_classes = 2
W = tf.Variable(tf.random_normal([2, nb_classes]), name='weight')
b = tf.Variable(tf.random_normal([nb_classes]), name='bias')
#hypothesis = tf.nn.softmax(tf.matmul(X, W) + b)
hypothesis = tf.sigmoid(tf.matmul(X, W) + b)
#cost/loss
cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) *
tf.log(1 - hypothesis))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)
#Launch graph
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for step in range(2001):
sess.run(optimizer, 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}))
print('--------------')
#Testing & One-hot encoding
a = sess.run(hypothesis, feed_dict={X: [[ 0.0, 0.0 ]]})
print(a, sess.run(tf.argmax(a, 1)))
print('--------------')
all = sess.run(hypothesis, feed_dict={
X: [[ 0.0, 0.0 ],[ 1.0, 0.0], [ 0.0, 1.0 ], [ 1.0, 1.0 ]]})
print(all, sess.run(tf.argmax(all, 1)))