텐서플로우의 변수

변수의 생성

  • 텐서와 연산(Op) 객체는 변경할 수 없다. 그러나 기계 학습의 속성 상 시간에 따라 변경되는 값을 저장할 수 있는 방법이 필요

  • 텐서플로우에서는 sess.run()을 여러 번 호출하는 동안 값을 유지하면서 변경하기 위해 변수(variable) 객체를 사용

  • tf.Variable() 생성자를 사용하여 변수 객체를 생성
import tensorflow as tf

my_var = tf.Variable(3, name="my_variable")


  • 변수는 텐서를 사용할 수 있는 어떤 텐서플로우 함수/연산에서도 사용 가능

    • 변수의 현재값은 변수를 사용하는 연산에 전달
add = tf.add(5, my_var)
mul = tf.multiply(8, my_var)


  • 변수의 초기값은 보통 많은 0이나 1 또는 난수들로 이루어진 큰 텐서들(large tensors)이다.
    • 이런 일반적으로 많이 사용되는 값들을 만들기 쉽게 다양한 연산이 존재
    • tf.zero() : 영으로 이루어진 텐서
    • tf.ones() : 1로 이루어진 텐서
    • tf.random_normal() : 정규분포를 따르는 난수들로 이루어진 텐서
    • tf.random_uniform() : 난수로 균등하게 이루어진 텐서
# 2x2 영 행렬
zeros = tf.zeros([2, 2])

# 길이가 6인 1로 이루어진 벡터
ones = tf.ones([6])

# 평균이 0이고 표준편차가 2인 정규 분포를 따르는 난수로 이루어진 3x3x3 텐서
normal = tf.random_normal([3, 3, 3], mean=0.0, stddev=2.0)

# 0과 10 사이 난수로 균등하게 이루어진  3x3x3 텐서
uniform = tf.random_uniform([3, 3, 3], minval=0, maxval=10)


    • tf.truncated_normal() : 평균에서 표준편차 이상의 값은 생성하지 않기 때문에 텐서 내부의 1~2개의 값이 다른 값들과 많은 차이가 날 가능성을 방지해준다.

# trunc 텐서에는 3이하나 7이상의 값이 없다.
trunc = tf.truncated_normal([2, 2], mean=5.0, stddev=1.0)


  • 위와 같은 연산은 텐서를 만들 때 변수의 초기값을 전달할 수 있다.

# 평균이 0이고 표준편차가 1인 정규분포를 따르는 난수로 이루어진 2x2 행렬
random_var = tf.Variable(tf.truncated_normal([2, 2]))



변수의 초기화

  • 변수 객체는 다른 텐서플로우의 다른 객체들처럼 그래프 내부에 존재

  • 변수의 상태는 Session()에 의해 관리됨

  • 변수를 사용하기 위해서는 세션 내부에서 변수들을 초기화해야 한다!

  • 초기화가 이루어지면 Session()이 변수의 현재 값들을 추적

  • 초기화 : tf.global_variables_initializer() 연산을 사용하여 sess.run()에 전달

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


  • 그래프에서 정의된 변수들의 일부분(subset)만 초기화하려면 tf.variables_initializer=()를 사용

    • 초기화될 변수들의 리스트를 받아들임

var1 = tf.Variable(0, name="initialize_me") var2 = tf.Variable(1, name="no_initialization") init = tf.variables_initializer([var1], name="init_var1") sess = tf.Session() sess.run(init)



변수값 변경하기

  • 변수값을 변경하기 위해서는 변수.assign() 메서드를 사용

  • 변수.assign()은 연산이기 때문에 세션에서 실행되어야 효과가 발생

import tensorflow as tf # 변수에 값 1을 할당 my_var = tf.Variable(1) # 연산이 실행될 때마다 변수에 2를 곱하는 연산 my_var_times_two = my_var.assign(my_var * 2) # 연산 초기화 init = tf.global_variables_initializer() # 세션 시작 sess = tf.Session() # 변수 초기화 sess.run(init) # 변수에 2를 곱한 결과 2를 반환 sess.run(my_var_times_two) # 변수에 2를 곱한 결과 4를 반환 sess.run(my_var_times_two) # 변수에 2를 곱한 결과 8을 반환 sess.run(my_var_times_two)


  • 세션을 통해 위의 코드를 실행한 결과
# 위의 코드를 다음과 같이 실행
print(f"1번째 세션 실행 결과 = {sess.run(my_var_times_two)}")
print(f"2번째 세션 실행 결과 = {sess.run(my_var_times_two)}")
print(f"3번째 세션 실행 결과 = {sess.run(my_var_times_two)}")

