728x90
반응형

훈련 데이터와 시험 데이터

  • 훈련 데이터만 사용해 학습하면서 최적의 매개변수를 찾는다.
  • 그 후 시험 데이터를 사용해 앞서 훈련한 모델의 실력을 평가한다.
  • 나누는 이유는 범용적으로 사용할 수 있는 모델을 원하기 때문

범용 능력

  • 아직 보지 못한 데이터(훈련 데이터에 포함되지 않는 데이터)로도 문제를 올바르게 풀어내는 능력
  • 기계학습의 최종 목표

 

손실 함수

  • 신경망도 '하나의 지표'를 기준으로 최적의 매개변수 값을 탐색한다.
  • 신경망 학습에서사용하는 지표는 손실 함수다.
  • 손실 함수는 임의의 함수를 사용할 수도 있지만 일반적으로는 평균 제곱 오차와 교차 엔트로피 오차를 사용한다.

 

평균 오차 제곱

  • 가장 많이 쓰이는 손실 함수 

[그림1] 평균 오차 제곱

yk는 신경망의 출력(신경망이 추정한 값), tk는 정답 레이블, k는 데이터의 차원 수를 나타낸다.

 

평균 제곱 오차 파이썬

import numpy as np

# 평균 오차 제곱
def mean_squared_error(y, t):
    return 0.5 * np.sum((y-t)**2)

# 정답은 2 
t = [0,0,1,0,0,0,0,0,0,0]

# '2'일 확률이 가장 높다고 추정(0.6)
y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]

print(mean_squared_error(np.array(y), np.array(t)))

# 7일 확률이 가장 높다고 추정(0.6)

y = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]

print(mean_squared_error(np.array(y), np.array(t)))

첫 번째 예의 정답은 2고 신경망의 출력도 2에서 가장 높은 경우고

두 번째 예의 정답도 2고 신경망의 출력은 7에서 가장 높은 경우다.

* 첫 번째 예의 손실 함수 쪽 출력이 작으며 정답 레이블과의 오차도 작은것을 알 수 있다.

평균 제곱 오차를 기준으로 첫 번째 추정 결과가 정답에 더 가깝다는 의미다.

 

 

교차 엔트로피 오차

  • 손실 함수중 하나.

[그림2] 교차 엔트로피 오차

log는 밑이 e인 자연로그다. yk는 신경망의 출력, tk는 정답 레이블이다.

tk는 정답에 해당하는 인덱스의 원소만 1이고 나머지는 0이다. (원-핫 인코딩).

예) 정답 레이블이 2일 경우 신경망의 출력이 0.6이라면 교차 엔트로피 오차는 -log0.6 = 0.51이 된다.

같은 조건에서 교차 엔트로피 오차 구현

 

파이썬 코드

import numpy as np

# 교차 엔트로피 오차

def cross_entropy_error(y, t):
    delta = 1e-7
    return -np.sum(t * np.log(y + delta))

# y와 t는 넘파이 배열
# np.log를 계산시 작은 값 delta를 더한다.

# 정답은 2
t = [0,0,1,0,0,0,0,0,0,0]

y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
print(cross_entropy_error(np.array(y), np.array(t)))
# 출력이 0.6인 경우 엔트로피 오차는 약 0.51 

y = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]
print(cross_entropy_error(np.array(y), np.array(t)))
# 2.3으로 더 작은 첫 번재 추정이 정답일 가능성이 높다고 판단

# 평균 제곱 오차 판단과 일치

[그림3] 교차 엔트로피 오차 결과 

 

 

미니배치 학습

  • 훈련 데이터 모두에 대한 손실함수의 합을 구하는 방법

 

 

[그림4] 미니배치 학습 교차 엔트로피 오차 식

 

데이터가 N개라면 tnk는 n번째 데이터의 k차원 째의 값을 의미한다. (ynk는 신경망의 출력, tnk는 정답 레이블이다.)

마지막에 N으로 나누어 정규화하고 있다. N으로 나눔으로 '평균 손실 함수'를 구하는 것이다.

 

데이터가 너무 많은 경우 데이터 일부를 추려 전체의 '근사치'로 이용할 수 있다. 신경망 배치에서도 일부만 골라 학습을 수행한다. 이 일부를 미니배치라고 한다.

