티스토리 뷰

공부공부/딥러닝

Linear Regression

필님님 2018. 2. 21. 21:29

Linear Regression을 하기전 간단한 용어에 대해서만 알아보면

머신러닝은 데이터로부터 컴퓨터가 학습하게 함으로써 새로운 지식을 얻어내게하는 분야입니다.

그리고 딥러닝은 머신러닝 기술의 한부분으로 인공신경망에 기반을 둔 기술입니다.

 

그리고 학습에는

지도학습, 비지도학습, 강화학습등이 있는데

지도학습(Supervised Learning)이란 데이터(data)에 대한 정답(Label이라 합니다.)이 주어진 상태에서 컴퓨터를 학습시키는 방법입입니다.

지도학습도 크게 예측 과 분류로 나누어 집니다.

이러한 지도학습을 활용하는 대표적인것으로는 MNIST가 있습니다.(손글씨 숫자구별 학습)

 

비지도학습(Unsupervised Learning)이란 데이터(data)에 대한 정답(Label)이 주어지지 않은 상태에서 컴퓨터를 학습시키는 방법입니다.

이때에는 학습을 어떻케 하느냐??!!하면 데이터의 "유사성"을 근거로 컴퓨터가 데이터를 스스로 분류 하는 방법으로 학습을 합니다.

 

여기에서 Linear Regression은 "지도학습"중에 "결과 예측"에 관한 대표적인 알고리즘입니다.

 

 

선형회귀분석

linear regression

 

간단하게 2차원으로 보면

x = 예측을 하기위한 기본적인자료 또는 feature

y = 예측해야할 대상 으로하여 데이터를 2차원 평면에 놓습니다.

(3차 4차 n차등으로 나중에 확장 가능합니다)

그리고 그 데이터와 잘 맞는 linear 선을 찾는것이 학습을 한다는 것입니다.

 

이때 Linear Hypothesis(데이터와 잘 맞는 직선이 있다는 가설)을 세우게 되는데

그리고 그직선은 

로 나타냅니다 W는 가중치(weight)라는 뜻이고 b는바이어스(bias)입니다

일차함수와 동일한 것입니다!!

요개념이 나중에 인공뉴런(인간의 뇌 속의 그 뉴런입니다!!)의 퍼셉트론으로 발전하게 됩니다. 

 

가장데이터와 일치하는 직선을 구하기 위해서는

직선과 데이터의 y값(실제값)의 차이를 구해서 그 차이가 가장 최소가 되게 W와b를 조정하는 방법을 사용합니다.

여기서 실제데이터와 H(x)의 차이를 Cost(Loss) Function이라고 부릅니다.

Cost function이 음수가 되는것을 방지하고, 또 그 평균을 나타내기위해서

이렇케 나타냅니다!! (i는 각 데이터를 나타냅니다)

cost함수는 W와 b의 값에따라 변하므로

이렇케 나타낼 수 있습니다.

그리고 이러한 cost(W,b)의 값을 최소화하는 W와 b를 구하는 것을 "학습" 의 목표입니다!!!휴ㅠㅠ

 

즉!! 일차함수와 각 데이터 간의 오차의 평균을 구하고 그 평균이 최소가 되는 W와 b를 찾는것을 선형회귀분석이라고 합니다.

 

 

(사실과 다를수 있습니다...ㅠㅠ)

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import tensorflow as tf //텐서플로를 tf로 불러들인 모습입니다.
 
x_train = [1,2,3]
y_train = [1,2,3]//학습데이터들입니다
 
= tf.Variable(tf.random_normal([1]), name = 'weight')
= 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(2001):
    sess.run(train)
    if step % 20 ==0:
        print(step, sess.run(cost),sess.run(W), sess.run(b))
cs

Linear Regression을 이해하기 위한 간단한 코드입니다.

6번부터 tf.Variable 는 변수로써 모델을 학습시킬때 매개변수(parameter)의 업데이트와 유지를위해 매개변수를 사용합니다.

그리고 변수는 명시적으로 "초기화"작업을 시켜줘야하는데 이것이

17번째줄인 tf.global_variables_initializer()입니다.

변수는 여기서 W와 b이므로 2개를 정해줍니다.

 

linear hypothesis는

이므로 밑에 그대로 써줍니다.

 

이부분을 텐서플로우르 나타내면

redune_mean 이 식으로 앞의 시그마 부분까지이고

tf.square부분이 제곱입니다.

따라서 cost = tf.reduce_mean(tf.square(hypothesis - y_train))으로 나타냅니다

 

13번째줄의 optimizer는 최적화라는 뜻입니다. 이것은 train(학습)에 의해 이루어지고

GradientDescent으로 기울기를 음의방향쪽으로 진행시키면서 반복적으로 함수의 값이 최소화되도록 최적화를 시킨다는 뜻입니다.

