본문 바로가기
책&강의 학습/올인원 패키지 :딥러닝&인공지능

[패스트캠퍼스 수강 후기] 인공지능강의 100% 환급 챌린지 34회차 미션

by 소한보 2020. 8. 1.

Part4- 29. 쉽게 배우는 역전파 학습법 - 10. (STEP 3) 역전파 학습법을 이용한 심층 신경망 학습 - 1,2

동적학습법을 이용하기 위해 시그모이드, loss를 class로 구현

유틸리티 함수

def _t(x):
    return np.transpose(x)

def _m(A, B):
    return np.matmul(A, B)

시그모이드 구현

class Sigmoid:
    def __init__(self):
        self.last_o = 1

    # forward때
    def __call__(self, x):
        self.last_o = 1 / (1.0 + np.exp(-x))
        return self.last_o
    #BP 할때 
    def grad(self): # 이전 구현 : sigmoid(x)(1-sigmoid(x))
        return self.last_o * (1 - self.last_o)

Mean Squared Error 구현

class MeanSquaredError:
    def __init__(self):
        # gradient (체인룰 사용해서 계속 가져오기 위해 미리 저장)
        self.dh = 1
        self.last_diff = 1        

    def __call__(self, h, y): # 1/2 * mean ((h - y)^2) 미분해서 1/2과 상쇄됨
        self.last_diff = h - y
        return 1 / 2 * np.mean(np.square(h - y))

    def grad(self): # h - y
        return self.last_diff

뉴런 구현(Fully connected layer 하나구현)

class Neuron:
    def __init__(self, W, b, a_obj):
        # Model parameters
        self.W = W
        self.b = b
        self.a = a_obj()

        # gradient
        self.dW = np.zeros_like(self.W)
        self.db = np.zeros_like(self.b)
        self.dh = np.zeros_like(_t(self.W)) #이전입력으로 인한 gradient

        self.last_x = np.zeros((self.W.shape[0])) #마지막 x를 저장 이전입력을 알고 있어야 미분하기 때문에
        self.last_h = np.zeros((self.W.shape[1])) #마지막으로 나가는 출력값 

    def __call__(self, x):
        self.last_x = x
        self.last_h = _m(_t(self.W), x) + self.b
        return self.a(self.last_h)

    def grad(self): # dy/dh = W
        return self.W * self.a.grad()

    def grad_W(self, dh): #dh는 지금까지의 그라디언트를 누적해서 계산해온 값
        grad = np.ones_like(self.W) #W와 같은 크기의 1로 체워줌
        grad_a = self.a.grad()
        #출력하나하나마다 따로 계산
        for j in range(grad.shape[1]): # dy/dw = x 
            grad[:, j] = dh[j] * grad_a[j] * self.last_x
        return grad
    #b로 미분하면 단순 1
    def grad_b(self, dh): # dy/dh = 1
        return dh * self.a.grad()

이전과 달라진 부분

심층신경망 구현

class DNN:
    def __init__(self, hidden_depth, num_neuron, input, output, activation=Sigmoid):
        def init_var(i, o):
            return np.random.normal(0.0, 0.01, (i, o)), np.zeros((o,))

        self.sequence = list()
        # First hidden layer
        W, b = init_var(input, num_neuron)
        self.sequence.append(Neuron(W, b, activation))

        # Hidden Layers
        for index in range(hidden_depth):
            W, b = init_var(num_neuron, num_neuron)
            self.sequence.append(Neuron(W, b, activation))

        # Output Layer
        W, b = init_var(num_neuron, output)
        self.sequence.append(Neuron(W, b, activation))

    def __call__(self, x):
        for layer in self.sequence:
            x = layer(x)
        return x

    def calc_gradient(self, loss_obj):
        loss_obj.dh = loss_obj.grad() #마지막 loss function에 대한 gradient
        self.sequence.append(loss_obj) #편의성을 위해 loss를 넣어주고 나중 빼줌

        # back-prop loop
        for i in range(len(self.sequence) - 1, 0, -1): #순서로 반대로 구현 
            l1 = self.sequence[i]
            l0 = self.sequence[i - 1]

            l0.dh = _m(l0.grad(), l1.dh)
            l0.dW = l0.grad_W(l1.dh)
            l0.db = l0.grad_b(l1.dh)

        self.sequence.remove(loss_obj)

len(self.sequence) - 1, 0, -1)

순서를 뒤집고 0을 제외

경사하강 학습법

def gradient_descent(network, x, y, loss_obj, alpha=0.01):
    loss = loss_obj(network(x), y)  # Forward inference
    network.calc_gradient(loss_obj)  # Back-propagation
    for layer in network.sequence:
        layer.W += -alpha * layer.dW
        layer.b += -alpha * layer.db
    return loss

동작테스트

x = np.random.normal(0.0, 1.0, (10,))
y = np.random.normal(0.0, 1.0, (2,))

t = time.time()
dnn = DNN(hidden_depth=5, num_neuron=32, input=10, output=2, activation=Sigmoid)
loss_obj = MeanSquaredError()
for epoch in range(100):
    loss = gradient_descent(dnn, x, y, loss_obj, alpha=0.01)
    print('Epoch {}: Test loss {}'.format(epoch, loss))
print('{} seconds elapsed.'.format(time.time() - t))

엄청난 속도 향상이 생김

딥러닝/인공지능 올인원 패키지 Online

댓글