Deep learning/모델 구현

34. 신경망

jwjwvison 2021. 10. 17. 14:07
  • DeZero의 linear 함수

이와 같이 입력 x와 매개벼수 W사이에서 행렬 곱을 구하고, 거기에 b를 더한다. 이 변환을 선형 변환 혹은 아핀 변환이라고 한다.

 오른쪽 그림은 Function 클래스를 상속하여 Linear 클래스를 구현하는 방식이다. 이 방식에서는 중간 결과가 Variale 인스턴스로 보존되지 않기 때문에 순전파 시 사용하던 중간 데이터는 순전파가 끝나는 즉시 삭제된다.

def linear_simple(x,W,b=None):
    t=matmul(x,W)
    if b is None:
        return t
    
    y= t + b
    t.data = None
    return y

 인수 x와 W는 Variable 인스턴스 혹은 ndarray 인스턴스라고 가정한다. ndarray 인스턴스라면 matmul 함수(정확하게는 Function 클래스의 __call__ 메서드) 안에서 Variable 인스턴스로 변환된다. 그리고 편향이 주어지면 단순히 더해준다. 이때 중간 결과인 t의 데이터는 역전파 시 아무에게도 필요치 않으므로 y=t+b 계산이 끝난 후 삭제할 수 있다. 그래서 t.data=None 코드에서 t의 데이터를 메모리에서 삭제한다.

 

class Linear(Function):
    def forward(self, x, W, b):
        y = x.dot(W)
        if b is not None:
            y += b
        return y

    def backward(self, gy):
        x, W, b = self.inputs
        gb = None if b.data is None else sum_to(gy, b.shape)
        gx = matmul(gy, W.T)
        gW = matmul(x.T, gy)
        return gx, gW, gb


def linear(x, W, b=None):
    return Linear()(x, W, b)

 

  • 비선형 데이터셋
    import numpy as np
    np.random.seed(0)
    x0=np.random.rand(100,1)
    y0=np.sin(2*np.pi*x0) + np.random.rand(100,1)​

 보다시피 x와 y는 선형관계가 아니다. 이러한 비선형 데이터셋은 당연히 선형 회귀로는 풀 수 없다. 신경망이 해결사로 등장하는 순간이다.

 

 

  • 활성화 함수와 신경망

선형 변환은 이름 그대로 입력 데이터를 선형으로 변환해준다. 한편 신경망은 선형 변환의 출력에 비선형 변환을 수행한다. 이 비선형 변환을 활성화 함수라고 하며, 대표적으로  ReLU 함수와 시그모이드 함수 등이 있다.

class Sigmoid(Function):
    def forward(self, x):
        y = 1 / (1 + np.exp(-x))
       
        return y

    def backward(self, gy):
        y = self.outputs[0]()
        gx = gy * y * (1 - y)
        return gx


def sigmoid(x):
    return Sigmoid()(x)

 

  • 신경망 구현

 일반적인 신경망은 '선형 변환 -> 활성화 함수 -> 선형 변환 -> ...' 형태로 연속적으로 변환을 수행한다.

import numpy as np
from dezero import Variable
import dezero.functions as F

np.random.seed(0)
x=np.random.rand(100,1)
y=np.sin(2 * np.pi * x) + np.random.rand(100,1)

I,H,O=1,10,1
W1=Variable(0.01 * np.random.randn(I,H))
b1=Variable(np.zeros(H))
W2=Variable(0.01 * np.random.randn(H,O))
b2=Variable(np.zeros(O))

def predict(x):
    y=F.linear(x,W1,b1)
    y=F.sigmoid(y)
    y=F.linear(y,W2,b2)
    return y

lr=0.2
iters=10000

for i in range(iters):
    y_pred=predict(x)
    loss=F.mean_squared_error(y,y_pred)
    
    W1.cleargrad()
    b1.cleargrad()
    W2.cleargrad()
    b2.cleargrad()
    loss.backward()
    
    W1.data -= lr * W1.grad.data
    b1.data -= lr * b1.grad.data
    W2.data -= lr * W2.grad.data
    b2.data -= lr * b2.grad.data
    
    if i % 1000 == 0:
        print(loss)

'Deep learning > 모델 구현' 카테고리의 다른 글

36. Model 클래스  (0) 2021.10.23
35. 매개변수를 모아두는 계층  (0) 2021.10.17
33. 형상 변환 함수, 합계 함수  (0) 2021.10.16
32. 고차 미분  (0) 2021.10.14
31. 함수 최적화(중요)  (0) 2021.10.12