본문 바로가기
DeepLearning Framework & Coding/Tensorflow 1.X

[코드로 이해하는 딥러닝 4] - 선형회귀(Linear Regression)

by 노마드공학자 2020. 12. 17.

[코드로 이해하는 딥러닝 0] - 글연재에 앞서 https://limitsinx.tistory.com/27

[코드로 이해하는 딥러닝 1] - Tensorflow 시작 https://limitsinx.tistory.com/28 

[코드로 이해하는 딥러닝 2] - Tensorflow 변수선언 https://limitsinx.tistory.com/29

[코드로 이해하는 딥러닝 3] - Tensorflow placeholder변수 https://limitsinx.tistory.com/30

 

※이 전글에서 정리한 코드/문법은 재설명하지 않으므로, 참고부탁드립니다

 

[코드 전문]

 

이번 글에서 정리를 할 부분은, 아주! 중요합니다

수치해석과 머신러닝의 경계에 있는 "회귀"라는 방식을 코드로 짜는것도 유의미하지만,

 

여기에 적힌 코드들이 사실상 앞으로 사용할 머신러닝 코드들의 전신입니다.

 

이부분을 정확하게 이해하지 못하고 넘어가면, 머신러닝을 할 수가 없습니다.(다른 언어 동일)

 

수식설명을 위한 글이 아니므로, 최대한 간단하게 함수가 의미하는바만 설명하고 코드분석을 진행하겠습니다.

(머신러닝의 개념에 대한 글은 차후 정리예정..)

 

혹시나 개념적인 부분이 궁금하실 분들을 위해, 키워드(Keyword)들을 적어놓도록 하겠습니다.

 

 

 

※ ★선형회귀 (Linear Regression)

: (0,1) , (1,2)를 지나는 직선식은 무엇일까요?

y=x+1입니다.

 

그럼, (0,1) , (1,2), (5,5)를 지나는 직선은 무엇일까요?

y=Wx+b라고 생각해보고 ,W와 b를 구해보시죠...

 

이 세점을 완벽하게 지나는 직선은 없습니다.

 

하지만, 세점을 완벽하게 지나가진 않지만, 가장 합리적으로 지나간다고 생각하는 직선은 구할 수 있죠

찾아본 결과, W=0.857, b=0.6190정도면... 완벽하게 세점을 지나진 않지만

 

누가봐도 합리적이게(오차가 가장적게) 세점들을 관통하는 직선을 얻을 수 있습니다.

수식으로는 , y=0.857x + 0.619가 되는거죠

 

이런식으로 수많은 점(학습데이터)들을 주고, 이 점들을 모두 관통할 수 있다고 할 수 있는 가장 합리적인 직선을 찾아라!

 

라는게 선형회귀입니다.

 

 

 

[코드 분석-1]

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

: (1,1),(2,2),(3,3)을 의미합니다.

즉, 학습데이터로 위 세개의 점을 주는거죠

 

② W=tf.Variable(tf.random([1]),name='weight')

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

 

W와 b는 추정할 y=Wx+b의 기울기(Weight)와 절편(bias)에 해당하는 부분입니다.