learning_rate는 학습율로써 이 학습율 또한 최적화하여 가장 적당한 rate를 찾는 방법이있지만 아직은 처음배우므로 지금은 그냥 0.1정도로 한다는 것만 알면 될것 같습니다. (이 learning_rate는 텐서플로가 반복할때마다 얼마나 크게 이동할 것인가를 제어하는 것으로 너무커도 안되고 너무 작아도 안됩니다!!)

 

14번째줄의 train은 학습을 하는데 cost가 최소가 되는 방향으로 학습을 진행한다는 뜻입니다.(요기 앞의 학습의 목표가 cost가 최소가될때의 W와 b를 구하는 것이기 때문입니다.

 

16번부터 Session이 등장하기 시작하는데 이 Session의 개념이 처음공부할때에 어려운것 같습니다. 이것을 이해하려면 텐서플로의 구조를 알아야 조금 도움이 될것 같습니다.

앞으로도 코드 마지막쯤에는 Session이 꼭쓰이는데 이 이유는 코드를"실행!!"하기 위해서는 Session을 사용해야 하기 때문입니다.

https://www.tensorflow.org/programmers_guide/graphs

공식사이트에 설명이 나와있지만 그래프를 그리는것이 위의 단계라고 하면 16번 밑에서는 그 그린것들을 실행하는 부분이라고 이해하시면 됩니다.

 

 

19번의 부분은 for문으로 range안의 2000번까지 학습을 수행하는 부분입니다.

C에선 중괄호로 묶은것을 Python에선 먼저 " : "를찍고 밑에서 띄어쓰기로 구분합니다 따라서 20번 21번은 같은 Line에 있어야합니다!! 보통 Tab키로 구분하는 것이 일반적으로 알고있습니다

20번에 sess.run(train)부분이 이제 정말 학습을 시작하는 부분입니다.

21번,21번에서는 20번째마다 cost, W, b의 값을 출력하여 학습이 어떻케 이루어지는지 확인하려고 넣은코드입니다.

 

결과를 보시면

20번씩 학습을 할때마다의 cost, W, b 의 값이 나오고 cost값은 점점 작아지고 있으며

그때 W는 1로, b는 0으로 가고 있음을 확인할 수 있습니다.

 

※이것을 그래프로 확인하고싶으면

가장 위쪽의 import 하는부분에

 

from matplotlib import pyplot as plt

추가해 주시고

 

가장 밑부분에

 

for step in range(2001):
sess.run(train)
if step % 20 ==0:
print(step, sess.run(cost),sess.run(W), sess.run(b))
plt.plot(x_train, y_train, 'ro')
plt.plot(x_train, sess.run(W) * x_train + sess.run(b))
plt.xlabel('x')
plt.xlim(1,3)
plt.ylim(1,3)
plt.ylabel('y')
plt.show()

이렇케 plt 부분만 추가해주시면

print 밑의 plt.plot 는 각각 데이터를 점으로 나타내고, Hypothesis를 선으로 나타낸 것입니다

그리고 label로 x와 y축 이름을 정해주었고, xlim, ylim으로 1~3까지 범위를 나타내었습니다.

 

 

그냥 시각적으로 확인하고 싶을때 사용하시면 될것 같습니다.

 

 

 

cost함수를 최소화하는 방법(Gradient Descent)에 대하여 더 자세히 알아보면

먼저 W의 값에 따라 cost 가 어떻케 변화하는지 알아야합니다

 

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
import tensorflow as tf
from matplotlib import pyplot as plt
 
x_train = [1,2,3]
y_train = [1,2,3]
 
= tf.placeholder(tf.float32)
 
hypothesis =  x_train * W
 
cost= tf.reduce_mean(tf.square(hypothesis -y_train))
 
sess = tf.Session()
sess.run(tf.global_variables_initializer())
 
W_val = []
cost_val = []
for i in range(-30,50):
    feed_W = i*0.1
    curr_cost, curr_W = sess.run([cost,W], feed_dict={W:feed_W})
    W_val.append(curr_W)
    cost_val.append(curr_cost)
 
plt.plot(W_val, cost_val)
plt.show()
 
cs

이것은 위에나온 데이터에서 W와 cost의 관계를 알아보기위한 코드입니다.

여기서는

대신에 를 사용하는데 이것은 나중에 엄청많은 항이 있을경우 방정식을 풀기 어렵기때문에 변수를 줄여 간단하게하여 진행하는것이 일반적으로 알고 있습니다.

 

▶placeholder는 정해지지않은 그릇??!!으로 보면 이해하기 편할것 같습니다.안에 float32가 있으므로 실수형을 담는 그릇정도로 보면 됩니다.

값을 미리 정해 놓는것이 아니라 프로그램 실행중에 값을 변경할수 있습니다

▶placeholder에 들어갈값은 20번째줄인 feed_dict에서 던져줍니다. 자료구조를 배우셨다면 hash table과 비슷한개념인것 같습니다...

▶그때 나오는값을 W_val, cost_val 이라고 합니다.

 

 

 

 

 

이렇케 W의 값이 변화함에따라 cost값도 달라지는것이 이차함수모양으로 달라지는것을 확인하였습니다.

여기에서 cost가 최소이고 그때의 W값을찾아야하는데 사용하는 방법이 Gradient Descent 입니다. 바로 미분을이용하여 구하는 것입니다.

그러기 위해서는 다시 cost함수를 바꿔주는것이 간편하여 이렇케 바꾸어줍니다

 m을 2m으로 바꾸어주었습니다.

그 후에 미분을 하고 최소화되는 W를 구하는 식은 바로 이렇케 됩니다. 

이그래프는 시작점에서의 기울기가 양수면 W값을 작아지게하고 음수면 W의 값을 커지게하여 결국 W가 0인지점(cost가 최소)인지점으로 가게 해주는 식입니다.

이렇케 해놓으면 처음의 위치와 상관없이 cost가 가장 작은쪽으로 이동하게 됩니다.

그리고, 여기서의 a가 바로 learnig_rate 이고 learning_rate가 너무 커버리면 예제를 보면 W가 1로 가야하지만 갈수 없게 됩니다. 그리고 learning_rate가 너무 작으면 결과값을 찾는데 너무 오래걸리거나 아니면 엉뚱한값이 나올수 있습니다.

 

W에다가 b까지 고려한 그래프는 3차원으로 나타나게되며 밑의 그래프처럼 움푹파인것처럼 오목한 모양이여야치 정확한값을 얻을수 있습니다.

 

https://www.quora.com/Why-is-convexity-a-useful-property-for-a-function-to-have

 

그리고 이러한 움푹파인 그래프를 Convex Function이라고 합니다

따라서 Linear Regression을 사용하기 위해서는 Cost Function이 Convex Function인지 꼭 확인하여야 합니다. 그렇치 않으면 한곳으로 모이는것이아니라 엉뚱한 값이 나오게 됩니다ㅠㅠ

 

 

 

 

입력이 여러개일때엔??

위에서는 입력이 X 하나인경우만 다루었습니다.

입력이 하나일경우,이고

만약 입력이 3개일 경우엔 ,

이렇케 나타내주시면 됩니다

그러면 cost 함수도

이렇케 나타나게 됩니다.

입력이 n개일경우 점점더 길어지게 되는데

이것을 간단하게 하기위해서 "행렬(Matrix"을 이용합니다.

위의것을 행렬을 이욯하여 표현해보면

이렇케 나태낼 수 있으며 이것은 다시

이렇케 행렬의 곱으로 간단히 나타낼 수 있습니다.(bias는 생략한 상태입니다)

위의 식에서 X에다가 1,2,3을 넣어봤는데 각각을 instance라고 부릅니다

입력이 3개인경우에 instance가 늘어난 경우를 보면

이렇케 표현할 수 있습니다

입력이 여러개일때를 텐서플로로 구현해보면

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
import tensorflow as tf
 
x_data = [[73.,80.,75.],[93.,88.,93.],[89.,91.,90.],[96.,98.,100.],[73.,66.,70.]]
y_data = [[152.],[185.],[180.],[196.],[142.]]
 
= tf.placeholder(tf.float32, shape=[None,3])
= tf.placeholder(tf.float32, shape=[None,1])
 
W= tf.Variable(tf.random_normal([3,1]), name='weight')
b= tf.Variable(tf.random_normal([1]), name='bias')
 
hypothesis = tf.matmul(X,W)+b
cost = tf.reduce_mean(tf.square(hypothesis-Y))
 
optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-5)
train = optimizer.minimize(cost)
 
