신경망 학습 목차
👀, 🤷♀️ , 📜
이 아이콘들을 누르시면 코드, 개념 부가 설명을 보실 수 있습니다:)
전체 딥러닝 학습과정
이번 포스트에선 어딜 배울까?
바로 노델이 추정한 출력값과 실제 정답값 사이의 오차를 구하는 함수들을 볼 것이다
신경망 학습은 손실 함수를 지표로, 손실 함수의 값이 작아지는 방향으로 가중치 매개변수를 갱신한다.
이때 쓰이는 손실 함수의 종류를 볼 것이다
신경망 학습
INTRO
손실 함수: 신경망이 학습할 수 있도록 해주는 지표
➡ 신경망에서의 output과 실제 정답 사이의 차이를 나타내줌
목표 손실 함수의 결괏값을 가장 작게 만드는 가중치 매개변수를 찾는 것
- 경사법 사용: 함수의 기울기를 활용
데이터 주도 학습
특징 feature
입력 데이터(입력 이미지)에서 본질적인 데이터(중요한 데이터)를 정확하게 추출할 수 있도록 설계된 변환기
Ex) 손글씨‘5’를 인식하기 위한 특징
[기술법]
벡터
: 이미지 특징SIFT, SURF, HOG
: 컴퓨터 비전 분야
[과정]
1) 이런 특징을 사용하여 이미지 데이터를 벡터로 변환(여전히 사람 설계)
2) 변환된 벡터로 지도 학습 방식의 대표 분류 기법인 SVM, KNN 등으로 학습
- 이와 같은 기계학습에서는 모아진 데이터로부터 규칙을 찾아내는 역할을 ‘기계’가 담당
즉 딥러닝= 신경망 = 종단간 기계학습 end-to-end machine learning = 처음부터 끝까지 기계혼자 학습
훈련 데이터와 시험 데이터
데이터 더 자세히 보러가기
1) 우선 훈련 데이터만 사용하여 학습하면서 최적의 매개변수를 찾음
2) 시험 데이터를 사용하여 앞서 훈련한 모델의 실력을 평가
[훈련데이터와 시험데이터를 나누는 이유]
범용 능력(아직 보지 못한 데이터(훈련 데이터에 포함되지 않는 데이터)로도 문제를 올바르게 풀어내는 능력) 을 제대로 평가하기 위해
➕ 오버피팅 overfitting(한데이터셋에만 지나치게 최적화된 상태)를 피해야 함
손실 함수(loss function)
목표
신경망은 ‘하나의 지표(loss function)’를 기준으로 최적의 매개변수 값을 탐색
정의
생성된 모델의 예측값과 실제값 간의 차이를 나타내는 함수
- 즉, 이 값이 0에 가까울수록 모델의 정확도가 높음
- 반대로 0에서 멀어질수록 모델의 정확도가 낮음
임의의 함수를 사용할 수도 있지만 일반적으로는 오차제곱합과 교차 엔트로피 오차를 사용
손실함수는 신경망 성능의 ‘나쁨’을 나타내는 지표
- (-)를 곱해주면 ‘좋음’을 나타내는 지표
- <나쁨을 최소로 하는 것 ➡ 좋음을 최대로 하는 것>
오차 제곱 합(sum of squares for error, SSE)
- \(y_k\): 신경망의 출력(신경망이 추정한 값)
- \(t_k\): 정답 레이블
- \(k\): 데이터의 차원 수
ex)
>>> y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
>>> t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[해석]
- \(y\): 소프트맥스 함수의 출력 => 확률
- 이미지가 ‘0’일 확률은 0.1, ‘1’일 확률은 0.05
- 정답 레이블인 \(t\) => 정답
- 답을 가리키는 위치의 원소는 1로, 그 외에는 0으로 처리
- 원-핫 인코딩: 한 원소만 1로 하고 그 외는 0으로 나타내는 표기법
[구현]
def sum _squares _error(y, t):
return 0.5 * np.sum((y-t)**2)
값이 작으면 오차일 확률 낮음
교차 엔트로피 오차(cross entropy error, CEE)
교차 엔트로피는 주어진 확률 변수 또는 일련의 이벤트에 대한 두 확률 분포 간의 차이를 측정한 것.
정보가 이벤트를 인코딩하고 전송하는 데 필요한 비트 수를 수량화 한다는 것을 기억할 수 있음
➡️ 낮은 확률의 사건은 더 많은 정보를 갖고, 높은 확률의 사건은 더 적은 정보를 기억하게 해줌
- \(log\): 밑이 e인 자연로그(\(log_e\))
- \(y_k\): 신경망의 출력
- \(t_k\): 정답 레이블(원-핫 인코딩)
실질적으로 t=1 (정답)일 때인 자연로그 계산 (정답일 때의 출력이 전체 값을 정함)
- x가 1일 때 y는 0
- x가 0에 가까워질수록 y의 값은 점점 작아짐
-
정답에 해당하는 출력이 커질수록 0에 다가감
- X 축: 정답일 확률
- y 축: 손실값에 -1을 곱한 값
- ➡ 가로축값이 1, 즉 정답이 확률이 100%일때 손실값은 0이 됨
- 정답이 확률이 낮아 질수록 손실값은 무한대로 커지게 됩니다
[구현]
def cross _entropy _error(y, t):
delta = 1e-7
return -np.sum(t * np.log(y + delta))
- y와 t는 넘파이 배열
- 코드 마지막 + delta 이유
- np.log ( ) 함수에 0을 입력하면 마이너스
- 무한대를 뜻하는 -inf가 되어 더 이상 계산을 진행할 수 없게 되기 때문 아주 작은 값을 더해서 절대 0이 되지 않도록, 즉 마이너스 무한대가 발생하지 않도록 한 것
미니배치 학습
앞의 방법을 활용하면 모든 훈련 데이터를 대상으로 손실 함수 값을 구해야 함
그러므로 배치사이즈를 정하여 부분적으로 학습시키고,
훈련 데이터 모두에 대한 손실 함수의 합을 구하는 방법
- \(N\): 데이터의 개수
- \(t_nk\): n번째 데이터의 k번째 값
[해석]
데이터 하나에 대한 손실 함수인 위 식을 단순히 N개의 데이터로 확장
마지막에 N으로 나누어 정규화(‘평균 손실 함수’를 구함): 훈련 데이터 개수와 관계없이 언제든 통일된 지표를 얻을 수 있음
[미니배치 mini-batch]
많은 데이터 모두 손실 함수를 계산 힘듦
데이터 일부를 추려 전체의 ‘근사치’로 이용 가능
신경망 학습에서도 훈련 데이터로부터 일부만 골라학습을 수행 //이 일부를 뜻함
훈련 데이터에서 지정한 수의 데이터를 무작위로 골라 내는 코드구현
👀코드 보기
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) # (60000, 784)
print(t_train.shape) # (60000, 10)
# np.random.choice (범위, 뽑아 낼 개수) 쓰자!!!
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(60000, 10)
array([ 8013, 14666, 58210, 23832, 52091, 10153, 8107, 19410, 27260, 21411])
(배치용) 교차 엔트로피 오차 구현하기
1️⃣ 정답 레이블이 원-핫 인코딩
👀코드 보기
def cross_entropy_error(y, t):
if y.ndim = = 1: # 1차원 함수
t = t.reshape(1, t.size)
y = y.reshape(1, y.size)
#행의 크기
batch _size = y.shape[0]
#배치의 크기로 나눠 정규화하고
#이미지 1장당 평균의 교차 엔트로피 오차를 계산
return -np.sum(t * np.log(y + 1e-7)) / batch _size
2️⃣ 정답 레이블이 ‘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] + 1e-7)) / batch_size
📜 코드 설명 보기
y[np.arange(batch _size), t]
- 정답만 교차 엔트로피를 계산하기 위해서
- (batch_size)-> 0부터 batch_size - 1까지 배열을 생성.
- 즉, batch_size가 5이면 np.arange (batch_size )는 [0, 1, 2, 3, 4 ]라는 넘파이 배열을 생성
- t에는 레이블이 [2, 7, 0, 9, 4 ]와 같이 저장되어 있으므로 y[np.arange (batch_size ), t ]는 각 데이터의 정답 레이블에 해당하는 신경망의 출력을 추출
- (이 예에서는 y[np.arange (batch_size ), t ]는 [y[0,2 ], y[1,7 ], y[2,0 ], y[3,9 ], y[4,4 ] ]인 넘파이 배열을 생성).
손실함수 설정 이유
‘정확도’라는 지표를 놔두고 ‘손실 함수의 값’이라는 우회적인 방법을 택하는 이유- ➡ 미분 떄문
[신경망학습 최적의 매개변수(가중치와 편향)를 탐색과정]
손실 함수의 값을 가능한 한 작게 하는 매개변수 값을 찾음
1️⃣ 매개변수의 미분(정확히는 기울기)을 계산
2️⃣ 그 미분 값을 단서로 매개변수의 값을 서서히 갱신하는 과정을 반복
[손실 함수의 미분]
‘가중치 매개변수의 값을 아주 조금 변화시켰을 때, 손실 함수가 어떻게 변하나’
- 미분값 양수면 매개변수를 음의값으로 변환(반대도 =)
- 0일 때 멈춤
[정확도를 지표로 삼지 않는 이유]
미분 값이 대부분의 장소에서 0이 되어 매개변수를 갱신할 수 없음
매개변수의 미소한 변화에는 거의 반응을 보이지 않고, 반응이 있더라도 그 값이 불연속적으로 갑자기 변화
불연속적임 100개중 32개가 정확하다면 정확도는 32%(손실 함수 0.92543…)
계단함수처럼 한순간에서만 변화를 일으킴
이번 장에서 배운 내용
● 기계학습에서 사용하는 데이터셋은 훈련 데이터와 시험 데이터로 나눠 사용한다.
● 훈련 데이터로 학습한 모델의 범용 능력을 시험 데이터로 평가한다.
● 신경망 학습은 손실 함수를 지표로, 손실 함수의 값이 작아지는 방향으로 가중치 매개변수를 갱신한다.
● 가중치 매개변수를 갱신할 때는 가중치 매개변수의 기울기를 이용하고, 기울어진 방향으로 가중치의 값을 갱신하는 작업을 반복한다.