(* 참고:https://keras.io/api)
예제에 주어진 요소
데이터
- train data: 60000
- test data: 10000
입력 차원 = 784
히든레이어1 차원 = 128, 활성함수 = 시그모이드
히든레이어2 차원 = 128, 활성함수 = 시그모이드
히든레이어3 차원 = 128, 활성함수 = 시그모이드
출력 차원 = 10, 활성함수 = 소프트맥스
최적화 함수 = 확률적 경사 하강법(SGD)
학습률 = 0.01
손실함수 = categorical_crossentropy
검증 지표 = accuracy
배치 크기 = 32
에포크(학습 횟수) = 10
주어진 요소의 의미와 실험항목
히든레이어 - 총 3개의 히든레이어를 가진 딥러닝 구조이며 다음과 같은 실험을 진행
- 층을 수정: 3 -> 5, 10
- 차원 수정: 128 -> 10, 256
- #1, #2 모두 진행
활성함수 - 다른 활성함수를 가지고 실험 진행
- 시그모이드: 0~1 사이의 값을 가지며 이진분류에 많이 사용. 출력 중앙값이 0.5이기 때문에 편향이 양의 값으로 이동하는 편향이동이라는 문제가 있다. 기울기 소실 문제가 있어 층을 많이 쌓으면 기울기 소실 문제 발생. 반환값이 0~1이기에 확률과 비슷하기에 출력층에서 주로 사용한다고 한다.
- 하이퍼볼릭탄젠트: -1~1 사이의 값을 가지고 중앙값이 0이기 때문에 편향이 입력과 출력의 편향의 차이가 발생하지 않는다. 시그모이드와 동일하게 기울기 소실 문제가 있다. 시그모이드와 비슷하게 출력층에서 주로 사용한다고 한다.
- ReLU: 기울기 소실 문제가 없다. 음수 값의 경우 출력이 항상 0이다. 기울기 소실 문제가 없기 때문에 주로 히든레이어에서 사용한다고 한다.
- Softmax: 출력값이 여러개인 경우 해당 값들의 합이 1인 확률적 분포의 값을 내보낸다. 여러개의 출력값의 결과를 확인하기 위해 주로 출력층에서 사용한다.
최적화 함수 - Adam, Nadam, AdaDelta에 대해서 성능 비교
학습률 - 0.01, 0.001, 0.05, 0.1 로 진행
손실함수 - 0~9 숫자를 고르는 다중 선택 문제이고 원핫인코딩이 된 상태에선 categorical_crossentropy를 사용, 원핫인코딩이 안된 상태에서는 sparse_categorical_crossentropy를 사용해서 비교
- 그 외 기타 손실함수
- mean_squared_error: 회귀 예측 손실 함수. 예측값과 실제값의 평균 제곱 오차로 측정
- mean_absolute_error: 회귀 예측 손실 함수. 예측값과 실제 값의 평균 절대 오차 측정
- binary_crossentropy: 이진 분류 손실 함수. 정답이 0 또는 1인 이진 분류 문제에서 사용
- categorical_crossentropy: 다중 클래스 분류 손실 함수. 클래스의 확률 분포와 실제 값 간의 크로스 엔트로피를 계산. 정답이 원핫인코딩으로 변환된 경우 사용
- sparse_categorical_crossentropy: 다중 클래스 분류 손실 함수. 정답 레이블을 원한인코딩으로 변호나하지 ㅇ낳고 정수 값으로 사용하는 경우 사용
- 기타 다수...
검증 지표 - 기준을 일원화 하기 위해 Accuracy 사용
- Accurcy: 정답과 예측이 맞을때의 지표
- BinaryAccuracy
- CategoricalAccuracy
- SparseCategoricalAccuracy
- TopKCategoricalAccuracy
배치 크기 - 30, 1, 10, 100, 10000, None으로 테스트
에포크 - 5, 10, 20으로 진행
테스트 진행 단계
성능을 높이는 것이 목표이기 때문에 고정할 수 있는 하이퍼 파라미터를 먼저 선정해 둔다.
모든 실험은 예제 기준값에서 각 특정 항목만을 조정하여 실험하였다. (누적 변경 아님)
1. 평가지표: accuracy
2. 배치크기 - None
batch size | 32 | 1 | 100 | 10000 | None |
accuracy | 0.9225 | 0.6119 | 0.8798 | 0.1674 | 0.9294 |
한 에포크당 소요시간(초) | 1 | 26.6 | 0 | 0 | 1.1 |
3. 에포크 - 20
total epochs | 5 | 10 | 20 |
accuracy | 0.8914 | 0.9294 | 0.9358 |
4. 손실함수 - sparse_categorical_crossentropy (유의미한 차이는 없는 정도로 파악된다.)
(* 유의미한 차이가 있는지는 p-값 확인이 필요할 것 같다. 추가적으로 귀무가설 검증기법 적용할것)
loss | categorical_crossentropy | sparse_categorical_crossentropy |
accuracy | 0.9225 | 0.9229 |
5. 학습률 - 0.01
- 0.001: 학습률이 낮아서 동일 에포크당 학습이 많이 진행이 안 된 것 같다.
- 0.05: 기존 0.01보다 학습률이 낮아진 것으로 보아 더 큰 값의 학습률을 테스트하는 것은 무의미한 것 같다.
learning rate | 0.01 | 0.001 | 0.05 | 0.1 |
accuracy | 0.9225 | 0.6919 | 0.8391 | 0.7702 |
6. 최적화 함수 - SGD
- 보통 Adam이 Momentun과 AdaGrad를 융합하여 사용하며 성능이 가장 좋을 줄 알았는데 오히려 SGD 보다 못한 결과가 나와서 추가적인 하이퍼파라미터 조정에 의한 실험이 필요해 보인다.
optimizer | SGD | Adam | Nadam | AdaDelta |
accuracy | 0.9225 | 0.8352 | 0.7969 | 0.7638 |
7. 활성함수
히든레이어 - 시그모이드
출력함수 - 소프트맥스
- 히든레이어에서 ReLU를 사용하면 그래디언트배니싱 문제가 해결되어 학습이 더 잘될 줄 알았는데 오히려 성능이 점점 떨어졌다.
activation | 시그모이드 + 소프트맥스 | tanh + 소프트맥스 | ReLU + 소프트맥스 |
accuracy | 0.9225 | 0.8834 | 0.1134 |
8. 차원 변경 - Layers 3개 + 차원 256
- 층을 적절히 설정하지 않으면 오히려 성능이 많이 떨어진다.
- 차원을 많이 늘렸을 시 오히려 성능이 좋게 나왔다. 추가 실험 필요.
hidden layer | Layers 3개 + 차원 128 | Layers 5개 + 차원 128 | Layers 10개 + 차원 128 | Layers 3개 + 차원 10 | Layers 3개 + 차원 256 |
accuracy | 0.9225 | 0.2199 | 0.1133 | 0.6776 | 0.9412 |
성능개선 결과
위 항목에서 가장 잘 나온 결과들을 종합해서 실험을 실시
accuracy: 0.9512
총평
실제 배운 것과 문제 해결은 다르다는 것을 알게 됨.
최적화 문제는 보통 Adam을 쓰는 것이 좋다고 하였으나 문제의 규모에 따라 모두 적용되는 것은 아닐 수 있다.
한번에 학습할 수 있는 양을 제한하기 위한 배치사이즈는 해당 실험은 규모가 작아서 한 에포크에 모든 데이터를 다 학습했지만, 데이터 양이 커지면 메모리의 양을 고려하여 적당한 서에서 학습을 해야 할 것 같다. 그런데 배치사이즈를 크게 하면 한 에포크당 학습하는 양이 커져서 좋을것이라 생각했는데 결과는 예상과 다르게 나왔다. 이건 실험이 잘못되었는지 다시 확인 필요하다.
이 작은 문제에서도 튜닝할 하이퍼 파라미터가 많아 최적화를 자동화 하는 방법을 고민하게 된다.