728x90
Tensorflow는 현존하는 머신러닝 프레임워크 중 가장 유명한 프레임 워크이다.

필자가 딥러닝을 배우기시작하면서 선택한 프레임워크인데 생각보다 어렵지는 않다.


그러나 필자가 블로그에 포스팅 하는 부분들 중에서는 거의 해본적없는 분야이고

빨리 빨리 바뀌기에 이 포스터는 항상 맞을수 없다고 볼 수 있다.

그러기 때문에 읽는 입장에서 그 부분을 고려해서 읽길 바란다.


이 포스터는 Python3.6으로 Tensorflow1.2로 테스팅 했으며 작업환경은 PyCharm이며 특별한 경우가 아니면 쉘에서 실행하지 않음.


저번시간까지 그냥 무작정 실습을 했다. 이번시간에는 텐서가 뭔지에 대해서 가볍게 설명하고 넘어가겠다.

텐서 = n차원의 행열을 의미한다. 즉 텐서는 행열이며 행열은 영어로 Matrix이다.

다시 전시간의 강의의 코드를 한번 보자.


import tensorflow as tf

a = tf.constant(5, name='input_a')
b = tf.constant(7, name='input_b')

c = tf.multiply(a, b, name='mul_c')
d = tf.add(a, b, name='add_d')
e = tf.add(c, d, name='add_e')

sess = tf.Session()
print(sess.run(e))


이 코드에서 뭐가 텐서일까? 정말 간단한데 input_a와 input_b가 텐서이다.

이 데이터들은 몇차원일까? 0차원이다.


즉 일반적인 자료형들은 당연히 배열이 아니며 배열이 아니기에 행열이라고 할 수 없다.

그러나 조금 세련되게 이야기를 하자면 행열이 아니라기보다는 0차원 행열이라고 할 수 있다.


텐서플로우에서는 중요한것은 텐서의 값(value)과 타입(dtype), 그리고 모양(shape)이다.

아래에서는 이들에 대해서 알아보자.


파이썬의 기본자료형을 텐서로 사용


D0_Scalar = 15
D1_Vector = [1,2,3]
D2_Matrix = [[1,2],[3,4]]
D3_Tensor = [[[1,2],[3,4]],[[5,6],[7,8]]]


여기서 리스트(배열)에 들어있지 않은 데이터를 스칼라 데이터라 부르며 이는 0차원 텐서이다.

이제 1차원 리스트에 들어있는 값을 보자. 이 값은 1차원 텐서이며 벡터라고 부른다.

또한 2차원 리스트에 들어있는 값은 매트릭스라구 부르며 2차원 텐서라고 부른다.

3차원 부터는 그냥 3차원 텐서라고 부른다.

즉 모든 입력 값은 텐서라고 할 수 있다.


텐서플로우에서 파이썬의 기본자료형을 텐서로 사용해도 된다. 애당초 그렇게 설계되어있으니까.

그러나 일반적으론 파이썬의 리스트를 텐서로 사용하기는 조금 애매한 면이 있다.

그 이유는 아래에서 설명하도록 하겠다.


텐서플로우 데이터 형


여러분이 파이썬에 대해서 기억을 한다면 파이썬에서는 상세한 자료형이 존재하지 않는다.

사실 파이썬의 특징이라기 보단 인터프리터 언어들은 대게 상세 자료형이 존재하지 않는다.

자료형이 존재한다고 해봐야 문자열(문자포함),부울린값,정수,실수형 정도이다.

그러나 텐서플로우는 일반 컴파일언어나 바이트코드언어처럼 자료형이 존재한다. 존재하는 자료형은 아래와 같다.


 자료형

 상세

tensorflow.int8

8비트 정수 

tensorflow.int16

16비트 정수 

tensorflow.int32

 32비트 정수

tensorflow.int64

 64비트 정수

tensorflow.uint8

8비트 0을 포함한 자연수 

 tensorflow.string

 문자열

 tensorflow.bool

 부울린값(True,False)

 tensorflow.complex64

 복소수

 tensorflow.qint8

 양자화 명령어용 8비트 정수

 tensorflow.qint32

 양자화 명령어용 21비트 정수

 tensorflow.quint8

 양자화 명령어용 8비트 0을 포함한 자연수

 tensorflow.float32

 32비트 실수

 tensorflow.float64

 64비트 실수


