동아리 활동

선형회귀 (Linear Regression) 기본 소스코드 분석

떡잎몬 2018. 5. 13. 15:46
반응형

원본 소스 출처 : https://github.com/hunkim/DeepLearningZeroToAll/blob/master/lab-02-3-linear_regression_tensorflow.org.py

import tensorflow as tf

# Model parameters
W = tf.Variable([.3], tf.float32)
b = tf.Variable([-.3], tf.float32)

# Model input and output
x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)

linear_model = x * W + b

# cost/loss function
loss = tf.reduce_sum(tf.square(linear_model - y))  # sum of the squares

# optimizer
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)

# training data
x_train = [1, 2, 3, 4]
y_train = [0, -1, -2, -3]

# training loop
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)  # reset values to wrong
for i in range(1000):
    sess.run(train, {x: x_train, y: y_train})

# evaluate training accuracy
curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x: x_train, y: y_train})
print("W: %s b: %s loss: %s" % (curr_W, curr_b, curr_loss))

한줄 한줄 살펴보면,

import tensorflow as tf

tensorflow 라이브러리를 import 하여 tf로 약칭을 정한다. (이후로 tf 라고 타이핑한다면 tensorflow 라이브러리를 사용할 수 있도록 만든다.)

W = tf.Variable([.3], tf.float32)
W라는 변수를 만들고, tensorflow 내장함수인 Variable 함수를 이용하여 [0.3] 이라는 32비트 실수형 (float32) Variable을 지정한다.
b = tf.Variable([-.3], tf.float32)
b라는 변수를 만들고, tensorflow 내장함수인 Variable 함수를 이용하여 [-0.3] 이라는 32비트 실수형 (float32) Variable을 지정한다.
x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)
x와 y라는 변수를 만들고, tensorflow 내장함수인 placeholder 함수를 이용하여, 32비트 실수형 (float32) placeholder를 지정한다.
이때 Variable과 placeholder의 차이점을 간단히 말하자면, 
Variable은 0.3, -0.3 등과 같이 초기값을 미리 할당을 시켜주어야 하며, placeholder는 자료형만 주어져 값을 미리 할당시키지 않아 유연하다.
linear_model = x * W + b
linear_model 이라는 변수를 만들고, 위에서 만들었던 x(뒤에서 x_train으로 train할 x값을 할당) 와 W [0.3] 과 곱해 b [-0.3] 을 더하는 식으로 지정한다.

이는, 선형 회귀의 그래프를 그릴 수 있는 방정식이며, 뒤에서 주어지는 x_train 값을 넣었을때의 계산 결과 Y가 뒤에서 주어질 y_train 값과 일치하는 횟수가 가장 많은 최적의  W값과 b값을 구하기 위해 만든다.

loss = tf.reduce_sum(tf.square(linear_model - y))  # sum of the squares

loss라는 변수를 만들고, tensorflow 내장함수인 reduce_sum 함수와 square 함수를 이용하여 손실함수를 할당한다.

square는 제곱이며, 학습되어 예상된 Y값과 정답으로 주어진 Y값의 오차를 구해 제곱한 뒤 reduce_sum 함수로 값들을 모두 더한다.

optimizer = tf.train.GradientDescentOptimizer(0.01)
optimizer라는 변수를 만들고, tensorflow 내장함수인 GradientDecentOptimizer 함수를 이용해 0.01 간격의 optimizer를 할당한다.
optimizer는 손실함수를 최소화 하기 위해 조금씩 variable들을 변경한다. 이 소스코드에서는 W값과 b값을 변경한다.

train = optimizer.minimize(loss)
train이라는 변수를 만들고, 위 optimizer를 이용해 loss의 최솟값을 할당한다. 이 변수는 학습모델로 사용될 예정이다.
loss는 손실함수를 의미하며, 손실함수의 Variable인 Wb의 최솟값을 찾도록 동작시키며, 그 진행 방향이 loss가 작아지는 쪽을 의미한다.
x_train = [1, 2, 3, 4]
y_train = [0, -1, -2, -3]
x_train 과 y_train 으로 학습시킬 입력값과 출력값을 할당해준다. 
이 글의 알고리즘은 선형회귀이므로, 선형그래프와 비슷한 형태의 할당이면 더 효과적으로 결과를 받아볼 수 있다.
init = tf.global_variables_initializer()
트레이닝을 본격적으로 시작하기에 앞서, 세션을 초기화 하기 전에 Variable의 값을 global_variables_initializer()를 이용해 초기화 시켜놓는다.
sess = tf.Session()
sess.run(init)  # reset values to wrong
sess라는 변수를 만들고, 세션을 초기화시킨다. 
tensorflow의 세션 내장함수인 run함수를 사용해 위에서 초기화했던 Variable을 넣어준다.
for i in range(1000):
    sess.run(train, {x: x_train, y: y_train})
이제 반복문을 사용해 n번 (예시에서는 1000번) train이라는 위에서 만들었던 학습모델과 함께, feed_dict (생략가능) 자리의 x에 x_train, y에 y_train 값을 넣어 학습시킨다. 

curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x: x_train, y: y_train})

for문을 빠져나왔으면 (학습이 n번 완료되었으면), curr_w 변수와 curr_b 변수, curr_loss 변수를 각각 만들어,

curr_w 에는 학습 후 최적이라 판단된 W 의 값,

curr_b 에는 학습 후 최적이라 판단된 b의 값,

curr_loss 에는 학습 후 최적이라 판단된 최후의 오차값을 할당한다.

print("W: %s b: %s loss: %s" % (curr_W, curr_b, curr_loss))

최적의 값들을 출력해 본다.

실제 출력 결과이다. 

W 는 -1에 수렴하고있으며, b는 1에 수렴하고 있다. loss는 매우 적게 표시됨을 확인 할 수 있다. 



linear_regression_intro.py




반응형