소스 코드는 https://github.com/melonicedlatte/tensorflow_basic/tree/master 에 모두 올라와 있습니다.
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
input_data = [[1,5,3,7,8,10,12],
[5,8,10,3,9,7,1]]
label_data = [[0,0,0,1,0],
[1,0,0,0,0]]
INPUT_SIZE = 7
HIDDEN_SIZE_1 = 10
HIDDEN_SIZE_2 = 8
CLASSES = 5
shape 에서 첫 번째 요소는 batch의 크기. 일반적으로 잘 모르기 때문에 None으로 써도 된다.
x = tf.placeholder(tf.float32, shape = [None, INPUT_SIZE] )
y = tf.placeholder(tf.float32, shape = [None, CLASSES] )
tensor_map = {x : input_data, y : label_data}
input weight 정의
weight_hidden_1 = tf.Variable( tf.truncated_normal(shape=[INPUT_SIZE, HIDDEN_SIZE_1]) , dtype=tf.float32 )
bias 정의
bias_hidden_1 = tf.Variable( tf.zeros(shape=[HIDDEN_SIZE_1]) , dtype=tf.float32 )
tf.matmul( x , weight_hidden_1 )
<tf.Tensor 'MatMul:0' shape=(?, 10) dtype=float32>
print (x)
print (weight_hidden_1)
Tensor("Placeholder:0", shape=(?, 7), dtype=float32) Tensor("Variable/read:0", shape=(7, 10), dtype=float32)
hidden_1 = tf.matmul( x , weight_hidden_1 ) + bias_hidden_1
weight_hidden_2 = tf.Variable( tf.truncated_normal(shape=[HIDDEN_SIZE_1, HIDDEN_SIZE_2]) , dtype=tf.float32 )
bias_hidden_2 = tf.Variable( tf.zeros(shape=[HIDDEN_SIZE_2]) , dtype=tf.float32 )
hidden_2 = tf.matmul( hidden_1 , weight_hidden_2 ) + bias_hidden_2
weight_output = tf.Variable( tf.truncated_normal(shape=[HIDDEN_SIZE_2, CLASSES]) , dtype=tf.float32 )
bias_output = tf.Variable( tf.zeros(shape=[CLASSES]) , dtype=tf.float32 )
answer = tf.matmul( hidden_2 , weight_output ) + bias_output
위의 내용을 한 번에 모아서 해보자
신경망을 미리 설계해 놓고 아래에서 연산을 수행하여 답을 도출해낸다
weight_hidden_1 = tf.Variable( tf.truncated_normal(shape=[INPUT_SIZE, HIDDEN_SIZE_1]) , dtype=tf.float32 )
bias_hidden_1 = tf.Variable( tf.zeros(shape=[HIDDEN_SIZE_1]) , dtype=tf.float32 )
weight_hidden_2 = tf.Variable( tf.truncated_normal(shape=[HIDDEN_SIZE_1, HIDDEN_SIZE_2]) , dtype=tf.float32 )
bias_hidden_2 = tf.Variable( tf.zeros(shape=[HIDDEN_SIZE_2]) , dtype=tf.float32 )
weight_output = tf.Variable( tf.truncated_normal(shape=[HIDDEN_SIZE_2, CLASSES]) , dtype=tf.float32 )
bias_output = tf.Variable( tf.zeros(shape=[CLASSES]) , dtype=tf.float32 )
hidden_1 = tf.matmul( x , weight_hidden_1 ) + bias_hidden_1
hidden_2 = tf.matmul( hidden_1 , weight_hidden_2 ) + bias_hidden_2
answer = tf.matmul( hidden_2 , weight_output ) + bias_output
print (x)
print (hidden_1)
print (hidden_2)
print (answer)
Tensor("Placeholder:0", shape=(?, 7), dtype=float32) Tensor("add_3:0", shape=(?, 10), dtype=float32) Tensor("add_4:0", shape=(?, 8), dtype=float32) Tensor("add_5:0", shape=(?, 5), dtype=float32)
print (weight_hidden_1)
print (bias_hidden_1)
print (weight_hidden_2)
print (bias_hidden_2)
print (weight_output)
print (bias_output)
Tensor("Variable_6/read:0", shape=(7, 10), dtype=float32) Tensor("Variable_7/read:0", shape=(10,), dtype=float32) Tensor("Variable_8/read:0", shape=(10, 8), dtype=float32) Tensor("Variable_9/read:0", shape=(8,), dtype=float32) Tensor("Variable_10/read:0", shape=(8, 5), dtype=float32) Tensor("Variable_11/read:0", shape=(5,), dtype=float32)
sigmoid 함수 적용 법
weight_hidden_1 = tf.Variable( tf.truncated_normal(shape=[INPUT_SIZE, HIDDEN_SIZE_1]) , dtype=tf.float32 )
bias_hidden_1 = tf.Variable( tf.zeros(shape=[HIDDEN_SIZE_1]) , dtype=tf.float32 )
hidden_1 = tf.sigmoid(tf.matmul( x , weight_hidden_1 ) + bias_hidden_1)
weight_hidden_2 = tf.Variable( tf.truncated_normal(shape=[HIDDEN_SIZE_1, HIDDEN_SIZE_2]) , dtype=tf.float32 )
bias_hidden_2 = tf.Variable( tf.zeros(shape=[HIDDEN_SIZE_2]) , dtype=tf.float32 )
hidden_2 = tf.sigmoid(tf.matmul( hidden_1 , weight_hidden_2 ) + bias_hidden_2)
weight_output = tf.Variable( tf.truncated_normal(shape=[HIDDEN_SIZE_2, CLASSES]) , dtype=tf.float32 )
bias_output = tf.Variable( tf.zeros(shape=[CLASSES]) , dtype=tf.float32 )
answer = tf.sigmoid(tf.matmul( hidden_2 , weight_output ) + bias_output)
cost 엔트로피 ( tip : 매뉴얼을 항상 자주 보자 )
cost = -y*tf.log(answer)-(1-y)*tf.log((1-answer))
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
sess.run(cost, feed_dict = tensor_map)
array([[ 0.08700245, 0.08184471, 1.83177435, 0.94000405, 0.57135564], [ 2.02943397, 0.17305857, 1.6006968 , 0.26148587, 0.74627531]], dtype=float32)
recude sum 과 reduce mean 사용해보기
cost = tf.reduce_sum(-y*tf.log(answer)-(1-y)*tf.log((1-answer)))
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
sess.run(cost, feed_dict = tensor_map)
8.2579012
cost = tf.reduce_mean(-y*tf.log(answer)-(1-y)*tf.log((1-answer)))
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
sess.run(cost, feed_dict = tensor_map)
0.8043766
수행
- cost를 최소화 하는 방향으로 최적화 해야 되니까 gradient descent가 필요.
- learning rate 사용
조대협님의 블로그에서 가져온 내용 (Mnist data를 기준으로 한다. 자세한 내용은 링크 참조)
우리가 구하고자 하는 값은 x 값으로 학습을 시켜서 0~9를 가장 잘 구별해내는 W와 b의 값을 찾는 일이다.
여기서 코드를 주의깊게 봤다면 하나의 의문이 생길것이다.
x의 데이타는 총 55000개로, 55000x784 행렬이 되고, W는 784x10 행렬이다. 이 둘을 곱하면, 55000x10 행렬이 되는데, b는 1x10 행렬로 차원이 달라서 합이 되지 않는다.
텐서플로우와 파이썬에서는 이렇게 차원이 다른 행렬을 큰 행렬의 크기로 늘려주는 기능이 있는데, 이를 브로드 캐스팅이라고 한다. (브로드 캐스팅 개념 참고 - http://bcho.tistory.com/1153)
브로드 캐스팅에 의해서 b는 55000x10 사이즈로 자동으로 늘어나고 각 행에는 첫행과 같은 데이타들로 채워지게 된다.
소프트맥스 알고리즘을 이해하고 사용해도 좋지만, 텐서플로우에는 이미 tf.nn.softmax 라는 함수로 만들어져 있고, 대부분 많이 알려진 머신러닝 모델들은 샘플들이 많이 있기 때문에, 대략적인 원리만 이해하고 가져다 쓰는 것을 권장한다.
보통 모델을 다 이해하려고 하다가 수학에서 부딪혀서 포기하는 경우가 많은데, 디테일한 모델을 이해하기 힘들면, 그냥 함수나 예제코드를 가져다 쓰는 방법으로 접근하자.
우리가 일반적인 프로그래밍에서도 해쉬테이블이나 트리와 같은 자료구조에 대해서 대략적인 개념만 이해하고 미리 정의된 라이브러리를 사용하지 직접 해쉬 테이블등을 구현하는 경우는 드물다.
코스트(비용) 함수
이 소프트맥스 함수에 대한 코스트 함수는 크로스엔트로피 (Cross entropy) 함수의 평균을 이용하는데, 복잡한 산식 없이 그냥 외워서 쓰자. 다행이도 크로스엔트로피 함수역시 함수로 구현이 되어있다.
Cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_withlogits(tf.matmul(x, W) + b, y))
가설에 의해 계산된 값 y를 넣지 않고 tf.matmul(x, W) + b 를 넣은 이유는 tf.nn.softmax_cross_entropy_withlogits 함수 자체가 softmax를 포함하기 때문이다. y은 학습을 위해서 입력된 값이다.
-> 코스트 함수로 위 함수는 써 본 적은 없고, 자세한 내용은 저도 잘 모르겠으나 일단 사용해보겠습니다.
Learning_Rate = 0.05
cost = tf.reduce_mean(-y*tf.log(answer)-(1-y)*tf.log((1-answer)))
train = tf.train.GradientDescentOptimizer(Learning_Rate).minimize(cost)
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
for i in range(10):
print (sess.run([train, cost], feed_dict = tensor_map))
print ("Step : ",i )
[None, 1.1322856] Step : 0 [None, 1.1105931] Step : 1 [None, 1.0896574] Step : 2 [None, 1.069412] Step : 3 [None, 1.049744] Step : 4 [None, 1.0305212] Step : 5 [None, 1.0116106] Step : 6 [None, 0.99288923] Step : 7 [None, 0.97425824] Step : 8 [None, 0.9556694] Step : 9
학습 100 번 수행
for i in range(100):
print (sess.run([train, cost], feed_dict = tensor_map))
print ("Step : ",i )
[None, 0.93716115] Step : 0 [None, 0.91888553] Step : 1 [None, 0.90108842] Step : 2 [None, 0.88402575] Step : 3 [None, 0.86786509] Step : 4 [None, 0.8526473] Step : 5 [None, 0.83831531] Step : 6 [None, 0.82476711] Step : 7 [None, 0.81189477] Step : 8 [None, 0.79960364] Step : 9 [None, 0.78781605] Step : 10 [None, 0.77647078] Step : 11 [None, 0.76552039] Step : 12 [None, 0.75492728] Step : 13 [None, 0.74466175] Step : 14 [None, 0.7346999] Step : 15 [None, 0.7250222] Step : 16 [None, 0.71561205] Step : 17 [None, 0.70645541] Step : 18 [None, 0.69754016] Step : 19 [None, 0.68885505] Step : 20 [None, 0.68039048] Step : 21 [None, 0.67213714] Step : 22 [None, 0.66408694] Step : 23 [None, 0.65623158] Step : 24 [None, 0.64856368] Step : 25 [None, 0.64107591] Step : 26 [None, 0.63376105] Step : 27 [None, 0.62661254] Step : 28 [None, 0.61962378] Step : 29 [None, 0.6127882] Step : 30 [None, 0.60609972] Step : 31 [None, 0.59955251] Step : 32 [None, 0.59314096] Step : 33 [None, 0.58686018] Step : 34 [None, 0.58070558] Step : 35 [None, 0.57467395] Step : 36 [None, 0.56876218] Step : 37 [None, 0.56296927] Step : 38 [None, 0.55729473] Step : 39 [None, 0.55174035] Step : 40 [None, 0.5463084] Step : 41 [None, 0.54100311] Step : 42 [None, 0.53582913] Step : 43 [None, 0.5307914] Step : 44 [None, 0.52589446] Step : 45 [None, 0.52114213] Step : 46 [None, 0.51653636] Step : 47 [None, 0.51207763] Step : 48 [None, 0.5077644] Step : 49 [None, 0.50359321] Step : 50 [None, 0.4995594] Step : 51 [None, 0.49565735] Step : 52 [None, 0.49188066] Step : 53 [None, 0.48822254] Step : 54 [None, 0.48467636] Step : 55 [None, 0.48123559] Step : 56 [None, 0.47789398] Step : 57 [None, 0.47464561] Step : 58 [None, 0.47148538] Step : 59 [None, 0.46840811] Step : 60 [None, 0.46540934] Step : 61 [None, 0.46248493] Step : 62 [None, 0.45963106] Step : 63 [None, 0.45684448] Step : 64 [None, 0.45412198] Step : 65 [None, 0.4514606] Step : 66 [None, 0.44885769] Step : 67 [None, 0.446311] Step : 68 [None, 0.44381824] Step : 69 [None, 0.44137725] Step : 70 [None, 0.43898621] Step : 71 [None, 0.43664327] Step : 72 [None, 0.43434677] Step : 73 [None, 0.43209523] Step : 74 [None, 0.42988712] Step : 75 [None, 0.42772102] Step : 76 [None, 0.4255957] Step : 77 [None, 0.42350993] Step : 78 [None, 0.42146248] Step : 79 [None, 0.41945225] Step : 80 [None, 0.41747823] Step : 81 [None, 0.41553935] Step : 82 [None, 0.41363472] Step : 83 [None, 0.41176343] Step : 84 [None, 0.40992445] Step : 85 [None, 0.40811712] Step : 86 [None, 0.40634051] Step : 87 [None, 0.40459388] Step : 88 [None, 0.40287656] Step : 89 [None, 0.40118772] Step : 90 [None, 0.39952669] Step : 91 [None, 0.39789283] Step : 92 [None, 0.39628547] Step : 93 [None, 0.39470392] Step : 94 [None, 0.39314777] Step : 95 [None, 0.39161617] Step : 96 [None, 0.39010882] Step : 97 [None, 0.388625] Step : 98 [None, 0.38716426] Step : 99
sess.close()
Learning_Rate = 0.05
cost = -y*tf.log(answer)-(1-y)*tf.log((1-answer))
train = tf.train.GradientDescentOptimizer(Learning_Rate).minimize(cost)
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
loss = sess.run(cost, feed_dict = tensor_map)
print (loss)
print ()
for i in range(10):
loss = sess.run(cost, feed_dict = tensor_map)
print (loss)
sess.close()
[[ 0.14097062 1.50098753 0.28970671 0.22760819 2.3666749 ] [ 1.57549131 2.54993439 0.26265255 1.0441227 2.69189954]] [[ 0.14097062 1.50098753 0.28970671 0.22760819 2.3666749 ] [ 1.57549131 2.54993439 0.26265255 1.0441227 2.69189954]] [[ 0.14097062 1.50098753 0.28970671 0.22760819 2.3666749 ] [ 1.57549131 2.54993439 0.26265255 1.0441227 2.69189954]] [[ 0.14097062 1.50098753 0.28970671 0.22760819 2.3666749 ] [ 1.57549131 2.54993439 0.26265255 1.0441227 2.69189954]] [[ 0.14097062 1.50098753 0.28970671 0.22760819 2.3666749 ] [ 1.57549131 2.54993439 0.26265255 1.0441227 2.69189954]] [[ 0.14097062 1.50098753 0.28970671 0.22760819 2.3666749 ] [ 1.57549131 2.54993439 0.26265255 1.0441227 2.69189954]] [[ 0.14097062 1.50098753 0.28970671 0.22760819 2.3666749 ] [ 1.57549131 2.54993439 0.26265255 1.0441227 2.69189954]] [[ 0.14097062 1.50098753 0.28970671 0.22760819 2.3666749 ] [ 1.57549131 2.54993439 0.26265255 1.0441227 2.69189954]] [[ 0.14097062 1.50098753 0.28970671 0.22760819 2.3666749 ] [ 1.57549131 2.54993439 0.26265255 1.0441227 2.69189954]] [[ 0.14097062 1.50098753 0.28970671 0.22760819 2.3666749 ] [ 1.57549131 2.54993439 0.26265255 1.0441227 2.69189954]] [[ 0.14097062 1.50098753 0.28970671 0.22760819 2.3666749 ] [ 1.57549131 2.54993439 0.26265255 1.0441227 2.69189954]]
https://www.tensorflow.org/api_docs/python/tf/reduce_mean 에서 확인해보세요
예시 (For example):
x = tf.constant([[1., 1.], [2., 2.]])
tf.reduce_mean(x) # 1.5
tf.reduce_mean(x, 0) # [1.5, 1.5]
tf.reduce_mean(x, 1) # [1., 2.]
비교하기 쉽게 출력 해보자
- 차원의 차이가 아래와 같이 난다.
Learning_Rate = 0.05
cost_ = -y*tf.log(answer)-(1-y)*tf.log((1-answer))
cost = tf.reduce_sum(cost_, reduction_indices=1)
train = tf.train.GradientDescentOptimizer(Learning_Rate).minimize(cost)
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
loss_, loss = sess.run([cost_, cost], feed_dict = tensor_map)
print (loss_)
print (loss)
sess.close()
[[ 0.22220834 1.42398429 1.05175662 0.19866461 0.28180537] [ 1.94174027 1.80546308 0.92534113 1.96047449 0.31566393]] [ 3.17841935 6.94868279]
배열에서 원소 하나 하나는 함수와 가지는 loss를 의미한다
따라서, 함수 하나와 모든 점들간의 loss를 보기 위해서 모든 파라미터에 대하여 평균을 구하거나 합을 구하는 reduce를 사용
Learning_Rate = 0.05
cost_ = -y*tf.log(answer)-(1-y)*tf.log((1-answer))
cost = tf.reduce_sum(cost_, reduction_indices=1)
cost = tf.reduce_mean(cost, reduction_indices=0)
train = tf.train.GradientDescentOptimizer(Learning_Rate).minimize(cost)
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
for i in range(1000):
if i%100 == 0:
_ , loss = sess.run([train, cost], feed_dict = tensor_map)
print (i)
print (loss)
sess.close()
0 4.08091 100 3.77948 200 3.52982 300 3.32602 400 3.15119 500 2.99706 600 2.86232 700 2.74475 800 2.641 900 2.54821
Learning_Rate = 0.05
cost_ = -y*tf.log(answer)-(1-y)*tf.log((1-answer))
cost = tf.reduce_sum(cost_, reduction_indices=1)
cost = tf.reduce_mean(cost, reduction_indices=0)
train = tf.train.GradientDescentOptimizer(Learning_Rate).minimize(cost)
train 해서 나온 answer 중에서 가장 큰 것과, label 과 비교한다.
comp_pred = tf.equal( tf.arg_max(answer, 1), tf.arg_max(y, 1) )
accuracy = tf.reduce_mean(tf.cast(comp_pred, tf.float32))
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
for i in range(1000):
_ , loss, acc = sess.run([train, cost, accuracy], feed_dict = tensor_map)
if i%100 == 0:
print (i)
print (loss)
print (acc)
print ()
sess.close()
0 4.54525 0.5 100 0.853118 1.0 200 0.436865 1.0 300 0.269513 1.0 400 0.189196 1.0 500 0.143947 1.0 600 0.115434 1.0 700 0.0960026 1.0 800 0.0819866 1.0 900 0.0714351 1.0
weight_hidden_1 = tf.Variable( tf.truncated_normal(shape=[INPUT_SIZE, HIDDEN_SIZE_1]) , dtype=tf.float32 )
bias_hidden_1 = tf.Variable( tf.zeros(shape=[HIDDEN_SIZE_1]) , dtype=tf.float32 )
weight_hidden_2 = tf.Variable( tf.truncated_normal(shape=[HIDDEN_SIZE_1, HIDDEN_SIZE_2]) , dtype=tf.float32 )
bias_hidden_2 = tf.Variable( tf.zeros(shape=[HIDDEN_SIZE_2]) , dtype=tf.float32 )
weight_output = tf.Variable( tf.truncated_normal(shape=[HIDDEN_SIZE_2, CLASSES]) , dtype=tf.float32 )
bias_output = tf.Variable( tf.zeros(shape=[CLASSES]) , dtype=tf.float32 )
아래의 영역을 추가해준다
param_list = [weight_hidden_1, bias_hidden_1, weight_hidden_2, bias_hidden_2, weight_output, bias_output ]
saver = tf.train.Saver(param_list)
hidden_1 = tf.sigmoid(tf.matmul( x , weight_hidden_1 ) + bias_hidden_1)
hidden_2 = tf.sigmoid(tf.matmul( hidden_1 , weight_hidden_2 ) + bias_hidden_2)
answer = tf.sigmoid(tf.matmul( hidden_2 , weight_output ) + bias_output)
saver.save 함수를 통하여 파일이 생성됨
Learning_Rate = 0.05
cost_ = -y*tf.log(answer)-(1-y)*tf.log((1-answer))
cost = tf.reduce_sum(cost_, reduction_indices=1)
cost = tf.reduce_mean(cost, reduction_indices=0)
train = tf.train.GradientDescentOptimizer(Learning_Rate).minimize(cost)
comp_pred = tf.equal( tf.arg_max(answer, 1), tf.arg_max(y, 1) )
accuracy = tf.reduce_mean(tf.cast(comp_pred, tf.float32))
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
for i in range(1000):
_ , loss, acc = sess.run([train, cost, accuracy], feed_dict = tensor_map)
if i%100 == 0:
saver.save(sess, './tensorflow_live.ckpt')
print (i)
print (loss)
print (acc)
sess.close()
0 4.40292 0.0 100 0.755229 1.0 200 0.393953 1.0 300 0.25012 1.0 400 0.177993 1.0 500 0.136179 1.0 600 0.109399 1.0