신경망 학습

Jiyoon·2023년 1월 25일
0

Deep Learning

목록 보기
3/6

신경망

입력층, 은닉층, 출력층으로 표현할 수 있는 구조
가중치를 갖는 층은 총 2개 → 2층 신경망

신경망 학습(딥러닝): 종단간 기계학습

  • 사람의 개입이 필요없음, 데이터 입력에서부터 목표한 결과를 사람의 개입 없이 얻는다.





손실함수

최적의 매개변수 값을 탐색하는 ‘하나의 지표’
이 지표를 가장 좋게 만들어주는 가중치 매개변수를 탐색한다.

- 오차제곱합

오차제곱합이 더 작은 예시가 정답에 가까운 추정 값

- 교차 엔트로피 오차

교차 엔트로피 오차가 더 작은 예시가 정답에 가까운 추정 값

미니배치 학습

전체 데이터에서 일부 데이터(미니배치)를 선별하여 학습하는 것
ex) 60,000개의 훈련 데이터 중 100개를 무작위로 뽑아 학습

정확도가 아닌 손실함수를 설정하는 이유
→ 정확도: 단순히 전체 경우에서 정확하게 맞춘 확률을 구한 것(확률이 불연속적이다)

매개변수의 값을 조정해도 정확도는 유지될 가능성 있음, 손실함수는 연속적



기울기

f(x0, x1) = x02 + x12 의 그래프

기울기는 각 지점에서 함수의 값이 낮아지는 방향을 가리킨다.

f(x0, x1) = x02 + x12 의 기울기
기울기가 가리키는 쪽은 각 장소에서 함수의 출력 값을 가장 크게 줄이는 방향

경사법(경사 하강법, 경사 상승법)

최적의 매개변수: 손실 함수가 최솟값이 될 때의 매개변수 값을 의미, 함숫값이 작아지는 방향으로 이동하며 극값에 도달할 때까지 반복한다.

기울기가 가리키는 방향이 함수의 값을 줄일 수 있다는 점을 이용 → 경사법

정의

현 위치에서 일정한 거리만큼 이동한 후, 그 위치에서 다시 기울기를 구하고 기울어진 방향으로 나아가는 것을 반복하는 것

에타(eta): 갱신하는 양을 나타냄

  • (함수 값이 낮아지는 곳으로 얼만큼 이동할 것인지 = 보폭)을 정하는 것

신경망에서의 기울기

가중치 매개변수에 대한 손실 함수의 기울기

가중치 행렬

손실함수 L의 각 가중치에 대한 편미분 행렬(경사)

손실 함수를 w11에 대해 미분한 결과가 0.14일 경우, w11을 h만큼 증가시키면 손실 함수의 값은 0.14h만큼 증가한다는 것을 의미

가중치 매개변수 갱신

  • 가중치 매개변수의 기울기를 이용하고, 기울어진 방향으로 가중치의 값을 갱신하는 작업을 반복한다



학습 알고리즘

1단계 - 미니배치

training data 중 일부를 random으로 가져온다. 선별된 데이터를 미니배치라 하며, 미니배치의 손실 함수 값을 줄이는 것이 목표이다.

2단계 - 기울기 산출

미니배치의 손실 함수 값을 줄이기 위해 손실 함수의 값을 가장 작게하는 방향을 제시해주는 각 가중치 매개변수의 기울기를 구한다.

3단계 - 매개변수 갱신

가중치 매개변수를 기울기 방향으로 갱신한다.

4단계 - 반복

1~3단계를 반복한다.


→ 확률적 경사 하강법(SGD)
확률적으로 무작위로 골라낸 데이터에 대해 수행하는 경사 하강법.

2층 신경망 클래스

import sys, os
sys.path.append(os.pardir)
from common.functions import *
from common.gradient import numerical_gradient

