-
개요
학습이란 훈련 데이터로부터 가중치 매개변수의 최적값을 자동으로 획득하는 것이다.
학습의 지표로 손실함수를 사용할 것이고, 손실함수의 최솟값을 구하는 것이 목표이다.
이것을 위한 기법으로 함수의 기울기를 활용하는 경사법을 이용할 것이다.
손실함수란
신경망 성능의 나쁨을 나타내는 지표.
그러므로 값이 작을수록 좋다.
그렇다면 학습의 지표로서 왜 정확도가 아닌 손실함수를 사용하는가?
정확도를 구하는 식을 보면 (정답 수)/(전체 수) 이므로 미세한 조절이 불가능하다.
그래서 우리는 손실함수를 사용할 것이고, 그 미분값을 활용해 최솟값을 찾을 것이다.
<종류>
-오차제곱합(평균오차제곱)
k : 데이터의 차원수
y : 신경망의 출력(신경망이 추정한 값)
t : 정답 레이블
식을 잘 보면 값이 작을수록 정답에 가까워진다는 것을 알 수 있다.
<구현>
def sum_squares_error(y, t): return -0.5 * np.sum((y-t)**2)
-교차 엔트로피 오차
변수는 위와 동일
log 함수 -log(y) 에서 y의 값이 1(정답)에 가까울수록 값이 작아집니다.
이때 y가 0이면 로그의 값은 무한에 수렴하게 됩니다.
이를 방지하기 위해 아주 작은 값을 더해줍시다.
<구현>
def cross_entropy_error(y, t): delta = 1e-7 return -np.sum(t*np.log(y + delta))
미분
자, 손실함수는 알았습니다.(배치용은 하지 않겠습니다.)
그럼 경사법을 알아봅시다. 그런데 경사법을 사용하려면 미분을 할 줄 알아야합니다.
그러므로 미분 구현을 먼저 알아봅시다.
오차를 줄이기 위해 x를 중심으로 그 전후의 차분을 계산하는 중앙차분을 이용해서 하겠습니다.
중앙차분 2층 신경망의 경우 W1, b1, W2, b2 이렇게 4가지의 매개변수가 있습니다.
손실함수의 미분을 통해 매개변수를 조절해야하므로 변수 각각에 대한 미분을 해야합니다.
<구현>
#f는 손실함수입니다. #x는 입력값이라고 생각하면 됩니다 def numerical_gradient(f, x): h = 1e-4 #x와 동일한 크기의 배열을 만든다 grad = np.zero_like(x) for i in range(x.size): tmp_val = x[i] #f(x+h) 와 f(x-h)를 구해봅시다 x[i] = tmp_val + h fxh1 = f(x) x[i] = tmp_val - h fxh2 = f(x) #편미분값을 저장합시다 grad[i] = (fxh1 - fxh2) / 2*h #x 복구 x[i] = tmp_val return grad
경사법
위의 손실함수들은 아래로 볼록한 모양을 갖습니다.
식을 유도해보면 알 수 있습니다.
따라서 기울기가 0일 때, 최솟값임을 보장할 수는 없지만 기울기가 0인 쪽으로 가야만 합니다.
이 알고리즘이 경사하강법입니다.
경사하강법 수식 학습률은 한 번의 학습으로 얼마만큼 학습하는 지를 결정합니다.
이 학습률은 너무 크면 값이 발산해버리고 너무 작으면 매개변수가 거의 갱신되지 않습니다.
정확히는 모르나 책에는 0.1, 0.01, 0.001 등을 언급했습니다.
<구현>
def gradient_descent(f, init_x, lr=0.01, step_num): x = init_x for i in range(step_num): grad = numerical_gradient(f, x) x -= lr*grad return x
f는 최적화하려는 함수, init_x는 초깃값, lr은 학습률, step_num은 경사법에 따른 반복 횟수를 뜻합니다.
[참고]
-밑바닥부터 배우는 딥러닝
반응형'딥러닝' 카테고리의 다른 글
미니배치 학습 구현하기 (0) 2020.01.16 2층 신경망 클래스 구현하기 (0) 2020.01.16 3층 신경망 구현해보기 (0) 2020.01.10 활성화함수 (0) 2020.01.10 퍼셉트론 (0) 2020.01.09