본문 바로가기

인공지능/ML

인공지능 3. Simple Linear Regression 구현

이 글은 edwith - [부스트코스] 텐서플로우로 시작하는 딥러닝 기초의 개인적인 공부기록이므로 오류가 있을 수 있습니다!

import tensorflow as tf
# tf.enable_eager_execution()


x_data = [1, 2, 3, 4, 5]
y_data = [2, 4, 6, 8, 10]

W = tf.Variable(2.9)
b = tf.Variable(0.5)

learning_rate = 0.01

for i in range(100+1):
    # Gradient descent
    with tf.GradientTape() as tape:
        hypothesis = W * x_data + b # 우리의 가정
        cost = tf.reduce_mean(tf.square(hypothesis - y_data))
    W_grad, b_grad = tape.gradient(cost, [W, b])
    W.assign_sub(learning_rate * W_grad)
    b.assign_sub(learning_rate * b_grad)
    if i % 10 == 0:
        print("{:5} | {:10.4f} | {:10.4} | {:10.5f}".format(i, W.numpy(), b.numpy(), cost))

 

 

분해해서 살펴보자.

 

 

 

x_data = [1, 2, 3, 4, 5]
y_data = [2, 4, 6, 8, 10]

x_data는 입력값이다. x_data를 기반으로 Hypothesis를 세우게 된다.

y_data는 출력 값이다. 우리는 x_data가 y_data에 가까워지며, cost(W, b)이 최소화되는 것을 목적으로 한다.

위의 x_data와 y_data를 보았을 때, Hypothesis는 사실 간단하다.

 

H(x) = 2x+0

 

이 가정이 x_data와 y_data를 100% 만족시키게 된다.

 

 

W = tf.Variable(2.9)
b = tf.Variable(0.5)

W(기울기)와 b(y값)을 임의의 값으로 설정한다.

이 값이 학습을 통해 점점 우리가 원하는 값(2, 0)으로 맞춰져 간다면 학습이 잘 되는 것이라고 볼 수 있다.

 

 

learning_rate = 0.01

학습률이라고 하는 Learning rate이다. 학습하면서 변경되는 W와 b값을 얼마나 반영할것인가 결정하는 상수인데, 이걸 정하는 명확한 기준은 없다. 그러나 0.1 이상이면 움직이는 속도가 너무 빨라서 최소에 도달하지 못할 확률이 높고, 0.001보다 작게 되면 수학적으로 발산에 가까워지므로 의미가 없어지게 된다. 그래서 보통 0 ~ 0.1 사이의 숫자를 많이 사용하고 오차를 보면서 가변적으로 learning rate를 변경하는 방법 또한 사용되고 있다.

 

많이 하다보면 짬으로 때려 맞추게 될 것이다.

 

 

    with tf.GradientTape() as tape:
        hypothesis = W * x_data + b # 우리의 가정
        cost = tf.reduce_mean(tf.square(hypothesis - y_data))

 

자동 미분을 위해 tf.GradientTape함수를 사용할 것이다.

텐서 플로는 자동 미분(주어진 입력 변수에 대한 연산의 그래디언트(gradient)를 계산하는 것)을 위한 tf.GradientTape API를 제공합니다. tf.GradientTape는 콘텍스트(context) 안에서 실행된 모든 연산을 테이프(tape)에 "기록"합니다. 그다음 텐서 플로는후진 방식 자동 미분(reverse mode differentiation)을 사용해 테이프에 "기록된" 연산의 그래디언트를 계산합니다.
- 텐서 플로 공식문서 https://www.tensorflow.org/tutorials/customization/autodiff?hl=ko

 

tape라는 변수에 context에서 일어나는 연산을 기록하고 자동 미분을 사용해 tape에 기록된 연산의 Gradient(기울기)를 계산한다.

 

hypothesis는 우리의 가정 W(x) + b의 형태와 일치하고,

제곱 함수 tf.square()와 차수를 하나 줄여가며 평균을 구해주는 함수 tf.reduce_mean 함수를 이용해 cost를 구하게 된다.

 

 

W_grad, b_grad = tape.gradient(cost, [W, b])

 

W와 b에 미분된 값을 반영하기 위해 gradient 함수를 사용하고 return 값을 W_grad, b_grad 변수에 할당한다.

 

 

W.assign_sub(learning_rate * W_grad)
b.assign_sub(learning_rate * b_grad)

assign_sub는 +=, -=와 같이 변수에 실시간으로 연산을 반영한다.

W에 learning rate와 위에서 미분된 값을 반영한 W_grad, b_grad를 곱해

학습하면서 변경되는 W와 b값을 얼마나 반영할 것인가를 결정해 반영한다.

 

 

0, 10, 20, 30... 100일 때 찍혀있는 print를 확인해보면

    i |     	W  |        b   |  	cost
    0 |     2.4440 |      0.372 |  11.860003
   10 |     1.9410 |     0.2163 |   0.008649
   20 |     1.9441 |     0.2019 |   0.007523
   30 |     1.9477 |     0.1887 |   0.006569
   40 |     1.9512 |     0.1763 |   0.005735
   50 |     1.9544 |     0.1647 |   0.005007
   60 |     1.9574 |     0.1539 |   0.004372
   70 |     1.9602 |     0.1438 |   0.003817
   80 |     1.9628 |     0.1344 |   0.003333
   90 |     1.9652 |     0.1256 |   0.002910
  100 |     1.9675 |     0.1173 |   0.002541
  • W는 2에 가까워지고, b는 0에 가까워지고 있다.
  • cost가 0에 가까워지고 있다

2가지 사실을 통해 학습이 원하는 대로 이루어지고 있음을 알 수 있다.