이 제목을 풀어쓰면 classification이 불가능한 XOR 로직 perceptron 이 된다. 이미 AND 로직과 OR 로직 문제를 다루어 보았다. 이 두 문제는 쉽게 말하자면 성냥 한 개비를 사용하여 두 영역으로 분리하는 수준의 문제이다.
하지만 XOR 문제에서는 상황이 달라진다. (0,1)과 (1,0) 점을 포함해서 도려내려면 두 개의 선을 그어 파 내야 한다. 즉 두 개의 분리선이 당연히 필요하다.
머신 러닝에서 분리선 1개는 hypothesis = W∙X + b 이므로 즉 웨이트 벡터 W=(w1, w2) 1개와 바이아스 b1 1개가 필요하다는 뜻이다. 앞 예제에서 최소제곱법에 의해 계산했던 결과가 결국 웨이트 벡터와 바이아스 값이었다.
하지만 XOR 문제에서는 명백히 2개의 분리선이 필요하며 결국 웨이트 벡터 2개 및 각각의 편향(바이어스) 값 2개가 필요한 것이다. 하지만 별 대단한 문제가 아닌 듯한데 1969년에 민스키와 페파트 교수가 공동 저술한 Perceptron이란 저서에서 뉴론을 모델링하여 만들었던 단일 퍼셉트론은 AND 나 OR 논리를 처리할 수는 있었으나 단일 퍼셉트론만으로는 배타논리인 XOR 처리가 불가능하다는 점을 지적하였다.
단일 퍼셉트론이란 점이 수학문제이기 때문에 극단적이기는 하지만 도대체 왜 퍼셉트론만으로 XOR 논리를 처리할 수 없는지 TensorFlow로 예제 계산을 통해 확인해보도록 한다.
배타논리는 위 그림에서처럼 x1 이나 x2 2개 중 1개만이 “1”일 때에 출력 y가 “1”이 되는 이상스런 논리이지만 그래도 대단히 중요한 논리 중의 하나이다.
그림의 좌표 평면에서 관찰해 보면 (0,0) 과 (1,1) 이 라벨 값 “0”이며 (1,0)과 (0,1) 이 라벨 값 “1”이 되므로 서로 교차 하는 위치에 있으므로 2개를 그으면 분리가 가능할지도 모르겠지만 상식적으로 하나의 분리선을 긋기란 불가능하다.
그래도 못 미더운 부분이 있으므로 이러한 분리선을 과연 tensorFlow 학습에 의해 찾아낼 수 있는지 알아보기 위해서 입력 벡터와 웨이트 벡터를 도입하자.
X와 W에 의해 hypothesis를 다음과 같이 설정하자. hypothesis = X*W + b
즉 hypothesis = x1*w1 + x2*w2 + b 이 성립한다.
이 분리선을 결정해보기 위해 TensorFlow 학습을 위한 코드 데이터를 아래와 같이 리스트 데이터 구조로 준비하자. AND와 OR 로직 문제와 다 동일하지만 y-data 만 수정하면 된다.
x1_data = [0, 1, 0, 1], x2_data = [0, 0, 1,1 ], y_data = [0, 1, 1, 0]
learning_rate 값은 AND 로직의 경우에서처럼 동일하게 0.005 로 설정한다. 이 값은 여러 번 학습을 시도해 보고 결정해도 무방하다. 다음 결과는 라즈베리 파이 보드에서 계산한 결과이나 아나콘다에서 도일한 결과를 얻을 수 있다.
4개의 y 출력 값 (0, 1, 1, 0) 에 대응하여 분리가 곤란한 (0.5, 0.5, 0.5, 0.5) 가 얻어졌다. 아울러 이 계산 결과를 잘 살펴보면 웨이트 w1, w2 은 거의 0 의 값이 얻어지며 바이어스 b 는 상수 값 0.5가 얻어졌다. 즉 아무리 많이 학습을 해도 hypothesis 가 거의 0.5에 가까운 상수가 얻어졌다는 점은 결국 activation function 개념에서 HIGH 또는 LOW 로 분리 식별이 불가능하다는 의미일 것이다. 이 문제는 방법을 바꾸어서 softmax 나 Sigmoid를 사용하여 풀어도 마찬가지 결과가 얻어진다는 점에 유의하자. 즉 방법이나 기법 상의 문제가 아니다. 성냥개비로 풀어도 마찬가지인 것이 하나로는 답이 없다.
내용을 요약 해보면, 즉 2개의 입력 값을 처리하여 1개의 출력 값을 계산하는 퍼셉트론 구조로는 더 이상 XOR 논리 학습이 이루어지지 않는다는 점이다.
생명체에서 오직 하나의 신경세포만으로 특별한 논리를 처리할 수 있도록 구성 되었을 리는 만무하며 어떻게 해서든 수많은 뉴론들을 엮어서 필요한 처리를 하고 있음에 비추어 보아 결국 우리도 신경망을 어떻게 구성해야 할지 그 방법을 모색해야 할 것이다. 즉 성냥개비 1개비로 안되며 2개를 써서 문제를 풀어야 할 것이다. 다시 말하면 또 다른 웨이트 벡터가 적어도 하나 필요한 시점으로서 여기서 부터가 뉴럴네트워크(NN: Neural Network)의 시작점이다. 머신러닝에서 특히 구글과 딥러닝이 작당하여 지나칠 정도의 흥행을 통해 엄청난 자본을 성공적으로 펀딩했는지는 모르겠으나 너무 스포(spoiled)가 되어 가장 재미없는 분야이기도 하다. 그래도 어쩔 수 없이 딥러닝을 어느 정도 살펴 본 후 CNN(Convolutional Neural Network) 으로 넘어갈 필요가 있다.
※CNN 단계에서 카메라에서 캡츄어 한 이미지를 분석하여 이놈은 고양이 저놈은 개 ∙∙∙ 로 분리를 넘어 식별하는 단계가 있다고 얘기는 들었는데 해보지는 못했음. 그래서 미리 미리 준비 차원에서 거금을 투자하여 5만원짜리 라즈베리 파이 보드에 3만원짜리 파이 카메라를 준비하고 대기하고 있음. 이 정도 단계가 90년대 초반 정도 수준이라는데 훌쩍 넘어가야겠죠.
첨부된 파이선 코드를 실행해 보자. 단 session = tf.Session() 이하 영역에서 indentation 이 무너진 부분을 반드시 복구하여 실행하기 바란다.
#multi_variable_linear_reg_XOR.py
import tensorflow as tf
tf.set_random_seed(777) # for reproducibility
x1_data = [0., 1., 0., 1.]
x2_data = [0., 0., 1., 1.]
y_data = [0., 1., 1., 0.]
#placeholders for a tensor that will be always fed.
x1 = tf.placeholder(tf.float32)
x2 = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)
w1 = tf.Variable(tf.random_normal([1]), name='weight1')
w2 = tf.Variable(tf.random_normal([1]), name='weight2')
b = tf.Variable(tf.random_normal([1]), name='bias')
hypothesis = x1 * w1 + x2 * w2 + b
print(hypothesis)
#cost/loss function
cost = tf.reduce_mean(tf.square(hypothesis - Y))
#Minimize. Need a very small learning rate for this data set
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.005)
train = optimizer.minimize(cost)
#Launch the graph in a session.
sess = tf.Session()
#Initialize global variables in the graph.
sess.run(tf.global_variables_initializer())
for step in range(4001):
cost_val, hy_val, _ = sess.run([cost, hypothesis, train],
feed_dict={x1: x1_data, x2: x2_data, Y: y_data})
if step % 400 == 0:
print(step, cost_val, hy_val)
'머신러닝' 카테고리의 다른 글
3-6 NN(Neural Network)이 아닌 집합계산 원리를 이용한 Perceptron XOR 논리 처리 (0) | 2021.07.02 |
---|---|
3-5 XOR 논리 처리를 위한 Neural Network(NN) 구성 (0) | 2021.07.02 |
3-1 OR 로직 머신 러닝 (0) | 2021.07.02 |
2-17 Iris flower data를 이용한 Rosenblatt 퍼셉트론 파이선 코딩 (0) | 2021.07.02 |
2-17 Iris flower data를 이용한 Rosenblatt 퍼셉트론 파이선 코딩 (0) | 2021.07.01 |