티스토리 뷰

이번 포스팅에서는 머신러닝 카테고리에서 포스팅한 선형 회귀에 대한 이해를 바탕으로 텐서플로우로 구현을 해볼 것이다.



텐서플로우는 다음과 같은 처리를 반복한다.


1. 텐서노드와 엣지로 이루어진 그래프를 빌드한다.

2. 세션을 통해서 그래프를 실행 시킨다. ( Session.run() )

3. 실행 결과를 기반으로 텐서 플로우는 다시 그래프를 업데이트 시키기 위해 W(가중치) 값과 b(바이어스) 값을 조절한다.


우리는 선형 회귀 모델에서 H(x) = Wx + b 라는 간단한 식을 알 수 있다.

이 간단한 식을 통하여 구현하게 되는데..


우리는 이와 같은 아주 간단한 데이터 셋이 있다고 하자.

X


이에 해당하는 코드를 작성하면 아래와 같다.

1
2
3
4
import tensorflow as tf
 
x_train = [1,2,3]
y_train = [1,2,3]
cs


그 다음 W(가중치) 값과 b(바이어스) 의 값을 지정해야 하는데 이는 학습을 위해 임의의 값( 아직 잘 모른다고 가정 )을 던져준다.

텐서플로우에서는 가중치와 바이어스에 해당하는 변수를 Variable 을 사용하여 나타낸다. 그리고 텐서 플로우가 알아서 이 값을 자동으로 조절해 줄 것이며 나중에 비용함수가 최소(minimize)가 되는 가중치와 바이어스 값으로 조정하게 된다.


1
2
= tf.Variable(tf.random_normal([1]), name="weight")
= tf.Variable(tf.random_normal([1]), name="bias")
cs



그리고 아래와 같이 간단한 모델을 설계한다.

비용 함수는 아래와 같이 가설 데이터와 실제 데이터의 뺀 값의 2승의 합을 구해 데이터의 개수 만큼 나누는 것이다. ( 머신러닝 카테고리에 비용함수를 구하는 식 참조 )

그 함수로 텐서플로우의 tf.square() 와 tf.reduce_mean() 을 사용한다.



1
2
3
hypothesis = x_train * W + b
 
cost = tf.reduce_mean(tf.square(hypothesis - y_train))
cs


즉, cost가 주어졌을 때 이것을 최소로 하는 값이 가장 적합도가 좋은 것이라 볼 수 있다.


텐서플로우에서는 cost 값을 최소화 하기 위해 최적화 알고리즘인 경사 하강법(Gradient Desent)를 활용한다.

이에 대해서는 나중에 자세히 포스팅 하겠다!



텐서플로우에게 학습도를 0.01로 준 경사 하강법 알고리즘을 실행한다.

(학습률의 값이 너무 크거나 작으면 적합도가 좋은 곳을 찾아갈 수 없기 때문에 보통 이 학습률의 값을 조정해가면서 올바르게 학습이 진행되고 있는지 계속해서 확인하고 변경하게 된다)


1
2
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
train = optimizer.minimize(cost)
cs


그럼 이렇게 최종적으로 그래프가 구현이 되었다 
이제 이것을 세션 위에 올려 그래프를 실행 시켜 보자!
(다들 이제는 알겠지만, 텐서플로우의 Variable을 초기화 시키기 위해 global_variables_initializer() 함수를 사용 했다)

1
2
sess = tf.Session()
sess.run(tf.global_variables_initializer())
cs


이제 이 모델을 2천번 가량 학습을 시키면서 중간 중간의 파라미터의 출력 값을 관찰하면 된다.
실제로 이 모델이 잘 동작하고 있는지 한번 들여다보자

1
2
3
4
5
for step in range(2001):
    sess.run(train)
    if(step % 20 == 0):
        print(step,'\t', sess.run(cost),'\t', sess.run(W), '\t', sess.run(b))
  
cs


실제로 training을 하게되면 cost 의 값을 점점 최소화 하게 되고 이에따라 hypothesis 의 W와 b 의 값을 조정하게 된다.

우리는 W와 b의 값에 랜덤 데이터 값을 주었다.
위의 트레이닝의 모델로 봤을 때 W=1 그리고 b=0 으로 수렴하는지 지켜보면 된다.

