딥러닝(텐서플로우): 간단한 선형 회귀(linear regression) 구현하기

Posted by 드린
2017. 5. 13. 08:00 IT

오늘은 딥러닝에서 기본적으로 알아야할 간단한 선형 회귀(linear regression)을 구현해보려고 해요.

선형 회귀의 공식은 이렇습니다.

H(x) = Wx + b

어디서 많이 봐왔던 공식같지 않나요?

네, 우리는 수학에서 일차방정식으로 y = x+1 같이 배워 왔지요.

여기서 H는 hypothesis으로 가설이라고 말하고, 상황에 따른 가설들이 나오게됩니다.

W는 Wegiht 그리고 b는 bias를 뜻하며, 가설을 위한 공식에 들어가는 구성요소입니다.


그럼 실습을 통해 알아보겠습니다.

baegui-MacBook-Pro:~ baeg$ python3

Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04) 

[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin

Type "help", "copyright", "credits" or "license" for more information.

>>> import tensorflow as tf

자 여기까지는 모두 익숙하시죠?


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

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

먼저 x와 y의 값이 정해져있습니다.

위의 뜻은 x가 1일때 y도 1이라는 뜻이예요.

[]는 배열을 선언하는 것이라고 저번시간에 알려드렸죠?


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

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

여기서 W와 b는 텐서플로우에서 제공하는 Variable이라는 함수를 사용합니다.

이것은 텐서플로우가 자체적으로 변경시키는 값이라고 생각하시면 됩니다.

이 Variable의 구성은 값, 이름을 지정하게 됩니다.

먼저 random_normal()은 랜덤한 값을 지정하는 것이고, [1]은 1차원 배열을 넣는다는 것을 뜻합니다.

[2]이면 2차원 배열을 넣는 것을 뜻하구요.


>>> hypothesis = x_train * W + b

이 부분은 위에서 보여드린 H(x) = Wx + b를 표현한것입니다.


이제 우리는 각 점과 점 사이의 차이를 알기위하여 다음과 같은 cost function을 사용합니다.

위에서 구해진 Hypothesis에 y를 빼준 뒤 제곱을 해줍니다.

그 이유는 일차방정식의 각 선들 즉, H선과 y점 사이의 거리가 얼마나 차이나는지를 계산하기 위함입니다.

제곱을 해주는 이유는 H-y는 음수 또는 양수가 나오기에 체크하기 어려워 모두 양수를 만들어 준다는 이유와

차이가 많이 나면 그만큼 제곱이 되기 때문에 각각의 차이를 확연하게 알수있습니다.

시그마는 아시죠? 1~m까지!

m만큼 값을 구해 더했기 때문에 1/m을 해주어 평균을 내줍니다.


이는 다음과 같이 구현합니다.

>>> cost = tf.reduce_mean(tf.square(hypothesis - y_train))

reduce_mean은 여러개의 값이 나왔을 때 평균을 내주는 것입니다.

square은 뜻 그대로 제곱을 해주는 것이구요.


>>> optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)

>>> train = optimizer.minimize(cost)

위의 코드는 0.01초 단위로 학습을 시키며,

해당 값을 최소화 시킨다는 뜻입니다.

자세한 것은 잘모르니 다른 글을 참고해주시기 바랍니다.

이 딥러닝은 값을 최소화시키는데 목적이 있기에 중요한 부분입니다.


>>> sess = tf.Session()

이제 출력을 위해 세션을 생성해줍니다.


>>> sess.run(tf.global_variables_initializer())

텐서플로우에서 변수는 초기화되어야 그 값이 변수에 지정되기에 초기화를 해주어야하는데,

그게 바로 global_variables_initializer()예요.


>>> for step in range(1001):

...     sess.run(train)

...     if step % 20 ==0:

...             print(step, sess.run(cost), sess.run(W), sess.run(b))

이제 우리는 1000번을 학습시켜 값을 찾아내려고 합니다.

이때 모두 출력하다보면 스크롤이 엄청 길어지기때문에, 20번마다 출력을 하도록 설정했습니다.

출력은 횟수, cost function결과, W, b 순으로 출력이 되었습니다.


0 9.79054 [-0.9934482] [ 1.31457281]

20 0.523656 [ 0.1173232] [ 1.70021105]

40 0.39972 [ 0.25565204] [ 1.66291022]

60 0.362344 [ 0.2998552] [ 1.5888164]

80 0.329081 [ 0.33363751] [ 1.51453435]

100 0.298876 [ 0.36503768] [ 1.44339323]

120 0.271444 [ 0.39488661] [ 1.37556255]

