CHAPTER 4 신경망학습
학습 : 훈련 데이터로부터 가중치 매개변수의 최적값을 자동으로 획득하는 것. 손살 함수의 결과값을 가장 작게 만드는 가중치 매개변수를 찾는 것이 목표. 함수의 기울기를 활용하는 경사법을 배운다
4.1 데이터에서 학습한다!
신경망은 데이터를 보고 학습할 수 있다.(가중치 매개변수의 값을 데이터를 보고 자동으로 결정한다)
4.1.1 데이터 주도 학습
기계학습은 데이터에서 답을 찾고, 패턴을 발견하고, 이야기를 만든다. 기계학습의 중심은 데이터라고 할 수 있다. 이미지에서 특징을 추출하고 특징의 패턴을 기계학습 기술로 학습한다. 이미지의 특징은 벡터로 기술. 즉, 신경망은 모든 문제를 주어진 데이터 그대로를 입력 데이터로 활용해 ‘END-TO-END’로 학습할 수 있다.
4.1.2 훈련 데이터와 시험 데이터
훈련 데이터를 사용하여 학습하면서 최적의 매개변수를 찾는다. 시험 데이터를 사용하여 훈련한 모델의 실력을 평가한다. 이 둘을 나누는 이유는 범용적으로 사용할 수 있는 모델을 원하기 때문이다. 이 범용 능력을 제대로 평가하기 위해 둘을 나눈다. 범용 능력은 아직 보지 못한 데이터로도 문제를 올바르게 풀어가는 능력. 한 데이터셋에만 지나치게 최적화 된 상태를 오버피팅이라고 하는데 이것을 피하는 것이 기계학습의 중요한 과제이다.
4.2 손실 함수
신경망 학습에서는 현재의 상태를 하나의 지표로 표현한다. 이 지표를 가장 좋게 만들어 주는 가중치 매개변수의 값을 탐색하는 것이다. 신경망 학습에서는 손실함수라는 지표를 사용한다. 일반적으로는 평균 제곱 오차, 교차 엔트로피 오차를 사용한다. (손실 함수는 신경망 성능의 나쁨을 나타낸다. 즉, 현재의 신경망이 훈련 데이터를 얼마나 잘 처리하지 못하느냐를 나타낸다.)
4.2.1 평균 제곱 오차(MSE)
각 원소의 출력(추정 값)과 정답 레이블(참 값)의 차를 제곱한 후 그 총합을 구한다.
def mean_squared_error(y, t):
return 0.5*np.sum((y-t)**2)
4.2.2 교차 엔트로피 오차(CEE)
정답에 해당하는 출력이 커질수록 0에 다가가다가 그 출력이 1일 때 0이 된다.
def cross_entrophy_error(y, t):
delta=1e-7
return -np.sum(t*np.log(y+delta))
4.2.3 미니배치 학습
훈련 데이터 모두에 대한 손실함수의 합을 구하자
많은 데이터를 대상으로 손실함수를 계산하지 않고 데이터 일부를 추려 전체의 근사치로 이용한다. 그 일부를 미니배치라고 한다.
import sys, os
sys.path.append(os.pardir)
import numpy as np
from dataset.mnist import load_mnist
(x_train, t_train), (x_test, t_test)=load_mnist(normalize=True, one_hot_label=True)
print(x_train.shape)
print(t_train.shape)
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_batxh=t_train[batxh_mask]
np.random.choice(60000,10)
1. load_mnist 함수는 MNIST 데이터셋을 읽어노는 함수이다. 이 함수는 dataset/mnist.py 파일 안에 있다.
2. 호출할 때 `one_hot_label=True`로 지정하여 원핫 인코딩(정답 위치 원소만 1, 나머지는 0인 배열)로 호출
3. 훈련데이터는 60000개, 784차원(원래는 28*28) : x_train은 (60000, 784)
4. 정답 레이블은 10차원 데이터 : (60000, 10)
4.2.4 교차 엔트로피 오차 구현하기
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(y)) / batch_size
y는 신경망 출력, t는 정답 레이블. y가 1차원이면 데이터의 형상을 바꿔준다. 그리고 배치의 크기로 나눠 정규화하고 이미지 1장당 평균의 교차 엔트로피 오차 계산한다.
원핫 인코딩이 아니라 숫자 레이블이면 다음과 같이 구한다.
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
원핫 인코딩일 때 t가 0인 원소는 교차 엔트로피의 오차도 0이므로 무시 가능. 즉, 정답에 해당하는 신경망의 출력만으로 교차 엔트로피 오차 계산 가능.
4.2.5 왜 손실함수를 설정하는가?
높은 정확도를 이끌어 내기 위해 신경망 학습에서는 손실함수 값을 가장 작게 하는 매개변수 값을 찾는다. 이 때 매개변수의 미분을 계산하고 이를 단서로 그 값을 갱신하는 과정을 반복한다. 매개변수의 손실 함수의 미분이란 가중치 매개변수의 값을 아주 조금 변화시켰을 때 손실함수가 어떻게 변하는가라는 뜻이다. 만약, 이 미분값이 음수면 그 가중치 매개변수를 양의 방향으로 변화시켜 손실 함수의 값을 줄일 수 있다. 만약, 미분값이 0이면 갱신을 멈춘다. 즉, 신경망을 학습할 때 정확도를 지표로 삼으면 안된다. 대부분의 장소에서 미분값이 0이 되어 매개변수를 갱신할 수 없기 때문이다.
4.3 수치 미분
4.3.1 미분
미분은 특정 순간의 변화량이다.
def numerical_diff(f, x):
h=1e-4 # 작은 값
return (f(x+h) -f(x)) / (2*h)
4.3.3 편미분
변수가 여럿인 함수에 대한 미분을 편미분이라고 한다. 변수 하나하나를 고정해서 수치 미분 함수를 적용한다. 편미분 또한 특정 장소의 기울기를 구하지만 여러 변수 중에서 하나의 목표 변수에 초점을 맞추고 다른 변수들을 모두 고정시킨다.
4.4 기울기
모든 변수의 편미분을 벡터로 정리한 것을 기울기라고 한다.
기울기가 가리키는 쪽은 각 장소에서 함수의 출력값을 가장 줄이는 방향이다.
def numerical_gradient(f, x):
h=1e-4 # 0.0001
grad=np.zeros_like(x) # x와 같은 모양인 0인 배열 만든다.
for
idx in range(x.size):
tmp_val=x[idx]
# f(x+h) 계산한다
x[idx]=tmp_val+h
fxh1=f(x)
# f(x-h)
x[idx]=tmp_val-h
fxh2=f(x)
grad[idx]=(fxh1-fxh2)/(2*h)
x[idx]=tmp_val
return grad
4.4.1 경사법(경사하강법)
기울기를 이용해서 함수의 최솟값을 찾는 방법
최적의 매개변수(가중치, 편향)를 학습시에 찾아야 한다. 최적이란, 손실 함수가 최솟값이 될 때의 매개변수 값이다. 이럴 때 기울기를 잘 이용해서 함수의 최솟값을 찾는 것이 경사법이다. 기울어진 방향이 꼭 최솟값을 가리키는 것은 아니지만, 그 방향으로 가야 함수의 값을 줄일 수 있다. 경사법은 현 위치에서 기울어진 방향으로 일정 거리만큼 이동한다. 그 다음 이동한 곳에서도 기울기를 구하고, 또 그 기울어진 방향으로 나아가는 일을 반복한다. 이 일을 반복해서 함수의 값을 줄이는 것이 경사법이다. 학습률은 한번의 학습으로 얼마만큼 학습해야 할지, 매개변수 값을 얼마나 갱신하느냐를 정하는 것이 학습률이다. 또, 학습률 값은 0.01이나 0.001 등 미리 특정 값으로 정해두어야 한다. 학습률은 너무 커서도 안되고 너무 작아서도 안된다.
def gradient_descent(f, init_x, lr=0.01, step_num=100):
x=init_x
for i in range(step_num):
grad=numerical_gradient(f, x)
x-=lr*grad
return x
f는 최적화하려는 함수, init_x는 초기값, lr는 learning rate를 의미하는 학습률,step_num은 경사법에 따른 반복 횟수이다.
함수의 기울기는 numerical_gradient(f,x)로 구하고, 그 기울기에 학습률을 곱한 값으로 갱신하는 처리를 step_num번 반복한다.
4.4.2 신경망에서의 기울기
신경망에서의 기울기는 가중치 매개변수에 관한 손실 함수의 기울기다.

