(TensorFlow) 자료형과 기본적인 사용법
https://www.tensorflow.org/programmers_guide/graphs#building_a_tfgraph
텐서플로우는 dataflow-graph를 구성하고, graph의 일부를 Session으로 구성해 실행시키는 방식이다.
Note)단순히 TensorFlow API를 호출하는 것 만으로도tf.Graph 에tf.Operation (Node)와tf.Tensor (Edge)가 추가된다. 따라서 노드가 추가될 graph를 명시할 수 있는데, 명시하지 않는 경우 default graph에 추가된다. 다른 graph에 노드를 추가하려면 graph.as\_default()
를 사용한다. * with
가 끝나면 다시 default context다.
1
2
3
4
5
6
7
8
9
10
11
12
>>> import tensorflow as tf
>>> g1 = tf.Graph()
>>> with g1.as\_default() as graph:
... const1 = tf.constant(3) # g1에 const1 Node 생성 및 추가
...
>>> sess = tf.Session() # graph 명시하지 않으면 default graph 사용
>>> sess.run(const1)
RuntimeError: The Session graph is empty. Add operations to the graph before calling run().
>>> sess1 = tf.Session(graph=g1)
>>> sess1.run(const1)
3
* default graph와 default session은 현재 thread의 속성이다. 따라서 multi-thread인 경우 각각의 thread마다 다른 default graph/session을 가진다. * default graph는 자동으로 생성되며 default session은 None
이 기본이다.
이렇게 생성된 그래프를 실행하기 위해서는tf.Session 객체를 이용한다. 연산의 시작 지점이 되는 가지를 sess.run(fetches)
로 넘기면, 그 가지를 따라서 연산이 시작되는 방식이기 때문에 항상 그래프 전체를 실행할 필요 없이 그래프의 일부분(fetches
)만 넘겨서 실행할 수 있다. 또, feed\_dict
를 Session에 지정하기 때문에 같은 fetches
를 넘겨 graph의 같은 부분을 실행하더라도 서로 다른 상태(가중치 값)를 가지는 여러 Session을 만들 수 있다.
Session은 graph의 일부분(+초기값)을 대상으로 정의되기 때문에 graph에 종속적이다. Session(graph='')
을 호출하면서 graph를 지정할 수 있으며 지정하지 않으면 default graph를 사용한다.
Note ) sess.run()
에 여러 fetches를 넘기더라도, 각 노드의 값을 산출하기 위한 Ops는 한 번씩만 수행된다. 그러니까, 성능 고려할 필요 없이 무엇을 반환할지만 생각하면 된다.
tf.constant
1
2
3
4
5
6
7
8
9
10
11
12
import tensorflow as tf
const1 = tf.constant(3.0, tf.float32) # type 지정 해도 되고 안해도 된다.
const2 = tf.constant(4.0)
const\_add = tf.add(const1, const2)
print("node1:", const1, "\nnode2:", const2)
print("node3:", const\_add)
#단순히 print로 출력하면 tensorflow 객체가 출력되기 때문에
#내부에 있는 값을 보고 싶다면 sess.run()에 넣어야 한다.
sess = tf.Session()
print("sess.run(node1, node2): ", sess.run((const1, const2)))
print("sess.run(node3): ", sess.run(const\_add))
1
2
3
4
5
6
7
========== constant ===========
node1: Tensor("Const:0", shape=(), dtype=float32)
node2: Tensor("Const\_1:0", shape=(), dtype=float32)
node3: Tensor("Add:0", shape=(), dtype=float32)
sess.run(node1, node2): (3.0, 4.0)
sess.run(node3): 7.0
tf.placeholder
값만 가지고 있는거라, 입력 데이터를 받는 노드에 사용.
1
2
3
4
5
6
7
8
import tensorflow as tf
a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
adder\_node = a+b
print(sess.run(adder\_node, feed\_dict={a: 3, b: 4.5}))
print(sess.run(adder\_node, feed\_dict={a: [1, 3], b: [2, 4]}))
## float로 지정했기 때문에 배열 내부 데이터가 float로 간주된다.
1
2
3
4
========== placeholder ===========
7.5
[ 3. 7.]
tf.Variable
변하는, 즉 업데이트가 필요한 노드에 사용. 가중치라던가, 편향이라던가.
1
2
3
4
5
6
7
8
9
10
11
#matmul은 rank >= 2에서만 동작하기 때문에 한번 더 묶었다.
va = tf.Variable([[1, 2, 3]])
vb = tf.Variable([[1, 2, 3]])
result = tf.matmul(va, vb, transpose\_b=True)
sess = tf.Session()
## Variable을 사용하기 전에는 반드시 초기화해주어야 하므로
## Saver.restore()로 불러오지 않는 경우 아래 메서드를 호출해주어야 한다.
sess.run(tf.global\_variables\_initializer())
print("va, vb : ", sess.run((va, vb)))
print("result : ", sess.run(result))
1
2
3
4
========== Variable ===========
va, vb : (array([[1, 2, 3]], dtype=int32), array([[1, 2, 3]], dtype=int32))
result : [[14]]
Variable Scope
TensorFlow의 Variable scope 매커니즘은 두 개의 메인 함수로 구성되어 있다.
https://tensorflowkorea.gitbooks.io/tensorflow-kr/content/g3doc/how_tos/variable_scope/
https://www.tensorflow.org/api_docs/python/tf/get_variable
tf.get_variable(, , )
Creates or returns a variable with a given name. tf.Variable()
을 반환한다. tf.Variable()
은 value를 직접 지정하는 반면 tf.get\_variable()
은 initializer(shape을 넘기면 그 shape의 tensor를 반환하는 함수)를 지정하는 식으로 사용한다.
1
2
v1 = tf.get\_variable("v1", shape=[3], initializer = tf.contrib.layers.xavier\_initializer())
tf.variable_scope(<scope_name>)
Manages namespaces for names passed to tf.get\_variable()
. tf.variable\_scope()
를 사용해 py tf.get\_variable()
로 선언한 변수들을 각자 다른 namespace로 관리할 수 있다.