텐서플로우는 자료형을 사용하게 된다. 만약 자료형을 명시적으로 적지 않았다면 텐서플로우는 알아서 자료형을 추론해서 사용하게 된다.

예를들어서 위의 예제코드에서 print(a)를 해보자. 우리는 자료형을 선언하지 않았지만 알아서 int32로 인식하게된다.


이게 문제이다. 사실 파이썬 자료형을 그냥 쓰기에는 좀 문제가 있는데 부울린값이나 문자열같이 단 하나인 경우에는 문제가 없다.

그러나 정수나 실수등의 여러 자료형이 필요한 경우 파이썬 자료형은 연계에 문제가 생길 수 있다는 것이다.

그래서 텐서플로우에서는 numpy를 사용하는 경우가 많다.


numpy 배열을 텐서로 사용


numpy배열은 텐서플로우로 사용하기 정말 좋다.

텐서 플로우의 자료형은 numpy의 자료형을 무리없이 인식한다는 것이다.

아래의 코드를 보자.


import tensorflow as tf
import numpy as np

D0_scalar = 15
D1_Vector = [1.5, 2.5, 3.0]
D2_Matrix = [['read a', 'book'], ['write a', 'book']]
D3_Tensor = [[[True, True], [False, False]], [[True, False], [False, True]]]

at = tf.constant(D0_scalar, name='input_d0t', dtype=tf.int64)
bt = tf.constant(D1_Vector, name='input_d1t', dtype=tf.float32)
ct = tf.constant(D2_Matrix, name='input_d2t')
dt = tf.constant(D3_Tensor, name='input_d3t', dtype=tf.bool)

an = tf.constant(np.array(D0_scalar, dtype=np.int64), name='input_d0n')
bn = tf.constant(np.array(D1_Vector, dtype=np.float32), name='input_d1n')
cn = tf.constant(np.array(D2_Matrix), name='input_d2n')
dn = tf.constant(np.array(D3_Tensor, dtype=np.bool), name='input_d3n')

sess = tf.Session()

print(at)
print(an)
print(bt)
print(bn)
print(ct)
print(cn)
print(dt)
print(dn)


이 코드를 실행해 보면 numpy로 텐서를 선언할 수 있으며 이렇게 선언한 텐서는 텐서플로우와 대응한다는 것을 알 수 있다.

대부분은 일대일 대응이 되지만 numpy에는 string이 없는데 그냥 dtype을 선언하지 않으면 된다.

앞으로 실습을 할 때 numpy를 무조건 쓸지는 모르곘지만 정말 텐서플로우를 제대로 사용한다면 numpy를 사용하는게 좋다.


텐서 모양(Tensor shape)


텐서를 만들면서 텐서는 0~n까지 다양한차원이 존재할 수 있다는것을 알 수 있다.

마지막으로 설명할 것은 텐서 모양이며 한글로 번역하니까 조금 이상하긴한데 그냥 차원이라고 생각하면 편하다.


사실 지금 까지는 constant로 상수를 선언하였고 값을 직접 넣어줬기에 shape를 선언할 필요는 없다.

이 때 shape가 중요해지는 시기는 값을 확정지을수 없는 변수일때 필요하다.

텐서 모양을 선언함으로써 어떤 형태의 값을 넣어야하는지 강제할 수 있기 때문이다.


텐서 모양은 리스트와 튜플을 사용할 수 있다. 아래와 같은 형식으로 말이다.


shape_0l = []
shape_1t = (7)
shape_2t = (2, 3)
shape_2l = [None, 7]
shape_3l = [None, None, None]


만약 0차원 텐서라면 빈 튜플이나 리스트를 만들면 된다.

shape_1t는 길이가 7인 1차원 텐서이다.

shape_2t는 2차원 텐서이며 행과 열의 길이가 각각 2와 3인것 이다.

shape_2l의 경우 행이 None이다. 이게 의미하는 것은 무한대로 들어간다는 뜻이다.

+ Recent posts