위의 그림을 보자. 위 행렬의 형상은 (2,3), 가중치가 W, 손실 함수가 L인 신경망이고 경사는 두 번째 행렬로 나타낼 수 있다. 이 행렬의 각 원소는 각각의 원소에 관한 편미분이다. 1행 1번째 원소는 w11을 조금 변경했을 때 손실함수 L이 얼마나 변화하느냐를 나타낸다. 이 때 중요한 것은 이 두 행렬의 형상은 같아야한다는 것이다.
import sys, os
sys.path.append(os.pardir)
import numpy as np
from common.functions import softmax, cross_entropy_error
from common.gradient import numerical_gradient
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
4.5 학습 알고리즘 구현하기
신경망의 학습 절차를 보자
전체 : 신경망에는 적용 가능한 가중치와 편향이 있고, 학습은 이 가중치와 편향을 훈련 데이터에 적응하도록 조정하는 과정이라고 한다.
1단계 : 미니배치
훈련 데이터 중 일부를 무작위로 가져오는데 이렇게 선별된 데이터를 미니배치라고 한다. 이 미니배치의 손실 함수 값을 줄이는 것을 목표로 한다.
2단계 : 기울기 산출
손실함수 값을 줄이기 위해 각 가중치 매개변수의 기울기를 구한다. 기울기는 손실 함수의 값을 가장 작게하는 방향을 제시한다.
3단계 : 매개변수 갱신
가중치 매개변수를 기울기 방향으로 조금 갱신한다.
4단계 : 반복
1~3단계 반복한다.
경사하강법으로 매개변수를 갱신하고 데이터를 미니배치로 무작위로 선정하기 때문에 확률적 경사 하강법이라고 부른다.(SGD)
4.5.1 2층 신경망 클래스 구현하기
4.5.2 미니배치 학습 구현하기
학습 횟수가 늘어가면서 손실 함수의 값이 줄어든다. 이는 학습이 잘 되고 있다는 뜻으로 신경망의 가중치 매개변수가 서서히 데이터에 적응하고 있음을 의미한다. 즉, 데이터를 반복 학습함으로써 최적 가중치 매개변수로 서서히 다가서고 있다는 것을 알 수 있다.
4.5.3 시험 데이터로 평가하기
신경망 학습에서는 훈련 데이터 외의 데이터를 올바르게 인식하는지 확인해야 한다. 즉, 오버피팅을 일으키지는 않는지 확인해야 한다. 신경망 학습의 목표는 범용능력 즉 훈련데이터에 포함되지 않은 데이터를 사용해서 범용 능력을 평가한다.
'Today I Learned > 밑바닥부터 시작한 딥러닝' 카테고리의 다른 글
밑바닥부터 시작하는 딥러닝1,2를 공부하며,,, (0) | 2020.03.01 |
---|---|
밑바닥부터 시작하는 딥러닝1 3장-신경망 (0) | 2020.02.03 |
밑바닥부터 시작하는 딥러닝1-7장 CNN (0) | 2020.01.28 |
밑바닥부터 시작하는 딥러닝1 2장-퍼셉트론 (0) | 2020.01.19 |