# 결과는 예상대로 다음과 같다.
1번째 세션 실행 결과 = 2
2번째 세션 실행 결과 = 4
3번째 세션 실행 결과 = 8


  • 변수값의 증가 :  변수.assign_add() 메서드를 사용

  • 변수값의 감소 :  변수.assign_sub() 메서드를 사용

# 변수에 값 1을 증가시킴
sess.run(my_var.assign_add(1))

# 변수에 값 1을 감소시킴
sess.run(my_var.assign_sub(1))


  • 앞의 코드에서 변수의 값을 증감하여 실행한 결과

import tensorflow as tf my_var = tf.Variable(1) my_var_times_two = my_var.assign(my_var * 2) init = tf.global_variables_initializer() sess = tf.Session() sess.run(init) print(f"1번째 세션 실행 결과 = {sess.run(my_var_times_two)}") print(f"2번째 세션 실행 결과 = {sess.run(my_var_times_two)}") # 변수에 값 1을 증가시킴 print(f"1을 증가시킨 my_var = {sess.run(my_var.assign_add(1))}") print(f"1을 증가시킨 후 1번째 세션 실행 결과 = {sess.run(my_var_times_two)}") print(f"1을 증가시킨 후 2번째 세션 실행 결과 = {sess.run(my_var_times_two)}") # 변수에 값 1을 감소시킴 print(f"1을 감소시킨 my_var = {sess.run(my_var.assign_sub(1))}") print(f"1을 감소시킨 후 1번째 세션 실행 결과 = {sess.run(my_var_times_two)}") print(f"1을 감소시킨 후 2번째 세션 실행 결과 = {sess.run(my_var_times_two)}") # 실행 결과 1번째 세션 실행 결과 = 2 2번째 세션 실행 결과 = 4 1을 증가시킨 my_var = 5 1을 증가시킨 후 1번째 세션 실행 결과 = 10 1을 증가시킨 후 2번째 세션 실행 결과 = 20 1을 감소시킨 my_var = 19 1을 감소시킨 후 1번째 세션 실행 결과 = 38 1을 감소시킨 후 2번째 세션 실행 결과 = 76



세션에 따른 변수값의 변화

  • 변수들은 세션에 따라 독립적으로 관리된다.
  • 각 세션은 그래프에 정의된 변수들의 현재값을 가진다.

import tensorflow as tf

# 변수에 0을 할당하고 초기화
my_var = tf.Variable(0)
init = tf.variables_initializer([my_var])

# 2개의 세션을 만든다.
sess1 = tf.Session()
sess2 = tf.Session()

# 세션1에서 변수를 초기화하고 5를 증가시킨다.
sess1.run(init)
result1 = sess1.run(my_var.assign_add(5))
print(f"세션1 : 초기화 후 변수에 5 증가시킨 결과 = {result1:02}")

# 세션2에서 변수를 초기화하고 2를 증가시킨다.
sess2.run(init)
result2 = sess2.run(my_var.assign_add(2))
print(f"세션2 : 초기화 후 변수에 2 증가시킨 결과 = {result2:02}")

# 세션1에서 변수를 초기화하지않고 변수에 다시 5를 증가시킨다.
print(f"세션1에 다시 5를 증가시킨 결과 = {sess1.run(my_var.assign_add(5)):02}")

# 세션2에서 변수를 초기화하지않고 변수에 다시 2를 증가시킨다.
print(f"세션2에 다시 2를 증가시킨 결과 = {sess2.run(my_var.assign_add(2)):02}")

# 실행 결과
세션1 : 초기화 후 변수에 5 증가시킨 결과 = 05
세션2 : 초기화 후 변수에 2 증가시킨 결과 = 02
세션1에 다시 5를 증가시킨 결과 = 10
세션2에 다시 2를 증가시킨 결과 = 04



변수를 초기값으로 재설정하기

  • 전체 변수 초기값으로 재설정 : tf.global_variables_initializer()를 다시 호출
  • 변수의 일부분만 초기값으로 재설정 : tf.variables_initializer()를 다시 호출

import tensorflow as tf

# 변수에 0을 할당
my_var = tf.Variable(0)
init = tf.global_variables_initializer()

# 세션을 만들고 변수를 초기화
sess = tf.Session()
sess.run(init)

# 변수에 10을 증가시킴
result = sess.run(my_var.assign_add(10))
print(f"my_var 변수에 10을 증가시킨 결과 = {result}")

# 변수를 다시 초기화
sess.run(init)
print(f"초기화한 후의 my_var의 값= {sess.run(my_var)}")



+ Recent posts