텐서(tensor), 플레이스홀더(placeholder)와 변수

학습 환경은 tensorflow verison 1.15이다.

tensorflow version 1과 2는 상당히 차이가 있는 것 같지만 요즘에도 주로 사용되는 version 1을 먼저 학습하기로 하였다.

 

우선은 텐서플로우를 사용하기 위해서는 tensorflow 모듈을 import 해야 한다.

import tensorflow as tf

이때, 이후에 다른 버전을 이용해야 할 일이 생길 수도 있고 다른 모듈과 함께 사용하다가 버전 충돌이 발생할 수도 있다는 점을 고려하여 별도의 가상 환경을 구축하여 진행하기를 권장한다.

 

가상 환경을 생성하고 관리하는 방법은 이전 포스트에 기술해 두었다.

2020/07/13 - [개발 일지/ML] - Pycharm을 이용한 Anaconda 가상 환경(env) 설정

 

Pycharm을 이용한 Anaconda 가상환경(env) 설정

학습에 사용된 운영체제는 Windows이다. ​ Anaconda를 이용하면 필요에 따라 간편하게 여러 가상 환경을 생성/제거하고 사용할 수 있다. CMD를 이용한 가상 환경 관리 명령어는 다음과 같다. ' 가상환

devpanpan.tistory.com

 


 

Tensor(텐서): 다양한 식을 계산하기 위한 자료형
hi = tf.constant('Hi, World!')
print(hi)

위의 코드에서 변수 hi는 텐서 자료형에 해당한다. 해당 코드의 실행 결과는 다음과 같다.

Tensor("Const:0", shape=(), dtype=string)

텐서는 랭크(rank)와 셰이프(shape)라는 속성을 가진다. 랭크는 몇 차원인지, 셰이프는 차원당 요소의 개수가 몇 개인지를 나타낸다.

 

예를 들어, [[[1,2]], [[3,4]], [[5,6]]] 의 경우 랭크는 3이며 셰이프는 [3, 1, 2]이다. 셰이프를 모두 곱하면 총 요소의 개수를 알 수 있다.

 

텐서의 지연 실행

텐서플로우에서는 텐서들의 연산 모음을 통해 그래프를 생성하고, 이후 세션(Session)을 통해 실행하는 지연 실행 방식을 이용한다.

a = tf.constant(10)
b = tf.constant(20)
c = tf.add(a, b)
print(c)

위 코드의 결과는 다음과 같다.

Tensor("Add:0", shape=(), dtype=int32)

즉, 10과 20을 더하는 add 연산자를 호출했으나 그 결과는 30이 아님을 알 수 있다. 이후 다음과 같이 세션을 실행했을 때,

sess = tf.Session()
print(sess.run(hi))
print(sess.run([a, b, c]))
b'Hi, World!'
[10, 20, 30]

연산(대입, 산술)이 수행됨을 알 수 있다.

※ tensorflow version 2에서는 세션이 삭제되었으며, 연산이 호출 즉시 실행됨을 확인할 수 있었다.

(이유는 아직 안 배워서 모른다. 미래의 내가 알려 줄 것이다.)

 

 


 

플레이스홀더(placeholder) 변수
  • 플레이스홀더: 그래프에 사용할 입력값을 나중에 받기 위해 사용하는 매개 변수
  • 변수: 그래프의 최적화를 위한(학습 결과의 갱신을 위한) 변수
p = tf.placeholder(tf.int32, [None, 2])
print(p)

다음과 같이 플레이스홀더를 생성하면

Tensor("Placeholder:0", shape=(?, 2), dtype=int32)

이렇게 먼저 생성되고, 이후에 선언한 변수를 해당 변수로 지정해줄 수 있다.

# 플레이스홀더 p에 할당할 변수 (2행 2열)
p_data = [[1, 2], [3, 4]]

# a는 2행 1열
a = tf.Variable([[1], [2]])
# b는 2행 1열
b = tf.Variable([[3], [4]])

result = tf.matmul(p, a) + b

다음과 같이 선언했을 때,

sess = tf.Session()
# 정의한 변수들 초기화
# 최초 실행 시 반드시 호출
sess.run(tf.global_variables_initializer())

print('p_data: {}\na: {}\nb: {}'.format(p_data, sess.run(a), sess.run(b)))
print('result: {}'.format(sess.run(result, feed_dict={p:p_data})))
sess.close()

print(sess.run(result, feed_dict={p:p_data})) 해당 문장에서 플레이스홀더에 임의의 변수를 할당해 결과를 얻어낼 수 있다.

이 코드의 결과는 다음과 같았다.

p_data: [[1, 2], [3, 4]]
a: [[1]
 [2]]
b: [[3]
 [4]]
result: [[ 8]
 [15]]