머신러닝

New Multi Hot Code 알고리듬에 의한 TensorFlow Softmax 훈민정음 자음 Classification 예제

coding art 2019. 5. 1. 16:42
728x90



파이선 코딩을 배우는 초보자도 머신 러닝에 독학으로 한번 도전해 보자.

왜냐구요? 그다지 어렵지 않으니까요!

머신 러닝을 배우려는 파이선 코딩 초보자들이 가지게 될 확률이 높은 의문점들을

하나하나 찾아내어 실제 풀어보고 결과를 확인해볼 수 있는 머신 러닝!

인터넷 교보문고에서 450페이지19900원에 판매중입니다.











________________________________________________________________________________________________________________________

파이선 코딩 초보자를 위한 텐서플로우 OpenCV 26절에서 아래와 같이 훈민정음 자모 중 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 Codey_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를 저장하는 Y4개이지만 None으로 하고 각 각각의 리스트 데이터 요소는 3개로 이루어진다. class의 수는 라벨 수에 해당하는 4이다. 웨이트 WX의 리스트 데이터의 수 9개와 class의 수 4에 맞춰 배열을 선언한다. 바이아스 bclass의 수 4로 두자. learning rate 0.1로 두고 학습 횟수는 10,000 회로 하였다.

 

그림입니다.

원본 그림의 이름: CLP0000286c0009.bmp

원본 그림의 크기: 가로 666pixel, 세로 374pixel 다음의 결과는 테스트용 데이터에 대한 Softmax 명령에 의한 계산 결과로서 Multi Hot Code1 위치에 대응하는 지점의 가장 확률값이 높은 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")