예) 6만장의 훈련 데이터중 100장을 무작위로 뽑아 100장을 사용해 학습하는 것. 이 학습 방법은 미니배치 학습이라고 한다.

 

 

미니배치 학습

# 미니배치 학습
import sys,os
sys.path.append(os.pardir) # 부모 디렉토리 참조
import numpy as np
from mnist import load_mnist




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

print(x_train.shape) # 6만개 훈련 데이터 784차원
print(t_train.shape)  # 6만개 정답 레이블 - 10차원


# 이 데이터 중에서 무작위 10개만 뽑아내기

train_size = x_train.shape[0]
batch_size = 10
batch_mask = np.random.choice(train_size, batch_size)
x_batch = x_train[batch_mask]
t_batch = t_train[batch_mask]

# np.random.choice()는 지정한 범위의 수 중에서 무작위로 원하는 개수만 꺼낼 수 있다.
# np.random.choice(60000, 10)  0에서 60000 미만의 수 중에서 무작위로 10개를 골라낸다.

 

미니배치 처리 가능한 교차 엔트로피

#  미니배치 배치 데이터를 처리할 수 있는 교차 엔트로피 오차 구현
# 기존 교차 엔트로피 오차를 조금만 수정 - 데이터가 하나인 경우와 배치로 묶여 입력될 경우 모두를 처리할 수 있도록 구현

def cross_entropy_error(y,t) : 
    if y.ndim == 1:
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)
        
        
    batch_size = y.shape[0]
    return -np.sum(t * np.log(u)) / batch_size

# y는 신경망의 출력, t는 정답 레이블 y가 1차원이라면 
# 데이터 하나당 교차 엔트로피 오차를 구하는 경우는 reshape 함수로 데이터의 형상을 바꿔준다.

 

정답 레이블이 원-핫 인코딩이 아니라 숫자 레이블로 주어졌을 경우

# 정답 레이블이 원-핫 인코딩이 아니라 '2'나 '7'등의 숫자 레이블로 주어졌을 때 교차 엔트리 오차

def cross_entropy_error(y,t) : 
    if y.ndim == 1:
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)
        
        
    batch_size = y.shape[0]
    return -np.sum(np.log(y[np.arange(batch_size),t])) / batch_size
# np.arange(batch_size)는 0부터 batch_szie - 1 까지의 배열을 생성한다.
# batch_size가 5이면 np.arange(batch_szie)는 [0,1,2,3,4]라는 넘파이 배열을 생성한다. 
# 이 예에서 y[np.arange(batch_size),t] 는 [y[0,2],y[1,7],y[2,0],y[3,9],y[4,4]] 라는 넘파이 배열 생성

 

 

손실 함수를 설정하는 이유

  • 궁극적인 목적이 높은 '정확도'를 끌어내는 매개변수 값을 찾는 것이기 때문.
  • 신경망 학스에서는 최적의 매개변수(가중치와 편향)을 탐색할 때 손실 함수의 값을 가능한 한 작게 하는 매개변수 값을 찾는다.
  • 매개변수의 미분(기울기)을 계산하고, 미분 값을 단서로 매개변수의 값을 서서히 갱신하는 과정을 반복한다.
  • 신경망 학습시 정확도를 지표로 삼아서는 안 된다. 정확도를 지표로 하면 매개변수의 미분이 대부분의 장소에서 0이 되기 때문
  • 0이 되는 이유는 정확도는 매개변수의 미소한 변화에는 거의 반응을 보이지 않고, 반응이 있더라도 그 값이 불연속적으로 갑자기 변화한다.  '계단 함수'를 활성화 함수로 사용하지 않는 이유와도 들어맞는다.
  • 계단 함수는 한순간만 변화를 일으키지만 시그모이드 함수의 미분은 어느 장소라도 0이 되지는 않는다. 기울기가 0이 되지 않기 때문에 신경망이 올바르게 학습할 수 있는 것이다.

*계단 함수는 대부분의 장소에서 기울기가 0이다.

*시그모이드 함수는 기울기가 0이 아니다.

 

출처 : 밑바닥부터 시작하는 딥러닝

https://www.hanbit.co.kr/store/books/look.php?p_code=B8475831198

 

밑바닥부터 시작하는 딥러닝

직접 구현하고 움직여보며 익히는 가장 쉬운 딥러닝 입문서

www.hanbit.co.kr

 

 

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기