인공지능/모두를 위한 딥러닝 (sung kim) lab

본 글은 스스로 정리 겸, 머신러닝을 처음 배우는 사람들도 쉽게 머신러닝을 배울 수 있도록 쓴 글입니다.

수학적 지식이 부족하더라도, 머신러닝이 어떻게 돌아가는지 최대한 쉽게 이해할 수 있도록 적는 것을 목표로 하고 있습니다.

sung kim 님의 '모두를 위한 딥러닝'의 자료를 사용하여 설명합니다.

 

* lab 1 이번 lab 2와 병합하여 설명하겠습니다.

 

깃허브 주소 : https://github.com/hunkim/DeepLearningZeroToAll

 

 

이번에는 Tensorflow를 활용하여 간단하게 Linear regression 코드를 작성해 보겠습니다.

Linear regression의 Hypothesis와 Cost function

우선, 코드를 짜기 전에 저번에 배웠던 Linear regression의 Hypothesis와 cost function을 리뷰해봅시다.

 

H(x)는 Hypothesis function, 즉 가설 함수로 "데이터가 아마 이런 식으로 나열되어 있을 것이다." 라는 것을 예측하는 함수입니다.

Linear regression의 경우, 이름 그대로 Linear한 직선인 H(x) = Wx + b 라는 식을 사용합니다.

 

Cost (W,b) 라고도 쓰이는 Cost function은 각각의 데이터에 대해서 가설함수 H(x)가 얼마나 잘 피팅되어 있는지 (적합한지) 나타내는 함수입니다. 값이 작으면 작을수록 가설함수 H(x)는 데이터에 더 적합하죠.

 

리뷰는 대충 이정도로만 끝내고, 이제 텐서플로우가 어떻게 돌아가는지 알아봅시다.

(만약 기억이 잘 나지 않거나 한다면, 이전 포스트를 보고 와주세요.)

텐서플로우 메카닉

1. Tensorflow의 연산을 사용하여 그래프를 만든다.

 

2. 데이터를 집어넣고 그래프를 돌린다.

 

3. 그래프의 변수들을 업데이트하고, 값을 반환한다.

 

이게 뭔뜻이냐구요? 이제부터 하나하나 알아가 봅시다.

 

1. Tensorflow의 연산을 사용하여 그래프를 만든다.

일단 Tensorflow의 연산을 이용해서 그래프를 만듭니다.

그래프란, 우리가 만들 모델을 의미합니다.

 

만약 우리가 Linear regression의 모델을 만들고 싶다 한다면, Linear regression의 H(x)와 Cost function 등을 구현하는 겁니다.

이 때는 코드가 직접 돌아가는 것이 아니고, "나는 이런 모델을 만들 것이다!" 라고 컴퓨터에게 알려주는 것이죠.

 

자동차를 만드는 것을 예로 든다면, 자동차의 설계도를 작성하는 부분인 것입니다.

자동차의 엔진은 어떤 것을 사용할 것이고, 차체는 어떤 모양으로 만들 것이며, 바퀴는 어떻게 만들 것이고 등...

자동차를 만드는 데 있어서 필요한 모든 것들을 미리 만들어 놓는 것입니다.

대충 이런거 하는 작업인거죠.
두번째 등장!

 

다시 위 슬라이드로 돌아와서, 설명하겠습니다.

 

2. 데이터를 집어넣고 그래프를 돌린다.

 

이제 이 부분에서는 아까 전에 설계한 모델을 직접 만들고 실행시킵니다.

모델을 설계한 대로 데이터를 집어넣고, 모델에서 정의한 대로 코드가 실행되며 모든 연산들이 계산됩니다.

 

자동차의 예시를 다시 들어보겠습니다.

이번에는 아까 만들어놨던 설계도를 바탕으로 자동차에 필요한 재료들을 가져와서 실제로 자동차를 만들고, 직접 자동차를 타 보는 부분입니다.

 

차체에 타이어를 가져와서 붙이고, 엔진을 가져와서 붙이고, 그런 식으로 완성된 자동차를 직접 타는 것이죠.

 

 

Q. 왜 데이터를 1번 파트에서 집어넣지 않고 2번 파트에서 집어넣는 것인가요?

모델을 설계할 때에 데이터를 넣어버리면, 추후에 같은 모델로 다른 데이터를 집어넣기 쉽지 않다는 단점이 존재합니다.

 

Linear regression의 모델 하나만으로도 굉장히 많은 양의 문제를 해결할 수 있습니다.

시험점수 예측, 집값 예측 등 다양한 데이터들을 Linear regression으로 해결할 수 있다는 겁니다.

그런데 만약 설계도 처음부터 데이터를 박아버리면, 나중에 다른 데이터를 집어넣을 때 설계도 자체를 바꿔야 합니다.

 

자동차의 예시를 다시 가져오자면, 설계도에 자동차의 도색까지 다 해버리는 것과 비슷합니다.

똑같은 차라도 굉장히 다양한 도색을 할 수 있는데, 설계도에서부터 벌써 도색을 해버리면, 다음에 다른 도색을 하고 싶을때는 설계도를 다시 수정해야 한다는 것이죠.

 

일단 이정도로만 알아두고, 넘어가도록 합시다.

 

그림자분신술!!

