텐서플로우(Tensorflow) - 플레이스홀더(Placeholder)
텐서플로우(tensorflow)에는 플레이스홀더(Placeholder)라는 기능이 있습니다. 바로 전 포스팅에서 텐서플로우의 그래프(graph)에 대해서 설명을 드렸는데 텐서플로우는 그래프라는 것을 미리 만들어 놓고, 필요한 시점에 해당 그래프를 실행하는 지연실행(lazy evaluation)이라는 방식을 사용합니다. 이런 내용에 걸맞게 플레이스홀더는 변수의 타입을 미리 설정해놓고 필요한 변수를 나중에 받아서 실행하는 것을 의미합니다.
텐서플로우는 신경망을 구현하기 때문에 신경망과 가장 어울리는 변수 설정이 바로 플레이스 홀더 입니다.
왜 인지 한번 생각해보도록 합시다.
우리가 신경망을 구현하기 위해서는 우선 Input 노드와 Output 노드를 설계합니다. Input 노드는 Feature들이겠고, Output 노드는 연산이 되어서 최종적으로 나온 결과값이겠지요. 그리고 중간에 Hidden 노드를 생성하고 튜닝해서 Output 노드를 최적화 합니다
즉 데이터셋과 모델셋을 분리를 하게 되어서, 필요한 데이터셋을 모델에 대입을 하게 되면 신경망을 구축하기 상당히 수월해 집니다. 이 개념을 한번 코딩으로 구현해보도록 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 | import tensorflow as tf a = tf.placeholder(tf.float32, [None, None]) b = tf.placeholder(tf.double, [3, 2]) c = tf.placeholder(tf.float32, [2, 3]) d = tf.placeholder(tf.string, [5, 5]) print(a) print(b) print(c) print(d) | cs |
위 소스를 실행하면 아래와 같은 결과값을 보여줍니다
Tensor("Placeholder:0", shape=(?, ?), dtype=float32)
Tensor("Placeholder_1:0", shape=(3, 2), dtype=float64)
Tensor("Placeholder_2:0", shape=(2, 3), dtype=float32)
Tensor("Placeholder_3:0", shape=(5, 5), dtype=string)
Process finished with exit code 0
결과값을 설명드리면,
tf.placeholder로 a에는 실수형에 텐서의 구조가 어떤지 모르는 값을 세팅
tf.placeholder로 b에는 실수형에 텐서의 구조가 2차월 배열(행렬)로 [3,2]의 행렬 모습을 세팅
tf.placeholder로 c에는 실수형에 텐서의 구조가 2차월 배열(행렬)로 [2,3]의 행렬 모습을 세팅
tf.placeholder로 d에는 문자열형에 텐서의 구조가 2차월 배열(행렬)로 [5,5]의 행렬 모습을 세팅
이런식으로 구조가 완성이 되면, 우리는 데이터셋에 대해서만 생각을 하면 되는 것이죠. 그러면, 약간 구조를 복잡하게 해서 매우 간단한 신경망 구조를 만들어보도록 하겠습니다.
신경망은 일반적으로 Input, Hidden, Output 노드들이 필요하며 중간중간 가중치(weight)와 고정적인 스칼라값인 bias를 통해서 연산을 통해 최종적으로 값이 나오는 구조입니다. 처음부터 다양한 노드를 만들고 가중치를 연산하는 것은 이해를 어렵게 만들기 때문에 Input 노드와 Output 노드의 매우 간단한 구조만 설명하고, 코딩해보도록 하겠습니다
위 그림은 Input 값 즉 특징이 4개의 값으로 이루어져 있고, 어떠한 가중치와 연산을 통해서 2개의 값으로 결과가 출력이 되는 간단한 신경망 구조입니다. 이를 텐서플로우로 구현하면 아래와 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import tensorflow as tf # Input Node를 설계합니다. 열:4, 행2개의 행렬 구조입니다. I = tf.placeholder(tf.float32, [2, 4]) i = [[1,2,3,4],[5,6,7,8]] # 가중치를 설계합니다. 열:2, 행4개의 행렬 구조입니다. W = tf.placeholder(tf.float32, [4, 2]) w = [[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 |
플레이스홀더를 통해서, Input과 Weight에 행렬값을 세팅하게 되고, matmul을 통해서 행렬곱을 수행하게 됩니다. 위 소스를 실행하면, 행렬 연산으로 인해서 아래와 같은 결과값이 나오게 됩니다.
1 2 | [[ 30. 30.] [ 70. 70.]] | cs |
플레이스홀더의 사용법은 사실 외울 필요는 없습니다. 사용하다보면 자연스럽게 변수 대입하듯 연습이 될 것이기 때문입니다. 한번에 신경망 소스를 만들게 되면 사실 가장 오랫동안 하는 일은 코딩을 하는게 아니라 데이터를 정제하고, 튜닝작업에 많은 시간을 소요한다는 것을 알게 될 것입니다.
이전글