class TwoLayerNet:
    def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01):
        self.params = {}
        self.params['W1'] = weight_init_std * np.random.randn(input_size, hidden_size)
        self.params['b1'] = np.zeros(hidden_size)
        self.params['W2'] = weight_init_std * np.random.randn(hidden_size, output_size)
        self.params['b2'] = np.zeros(output_size)

    def predict(self, x):
        W1, W2 = self.params['W1'], self.params['W2']
        b1, b2 = self.params['b1'], self.params['b2']

        a1 = np.dot(x, W1) + b1
        z1 = sigmoid(a1)
        a2 = np.dot(z1, W2) + b2
        y = softmax(a2)

        return y

    def loss(self, x, t):  #x: 입력데이터, t:정답 레이블
        y = self.predict(x)

        return cross_entropy_error(y, t)

    def accuracy(self, x, t):
        y = self.predict(x)
        y = np.argmax(y, axis=1)
        t = np.argmax(t, axis=1)

        accuracy = np.sum(y == t) / float(x.shape[0])
        return accuracy

    def numerical_gradient(self, x, t):
        loss_W = lambda W:self.loss(x, t)

        grads ={}
        grads['W1'] = numerical_gradient(loss_W, self.params['W1'])
        grads['b1'] = numerical_gradient(loss_W, self.params['b1'])
        grads['W2'] = numerical_gradient(loss_W, self.params['W2'])
        grads['b2'] = numerical_gradient(loss_W, self.params['b2'])

        return grads

위에서 만든 신경망으로 mnist 데이터 셋 미니배치 학습

import numpy as np
from dataset.mnist import load_mnist
from two_layer_net import TwoLayerNet

(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)

train_loss_list = []

#hyperparameter
iters_num = 10000
train_size = x_train.shape[0]
batch_size = 100
learning_rate = 0.1

network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)

for i in range(iters_num):
    #미니배치 획득
    batch_mask = np.random.choice(train_size, batch_size)
    x_batch = x_train[batch_mask]
    t_batch = t_train[batch_mask]

    #기울기 계산
    grad = network.numerical_gradient(x_batch,  t_batch)
    #grad = network.gradient(x_batch, t_batch) #성능 개선판

    #매개변수 갱신
    for key in ('W1', 'b1', 'W2', 'b2'):
        network.params[key] -= learning_rate * grad[key]

    #학습 경과 기록
    loss = network.loss(x_batch, t_batch)
    train_loss_list.append(loss)

test data로 정확도 평가

  • epoch(학습 단위)사용
import numpy as np
from dataset.mnist import load_mnist
from two_layer_net import TwoLayerNet

(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_labe=True)

network = TwoLayerNet(input_size=784, hidden_size=50, output=10)

#hyperparameter
iters_num = 10000
train_size = x_train.shape[0]
batch_size = 100
learning_rate = 0.1

train_loss_list = []
train_acc_list = []
test_acc_list = []

#1epoch당 반복 수
iter_per_epoch = max(train_size / batch_size, 1)

for i in range(iters_num):
    #미니배치 획득
    batch_mask = np.random.choice(train_size, batch_size)
    x_batch = x_train[batch_mask]
    t_batch = t_train[batch_mask]

    #기울기 계산
    grad = network.numerical_gradient(x_batch, t_batch)
    #grad = network.gradient(x_batch, t_batch)
    
    #매개변수
    for key in ('W1, b1, W2, b2'):
        network.params[key] -= learning_rate * grad[key]
        
    #학습 경과 기록
    loss = network.loss(x_batch, t_batch)
    train_loss_list.append(loss)
    
    #1epoch당 정확도 계산
    if i % iter_per_epoch == 0:
        train_acc = network.accuracy(x_train, t_train)
        test_acc = network.accuracy(x_test, t_test)
        train_acc_list.append(train_acc)
        test_acc_list.append(test_acc)
        print("train acc, test acc :" +str(train_acc) + ", " +str(test_acc))

0개의 댓글

관련 채용 정보