ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 3. 신경망 학습(5)
    AI 모델(딥러닝 기초)/3. 신경망 학습 2023. 1. 10. 13:42
    728x90

    ※ 신경망에서의 기울기

     

    형상 2×3 행렬, 가중치 W, loss function이 L인 신경망을 생각해보자.

     

    이와 같은 W 행렬을 통해 기울기를 구현해보면

     

     

    이와 같은 편미분 행렬을 구해낼 수 있을 것이다. 여기서 1행 1번째 원소의 경우 w11을 변경했을 때 손실 함수 L이 얼마나 변화하느냐를 나타낸다. 또한, 미분을 적용한 행렬의 형상이 기존 W 행렬과 같은 2×3 행렬이라는 점을 알 수 있다.

     

    import sys, os
    sys.path.append(os.pardir)
    import numpy as np
    
    def softmax(a):
        c = np.max(a)
        exp_a = np.exp(a-c)
        sum_exp_a = np.sum(exp_a)
        y = exp_a / sum_exp_a
        
        return y
        
    def numerical_gradient(f, x):
        h = 1e-4 # 0.0001
        grad = np.zeros_like(x)
        
        it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
        while not it.finished:
            idx = it.multi_index
            tmp_val = x[idx]
            x[idx] = float(tmp_val) + h
            fxh1 = f(x) # f(x+h)
            
            x[idx] = tmp_val - h 
            fxh2 = f(x) # f(x-h)
            grad[idx] = (fxh1 - fxh2) / (2*h)
            
            x[idx] = tmp_val # 값 복원
            it.iternext()   
            
        return grad
        
    def cross_entropy_error(y, t):
        delta = 1e-7
        return -np.sum(t * np.log(y + delta))
        
    class simpleNet:
        def __init__(self):
            self.W = np.random.randn(2,3)
            
        def predict(self, x):
            return np.dot(x, self.W)
        
        def loss(self, x, t):
            z = self.predict(x)
            y = softmax(z)
            loss = cross_entropy_error(y, t)
            
            return loss

     

    앞에서 배워왔던 활성화함수 softmax, loss function인 cross_entropy_error, 미분값 numerical gradient를 사용해서 simpleNet Class를 구현해보았다. 간단한 신경망 속에서 2×3행렬의 더미 인수를 사용해서 구현했으며 predict()함수는 예측값을 불러오는 것, loss함수는 예측과 교차 엔트로피 오차를 이용한 loss 값을 불러오는 기능을 하는 Class이다.

     

    net = simpleNet()
    print(net.W)
    [[-0.68065703  1.19968356  0.7072641 ]
     [-0.06380419  2.14776974  0.44823901]]

     

    먼저 위와 같은 더미값을 불러왔다.

     

    x = np.array([0.6, 0.9])
    p = net.predict(x)
    print(p)
    [-0.46581799  2.6528029   0.82777357]

     

    예측값을 이처럼 불러올 수 있다.

     

    t = np.array([0, 0, 1])
    
    net = simpleNet()
    
    f = lambda w: net.loss(x, t)
    dW = numerical_gradient(f, net.W)
    
    print(dW)
    [[ 0.26184894  0.24028043 -0.50212937]
     [ 0.39277341  0.36042064 -0.75319405]]

     

    t에 정답 레이블을 답고 loss 값을 구현할 수 있는 f 변수를 lamda 식으로 나타내어주었으며 numerical_gradient 함수를 사용하여 net.W를 인수로 받아 f로 구해진 loss 값의 변화량을 dW에 담아 출력해주었다.

     

    결과값은 net.W로 받은 2×3 행렬의 더미값의 loss 값의 변화량을 의미한다.

    그렇다면 1행 1열의 0.26184894는 무엇을 의미할까? 이는 w11을 h만큼 늘리면 0.26184894h 만큼 증가한다는 의미이다.

    그렇다면 2행 3열의 -0.75319405는 또 무엇을 의미할까? 부호가 (-) 인 것을 통해 w23을 h 만큼 늘리면 0.75319405 만큼 감소한다는 것을 의미한다.

     

    손실 함수를 줄인다는 개념에서는 w11의 경우는 음의 방향으로, w23의 경우는 양의 방향으로 갱신해야 한다. 또한, 변화량의 관점에서 w23이 w11보다 더 많은 양을 기여한다는 것을 알 수 있다.

     

    이렇게 신경망의 기울기를 구한 다음 경사법에 따라 가중치 매개변수를 갱신하는 방향으로 구현이 가능하다.

    728x90

    'AI 모델(딥러닝 기초) > 3. 신경망 학습' 카테고리의 다른 글

    3. 신경망 학습(7)  (0) 2023.01.15
    3. 신경망 학습(6)  (0) 2023.01.15
    3. 신경망 학습(4)  (0) 2023.01.09
    3. 신경망 학습(3)  (0) 2023.01.07
    3. 신경망 학습(2)  (0) 2023.01.07
Designed by Tistory.