sess= tf.Session()
sess.run(tf.global_variables_initializer())
 
for step in range(2001):
    cost_val, hy_val, _ = sess.run(
        [cost,hypothesis,train], feed_dict={X:x_data, Y:y_data}
    )
    if step %10 ==0:
        print(step,"cost:",cost_val,"\n prediction:\n",hy_val)
cs

행렬을 코드로 나타내는것도 대괄호 2개로간단하게 나타낼수 있습니다.

x_data, y_data, W는 각각

이것을 코드로 나타낸것입니다

X와 Y에 None이라 적혀놓은것은 나중에 입력이 추가될수 있기 때문에 None으로 해놓은것입니다.

print한것은 10번째 단위마다 cost값과 예측값을 보고 cost값에따른 예측값을 볼수있도록 한것입니다.

 

이때 결과값은

 

이렇케 나오게 됩니다!

 

 

 

※참고입니다

텐서플로로 가동하면 코드가 같아도 처음 결과값은 아마 다오게 나올수 있습니다. 왜냐하면 가중치 (W, b)값은 최초 값이 random이기때문입니다. 최초값에 대한 cost는 프로그램 수행마다 값의 편차가 크지만, 학습이 진행되면 cost가 적어지면서 결과값이 예측값과 점점 비슷해지게 됩니다!!ㅎㅎ

 

 

 

'공부공부 > 딥러닝' 카테고리의 다른 글

Sigmoid Softmax  (0) 2018.03.16
TensorFlow 설치  (0) 2018.02.19
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
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
글 보관함