tf.Varaible(tf.random_normal~~~~ 이부분은 그냥 그대로 외워주셔도 됩니다. 문법인지라...

그냥 텐서플로우 만든사람들이 이렇게 쓰겠다는거라서요ㅋㅋ

tensorflow변수를 추가할건데 초기값은 랜덤한 숫자를 잡겠다~~ 이런뜻

 

[코드 분석-2]

① Hypothesis = x_train * W + b

: y=wx+b라는 뜻입니다. 이건 제가 추정한 값이죠

앞으로는 y(추정) 이라고 쓰겠습니다!

제가 추정한 값과, 실제값의 오차가 가장 작을때가 가장 이상적인 값이죠

 

※ 예를들면

(1,1), (2,2)를 지나는 직선을 찾는다고 할때

Y=0.8x+0.1이라고 하면, x에 1을 넣을때 y(추정)=0.9 이고, 실제값은 1이죠

이때 오차(cost)는 (1-0.9) = 0.1이고, 오차(cost)가 0이되면 y=x라는 직선에 도달하게 될것입니다.

 

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

(내가 추정한값 - 실제값)을 제곱해준것이 cost(비용)함수 입니다.

loss(손실) function이라고도 부르는데요

추정값=실제값이 가장 이상적인 상황이기에, cost가 0이되는 지점을 학습으로 찾아가는 과정이 필요합니다.

 

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

    train = optimizer.minimze(cost)

Gradient Descent니, cost optimize니 어려운 용어는 사용하지 않겠습니다.

 

출처 : Wikimedia, Gradient Descent

 

이 이차함수 그래프를 봐주시기 바랍니다.

 

cost는 (내가 추정한값-실제값)의 제곱이라고 했습니다.

그러면 위와 같은 아래로 볼록한 이차함수가 나오게 되겠죠?

 

즉, 이 이차함수 자체가 "Cost"입니다.

그럼 cost가 가장작은값은 가장 아래에 있는 붉은점이지 않을까요?

 

이때의 붉은점은 미분했을때 기울기가 0인 유일한 점입니다. (변곡점)

즉, Cost(비용)을 아래로 볼록한 2차함수로 만들고, 미분했을때 0인 지점의 W와 b값이 이상적인 결과 라는것입니다.

이 과정을 텐서플로우가 함수형식으로 만들어서 그냥 제공해주는 부분이

 

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

train = optimizer.minimze(cost)

 

이 두줄 코드의 의미입니다.

 

오차가 0이될때까지 N번반복~~ 하는것(이것을 "N번 학습한다"라고 말합니다.)이 머신러닝입니다.

 

 

[코드 분석-3]

① for step in range(2001) : 2000번의 반복으로 cost가 0이되는 부분을 찾겠다

② sess.run(train) : 학습시작

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

    : cost와 y=wx+b의 W,b를 차례대로 보겠다.

 

(1,1),(2,2),(3,3)을 지나는 직선을 찾는것이므로, 예상되는 결과값은 W=1, b=0입니다.

 

[결과값(2000번 학습)]

2000번의 학습을 진행한결과

 

최종적으로 W=1.0037, b=-0.0084177이 나왔네요

2000번 밖에 학습하지 않은것 치고 cost는 0.0000022, W=1.00371, b=-0.00844가 나왔네요

 

10000번 학습을 진행하면 더더욱 W=1 , b=0에 가까워져야겠죠?

한번 확인해보겠습니다.

for step in range(10001)로만 바꿔주시면 됩니다.

 

[결과값(10000번 학습)]

10000번 학습한 결과

오차는 0.00000000003244, W=0.99999, b= 0.0000449가 나왔네요

2000번 학습한것보다 확실히 나아진 결과를 보입니다.

10만번, 100만번 학습한다면, 시간은 걸리겠지만 W=1, b=0으로 점점 수렴할것으로 예측할 수 있습니다.

 

 

Summary

 

이부분까지만 잘 이해하셨어도, 머신러닝의 절반은 끝났다고 보시면됩니다.

머신러닝이 별거아니다 가아니라, 이부분이 그만큼 중요하다는 뜻이죠

키워드를 하기와 같이 정리해두었으니, 상세하게 수학적으로 이해를 해보고 싶으신분들은 키워드로 검색해서 공부를 해주시면 될것같습니다.

 

▶Keywords : Gradient Descent, Linear regression, convex optimization, cost function

 

[코드 공유]

import tensorflow.compat.v1 as tf

import numpy as np

tf.disable_v2_behavior()

 

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.01)

train = optimizer.minimize(cost)

 

sess = tf.Session()

sess.run(tf.global_variables_initializer())

 

for step in range(10001) : 

    sess.run(train)

    if step%100 == 0 :

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

댓글