본문 바로가기
Always Awake/모두를 위한 딥러닝 시즌2 정리 (20.03.15~)

모두를 위한 딥러닝 시즌2 / Lab 2강 정리

by 욕심많은알파카 2020. 3. 24.

복습

> cost = (1/갯수)*([(예측값-실제값=오차)^2]들의 합)

즉 오차 제곱의 평균.
따라서 cost가 최소가 되도록 만드는 W,b값(예측값의 변수)를 찾는것이 learning의 핵심목적.

hypothesis와 cost 만들어보기

- 데이터 셋을 설정 (x_data -> 입력 값, y_data -> 출력 값)
- W값과 b값을 설정 (초기에는 random값으로 설정)
- hypothesis = W * x_data + b
- cost = tf.reduce_mean(tf.square(hyphothesis - y_data))

reduce_mean이라는 이름은 높은 차원(리스트는 1차원이다)을 낮은차원(하나의 value는 0차원이다)으로 끌어내리므로 reduce라는 이름이 붙었다.

Gradient descent

# learning_rate initialize
learning_rate = 0.01

# 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)

cost를 minimize시키는 W,b를 찾는 대표적인 알고리즘 중 하나.

- learning_rate를 설정한다.
- with 구문안의 변수들의 변화정보를 GradientTape에 기록한다.
- 이후 tape.gradient를 호출해서 W와 b의 경사도(미분값)을 각각 기록하여 튜플로 반환한다.
- assign_sub(-=연산)을 가져와 W와 b를 각각 업데이트한다.
- 이 때, learning_rate는 위에서 가져온 경사도를 얼마만큼 반영하여 업데이트 할 것인가를 결정하는데 일반적으로 굉장히 작은 값(0.01,0.001 등)을 사용한다.

with 구문부터 마지막까지의 block이 한 번의 update cycle이 된다.
이런 cycle을 for문으로 여러번 반복하여 예측값의 오차를 줄여나간다.

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

for i in range(100):
    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.4f}|{:10.6f}".format(i, W.numpy(), b.numpy(), cost)) 

for문을 돌려 업데이트하되, 중간중간 어떻게 바뀌는지 확인하기 위해 print를 사용했다.

전체코드

import tensorflow as tf
import numpy as np
tf.enable_eager_execution()

# Data
x_data = [1, 2, 3, 4, 5]
y_data = [1, 2, 3, 4, 5]

# W, b initialize
W = tf.Variable(2.9)
b = tf.Variable(0.5)

# W, b update
for i in range(100):
    # 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.4f}|{:10.6f}".format(i, W.numpy(), b.numpy(), cost))

print()

# predict
print(W * 5 + b)
print(W * 2.5 + b)

> 실제로 가장 중요한 부분은 Gradient descent 파트로,
> Tape에 경사도를 기록하여 업데이트 시키는 cycle이 알고리즘의 핵심이다.

* Epoch=1 cycle

predict

위의 경우에서 입력 값 x_data와 출력 값 y_data는 둘다 동일한 값을 사용했는데,
이 데이터를 통해서 학습시킨 hyphothesis model (W, b)는 과연 새로운 x를 집어넣었을 때에 학습시킨것처럼 거의 동일한 값을 출력시킬까?

> 결과는 Yes. 학습되어 update된 W,b는 입력값에 대해 거의 같은 출력값을 내보낸다.

댓글