3. 그래프의 변수들을 업데이트하고, 값을 반환한다.

 

사실 이부분은, 아직까지 다뤄본 적이 없는 부분입니다.

다음 Lec 3. cost 최소화 부분에서 다루며 더욱 자세히 알아볼 것입니다.

 

간단하게만 말해두자면, cost를 최소화할 수 있는 방향으로 W값과 b값을 업데이트 해주는 과정 정도로 생각하시면 좋을 것 같습니다.

 

야생의 코드 (이)가 나타났다!

import tensorflow as tf	# tensorflow 가져오기

#W,b값 선언하기
W = tf.Variable(tf.random_normal([1]), name='weight')
b = tf.Variable(tf.random_normal([1]), name='bias')

#Placeholder로 X,Y값 선언하기
X = tf.placeholder(tf.float32, shape=[None])
Y = tf.placeholder(tf.float32, shape=[None])

코드는 자고로 몸으로 익히는 법.. 왠만하면 코드를 복사하지 말고 직접 타이핑하며 공부해 주세요.

 

tf.Variable : 텐서플로우에서 사용하는 변수 선언 방식으로 생각하시면 되겠습니다.

tf.random_normal([n]) : n의 크기만큼의 랜덤한 변수를 만드는 것입니다.

name선언은 나중에 그래프를 그릴 때 보기 편하라고 미리 지어주는 이름입니다.

 

Placeholder는 아까 설명한, Q. 왜 데이터를 1번 파트에서 집어넣지 않고 2번 파트에서 집어넣는 것인가요? 부분에 딱 들어맞는 함수로, 모델을 설계할때 직접 데이터를 쑤셔넣지 않고 나중에 2번 파트에서 집어넣기 위해 사용하는 함수입니다.

Placeholder를 쓰는 이유를 알고싶다면, 위의 Q.를 다시 한번 보고 와주세요.

 

X = tf.placeholder(tf.float32, shape=[None])
Y = tf.placeholder(tf.float32, shape=[None])

위의 두 줄의 코드는 X,Y를 각각 tf.float32라는 실수형 자료형으로, [None]이라는 shape로 만들라는 의미입니다.

이 때, [None]이라는 shape는 "내가 나중에 데이터 집어넣을 때 그 데이터 크기를 따라가면 돼!" 의 의미입니다.

 

# 가설함수 H(x) = X*W + b
hypothesis = X * W + b
# Cost function
cost = tf.reduce_mean(tf.square(hypothesis - Y))
# 최소화 (다음 시간에..)
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
train = optimizer.minimize(cost)

이제 데이터 선언은 끝났고, 이제 모델의 중심부를 구현해 봅시다!

 

가설함수 H(x)는 X*W + b 였던 것을 그대로, hypothesis = X * W + b 라고 입력해 줍시다.

 

cost = tf.reduce_mean(tf.square(hypothesis - Y))

이것은 무엇을 의미 하냐 하면..

 

tf.square(hypothesis - Y) : 가설 함수 H(x)에서 데이터를 뺀 것 만큼을 제곱하라!

 

tf.reduce_mean() : 그리고 () 안의 값 ( tf.square(hypothesis - Y) ) 을 평균을 내줘라!

 

라는 의미입니다 (대략적으로는)

 

optimizer = ... 부분은 나중에 lec 3 이후에, 다시 한번 정확히 설명하겠습니다.

 

train = optimizer.minimize

이 부분은, Cost를 최소화 시킬 것이다! 라는 의미입니다.

 

# 그래프 실행!
sess = tf.Session()
# 변수 초기화!
sess.run(tf.global_variables_initializer())

# 학습..
for step in range(2001):
   cost_val, W_val, b_val, _ = sess.run([cost, W, b, train],
                feed_dict={X: [1, 2, 3], Y: [1, 2, 3]})
   if step % 20 == 0:
       print(step, cost_val, W_val, b_val)

sess = tf.Session()

sess.run(tf.global_variables_initializer())

 

위 두 코드는, 대략 이런 의미입니다.

"내가 이 위에서 짰던 모델을 실행시키고, 이제 변수들도 다 제대로 초기화 해줘!"

 

위에서 설명했듯, 1번 파트에서는 그저 설계도를 작성하는 부분이고, 어떤 것도 실제로 만들어지지 않습니다. 그렇기에, 변수들도 2번 파트에서 초기화 해 주어야 하죠.

 

그뒤의 나머지 부분들은, 2001번 만큼 모델을 학습시키겠다는 의미인데, 이것 또한 Lec 3 이후에 자세히 설명하겠습니다.

 

feed_dict = ...

의 부분만 설명하자면, 아까 전에 Placeholder로 지정해 두었던 부분에, 내가 넣고 싶은 데이터를 넣겠다는 의미입니다.

즉, 1번 파트에서 미리 넣어두지 않았던 데이터를 지금 집어넣겠다는 의미이죠.

위의 feed_dict 부분만 이렇게 바꿔주면, 아예 다른 데이터들을 집어넣어서도 훈련시킬 수 있습니다!

 

 

이렇게, Tensorflow로 기본적인 Linear regression 코드 작성 튜토리얼을 마치겠습니다.

다음에는 Lec 3로 찾아뵙겠습니다!

+ Recent posts