핵심 키워드
- #Conv2D #MaxPooling2D #plot_model
- 케라스 API를 사용해 합성곱 신경망 모델을 만들어 패션 MNIST 이미지를 분류하는 방법을 배우자
패션 MNIST 데이터 불러오기
- 패션 MNIST 데이터
케라스 API를 사용해 패션 MNIST 데이터를 불러오고
데이터 스케일을 0 ~ 255 사이에서 0 ~ 1 사이로 전처리한 후 훈련 세트와 검증 세트로 나눔
입력 이미지를 밀집층에 연결하기 위해 일렬로 펼쳐야했던 완전 연결 신경망과 달리,
합성곱 신경망은 2차원 이미지를 그대로 사용하기 때문에 일렬로 펼치지 않으며
입력 이미지는 항상 깊이(채널) 차원이 있어야 하므로 흑백 이미지에 채널 차원을 reshape() 메소드를 사용해 추가
합성곱 신경망 만들기
- 첫 번째 합성곱 층
합성곱 신경망의 구조는 합성곱 층으로 이미지에서 특징을 감지한 후 밀집층으로 클래스에 따른 분류 확률을 계산함
그러므로 케라스의 Sequential 클래스를 사용해 순서대로 구조를 정의하도록 해야 함
먼저 Sequential 클래스의 객체를 만들고, add() 메소드를 사용해 첫 번째 합성곱 층인 Conv2D를 추가
이 합성곱 층은 32개의 필터를 사용하며 커널의 크기는 (3, 3)이고 렐루 활성화 함수와 세임 패딩을 사용
그리고 신경망 모델의 첫 번째 층에서 입력의 차원을 지정해주어야 하므로 (28, 28, 1)을 input_shape 매개변수에 지정
그다음으로 풀링 층에 전형적인 풀링 크기인 (2, 2) 풀링을 사용해 추가
결과로는
패션 MNIST 이미지가 (28, 28) 크기에 세임 패딩을 적용했기 때문에 합성곱 층에서 출력된 특성 맵의 가로세로는 입력과 동일
그다음 (2, 2) 풀링을 적용햇으므로 특성 맵의 크기는 절반으로 줄어들며 32개의 필터를 사용했으므로 특성 맵의 깊이는 32
따라서 최대 풀링을 통과한 특성 맵의 크기는 (14, 14, 32)
- 두 번째 합성곱 층 + 완전 연결 층
두 번째 합성곱-풀링 층의 경우 위와 거의 동일하나 필터의 개수를 64개로 늘렸음
그러므로 최종적으로 만들어지는 특성 맵의 크기는 (7, 7, 64)
그 다음으로 마지막에 10개의 뉴런을 가진 밀집 출력층에서 확률을 계산하기 위해 3차원 특성 맵을 일렬로 펼쳐야 함
그 후 특성 맵을 일렬로 펼쳐서 바로 출력층에 전달하지 않고 중간에 하나의 밀집 은닉층(Dense)을 하나 더 두도록 함
또한 은닉층과 출력층 사이에 40%의 뉴런을 훈련시에 끄도록 하는 드롭아웃을 넣어
드롭아웃 층이 은닉층의 과대적합을 막아 성능을 조금 더 개선해주도록 함
은닉층은 100개의 뉴런을 사용하고 활성화 함수는 합성곱 층과 마찬가지로 렐루 함수를 사용
패션 MNIST 데이터셋은 클래스 10개를 분류하는 다중 분류 문제이므로 마지막 층의 활성화 함수는 소프트맥스를 사용
- 모델 요약
summary() 메소드로 모델 구조를 출력
summary() 메소드의 출력 결과를 보면 합성곱 층과 풀링 층의 효과가 잘 나타난 것을 볼 수 있음
첫 번째 합성곱 층을 통과하면서 특성 맵의 깊이는 32가 되고 두 번째 합성곱에서 특성 맵의 크기가 64개로 늘어나게 됨
반면 특성 맵의 가로세로 크기는 첫 번째 풀링 층에서 절반으로 줄어들고 두 번째 풀링층에서 다시 절반으로 줄게 되며
따라서 최종 특성 맵의 크기는 (7, 7, 64)
그리고 Flatten 클래스에서 (7, 7, 64) 크기의 특성 맵을 1차원 배열로 펼치면 (3136, ) 크기의 배열이 됨
모델 파라미터의 개수를 계산해보면
첫 번째 합성곱 층은 32개의 필터를 가지고 있고 크기가 (3, 3), 깊이가 1이며 필터마다 하나의 절편을 가지고 있으므로
총 3 x 3 x 1 x 32 + 32 = 320개의 파라미터
두 번째 합성곱 층은 64개의 필터를 사용하고 크기가 (3, 3), 깊이가 32이며 필터마다 하나의 절편을 가지고 있으므로
총 3 x 3 x 32 x 64 + 64 = 18496개의 파라미터
은닉층은 (3136, ) 크기의 배열을 100개의 뉴런과 완전히 연결해야 하므로
총 3136 x 100 + 100 = 313700개의 파라미터
마지막 출력층의 모델 파라미터 개수는 10개의 뉴런과 완전히 연결해야 하므로
총 100 x 10 + 10 = 1010개의 파라미터
- plot_model()
케라스는 층의 구성을 그림으로 표현해주는 plot_model() 함수를 keras.utils 패키지에서 제공
plot_model() 함수의 show_shapes 매개변수를 True로 설정하면 그림에 입력과 출력의 크기를 표시해줌
모델 컴파일과 훈련
- 컴파일과 훈련
Adam 옵티마이저를 사용하고 ModelCheckpoint 콜백과 EarlyStopping 콜백을 함께 사용해 조기 종료 기법을 구현
훈련 세트의 정확도가 이전보다 훨씬 좋아진 것을 알 수 있음
이를 가지고 손실 그래프를 그려서 조기 종료가 잘 이루어졌는지 확인
검증 세트에 대한 손실이 점차 감소하다가 정체되기 시작하고 훈련 세트의 손실은 점점 더 낮아지고 있으므로
열 번째 에포크에서 훈련이 중지되었음을 볼 수 있고, patience를 2로 지정했으므로 아홉 번째 에포크가 최상의 모델
- 평가와 예측
세트에 대한 성능을 평가해보면 fit() 메소드의 출력 중 아홉 번째 에포크의 출력과 동일한 것을 볼 수 있음
이를 통해 EarlyStopping 콜백이 model 객체를 최상의 모델 파라미터로 잘 복원한 것임을 알 수 있음
predict() 메소드를 사용해 훈련된 모델을 사용하여 새로운 데이터에 대해 예측을 만들기 위해
첫 번째 샘플 이미지를 확인하면 핸드백 이미지를 나타내는 것을 알 수 있고
모델은 이 이미지에 대해 predict() 메소드를 통해 10개의 클래스에 대한 예측 확률을 출력하게 됨
출력 결과를 보면 아홉 번째 값이 1이고 다른 값은 거의 0에 가까우므로 아홉 번째 클래스라고 강하게 주장하는 것
아홉 번째 클래스는 가방 (핸드백)
- 테스트 세트 점수
테스트로 합성곱 신경망의 일반화 성능을 가늠하기 위해
훈련 세트와 검증 세트에서 했던 것처럼 픽셀값의 범위를 0 ~ 1 사이로 바꾸고 이미지 크기를 (28, 23, 1)로 바꾼 후
evaluate() 메소드로 테스트 세트에 대한 성능을 측정하면 검증 세트보다 조금 더 작은 것을 확인할 수 있음
'ML > 혼자 공부하는 머신러닝 + 딥러닝' 카테고리의 다른 글
[혼공머신] 09. 텍스트를 위한 인공 신경망 - 순차 데이터와 순환 신경망 (0) | 2022.07.19 |
---|---|
[혼공머신] 08. 이미지를 위한 인공 신경망 - 합성곱 신경망의 시각화 (0) | 2022.07.14 |
[혼공머신] 08. 이미지를 위한 인공 신경망 - 합성공 신경망의 구성 요소 (0) | 2022.07.12 |
[혼공머신] 07. 딥러닝을 시작합니다 - 신경망 모델 훈련 (0) | 2022.07.07 |
[혼공머신] 07. 딥러닝을 시작합니다 - 심층 신경망 (0) | 2022.07.06 |