텐서플로우(Tensorflow) - 변수(Variable)

    바로 전 포스팅에는 개발자라면 대부분 처음 들어보는 개념의 플레이스 홀더(Placeholder)라는 것을 끄적여 봤습니다. 대부분 변수(Variable)라는 개념을 알고 있는 상황에서 변수와 비슷한데 약간 미묘하게 다른 플레이스 홀더로 인해서 약간 혼란스러울지도 모르겠습니다.


    저 역시도 이 부분에 대해서 혼동이 많이 왔었고, 주변의 텐서플로우를 시작한 개발자분들 역시 변수와 플레이스홀더의 차이점을 이해하는데 시간이 좀 걸린 것 같습니다. 사실 그리 어려운 것이 아닌데 헷갈려서 어려운 것이겠죠.




    변수는 말그대로 變數(변하는 수)입니다. 즉, 뭔가 값이 계속 변하며 그 값을 계속 세팅한다면 우리는 변수로 이해하면 되고, 파이(3.14)같이 이미 정해져 있는 수는 상수로서 프로그램 언어에 맞게 세팅을 하게 됩니다. 자바로 따지면 final이라는 표현을 써서 변하지 못하게 설정을 합니다.


    플레이스 홀더는 최종적으로 받아야 되는 값을 나중에 세팅하기 위해서 넣습니다. 공간을 미리 만들어 놓고 프로그램을 다 세팅해 놓은 후, 플레이스 홀더에 들어갈 값에 따라서 output이 나오게 됩니다. 즉 플레이스 홀더는 어떤 Input값에 따라서 Output내용이 달라지기 때문에 변수라는 개념보다는 값을 받아들이는 통로(?)로 인식하셔도 무방합니다. 이 모든것을 통털어서 우리는 변수로 인식하고 있지만, 구글은 확실하게 나누는 걸 좋아하는 것 같습니다. 


    바로 전에 "플레이스 홀더"에서 구현했던 소스를 기반을 변수로 변경하여 보여드리도록 하겠습니다.


    플레이스홀더로 구현했던 가중치 소스


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import tensorflow as tf
     
    # Input Node를 설계합니다. 행:2, 열4개의 행렬 구조입니다.
    = tf.placeholder(tf.float32, [24])
    = [[1,2,3,4],[5,6,7,8]]
     
    # 가중치를 설계합니다. 행:4, 열2개의 행렬 구조입니다.
    = tf.placeholder(tf.float32, [42])
    = [[1,1],[2,2],[3,3],[4,4]]
     
    node = tf.matmul(I, W)
     
    sess = tf.Session()
    sess.run(tf.global_variables_initializer())
     
    print(sess.run(node, feed_dict={I:i, W:w}))
     
    sess.close()
    cs


    위 소스를 보면, W라고 하는 가중치를 플레이스홀더로 설계하여 실행을 하는 것을 볼 수 있습니다만 일반적으로 W는 플레이스홀더로 구현하지는 않습니다. 가중치는 Input 값과 Output값을 기반으로 변경이 되며, 인공지능은 바로 W를 예측하는 것이 핵심이기 때문에, 변수로 선언하여 구현하게 됩니다. 



    가중치 변수인 W값을 플레이스홀더에서 변수로 변경하고 random_normal 메소드를 사용하여 정규분포의 값을 무작위로 넣은 후, 행렬곱을 수행하는 일반적인 신경망 형태의 구조로 소스를 변경해보겠습니다.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import tensorflow as tf
     
    # Input Node를 설계합니다. 행:2, 열4개의 행렬 구조입니다.
    = tf.placeholder(tf.float32, [24])
    = [[1234], [5678]]
     
    # 기존의 플레이스 홀더에서 변수형으로 변환하였고
    # 0~1 사이의 데이터를 행:4, 열2개로 선언하였습니다
    = tf.Variable(tf.random_normal([42]))
     
    # Input 데이터와 Weight를 행렬곱 수행
    node = tf.matmul(I, W)
     
    sess = tf.Session()
    sess.run(tf.global_variables_initializer())
     
    print(sess.run(W))
    print(sess.run(node, feed_dict={I: i}))
     
    sess.close()
    cs


    위 소스를 실행하면, 아래와 같이 실행이 됩니다.


    2018-04-23 17:26:22.532961: I C:\tf_jenkins\home\workspace\rel-win\M\windows\PY\35\tensorflow\core\platform\cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2

    [[-0.15929052  1.13860667]

     [-0.68646657 -0.77832597]

     [ 0.60499549  0.28911337]

     [ 0.70139474 -3.25974441]]

    [[  3.08834171 -12.58968258]

     [  4.93087435 -23.03108406]]


    Process finished with exit code 0


    아직 히든노드와 편향(bias)값이 구현하지 않아서, 매우 심플한 구조의 신경망 모양이 만들어 졌습니다. 여기에 추가적으로 옵티마이저(optimizer)와 cost의 차이를 구하는 연산등을 더해주면, 신경망이 계속 연산하면서 값을 찾아내는 기계학습을 구현할 수 있습니다. 다음 포스팅에서는 본격적으로 복잡한 구조를 구현해보도록 하겠습니다.


    이전 포스팅


    댓글

    Designed by JB FACTORY