#우리는 예전에 variable를 사용할때 tf.Variable([1,2,3]) 이렇게 값을 직접 지정 했지만 실제 사용할때에는 랜덤값으로 한다. 
#tf.truncated_normal(shape)를 넣는데 이때 리턴되는 결과가 Variable의 shape로 들어간다. 
W_h1 = tf.Variable(tf.truncated_normal([INPUT_SIZE, HIDDEN1_SIZE]), dtype=tf.float32,name='W_h1')

#bias라는 것도 중요하다 반드시 넣어줘서 high bias현상을 없애 줘야 한다.
b_h1 = tf.Variable(tf.zeros(shape=[HIDDEN1_SIZE]), dtype=tf.float32, name='b_h1')

W_h2 = tf.Variable(tf.truncated_normal([HIDDEN1_SIZE, HIDDEN2_SIZE]), dtype=tf.float32, name='W_h2')
b_h2 = tf.Variable(tf.zeros(shape=[HIDDEN2_SIZE]), dtype=tf.float32, name='b_h2')

W_o = tf.Variable(tf.truncated_normal([HIDDEN2_SIZE, CLASSES]), dtype=tf.float32, name='W_o')
b_o = tf.Variable(tf.zeros(shape=[CLASSES]), dtype=tf.float32, name='b_o')


#세이브를 할경우 Variable가 끝나는 시점에 생성을 해준다. 
#saver = tf.train.Saver()  #이렇게 해주면 위에 나오는 Variable는 다 저장 된다.

param_list = [W_h1, b_h1, W_h2, b_h2, W_o, b_o]
saver = tf.train.Saver(param_list)


hidden1 = tf.sigmoid(tf.matmul(x, W_h1) + b_h1, name='hidden1')
hidden2 = tf.sigmoid(tf.matmul(hidden1, W_h2) + b_h2 , name='hidden2')
y = tf.sigmoid(tf.matmul(hidden2, W_o) + b_o, name='y')

"""
Explanation: 위에까지로 보면 인풋데이터 정의 아웃풋데이터 정의 placeholder정의가 준비 되었다 이젠 모델을 설계 하면 된다. 
신경망은 인풋데이터들과 곱해질 weight가 필요 하다
End of explanation
"""


print(y)

"""
Explanation: 위에처럼 하면 모델 설계가 다 된 것이다.
End of explanation
"""


#크로스 엔트로피!
cost = tf.reduce_mean(tf.reduce_sum(-y_ * tf.log(y) - (1-y_) * tf.log(1-y), reduction_indices=1))  # y_이 0일경우에는 (1-y_)*tf.log(1-y) 가 돌게 한다. 
train = tf.train.GradientDescentOptimizer(learning_rate=LEARNING_RATE).minimize(cost)


comp_pred = tf.equal(tf.arg_max(y, 1), tf.arg_max(y_, 1))
accurcy = tf.reduce_mean(tf.cast(comp_pred, dtype=tf.float32))

sess = tf.Session()
sess.run(tf.global_variables_initializer())

for i in range(2000):
    _, cost_val, acc = sess.run([train, cost, accurcy], feed_dict=tensor_map)  #여기서 train과 cost는 따로 실행이 된다. 서로 연관된게 아니다. 
    if i % 100 == 0:
        saver.save(sess, "./hans")
        print("step: ", i, " loss: ", cost_val, " acc: ", acc)

sess.close()
    

"""
Explanation: 트레이닝을 시키기 위해서는 cost function이 필요하게 된다.
End of explanation
"""


