텐서플로우의 변수
변수의 생성
텐서와 연산(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)}")