1-15 TensorFlow 머신러닝 입문: 3점 데이터 선형회귀 예제

codingart(66)
Published in
#kr
Words
645
Reading
3 min
Listen
Play
8y

선형회귀 문제를 다룰려면 세상에서 일어나는 사실적인 통계 데이터를 사용하는 것이 제일 좋을 것이다. 하지만 TensorFlow 사용법을 배우는 취지 측면에서 너무나도 자명하면서 간단한 즉 선형회귀 분석을 하지 않아도 답을 알 수 있을 정도의 간단한 문제를 TensorFlow 로 적용하여 풀어보는 것도 좋을 듯하다.

TensorFlow를 설치하여 사용하는 방법에 대해서 알아보자. 간단한 방법 중의 하나로는 라즈베리파이 보드에서 Python2(IDLE) 또는 Python3(IDLE)를 사용하는 편집 실행하는 것이다. 윈도우즈10에서는 Anaconda 로 설치하여 Spyder3 편집기를 사용하는 방법이 있다. 본 블로그의 선형회귀 문제는 간단한 예제이므로 Python 2 나 Python 3 어느 버전을 사용해도 문제가 없다. 참고로 라즈베리 파이에 설치되는 TensorFlow는 1.0 수준이며 아나콘다에서는 TensorFlow 1.6 버전이 설치됨과 아울러 Python 3.5버전이 탑재된다.

3개의 점 데이터 (1,1), (2,2), (3,3) 을 사용하여 TensorFlow 라이브러리 모듈을 사용하는 선형회귀 문제를 코딩해 보자.

헤더 영역에서 tensorflow 모듈을 불러 오자.
import tensorflow as tf

3개의 점 데이터 (1,1), (2,2), (3,3) 를 x_train 과 y_train 으로 나누어 코드에서 편하게 사용할 수 있는 list 형태로 데이터를 표현하자.
x_train = [1, 2, 3]
y_train = [1, 2, 3]

이 데이터 세트들을 대상으로 y = W*x + b 형태로 선형회귀 형태를 설정하자. 웨이트 W 와 바이아스 b 는 경사 하강법에서 반복적인(iterative) 루틴을 적용하여 계산되며 처음에는 정규 분포하는 난수로 초기값을 지정한다. [1]은 shape 지정이다. 예를 들어 2X2 matrix 라면 [2,2]가된다. [1]은 그냥 숫자라 보면 될 것이다. 그밖에 아무런 지정이 없으므로 난수의 평균값과 표준편차에 대한 default 기준이 적용될 것이다.
W = tf.Variable(tf.random_normal([1]), name='weight')
b = tf.Variable(tf.random_normal([1]), name='bias')

경사하강법이 반복적인 루틴에 의한 TensorFlow 코드실행에 의해서 특정 값으로 접근내지는 수렴하게 될 웨이트 W 와 바이아스 b를 사용하여 반복적인 루틴 과정에서 계산되는 잠정적인 함수 값 hypothesis를 계산하자.
hypothesis = x_train * W + b

경사 하강법에서의 반복적인 루틴 계산에서 3개의 list 데이터 x_train 값에 대응하여 계산되는 잠정적인 hypothesis 값은 y_train 값과 차이 즉 오차를 가지게 되므로 그 3개의 오차를 제곱해서 합하여 평균을 취하여 cost 함수로 두자. cost 함수는 결국 결정되어야 할 웨이트 W와 바이아스 b의 함수가 됨을 의미한다.
cost = tf.reduce_mean(tf.square(hypothesis – y_train))

cost 함수 계산 코드에 의하면 제곱 과정이 들어 있으므로 W 와 b 에 대한 2차식 형태이므로 2차 항의 계수가 플러스라면 당연히 최소값을 가지게 될 것이다.

noname01.png

학습율 값 즉 learning rate 값을 지정하여 GradientDescent 경사하강법을 적용한다.
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)

learning rate α는 다음과 같이 cost 함수를 계산하는 반복루틴 과정 중에서 현재의 (W,b) 좌표에서 다음 번 좌표 값으로 변경하기 위한 증분 값을 계산하는데 사용된다.

그냥 미분이 아니고 편미분이 사용되는 까닭은 cost 함수의 독립 변수가 W 와 b 2개이기 때문이다. 아래 그림에서 는 우묵하게 패인 surface에서 바이아스 b 의 값을 상수로 묶어두었을 때 기울기를 뜻한다.
learning rate 즉 α값이 적당하면 점차적으로 경사를 따라 내려가게 되므로 현 단계와 다음 단계의 cost 함수의 값의 차이가 점차 줄어 들게 되어 최소값을 찾을 수 있게 된다. 물론 변수가 W 와 b 2개이므로 입체적으로 하강하게 될 것이다.
만약 learning rate 값이 즉 α값이 지나치게 크면 반대편 쪽의 경사 값이 더 큰 곳이로 이동해 버리게 된다. 따라서 대략 0.01∼0.5 사이의 적정한 learning rate α값을 주어야 한다.

cost 함수까지 준비가 되었으면 학습훈련을 정의하자.
train = optimizer.minimize(cost)

이 단계까지가 TensorFlow를 사용한 일종의 정식화 단계로 보인다. 구체적인 계산은 Session을 설정하여 이루어진다. Session 에서는 반복루틴의 횟수 즉 step 수를 지정하고 필요하다면 반복루틴과정에서 계산되는 파라메터들의 출력이 이루어진다.
sess = tf.Session()
sess.run(tf.global_variables_initializer())

for step in range(51):
sess.run(train)
if step % 10 == 0:
print(step, sess.run(cost), sess.run(W), sess.run(b))

아래는 아나콘다 스파이더3에서의 계산 결과 출력 사례이다. step 수가 커질수록 cost 함수가 작아진다. 아울러 W는 1.0에 b는 0.0에 수렴함을 볼 수 있다.

noname02.png

아울러 TensorFlow 연산과정에서 step 에 따른 cost 함수를 plot 해보기 위해서는 코드를 TensorBoard 기능을 사용할 수 있도록 다시 재작성해야 한다. 이 기능을 사용하게 되면 별도의 웹페이지가 생성되어 코드의 노드 구조와 cost 함수의 그래프 정보를 모니터 할 수 있다.

사이트에 첨부된 다음 코드를 실행해 보자.
//linear_regression_01.py
import tensorflow as tf

x_train = [1, 2, 3]
y_train = [1, 2, 3]

W = tf.Variable(tf.random_normal([1]), name='weight')
b = tf.Variable(tf.random_normal([1]), name='bias')

hypothesis = x_train * W + b
cost = tf.reduce_mean(tf.square(hypothesis - y_train))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
train = optimizer.minimize(cost)

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

for step in range(101):
sess.run(train)
if step % 20 == 0:
print(step, sess.run(cost), sess.run(W), sess.run(b))