그 결과는, 각 컬럼은 트레이닝 횟수, cost, W, b 의 값을 나타낸다.
0번째 수행결과에서... 최종 2000번의 수행결과를 봤을 때 W와 b의 값이 각 1과 0으로 수렴하는 것을 알 수 있다.
0 	 3.71932 	 [ 0.12182671] 	 [-0.03395895]
20 	 0.0449641 	 [ 0.80498177] 	 [ 0.25000292]
40 	 0.0106179 	 [ 0.87526667] 	 [ 0.26514038]
60 	 0.00936938 	 [ 0.88694853] 	 [ 0.25523993]
80 	 0.00850695 	 [ 0.89281565] 	 [ 0.24348839]
100 	 0.00772613 	 [ 0.89790565] 	 [ 0.23206855]
120 	 0.00701699 	 [ 0.90270871] 	 [ 0.22116441]
140 	 0.00637294 	 [ 0.90728158] 	 [ 0.21077074]
160 	 0.00578801 	 [ 0.91163903] 	 [ 0.20086528]
180 	 0.00525677 	 [ 0.91579169] 	 [ 0.19142532]
200 	 0.00477427 	 [ 0.9197492] 	 [ 0.18242902]
... (중략)
1800 	 2.158e-06 	 [ 0.99829382] 	 [ 0.00387848]
1820 	 1.95991e-06 	 [ 0.99837399] 	 [ 0.00369623]
1840 	 1.78005e-06 	 [ 0.99845046] 	 [ 0.00352253]
1860 	 1.61677e-06 	 [ 0.99852324] 	 [ 0.00335701]
1880 	 1.46824e-06 	 [ 0.99859262] 	 [ 0.00319926]
1900 	 1.33362e-06 	 [ 0.99865872] 	 [ 0.00304891]
1920 	 1.21128e-06 	 [ 0.99872178] 	 [ 0.00290566]
1940 	 1.09992e-06 	 [ 0.9987818] 	 [ 0.00276912]
1960 	 9.99065e-07 	 [ 0.99883902] 	 [ 0.00263902]
1980 	 9.07399e-07 	 [ 0.99889362] 	 [ 0.00251501]
2000 	 8.2407e-07 	 [ 0.99894565] 	 [ 0.00239682]


그렇다면 X와 Y에 해당하는 트레이닝 값을 명시적으로 주지 않을 경우에는 어떻게 할까?

이때는 텐서플로우의 placeholder 를 사용하여 그릇을 만들고 필요할 때 마다 feed 값을 던진다.

아래와 같이 shape를 None으로 설정한 이유는 1차원 데이터 (배열) 가 여러개 들어 올 수 있게 끔 설정 한 것이다.


1
2
= tf.placeholder(tf.float32, shape=[None])
= tf.placeholder(tf.float32, shape=[None])
cs


1
2
3
4
hypothesis = x * W + b
cost = tf.reduce_mean(tf.square(hypothesis - y))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
train = optimizer.minimize(cost)
cs




위와 동일하게 다시 학습을 하는데 학습을 시작하는 시점에 feed 값을 던진다.


1
2
3
4
5
6
for step in range(2001):
    _cost, _W, _b, _ = \
        sess.run([cost, W, b, train],
                feed_dict={x:[1,2,3,4,5], y:[2.1,3.1,4.1,5.1,6.1]})
    if step % 20 == 0:
        print(step, _cost, _W, _b)
cs



이와 같이, 학습 데이터의 파라미터를 던져주어서 학습하게 되었으면 테스트 데이터를 통하여 기대하는 값이 출력 되는지 실행하면.. (X의 파라미터를 던져 Y의 값을 기대해 본다.)


1
2
3
print(sess.run(hypothesis, feed_dict={x: [5]}))
print(sess.run(hypothesis, feed_dict={x: [2.5]}))
print(sess.run(hypothesis, feed_dict={x: [1.53.5]}))
cs



출력 값은 다음과 같다.

[ 6.10102272]
[ 3.59918356]
[ 2.5984478   4.59991932]


오늘도 모두의 딥러닝의 김성훈 교수님께 감사의 말씀 전하면서 포스팅을 마치겠다.



※ 해당 포스팅은 정리의 개념으로 남긴 포스팅이며 조금씩 틀린부분이 있을 수도 있습니다. 지나가다 보시면 댓글로 지적이 나 태클 부탁드립니다.!



반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함