New Multi Hot Code 알고리듬에 의한 TensorFlow Softmax 훈민정음 자음 Classification 예제
파이선 코딩을 배우는 초보자도 머신 러닝에 독학으로 한번 도전해 보자.
왜냐구요? 그다지 어렵지 않으니까요!
머신 러닝을 배우려는 파이선 코딩 초보자들이 가지게 될 확률이 높은 의문점들을
하나하나 찾아내어 실제 풀어보고 결과를 확인해볼 수 있는 머신 러닝!
인터넷 교보문고에서 450페이지19900원에 판매중입니다.
________________________________________________________________________________________________________________________
파이선 코딩 초보자를 위한 텐서플로우 OpenCV 2장 6절에서 아래와 같이 훈민정음 자모 중 4가지 class의 자음에 대한 학습을 통해 테스트 자모를 Classification 하는 예제를 이미 제시하였다. 물론 이 문제를 풀기 위해서 MNIST 수기 문자 해독 코드에서처럼 One Hot Code를 설정하여 사용하였다.
2-6 훈민정음의 자음 classification TensorFlow Softmax 예제
https://steemit.com/kr/@codingart/2-6-classification
하지만 이번에는 학습(Train)과정에서 One Hot Code 대신 Multi Hot Code를 사용해 보기로 하자. one Hot Code를 사용하여 4종류의 class 라벨을 설정하기 위해서는 3개의 “0”과 1개의 “1” 을 사용하는 4비트의 정보가 필요한 반면에 Multi Hot Code를 사용할 경우에는 3비트의 정보로도 충분하다. 단 확률 계산이므로 값이 1 인 특정 비트가 N개 포함되어 있을 경우 (1/N) 의 값을 주도록 한다.
훈민정음의 4개의 자음을 학습(train)시켜 보자. 4개의 자음에 대한 이미지 구성은 3X3 매트릭스로 가능하다. 더욱 많은 자음과 모음을 분류(Classification)하려면 적어도 5X5 또는 그 이상으로 해상도를 높여야 할 것이다. 각 라벨에 해당하는 Multi Hot Code 는 그림을 보면 쉽게 이해가 될 것이다. 라벨 0에 해당하는 첫 번째 “ㄱ”에 대한 입력 데이터를 작성해 보자.
검은색은 0 흰색은 1로 코딩한다.
“ㄱ”⟶ [ 0, 0, 0, 1, 1, 0, 1, 1, 0 ],
[ 0, 0, 1, 1, 0, 1, 1, 0, 1 ].
[ 1, 0, 0, 1, 1, 0, 1, 1, 0 ],
[ 1, 1, 1, 0, 0, 1, 1, 0, 1 ]
“ㄴ“⟶ [ 0, 1, 1, 0, 1, 1, 0, 0, 0 ],
[ 0, 1, 1, 0, 1, 1, 0, 0, 1 ],
[ 1, 1, 1, 0, 1, 1, 0, 0, 0 ],
[ 1, 1, 1, 1, 0, 1, 1, 0, 0 ]
“ㄷ”⟶ [ 0, 0, 0, 0, 1, 1, 0, 0, 0 ],
[ 0, 0, 1, 0, 1, 1, 0, 0, 1 ],
[ 1, 0, 0, 1, 0, 1, 1, 0, 0 ],
[ 0, 0, 1, 0, 1, 1, 0, 0, 0 ]
“ㅁ”⟶ [ 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
[ 1, 0, 0, 0, 1, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 1, 0, 1, 0, 0 ],
[ 0, 0, 0, 0, 1, 0, 0, 0, 1 ]
이 데이터들은 TensorFlow 코드에서 x_data로 입력하고 Multi Hot Code는 y_data로 입력한다. 마지막 컬럼의 Test 용 데이터는 Session에서 사용하기로 한다.
“ㄱ”⟶ [ 0, 0, 0, 1, 1, 0, 1, 0, 1 ]
“ㄴ“⟶ [ 0, 1, 1, 0, 1, 1, 0, 0, 1 ]
“ㄷ”⟶ [ 0, 0, 0, 0, 1, 1, 0, 0, 1 ]
“ㅁ”⟶ [ 0, 0, 1, 0, 1, 0, 0, 0, 1 ]
X의 샘플수는 4개이지만 None으로 하고 각 샘플의 리스트 데이터 요소는 9개이다. Multi Hot Code를 저장하는 Y는 4개이지만 None으로 하고 각 각각의 리스트 데이터 요소는 3개로 이루어진다. class의 수는 라벨 수에 해당하는 4이다. 웨이트 W는 X의 리스트 데이터의 수 9개와 class의 수 4에 맞춰 배열을 선언한다. 바이아스 b도 class의 수 4로 두자. learning rate 는 0.1로 두고 학습 횟수는 10,000 회로 하였다.
다음의 결과는 테스트용 데이터에 대한 Softmax 명령에 의한 계산 결과로서 Multi Hot Code의 1 위치에 대응하는 지점의 가장 확률값이 높은 hypothesis 값을 보여주지만 3번째의 경우 Multi Hot Code 가 [ 0, 1/2, 1/2 ] 이므로 두 번째 세 번째 hypothesis 값들이 0.5(1/2)에 가까운 값이어야 하며 그 합이 거의 1.0 이 되어야 함을 보여 주고 있다.
매트릭스 리스트 데이터 뒤의 브라켓 속의 값은 argmax 명령 사용에 의해서 열별 최대 값을 을 체크해 주지만 3번째 class에서는 0.5 에 가까운 값들이 2개가 계산되므로 argmax 사용 의미가 없어지며 오히려 2번째 와 3번째 값의 합과 편차를 고려하는 루틴을 코딩하여 사용할 필요가 있을 것이다.
첨부된 코드를 복사해서 실행할 경우 indentation 훼손 여부를 확인되면 바로 잡아 실행하기 바란다.
#softmax_classifier_hunmin_01.py
from matplotlib import pyplot as plt
import numpy as np
import tensorflow as tf
import time
start_time = time.time()
tf.set_random_seed(777) # for reproducibility
def gen_image(arr):
t_d = np.reshape(arr, (3, 3))
two_d = (np.reshape(arr, (3, 3)) * 255).astype(np.uint8)
print(two_d)
plt.imshow(two_d, interpolation='nearest')
plt.savefig('batch.png')
return plt
x_data = [[ 0, 0, 0, 1, 1, 0, 1, 1, 0 ],
[ 0, 0, 1, 1, 0, 1, 1, 0, 1 ],
[ 1, 0, 0, 1, 1, 0, 1, 1, 0 ],
[ 1, 1, 1, 0, 0, 1, 1, 0, 1 ],
[ 0, 1, 1, 0, 1, 1, 0, 0, 0 ],
[ 0, 1, 1, 0, 1, 1, 0, 0, 1 ],
[ 1, 1, 1, 0, 1, 1, 0, 0, 0 ],
[ 1, 1, 1, 1, 0, 1, 1, 0, 0 ],
[ 0, 0, 0, 0, 1, 1, 0, 0, 0 ],
[ 0, 0, 1, 0, 1, 1, 0, 0, 1 ],
[ 1, 0, 0, 1, 0, 1, 1, 0, 0 ],
[ 0, 0, 1, 0, 1, 1, 0, 0, 0 ],
[ 0, 0, 0, 0, 1, 0, 0, 0, 0 ],
[ 1, 0, 0, 0, 1, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 1, 0, 1, 0, 0 ],
[ 0, 0, 0, 0, 1, 0, 0, 0, 1 ]
]
y_data = [ [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0],
[0, 1, 0], [0, 1, 0], [0, 1, 0], [0, 1, 0],
[0, 0.5, 0.5], [0, 0.5, 0.5], [0, 0.5, 0.5], [0, 0.5, 0.5],
[0, 0, 1], [0, 0, 1], [0, 0, 1], [0, 0, 1]
]
X = tf.placeholder("float", [None, 9])
Y = tf.placeholder("float", [None, 3])
nb_classes = 3
W = tf.Variable(tf.random_normal([9, nb_classes]), name='weight')
b = tf.Variable(tf.random_normal([nb_classes]), name='bias')
# tf.nn.softmax computes softmax activations
# softmax = exp(logits) / reduce_sum(exp(logits), dim)
hypothesis = tf.nn.softmax(tf.matmul(X, W) + b)
# Cross entropy 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:
#for idx in range(16):
#output = x_data[idx]
#gen_image(output).show()
sess.run(tf.global_variables_initializer())
for step in range(10001):
sess.run(optimizer, 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}))
# Testing & Multi-hot encoding
print('--------------')
all = sess.run(hypothesis, feed_dict={
X: [[ 0, 0, 0, 1, 1, 0, 1, 0, 1 ],[ 0, 1, 1, 0, 1, 1, 0, 0, 1 ],
[ 0, 0, 0, 0, 1, 1, 0, 0, 1 ],[ 0, 0, 1, 0, 1, 0, 0, 0, 1 ]]})
print(all, sess.run(tf.argmax(all, 1)))
end_time = time.time()
print( "Completed in ", end_time - start_time , " seconds")