합성곱 신경망의 구성요소와 이미지 분류
합성곱 신경망(Convolutional Neural Network, CNN)은 주로 이미지 인식, 영상 처리, 컴퓨터 비전 분야에서 사용되는 심층 신경망의 한 종류이다. CNN은 이미지로부터 패턴을 인식하고 이해하는 데 특화되어 있으며, 이를 위해 합성곱 계층(convolutional layer)과 풀링 계층(pooling layer)을 포함한 특별한 구조를 가진다.
[출처 : 혼자 공부하는 머신러닝+딥러닝 8장. 이미지를 위한 인공신경망]
CNN의 주요 구성 요소:
- 합성곱 계층(Convolutional Layer): 이 계층은 이미지로부터 특성을 추출하는 데 사용된다. 여러 개의 필터(또는 커널)를 사용하여 이미지를 스캔하고, 이 과정에서 생성된 특성 맵(feature map)을 통해 이미지의 중요한 정보를 추출한다.
- 활성화 함수(Activation Function): 대부분의 CNN에서는 ReLU(Rectified Linear Unit) 함수가 활성화 함수로 사용된다. 이 함수는 비선형 변환을 제공하여 네트워크가 복잡한 패턴을 학습할 수 있게 한다.
- 풀링 계층(Pooling Layer): 특성 맵의 크기를 줄이거나 요약하여 계산량을 감소시키고, 과적합을 방지하는 역할을 한다. 최대 풀링(Max Pooling)과 평균 풀링(Average Pooling)이 일반적으로 사용된다.
- 완전 연결 계층(Fully Connected Layer): CNN의 마지막 부분에 위치하며, 앞서 추출된 특성을 바탕으로 최종적인 분류나 예측을 수행한다.
CNN의 특징 및 장점:
- 공간적 계층 구조: CNN은 이미지의 공간적 계층 구조를 이해할 수 있으며, 이를 통해 이미지의 로컬 패턴(예: 가장자리, 질감 등)부터 복잡한 객체까지 인식할 수 있다.
- 매개변수의 공유: 합성곱 필터는 이미지 전체에 걸쳐 공유되므로, 전통적인 심층 신경망에 비해 훨씬 적은 수의 매개변수를 사용한다.
- 이동 불변성(Translation Invariance): CNN은 이미지 내 객체의 위치가 변해도 동일한 객체를 인식할 수 있다.
활용 분야:
- 이미지 분류: 사진 속 객체를 분류한다(예: 강아지, 고양이 분류).
- 객체 탐지: 이미지 내에서 객체의 위치와 종류를 탐지한다.
- 시맨틱 분할: 이미지를 픽셀 수준에서 분류하여, 각 픽셀이 어떤 객체에 속하는지 결정한다.
- 얼굴 인식, 자율 주행 자동차, 의료 영상 분석 등 다양한 분야에서 광범위하게 활용된다.
이번에는 텐서플로 케라스 API를 이용해 패션 MNIST 데이터를 합성곱 신경망
(Convolutional Neural Network, CNN)으로 분류한다. 모델을 만들며 합성곱, 패딩, 스트라이드, 풀링의 개념도 같이 알아볼 것이다.
1. 데이터 준비
패션 MNIST 데이터를 불러오고 표준화 전처리 후 훈련세트와 검증세트로 나눈다.
이때, 합성곱 신경망은 2차원 이미지를 그대로 사용하기 때문에 일렬로 펼치지 않는다.
흑백 이미지이기 때문에 1차원 채널이 추가되며, 컬러 이미지는 3차원이 추가된다.
1 | from tensorflow import keras |
2. 합성곱 신경망 만들기
2-1. 합성곱 층 추가하기
합성곱 신경망의 구조는 합성곱 층에서 이미지의 특징을 감지한 후 밀집층에서 클래스에 따른 분류 확률을 계산한다.
먼저 Sequential
클래스 객체를 만들고, 첫 번째 합성곱 층인 Conv2D
를 추가한다. Conv2D() 매개변수로 커널의 개수, 커널 사이즈, 활성화 함수, 패딩, 입력 데이터 크기가 필요하다.
1 | # 32개 필터, 커널 크기 3x3, 렐루 함수, 세임패딩 |
커널의 개수를 32개로 지정하고, 커널 사이즈를 3으로 놓으면 (3, 3) 크기가 된다.
렐루 함수를 활성화 함수로 지정하고, 세임패딩 적용, 인풋 데이터 크기를 지정한다.
세임 패딩과 밸리드 패딩
패딩이란 입력 배열 주위를 가상의 원소로 채우는 것을 의미한다. 예로, (4, 4) 크기의 입력에 0을 1개 패딩하면 (6, 6)크기의 입력이 된다.
- 세임 패딩 : 합성곱 층의 출력 크기를 입력과 동일하게 만들기 위해 입력에 패딩을 추가하는 것이다.
- 밸리드 패딩 : 패딩 없이 순수한 입력 배열에서만 합성곱을 하여 특성 맵을 만드는 것, 특성 맵의 크기가 줄어든다.
만약 패딩이 없다면 원소들이 2번 이상 커널과 계산되는 것과 달리, 네 모서리에 있는 4개의 값은 커널에 한번만 계산되게 된다. 만약 이 입력이 이미지라면 모서리에 있는 중요한 정보가 특성 맵에 잘 전달되지 않을 가능성이 높다. 반대로 가운데 있는 정보는 잘 표현된다.
2-2. 풀링 층 추가하기
풀링과 스트라이드
- 풀링 : 합성곱 층에서 만든 특성 맵의 가로세로 크기를 줄이는 역할을 수행한다. 특성 맵의 개수는 줄이지 않는다.
- 최대 풀링 : 커널 영역에서 가장 큰 값을 고른다.
- 평균 풀링 : 커널 영역의 값을 평균화한다.
- 스트라이드 : 합성곱 층에서 필터가 입력 위를 이동하는 크기
예를 들어 (2,2,3) 크기의 특성 맵에 스트라이드가 1인 풀링을 적용하면 (1,1,3) 크기의 특성 맵이 된다.
많은 경우 평균 풀링보다 최대 풀링을 사용하는데, 평균 풀링은 특성 맵의 중요한 정보를 평균화하여 희석시킬 수 있기 때문이다.
케라스는 최대 풀링과 평균 풀링을 MaxPooling2D
, AveragePooling2D
로 제공한다. 그 중에서 최대풀링을 사용하며, 풀링 크기를 (2,2)로 지정한다.
1 | model.add(keras.layers.MaxPooling2D(2)) |
패선 MNIST 이미지가 (28,28) 크기에 세임 패딩을 적용하여 합성곱 층에서 출력된 특성 맵의 가로세로 크기는 입력과 동일하다. 이후 (2,2) 풀링을 적용하여 특성 맵의 크기는 절반으로 줄어들고, 합성곱 층에서 32개의 필터를 사용하여 최대 풀링을 통과한 특성 맵의 크기는 (14,14,32)
이다.
이제 두 번째 합성곱-풀링 층을 추가한다. 첫번째와 동일하지만, 필터 개수를 64개로 늘렸다.
1 | model.add(keras.layers.Conv2D(64, kernel_size=3, activation='relu', padding='same')) |
이 층을 통과하면 특성 맵의 크기는 (7,7,64)
가 된다.
2-3. Flatten, 은닉층, Drop, 출력층 구성하기
이제, 마지막에 10개의 뉴런을 가진 출력층에서 확률을 계산하기 위해 3차원 특성 맵을 펼쳐야 한다. Flatten
층을 만들고, Dense은닉층
, Dropout
, Dense출력층
순서대로 층을 구성한다.
1 | model.add(keras.layers.Flatten()) |
은닉층과 출력층 사이에 드롭아웃을 넣어 은닉층의 과대적합을 막아 성능을 개선할 수 있다.
은닉층에 100개의 뉴런을 사용하고 렐루
활성화 함수를 사용한다.
클래스 10개를 분류할 다중 분류 문제이기 때문에 출력층의 활성화 함수는 소프트맥스
함수를 사용한다.
3. 모델 구조 확인하기
summary()
메서드로 모델 구조를 확인할 수 있다.
1 | model.summary() |
1 | Model: "sequential" |
각 층의 파라미터의 개수를 계산할 수 있다.
첫 번째 합성곱 층은 32개의 필터를 가지고 있고 크기가 (3,3), 깊이가 1이다. 또 필터마다 하나의 절편이 있다. 3x3x1x32+32 = 320개의 파라미터가 있다.
두 번째 합성곱 층은 64개의 필터, 크기 (3,3), 깊이 32이다. 필터마다 하나의 절편이 존지하므로 3x3x32x64+64 = 18496개의 파라미터가 있다.
Flatten 층에서 (7,7,64) 크기의 특성 맵을 1차원으로 펼치면 (3136,)이며, 은닉층에서는 3136개가 100개의 뉴런과 연결되어야 하고, 100개의 절편이 있으므로 3136x100+100 = 313700개의 파라미터가 있다.
마지막 출력층은 100개의 특성이 10개의 뉴런과 연결되고, 10개의 절편이 있으므로 100x10+10 = 1010개의 파라미터가 있다.
keras.utils
패키지의 plot_model()
으로 층의 구성을 그림으로 볼 수 있다.
1 | keras.utils.plot_model(model, show_shapes=True, to_file='cnn-architecture.png', dpi=300) |
show_shapes=True
로, 입력과 출력의 크기가 표시되며, to_file
매개변수는 출력한 이미지를 파일로 저장한다. dpi
매개변수는 해상도를 지정한다.
4. 모델 컴파일과 훈련
Adam
옵티마이저를 사용하고, ModelCheckpoint
, EarlyStopping
콜백을 사용하여 조기 종료
법을 구현한다.
1 | model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy') |
1 | Epoch 1/20 |
이전보다 정확도가 훨씬 좋아진 것을 확인할 수 있다.
손실 그래프를 그려, 조기 종료가 잘 이루어졌는지 확인한다.
1 | import matplotlib.pyplot as plt |
일곱 번째 에포크가 최적임을 알 수 있다.
predict() 메서드를 사용하여 데이터에 대한 예측을 만들어 본다.
1 | import numpy as np |
1 | 가방 |
테스트 세트로 합성곱 신경망의 일반화 성능을 가늠해본다.
1 | test_scaled = test_input.reshape(-1, 28, 28, 1) / 255.0 |
1 | 313/313 [==============================] - 2s 7ms/step - loss: 0.2460 - accuracy: 0.9108 |
약 91% 정도의 성능을 기대할 수 있다.
합성곱 신경망의 구성요소와 이미지 분류
https://hamin7.github.io/2024/04/03/Convolutional-Neural-Network/
install_url
to use ShareThis. Please set it in _config.yml
.