머신러닝

Covariance 항을 포함한 softmax classifier의 XOR 로직 적용

coding art 2021. 7. 12. 18:14
728x90

XOR 로직 계산은 Rosenblatt 의 퍼셉트론 연구로부터 잉태되었던 뉴럴 네트워크 발전의 중요한 고비로 기억된다. 1969년에 MIT 민스키 교수가 그의 저서 퍼셉트론에서 Rosenblatt 의 퍼셉트론으로는 XOR 로직 계산이 불가능하다고 부정적인 의견을 제시했던 바로 그 문제로서 1971년에 퍼셉트론 개발의 주역이었던 Rosenblatt 이 사고로 사망하면서 이 문제의 해결을 보지 못했다. 아울러 1970년대에 들어서면서 인공지능 및 머신 러닝 분야의 연구개발 지원이 완전히 끓어지면서 인공지능 발전의 암흑기에 들어서게 된다. 하지만 MIT의 민스키 교수가 퍼셉트론으로 처리 할 수 없는 영역을 건드렸던 것이 사실이긴 하지만 그래도 인공지능의 발전을 위한 단서 정도는 남긴 듯하다. XOR 로직 문제는 multi-layer 뉴럴 네트워크를 사용하면 문제를 해결 할 수 있는 가능성은 없지는 않다는 점을 지적했다. 하지만 당시의 인공지능 수준으로는 불가능했지만 상당한 기간이 흘러 1986년에 Hinton 교수가 back -propagation 에 의한 웨이트 업데이트 알고리듬을 제안하면서 해결이 이루어진 것으로 보인다.

XOR 로직 문제는 그림의 우측에 볼 수 있듯이 2개의 영역으로 나누어야 할 데이타들이 서로 교차하는 지점에 있어 하나의 hyperplane 으로는 당연히 classification 이 불가능하다. 오늘날에도 이 문제는 머신 러닝을 공부하는 많은 이들에게도 꼭 다루어 보고 넘어가야 할 중요한 과제로 남아 있다. 이 문제 해결을 위한 고전적인 뉴럴 네트워크 구성문제는 필자의 저서 파이선 코딩 초보자를 위한 텐서플로우OpenCV 머신러닝편에서도 이미 다루었다. 아래 url 주소를 참조하기 바란다.

 

3-5 XOR 논리 처리를 위한 Neural Network(NN) 구성

http://blog.daum.net/ejleep1/1134

3-10 바이아스가 추가된 Quadratic Hypothesis Perceptron에 의한 XOR 논리 처리

https://steemit.com/kr/@codingart/3-11-quadratic-hypothesis-perceptron-xor

 

한편으로는 XOR 문제 자체가 비선형이므로 다항식 알고리듬에 의한 성공적인 계산 결과를 이미 제시하였다. 한편 뉴럴 네트워크나 다항식 알고리듬이 아닌 Covariance 항을 이용한 softmax에 의한 알고리듬을 제시하기로 한다. 유도 과정은 볼츠만 분포 이상으로 길므로 생략하고 최종 공식을 사용하여 설명하기로 하자.

softmax 공식에서 linear 파트만을 가지고는 아예 학습이 불가능하므로 배제하기로 하면 비선형 항 즉 Covariance 항만 남게 된다. Covariance 항을 구성하는 2개의 Hypothesis 자체가 학습 첫 단계에서 랜덤 넘버로 초기화 되므로 Lagrange’s multiplier α 값은 임의로 설정이 가능하다.

아래의 100회 학습 계산 결과를 참조해 보자. “1” True인 경우 0.97 이상으로 잘 수렴된 결과를 보여준다.

첨부된 파이선 코드를 실행해 보자.

#quadratic_softmax_XOR_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], [0, 1], [0, 1],[1, 0] ]

X = tf.placeholder("float", [None, 2])
Y = tf.placeholder("float", [None, 2])

dof = 2
threshold = 0.5
training_num = 101
lr=0.5
W2 = tf.Variable(tf.random_normal([2, dof]), name='weight2')
W3 = tf.Variable(tf.random_normal([2, dof]), name='weight3')
b2 = tf.Variable(tf.random_normal([ dof]), name='bias2')
b3 = tf.Variable(tf.random_normal([ dof]), name='bias3')

c_d = (tf.matmul(X, W2) + b2)*(tf.matmul(X, W3) + b3)

hypothesis = tf.nn.softmax(c_d)

#Cross entropy cost/loss
cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(hypothesis), axis=1))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=lr).minimize(cost)

predicted = tf.cast(hypothesis > threshold, dtype=tf.float32)
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype=tf.float32))

#Launch graph
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())

for step in range(training_num): sess.run(optimizer, 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(W2),sess.run(W3),sess.run(b2),sess.run(b3)) 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)))