140 0.24653 [ 0.42332548] [ 1.31091654]

160 0.223902 [ 0.45042711] [ 1.24930835]

180 0.203352 [ 0.47625503] [ 1.19059539]

200 0.184687 [ 0.50086921] [ 1.13464165]

220 0.167736 [ 0.52432656] [ 1.08131754]

240 0.15234 [ 0.54668152] [ 1.03049934]

260 0.138358 [ 0.56798589] [ 0.98206973]

280 0.125659 [ 0.58828884] [ 0.93591607]

300 0.114125 [ 0.60763782] [ 0.89193159]

320 0.103651 [ 0.62607735] [ 0.85001397]

340 0.094137 [ 0.64365035] [ 0.8100664]

360 0.0854968 [ 0.66039753] [ 0.77199626]

380 0.0776495 [ 0.67635763] [ 0.73571527]

400 0.0705225 [ 0.69156754] [ 0.70113939]

420 0.0640498 [ 0.70606273] [ 0.66818839]

440 0.058171 [ 0.71987677] [ 0.63678604]

460 0.0528318 [ 0.73304158] [ 0.60685945]

480 0.0479827 [ 0.74558753] [ 0.57833922]

500 0.0435787 [ 0.75754404] [ 0.5511595]

520 0.0395789 [ 0.76893848] [ 0.52525711]

540 0.0359462 [ 0.77979749] [ 0.50057209]

560 0.0326469 [ 0.79014623] [ 0.47704697]

580 0.0296504 [ 0.80000859] [ 0.45462754]

600 0.026929 [ 0.80940741] [ 0.43326175]

620 0.0244574 [ 0.8183645] [ 0.41290006]

640 0.0222126 [ 0.82690072] [ 0.39349535]

660 0.0201738 [ 0.83503574] [ 0.37500247]

680 0.0183222 [ 0.84278852] [ 0.35737872]

700 0.0166405 [ 0.85017693] [ 0.34058321]

720 0.0151131 [ 0.85721791] [ 0.32457712]

740 0.013726 [ 0.86392814] [ 0.30932319]

760 0.0124662 [ 0.87032312] [ 0.29478616]

780 0.011322 [ 0.87641734] [ 0.28093231]

800 0.0102828 [ 0.88222533] [ 0.26772946]

820 0.00933901 [ 0.88776034] [ 0.25514716]

840 0.00848184 [ 0.89303517] [ 0.24315614]

860 0.00770334 [ 0.89806205] [ 0.23172873]

880 0.0069963 [ 0.90285283] [ 0.22083834]

900 0.00635416 [ 0.90741843] [ 0.21045975]

920 0.00577093 [ 0.91176945] [ 0.2005689]

940 0.00524127 [ 0.91591591] [ 0.19114289]

960 0.00476019 [ 0.91986758] [ 0.18215989]

980 0.00432329 [ 0.92363346] [ 0.17359905]

1000 0.00392648 [ 0.92722243] [ 0.16544051]


위의 결과들이 바로 학습을 통해서 나오게된 결과인데요.
1000번으로는 확실한 결과는 얻지 못했네요.

하지만 W는 1에 b는 0에 가까워지는 것을 알 수 있습니다.
1=1*W+b
2=2*W+b
3=3*W+b
이 식을 보면 W는 1, b는 0이 들어간다는 것을 알 수 있습니다.
아마 2000번을 하면 거의 정확한 값이 나올지도 모르겠네요.

아 참! 그리고 신기한게 하나 더 있습니다.
우리가 1000번을 수행해서 결과를 얻었는데요.
또 1000번을 수행하는 코드를 써넣으면 어떻게 될까요?
처음부터 다시 시작할까요?
아니면
해왔던 결과부터 시작할까요?

네, 해왔던 결과부터 시작하게됩니다.

파이썬을 껐다가 켜보면 마찬가지로 해왔던 결과부터 시작할까요?
이 질문에 대한 답은 여러분이 직접 찾아보시길 바랄게요.
#파이썬 #딥러닝 #텐서플로우 #선형 회귀 #간단한 선형 회귀 #학습 시키기 


  1. 경제학과를 나왔지만 '선형'이 들어가는 수학은 정말 어렵습니다.. 딥러닝 간단한 선형회귀 구현하기 포스트 아주 잘보고 갑니다. 기분좋은 일요일 되세요
    • 그런데 컴퓨터쪽은 선형대수를 꼭 배우니.. ㅋㅋㅋㅋ
      버블님도 좋은 하루되세요
이 댓글을 비밀 댓글로