본문 바로가기
파이썬 프로그래밍/Numpy 딥러닝

3. 입력 특성이 2개인 선형회귀 구현(이론, 실습)

by Majestyblue 2022. 1. 3.

저번 시간에는 입력 특성이 1개인 단순 선형 회귀를 구현하였다. 

이번에는 입력 특성이 2개 혹은 그 이상에도 적용 가능한 선형회귀 구현을 하고자 한다.

 

사실 매우 쉽다. 조금만 변형해주면 된다.

예를 들어 아래와 같은 입력값과 목표값이 있다. 

 

위 식은 다음과 같은 선형 관계를 가진다.

 

 

 

 

즉, 위의 선형 관계는 Y = WX + B로 표현할 수 있고 식은 아래와 같다.

 

 

forward, 오차함수, 도함수(∂L/∂W, ∂L/∂B) 구하는 방법은 변한 것이 없다.

 

아래 코드를 보면서 변경점만 몇 가지 확인해 보자.

(이전 시간 코드 https://toyourlight.tistory.com/12 와 비교하면 더 좋다)

 

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
#import matplotlib.animation as animation

np.random.seed(220103)

input = np.array([[0, 0],
                  [1., 0],
                  [0, 1.],
                  [1., 1.]])

target = np.array([[1.], 
                   [3.], 
                   [4.],
                   [6.]])

W = np.random.randn(2, 1) 
B = np.random.randn(1, 1) 

"""
print('W : ', W) # correct value 2, 3
print('B : ', B) # correct value 1
W :  [[ 1.07106892]
      [-0.36954615]]
B :  [[-0.9918257]] 
"""

learning_rate = 0.005

def linear_forward(X, Y, W, B):
    XW = np.dot(X, W)
    pred = XW + B
    
    loss = np.mean(np.power(Y - pred, 2))
    return pred, loss

def loss_gradient(X, Y, W, B):
    XWB = np.dot(X, W) + B
    
    #∂L(g(X,W,B)) / ∂g(X,W,B)
    dL_dg = 2*(XWB - Y)
    
    #∂g(X,W,B) / ∂W
    dg_dW = np.transpose(X, (1, 0))
    
    #∂L(G(X, W, B)) / ∂W
    dL_dW = np.dot(dg_dW, dL_dg)
    
    #∂L(g(X,W,B)) / dB
    dL_dB = np.sum(dL_dg, axis=0)
    
    return dL_dW, dL_dB


pred, loss = linear_forward(input, target, W, B)
"""
print('pred : ', pred)
print('loss : ', loss)
pred :  [[-0.9918257 ]
 [ 0.07924321]        
 [-1.36137186]        
 [-0.29030294]]       
loss :  20.202602268952162

"""
dL_dW, dL_dB = loss_gradient(input, target, W, B)
"""
print('before weight : ', W)
print('before bias : ', B)
before weight :  [[ 1.07106892]
 [-0.36954615]]
before bias :  [[-0.9918257]]

"""

for i in range(500):
    dL_dW, dL_dB = loss_gradient(input, target, W, B)
    W = W + -1*learning_rate * dL_dW
    B = B + -1*learning_rate * dL_dB

"""
print('after weight : ', W)
print('after bias : ', B)
after weight :  [[2.0593418 ]
 [1.06153532]]
after bias :  [[0.85518773]]
"""

pred, loss = linear_forward(input, target, W, B)
print('pred : ', pred)
print('loss : ', loss)
"""

pred :  [[2.83083978]
 [4.88249283]
 [6.93414589]]
loss :  0.015586626144295427

"""

 

1) np.random.seed 번호 변경

2) input, target 변경

3) W 변경 (1, 1) → (2, 1)

4) learning_rate 변경 → 학습이 더 오래 걸려 0.005로 변경

5) for i in range 변경 → 학습이 더 오래 필요하여 500으로 변경

 

linear_forward, loss_gradient 함수는 아무것도 건들지 않았음에 주목해보자.