4. 신경망 학습
17 Nov 2020기계학습에서 학습이란 데이터로부터 가중치 매개변수의 최적값을 자동으로 획득하는 것을 말한다. 학습의 목표는 손실함수의 결과값을 가장 작게 만드는 가중치 매개변수를 찾는 것인데, 손실함수의 결과값을 작게 만드는 방법으로는 함수의 기울기를 활용하는 경사법 등이 있다.
데이터 학습
기계가 스스로 학습을 하면 가중치 매개변수의 값을 데이터를 보고 자동으로 결정할 수 있는데, 이것이 사람이 수작업으로 매개변수를 찾는 것에 비해 어떻게 이득일까?
실제 신경망에서의 매개변수는 수천~수만개이고, 층을 깊게 하면 수억개까지도 필요할 수 있어 수작업이 사실상 불가능하다.
기계학습에서는 사람의 개입을 최소화하고 수집한 데이터로부터 패턴을 찾는다. 예를 들어 이미지에서 특징을 추출하여 특징의 패턴을 가지고 학습을 하는데, 이 때 SIFT, SURF, HOG등의 특징을 사용하여 이미지를 벡터로 변환하고, 이러한 벡터들을 SVM, KNN등으로 학습한다. 이렇게 데이터에서 규칙을 찾는 것은 기계가 하지만, 이미지를 벡터로 변환할 때 사용하는 특징은 사람이 설계한다.
신경망을 사용하게 되는 경우 이미지에 포함된 특성 또한 기계가 스스로 학습하는데, 다시 말하면 신경망은 모든 문제를 주어진 데이터 그대로 입력 데이터로 활용해서 end-to-end 방식으로 사람의 개입 없이도 학습할 수 있다.
기계학습에서는 훈련 데이터와 시험 데이터를 나누어 학습과 실험을 수행하는데, 훈련 데이터로 학습한 후 시험데이터로 훈련한 모델의 실력을 평가한다. 이 때 시험 데이터를 나누는 이유는 훈련 데이터에 포함되지 않는 새로운 데이터로도 문제를 올바르게 푸는 능력인 ‘범용 능력’을 제대로 평가하기 위해서이다. 특정 데이터셋에 지나치게 최적화된 상태를 오버피팅이라고 하는데, 기계학습에서는 새로 들어온 데이터에 대해서도 문제를 잘 해결할 수 있어야 하기 때문에 오버피팅을 피하는 것이 중요하다.
손실 함수
신경망 학습에서는 현재의 상태를 하나의 지표로 표현하고, 이 지표를 가장 좋게 만들어주는 가중치 매개변수 값을 탐색한다. 손실함수(loss function, 비용함수(cost function)이라고 부르기도 한다)가 이 지표에 해당한다. 손실함수로는 일반적으로 오차제곱합과 교차엔트로피 오차를 사용한다.
-
오차 제곱합(sum of squares for error, SSE) 손실함수의 출력이 작으면 정답 레이블과의 오차가 작고 정답에 더 가깝다고 판단할 수 있다.
-
교차 엔트로피 오차(cross entropy error, CEE) 실질적으로 정답에 대응되는 추정값의 자연로그 값과 동일하다. 이 방법에서도 정답에 해당하는 출력이 커질수록 오차가 작아지고, 정답에 해당하는 출력이 작아질수록 오차가 커진다.
-
미니배치 학습 앞서 기계학습에서는 훈련 데이터에 대하 손실함수의 값을 구해 이를 최대한 줄여주는 매개변수를 찾는다고 했는데 데이터 하나에 대한 손실함수에서 모든 훈련 데이터에 대한 손실함수의 합을 9구하는 방법은 다음과 같다. 이는 평균 손실함수라고 볼 수 있으며, scalability가 좋다고 볼 수 있다. 데이터가 너무 커지면 일일이 손실함수를 계산하기 힘들기 때문에 일부 데이터에 대해 학습과 손실함수를 수행하는데, 이 일부를 미니배치라고 하고 이러한 학습 방법을 미니배치 학습ㅇ이라가ㅗ 한다.
정확도 대신 손실함수의 값을 사용하여 학습을 하는 이유는 무엇일까?
신경망 학습시 손실함수 값을 최소화 하는 매개변수의 값을 찾는다고 했는데, 이 때 매개변수의 미분값을 가지고 매개변수를 갱신한다. 예를 들어 미분값이 음수이면 가중치의 매개변수를 양의 방향으로, 미분값이 양수이면 가중치의 매개변수를 음의 방향으로 움직이면 손실함수 값이 줄어든다.
미분값이 0인 경우에는 매개변수를 어떻게 움직여도 손실함수의 값이 줄어들지 않기 때문에 더 이상 갱신을 하지 않는다.
정확도를 학습의 지표로 사용하지 않는 이유는 미분값이 대부분 장소에서 0이 되어 매개변수를 갱신할 수 없기 때문이라고 한다.(아직 잘 이해되지 않는다)
다시 말하면 정확도는 매개변수의 미미한 변화에 따라 부드럽게 값이 달라지지 않고, 달라진다고 해도 값이 불연속적으로 변하기 때문에 지표로 삼기에 적합하지 않은데, 활성화 함수로 계단함수를 사용하지 않는 것과 같은 맥락으로 이해하면 될 것 같다.
수치 미분
미분은 한순간의 변화량을 나타내는 방법으로 다음과 같이 계산한다.
미분은 x의 작은 변화가 함수 f(x)를 얼마나 변화시키는지를 의미한다.
위에서 작성한 미분의 식에서는 오차가 생기는데, 이 오차를 줄이기 위해 (x+h)와 (x-h)일 때의 함수 f의 차분을 계산하는 방법을 사용하기도 한다.
def numerical_diff(f, x):
h = 1e-4
return (f(x+h)-f(x-h)) / (2*h)
변수가 두 개인 함수에서는 어떻게 미분을 해야 할까?
변수가 여럿인 함수에 대한 미분을 편미분이라고 하는데 여러 변수 중 목표 변수 이외의 변수들의 값을 고정하여 미분한다.
이렇게 각각의 변수에 대해 편미분을 계산할 수 있고, 모든 변수의 편미분을 벡터로 정리한 것을 기울기라고 한다.
신경망에서도 기계학습에서처럼 학습 시에 최적의 매개변수를 찾아야 하는데 이 때 최적이란 손실함수가 최소가 되게 하는 매개변수를 말한다. 경사 하강법은 기울기를 통해 함수의 최솟값을 찾는 방법이다.
함수에서 기울기가 낮아지는 방향으로 간다고 해도 최솟값을 찾는다는 보장은 없지만 신경망에서는 최적화를 위해 경사법을 많이 사용한다. 현 위치에서 기울어진 방향으로 계속 이동해가면서 함수의 값을 점차 줄이는 방식이다. 이를 수식으로 나타내면 다음과 같이 표현할 수 있다.
이 때 learning rate인 학습율의 크기가 너무 작으면 한 스텝에서 너무 작은 거리씩 움직이고 너무 크면 너무 크게 움직여서 두 경우 모두 최솟값을 찾지 못할 수 있기 때문에 적당한 크기의 learning rate를 설정하는 것이 중요하다.
신경망에서의 기울기는 가중치 매개변수에 대한 손실함수의 기울기인데, 예를 들어 가중치가 2X3 크기의 행렬로 표현할 수 있을 때의 경사는 아래와 같이 계산할 수 있는데 기울기의 형상이 가중치와 동일한 것을 볼 수 있다.
학습 알고리즘 구현하기
간단한 학습 알고리즘을 구현해보면 다음과 같은 과정을 따르는 것을 알 수 있다.
- 미니배치: 훈련 데이터의 일부를 무작위로 가져와 해당 미니배치의 손실함수 값을 줄인다.
- 가중치 산출: 각 가중치 매개변수의 기울기를 구한다.
- 매개변수 갱신: 가중치 매개변수를 기울기 방향으로 아주 조금씩 갱신한다.
- 1~3을 반복한다.
위의 방법은 경사하강법을 사용하면서 무작위로 미니배치를 선정하는 방식인데, 이러한 방법을 확률적 경사 하강법(stochastic gradient descent, SGD)이라고 부른다. 다시 말하면 확률적으로 무작위로 골라낸 데이터에 대해 수행하는 경사하강법을 말한다.
간단한 2계층 신경망과 이를 가지고 MNIST 데이터를 학습하는 코드는 다음 github에서 확인할 수 있다.
근데 코드 실행이 더럽게 오래 걸린다. 책에서 미분이라 계산이 오래 걸린다고 나와있긴 하지만 감안해도 ㄹㅇ 너무 오래 걸린다..