본문 바로가기
python 및 머신러닝/3분 딥러닝

3분 딥러닝 - 3장 텐서플로 프로그래밍 101

by java개발자 2017. 10. 12.

scikit-learn에 비해 tensorflow는 정의가 매우 애매모호한 프레임워크라는 느낌을 받았다.

아마도, tensorflow를 설명하는 많은 글들, 책들이 단순히 MNIST 예제를 따라만 해왔기 때문이었을 것 같다.


왜 이렇게 하는지,,,

이렇게 하면 어떻게 되는지 모른채,,,

단지 예제만 돌리고 있다.


그에 비해, [3분 딥러닝]은 tensorflow 자체에 대해 천천히 소개해주고 있어서 좋았다.

가끔 코드가 있는 기술서적들을 보면, 책의 설명만으로는 부족해서 직접 데이터 디버깅을 해봐야 알 수 있었는데.

즉, 책 내용 자체를 다시 연구해야 하는 번거로운 경우들이 많이 있었는데,,, 

이 책은 그렇지 않았다.


그럼에도 부족한 부분이 있어서, 디버깅을 해보았고, 추가되면 좋은 부분을 남긴다.


ch3 - 50p 코드 중.

------------------------------------------------------------------------------------------------


import tensorflow as tf


x_data = [1, 2, 3]

y_data = [1, 2, 3]


W = tf.Variable(tf.random_uniform([1], -1.0, 1.0))

b = tf.Variable(tf.random_uniform([1], -1.0, 1.0))


X = tf.placeholder(tf.float32, shape=None, name="X")

Y = tf.placeholder(tf.float32, shape=None, name="Y")


hypothesis = W * X + b


cost = tf.reduce_mean(tf.square(hypothesis - Y))

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)

train_op = optimizer.minimize(cost)


with tf.Session() as sess:

    sess.run(tf.global_variables_initializer())


    for step in range(10000):

        _, cost_val = sess.run([train_op, cost], feed_dict={X: x_data, Y: y_data})


        print(step, cost_val, sess.run(W), sess.run(b))


    print("\n=== Test ===")

    print("X: 5, Y:", sess.run(hypothesis, feed_dict={X: 5}))

    print("X: 2.5, Y:", sess.run(hypothesis, feed_dict={X: 2.5}))

------------------------------------------------------------------------------------------------


설명1. placeholder의 shape가 1차 배열일때 어떻게 표현하나?

None으로 표현해야 하는데, tf.placeholder 함수로 들어가보면 다음과 같이 나와있다.


def placeholder(dtype, shape=None, name=None):


값이 없으면 어차피 None이므로 책에서는 생략되었다.


질문1. feed_dict의 key인 X, Y 는 어디서 왔나?

placeholder의 파라메터인 name이나, 기본 X,Y,Z,,, 일거라 생각했는데,,,

실제 변수명이었다. (일반적인 프로그래밍 방법은 아니라서 좀 의아했다. 문자열이 key가 아니라, 특정 객체 자체가 key가 된다.)


외부에서 다음의 코드를 돌려보면,

feed_dict={X: x_data, Y: y_data}

print(feed_dict)

결과:

{<tf.Tensor 'X:0' shape=<unknown> dtype=float32>: [1, 2, 3], <tf.Tensor 'Y:0' shape=<unknown> dtype=float32>: [1, 2, 3]}


더 나아가서

 코드

 결과

print(W)

print(X)

print(hypothesis)

print(cost)

print(optimizer)

print(train_op)



<tf.Variable 'Variable:0' shape=(1,) dtype=float32_ref>

Tensor("X:0", dtype=float32)

Tensor("add:0", dtype=float32)

Tensor("Mean:0", dtype=float32) 

<tensorflow.python.training.gradient_descent.GradientDescentOptimizer object at 0x0000000005EE8EB8> 

name: "GradientDescent" op: "NoOp"

input: "^GradientDescent/update_Variable/ApplyGradientDescent"

input: "^GradientDescent/update_Variable_1/ApplyGradientDescent"



질문2. sess.run([train_op, cost],,, 에서 [train_op, cost] 의 순서를 바꾸면 어떻게 될까?

train_op가 cost를 포함하고 있으므로, train_op를 먼저 실행하면, cost 값은 자연스럽게 나오지 않을까 싶다.

[cost, train_op] 로 순서를 바꾸면, 계산을 두배로 하지 않을까????

두 경우 모두 시간을 재어봤는데 별 차이가 없어서,,, 이상하다;;;


코드상에서 cost_val 는 print하기 위한 값이므로 실행하지 않아도 된다.

즉, return 없이 이렇게만 해도 된다.

sess.run(train_op, feed_dict={X: x_data, Y: y_data})