9. 텐서플로우 Basic

지금부터 텐서플로우에 대해서 알아보자


텐서플로우는 모든 프로그램이 계산 그래프 (computational graph)를 통해 구성되며, 이 계산 그래프가 CPU, GPU 등의 연산장치에서 작동된다.

계산 그래프란 프로그램의 계산 구조를 정의하는 방향성 그래프 (directional graph)를 말한다.


계산 그래프는 노드 (node)와 엣지 (edge)로 구성된다. 노드는 계산 그래프에서 값들의 계산하는 등의 작업을 나타낸다.

텐서플로우에서 노드는 오퍼레이션(OP)라고 부른다. 그리고 실제 값을 전달하는 것이 엣지이다. 엣지는 화살표로 표현된다.


텐서플로우의 계산 그래프는 엣지를 따라 텐서(tensor)라는 형태로 값이 다른 오퍼레이션으로 이동한다고 말한다. 

그래서 언어 이름이 텐서(tensor)의 흐름(flow)이다.

텐서는 데이터를 표현하는 기본 단위로 다차원(multi-dimensional) 행렬을 의미한다.


Session

텐서는 Spark의 RDD(Resilient Distributed Dataset)과 개념이 비슷하다.

공통점은 정의되었을 때 실행되는게 아니라 실제 연산을 수행할 때 실행한다.


import tensorflow as tf

x = tf.constant(8)
y = tf.Variable(x + 17)
print(y)

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
print(sess.run(y))

실행결과

<tf.Variable 'Variable:0' shape=() dtype=int32_ref>
25

tf.global_variables_initializer()는 세션 속의 tf.Variable 형태로 저장한 변수를 초기화 해주는 기능을 수행한다.


텐서플로우는 세션을 기준으로 성능을 향상시키기 위해 정의와 실행을 분리하였다.

파이썬은 다른 프로그램 언어에 비해 실행속도가 느린 단점이 있다. 이를 극복하기 위해 외부에서 연산을 수행하는 numpy와 같은 라이브러리를 사용하지만 외부에서 연산한 값이 파이썬으로 전환될 때 오버헤드가 발생하는 문제가 생깁니다.

텐서플로우는 이런 오버헤드를 피하기 위해 세션 이전에는 파이썬에서 계산 그래프를 그리고 세션을 통해 계산 그래프를 CPU와 GPU가 처리할 수 있는 다른 언어로 변환하여 연산하는 방법으로 속도 문제를 극복한 것이다.


텐서플로우 자료형


텐서플로우 자료형파이썬 자료형설명
DT_FLOATtf.float3232 비트 실수형
DT_DOUBLEtf.float6464 비트 실수형
DT_INT8tf.int88 비트 정수형
DT_INT16tf.int1616 비트 정수형
DT_INT32tf.int3232 비트 정수형
DT_INT64tf.int6464 비트 정수형
DT_UINT8tf.uint88 비트 부호 없는 정수형
DT_UINT16tf.uint1616 비트 부호 없는 정수형
DT_STRINGtf.string

가변 길이 문자열 배열

DT_BOOLtf.bool

boolean

DT_COMPLEX64tf.complex6432 비트 실수형과 복소수의 조합

DT_COMPLEX128tf.complex128

64 비트 실수형과 복소수의 조합

DT_QINT8tf.qint8

양자화된 오퍼레이션 안에서 사용되는 8비트 부호 있는 정수형

DT_QINT32tf.qint32

양자화된 오퍼레이션 안에서 사용되는 32비트 부호 있는 정수형

DTQUINT8tf.quint8

양자화된 오퍼레이션 안에서 사용되는 8비트 부호 없는 정수형

상수

상수는 변경할 수 없는 고정된 값을 말하며 tf.constant()를 통해 생성한다.

import tensorflow as tf

a = tf.constant([1, 2, 3, 4, 5, 6, 7, 8, 9])
b = tf.constant([[[1, 1], [2, 2]], [[3, 3], [4, 4]]])

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
print(sess.run(tf.reshape(a, [3, 3])))
print(sess.run(tf.reshape(b, [2, 4])))
print(sess.run(tf.reshape(b, [-1])))

실행결과

[[1 2 3]
 [4 5 6]
 [7 8 9]]
[[1 1 2 2]
 [3 3 4 4]]
[1 1 2 2 3 3 4 4]

행렬의 곱셉
import tensorflow as tf

a = tf.constant([[1., 2.]])
b = tf.constant([[3.], [4.]])

product = tf.matmul(a, b)
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
result = sess.run(product)
print(result)
print(result.shape)
sess.close()
실행결과
[[ 11.]]
(1, 1)

변수

변수는 tf.Variable()을 사용해서 만든다.
만약 세션 속에서 변수의 값을 변경하고 싶다면 tf.assign() 함수를 이용한다.
import tensorflow as tf

state = tf.Variable(0)
one = tf.constant(1)

new_value = tf.add(state, one)
update = tf.assign(state, new_value)

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
print(sess.run(state))
for _ in range(5):
sess.run(update)
print(sess.run(state))
sess.close()
실행결과
0
1
2
3
4
5

Placeholder

텐서플로우의 또 다른 데이터 저장형이다. Placeholder는 초기값을 입력하지 않고 정의한다는 특징이 있다.
세션 속에서 함수처럼 원하는 값을 넣고 실행할 수 있다는 장점을 가지고 있다.
tf.placeholder()는 데이터타입과 feed를 통해 데이터 모양을 정의한다.
import tensorflow as tf

x = tf.placeholder(tf.float32, [2])

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
print(sess.run(x, feed_dict={x: [1, 3]}))
sess.close()
실행결과
[ 1.  3.]

import tensorflow as tf

x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)

output = tf.multiply(x, y)

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
print(sess.run(output, feed_dict={x: [10.], y: [20.]}))
sess.close()

실행결과

[ 200.]


텐서플로우 기본 함수



함수설명
tf.add(x, y)

x값과 y값의 덧셈을 반환한다.

tf.add(2000, 17)

tf.subtract(x, y)

x값고 y값의 뺄셈을 반환한다.

tf.subtract(20, 17)

tf.multiply(x, y)x값과 y값의 곱셈 값을 반환한다.
tf.divide(x, y)x값과 y값의 나눗셈의 몫을 반환한다.
tf.abs(x)x의 절대값을 반환한다.
tf.squre(x)x의 제곱을 반환한다.
tf.less(x, y)x의 값이 y의 값보다 크면 true를, 적다면 false를 반환한다.
tf.sqrt(x)x의 제곱근을 반환한다.
tf.assign(x, y)y값을 x값에 대입하여 x값을 업데이트 한다.
tf.transpose(a, perm=none)

perm에 따라 a 변수들의 차원을 변경한다.

a = [[1,2],[3,4]]

tf.transpose(a, perm=[1,0]) #[[1,3],[2,4]]

tf.random_uniform(shape, minval, maxval, dtype, seed)

정규분포를 따르는 난수를 생성한다.

tf.random_uniform([1],0,1)

tf.maximum(x, y)x, y중 최대값을 리턴한다.
tf.minimum(x, y)x, y중 최소값을 리턴한다.
tf.reduce_mean(x)

x의 평균값을 구한다.

x = tf.Variable([[1, 2, 3], [4, 5, 6]])

y = tf.reduce_mean(x)

tf.reduce_sum(x)

x의 합을 구한다.

x = tf.Variable([[1, 2, 3], [4, 5, 6]])

y = tf.reduce_sum(x)


이상으로 텐서플로우에 대한 기본 내용을 마친다.