CNN 모델 구현 및 성능 향상 기본 기법 적용하기
210727
CIFAR10 데이터세트를 이용하여 CNN 모델 구현 실습 - 01
이미지넷보다 크기가 작아서 학습하는데 오래걸림. 이미지넷은 백만개 정도의 이미지. 그래서 좀 더 크기가 작은 CIFAR 사용. 6만개의 데이터가 있음.
이 중 훈련 데이터는 5만개, 테스트 데이터는 1만개
데이터를 이미지로 보여주는 함수.
figure는 전체 액자를 의미하며 axs는 개별 이미지(축)를 의미한다.
figsize는 액자의 크기.
nrows는 가로줄 개수
ncols는 세로줄 개수
라벨 같은 경우는 초기에 (50000, 1)과 (10000, 1)의 2차원 형태로 존재하므로 1차원으로 스퀴즈 해주는 모습
이미지 전처리
이미지의 각 픽셀값을 255.0 으로 나누어서 0~1사이의 값으로 존재하게 함.
추후에, sparse categorical crossentropy
를 알아보기 위해 원-핫 인코딩을 적용하지 않았음
CNN 2D
Convolution과 ReLU를 2번 하기 때문에 2D이다. 3번 하면 3D. 이 때 입력 채널은 항상 4차원이어야 한다. (이미지 개수, 세로, 가로, 채널)
3차원이어도 작동은 하지만, 꼭 4차원으로 입력할 것을 기억하자
추후에 predict를 할 때도 4차원으로 입력되어야 한다! 훈련과 테스트의 크기가 동일해야 한다
만약에 1개의 이미지만 predict 할 거라면 1개의 이미지(3차원)를 4차원으로 차원 변환 해줘야 함
CIFAR10 데이터세트를 이용하여 CNN 모델 구현 실습 - 02
Conv2D에서 활성화를 함께 할 수도 있고 3-4번 라인처럼 따로할 수도 있다.
각각의 한줄의 코드는 모두 같은 의미이다.
결과는 무조건 2차원 형태의 softmax 결과값이다
따라서 예측 클래스는 무조건
np.argmax
로 해줘야 한다.
CIFAR10 데이터세트를 이용하여 CNN 모델 구현 실습 - 03
필터 사이즈를 3 by 3 으로 할지, 5 by 5 로 할지는 실험적으로 해서 성능을 비교해야 한다. 정해진 골든룰 같은 것은 없다.
가중치 초기화(Weight Initialization)의 이해와 적용 - 01
좋은 가중치 초기화 조건
값이 동일 해서는 안됨
충분히 작아야 함
충분히란 얼마만큼?
적당한 분산(또는 표준편차)을 가져야 함
적당한 양은 어느정도?
표준 정규 분포의 난수를 출력하는 함수이다.
loc : location, 평균
scale : 표준 편차
가중치 초기화(Weight Initialization)의 이해와 적용 - 02
Xavier Glorot Initialization
He Initialization
Xavier는 Sigmoid에 최적화된 방법이라면 He는 ReLU에 최적화된 방법이다
그렇지만, 성능은 데이터 바이 데이터. 좋아질 수도 있고 나빠질 수도 있다. 무조건적으로 좋은 것은 아님.
또한, 이후에 배치 정규화를 거치면 따로 가중치 초기화 과정을 거치지 않아도 된다.
배치 정규화(Batch Normalization) 이해와 적용 - 01
Feature Scaling
서로 다른 Feature 값들을 동일한 척도로 변환
Min-Max Scaling
0에서 1 사이 값으로 변환 : (X - 최솟값) / (최댓값 - 최솟값)
[20, 30, 40] => [0, 0.5, 1]
Z Score 정규화
평균이 0이고 표준 편차가 1인 데이터 세트로 변환 : (X - 평균) / 표준편차
[20, 30, 40] => [-1.22, 0, 1.22]
평균 : 30, 표준편차 : 8.16
스케일링을 하지 않으면, GD 변화가 타원형으로 이동하게 된다.
Batch Normalization의 필요성
Internal Covariate Shift
신경망 내부의 각 층을 통과할 때마다 입력 데이터의 분포가 조금씩 변경되는 현상
많은 뉴런 중 하나가 매우 크거나 작은 값을 가지게 되면 Loss함수가 최적화되기에 어려워진다. 따라서 각 뉴런에서 나오는 값을 스케일링 해줄 필요가 있음.
분포가 바뀌면 학습하기가 어려워진다
레이어를 거치면서 초기의 데이터 분포가 유지될 필요성을 느낌
배치 정규화(Batch Normalization) 이해와 적용 - 02
Batch Normalization 개요
미니 배치의 평균과 분산을 구함
각 데이터마다 Z-Score 변환
이 후, 스케일링 파라미터를 곱하고 쉬프트 파라미터를 더한다
BN의 스케일링과 Shift 파라미터
정규화 제약이 너무 제약적이어서 고정적인 값들이 많이 나오게 됨
이를 해결하기 위해 적용
일반적으로 BN은 Conv 적용 후, Activation 전에 적용한다
따라서 Conv2D에 Activation 빼기.
효과
뛰어난 성능 향상 효과
Regularization 효과
일종의 Dropout 효과이다.
너무 Loss 함수에 휘둘리지 않도록 어느정도의 노이즈 추가 효과를 제공한다
가중치 초기화 설정을 크게 신경 쓸 필요가 없어진다.
테스트 데이터 적용시 BN
보통은 데이터가 적으므로 정규화 할 데이터가 많지 않음 또는 못함
지수 가중 이동 평균을 적용하여 평균과 표준 편차를 구해서 할 수 있다고 함
학습 데이터 Shuffle 적용 유무에 따른 모델 성능 비교
기본적으로 셔플을 하면 데이터 간의 연관성을 잊기 때문에 좋다. 예를 들어서, 문제집을 푼다고 할 때 1번 문제와 2번 문제가 서로 비슷한 문제라면 나중에 다시 볼 때 1번을 풀면서 뒤에 2번 문제가 어떤 문제인지 예상할 수 있는 것과 비슷한 것.
1 : 모델에서 자체적으로 셔플을 할 수 있다. 기본값은 True 다. 이 때 description을 참고하면 x가 image generator 일 때는 셔플이 True 더라도 무시될 수 있다고 한다.
4 : model이 반복적으로 메모리를 차지하는 것을 막기 위해서 수행한다.
셔플을 하는 것이 안하는 것보다 성능이 절대적으로 좋은 것은 아니지만, 대체로 비교적 좋은 성능을 보인다. 이 때, 주목할 점은 셔플을 하지 않으면 성능의 안정성이 떨어진다는 것입니다. 각 이터레이션 간의 편차가 심한 모습.
배치크기 변경에 따른 모델 성능 비교
큰 크기의 배치를 적용하면 더 많은 데이터를 SGD 하게 되고 이 때 안정성이 증가해서 더 나은 가중치가 Update 될 것 같지만 실제로는 그렇지 않다.
물론, 크기가 너무 크면 하드웨어적으로 부담될 수 있다
큰 배치 사이즈보다 작은 배치 사이즈를 적용하는 것이 성능이 더 좋다. 작은 배치사지으가 상대적으로 더 자주 SGD를 계산하고 Update 하기 때문이다.
논문에서는 8보다 크고, 32보다는 작을 것을 권고
BN이 적용되었을 경우는 적용하지 않았을 경우보다 더 작게 하면 좋다고 한다
학습율(Learning Rate) 동적 변경에 따른 모델 성능 비교
8 : validation loss가 향상될 때 저장되도록 한다. (이전에 나왔던 내용)
save_best_only
: validation loss가 가장 최고일 때만 저장하고 나머지는 다시 삭제save_weights_only
: 모델을 저장하는 것이 아니라 인자만 저장하도록 함
콜백을 가지고 성능 향상에 크게 기여할 수 있다.
필터수와 층(Layer) 깊이 변경에 따른 모델 성능 비교
Max Pooling의 효과를 Stride 2 로도 낼 수 있다. 성능적으로 큰 차이는 없었지만 Stride가 시간적으로 연산을 줄여준다.
Global Average Pooling의 이해와 적용
Flatten 대신 Global AveragePooling 을 적용하면 파라미터의 수를 크게 줄일 수 있다.
Global Average Pooling
피처맵의 가로 by 세로의 특정 영역을 Sub sampling 하지 않고, 채널별로 평균값을 추출한다.
채널이 100개면 GAP를 거치면 추출되는 값도 100개
충분히 채널수가 많을 경우만 적용해야 한다. 적을 때는 성능이 나쁘게 나와서 Flatten이 유리하다.
보통 512개 이상일 때 많다고 한다
성능이 전반적으로 좋아지지만 절대적이지는 않다
Flatten에서 발생하는 오버피팅을 줄여주는 효과라고 볼 수 있다.
가중치 규제(Weight Regularization)의 이해와 적용
모델이 Loss를 최적화(줄이는 것)에 지나치게 집중하면 정교화 되는 현상이 발생하기 쉽다. 원래 Loss에 전체 가중치 행렬값의 제곱값을 일정 계수만큼 곱한 값을 더해주면 어느 정도 Loss를 무뎌지게 할 수 있다.
l1, l2 그리고 l1_l2 를 적용할 수 있다.
규제 값을 너무 크게 하면 성능이 떨어진다.
일반적으로 Conv보다는 Dense에서 많이 적용한다.
l1 l2 l1_l2 중에 실험적으로 찾기
Last updated
Was this helpful?