[NLP] 머신 러닝 - (4) 자동 미분과 선형 회귀 실습

김규리·2022년 7월 9일
0

NLP

목록 보기
26/33
post-thumbnail

1. 자동 미분

  • 텐서플로우 tape_gradient(): 자동 미분 기능 수행
import tensorflow as tf

w = tf.Variable(2.)

def f(w):
  y = w**2
  z = 2*y + 5
  return z
  
with tf.GradientTape() as tape:
  z = f(w)

gradients = tape.gradient(z, [w])
print(gradients)

# w에 대해 미분한 값 저장
# [<tf.Tensor: shape=(), dtype=float32, numpy=8.0>]

2. 자동 미분을 이용한 선형 회귀 구현

# 학습될 가중치 변수를 선언
w = tf.Variable(4.0)
b = tf.Variable(1.0)

# 가설을 함수로 저장
@tf.function
def hypothesis(x):
  return w*x + b

# 임의의 입력값
x_test = [3.5, 5, 5.5, 6]
print(hypothesis(x_test).numpy())
# [15. 21. 23. 25.]

# 평균 제곱 오차를 손실 함수로서 정의
@tf.function
def mse_loss(y_pred, y):
  # 두 개의 차이값을 제곱을 해서 평균을 취한다.
  return tf.reduce_mean(tf.square(y_pred - y))
  
x = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 공부하는 시간
y = [11, 22, 33, 44, 53, 66, 77, 87, 95] # 각 공부하는 시간에 맵핑되는 성적

# 옵티마이저: 경사 하강법
# 학습률(learning rate): 0.01
optimizer = tf.optimizers.SGD(0.01)

# 약 300번에 걸쳐서 경사 하강법 수행
for i in range(301):
  with tf.GradientTape() as tape:
    # 현재 파라미터에 기반한 입력 x에 대한 예측값을 y_pred
    y_pred = hypothesis(x)

    # 평균 제곱 오차를 계산
    cost = mse_loss(y_pred, y)

  # 손실 함수에 대한 파라미터의 미분값 계산
  gradients = tape.gradient(cost, [w, b])

  # 파라미터 업데이트
  optimizer.apply_gradients(zip(gradients, [w, b]))

  if i % 10 == 0:
    print("epoch : {:3} | w의 값 : {:5.4f} | b의 값 : {:5.4} | cost : {:5.6f}".format(i, w.numpy(), b.numpy(), cost))

# w와 b값이 계속 업데이트 됨에 따라서 cost가 지속적으로 줄어듦
epoch :   0 | w의 값 : 8.2133 | b의 값 : 1.664 | cost : 1402.555542
... 중략 ...
epoch : 280 | w의 값 : 10.6221 | b의 값 : 1.191 | cost : 1.091434
epoch : 290 | w의 값 : 10.6245 | b의 값 : 1.176 | cost : 1.088940
epoch : 300 | w의 값 : 10.6269 | b의 값 : 1.161 | cost : 1.086645

3. 케라스로 구현하는 선형 회귀

  • 케라스 모델: Sequentialmodel이라는 이름의 모델을 만들고, add를 통해 입력과 출력 벡터의 차원과 같은 필요한 정보들을 추가
# 단순 선형 회귀: 출력 차원, 입력 차원 둘 다 1
model = Sequential()
model.add(keras.layers.Dense(output_dim=1, input_dim=1))
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras import optimizers

x = [1, 2, 3, 4, 5, 6, 7, 8, 9] # 공부하는 시간
y = [11, 22, 33, 44, 53, 66, 77, 87, 95] # 각 공부하는 시간에 맵핑되는 성적

model = Sequential()

# 출력 y의 차원은 1, 입력 x의 차원(input_dim)은 1
# 선형 회귀이므로 activation은 'linear'
model.add(Dense(1, input_dim=1, activation='linear'))

# sgd는 경사 하강법을 의미
# 학습률(learning rate, lr)은 0.01
sgd = optimizers.SGD(lr=0.01)

# 손실 함수(Loss function)은 평균제곱오차 mse를 사용
model.compile(optimizer=sgd, loss='mse', metrics=['mse'])

# 주어진 x와 y데이터에 대해서 오차를 최소화하는 작업을 300번 시도
model.fit(x, y, epochs=300)

# 모델 활용 예측
print(model.predict([9.5]))
profile
connecting the dots

0개의 댓글