합성곱 신경망 (Convolutional Neural Network, CNN)은 합성곱 (Convolution)이라는 수학적 결합방식을 적용한 인공신경망을 의미한다. CNN은 손글씨 인식을 이용하여 우편번호를 분류하기 위해 처음 개발된 딥러닝 모형으로서 현재에도 주로 이미리 처리 문제에 많이 활용된다. CNN이 이미지를 인식하는 방법은 입력된 이미지의 픽셀값 하나하나를 처리하는 것이 아니라, 일정한 이미지 영역을 픽셀들간의 유기적인 관계를 통해 한꺼번에 인지하는 인간의 대뇌 시각피질 구조를 모방한 방법을 사용한다.
CNN은 아래 그림과 같이 합성곱층 (Convolutional Layer)과 풀링층 (Pooling Layer)이라 불리는 특수한 층을 교대로 연결한 구조를 가지는데, 각 층별로 저수준 특성을 연결하여 고수준 특성을 만들어낸다. 즉, 저수준의 특성이 앞쪽 층에서 추출되면 이 저수준의 특성들이 서로 연결되어 건물이나 자동차, 강아지와 같은 고수준의 특성을 만들어내게 된다. 이때 특성 인자를 추출하기 위해서 합성곱층과 풀링층을 사용하며, 이 특성 인자들을 전결합층의 입력으로 전달하고, 전결합층에서 출력층으로 전달할 최종값을 출력한다.
[그림 1] 합성곱 신경망의 구조
(1) 합성곱층
합성곱층 (Convolutional Layer)은 입력 데이터의 특성을 추출하는 층으로서 입력 데이터 전체 중 일부분에 가중치 필터를 적용하여 특성맵 (Feature Map)으로 출력하는 기능을 담당한다.
[그림 2] 합성곱층의 처리
큰 이미지와 같이 입력 데이터의 범위가 클 경우 필터는 연속적으로 이동하며 데이터를 받아들이는데, 이때 필터가 이동하는 이동 거리를 스트라이드 (Stride)라고 한다. 한 번의 필터 수용 영역으로 적용하기 어려운 큰 이미지가 입력으로 주어졌을 때, 스트라이드를 조절함으로써 작은 수용 영역의 크기를 갖는 필터로도 큰 이미지를 인식할 수 있는 것이다.
[그림 3] 스트라이드가 1인 필터의 이동 변화
아래 [그림 4]는 합성곱층의 처리 계산 예시를 보여주고 있다. 합성곱층은 입력 데이터 영역의 각 요소값과 필터 영역의 각 요소값의 벡터 곱을 수행하여 백터 곱 행렬 안의 모든 요소값을 합하여 특성맵 요소 중 하나의 값을 산출한다. 합성곱층에서는 보통 여러 개의 필터를 사용하는데, 필터 안의 수치는 일종의 가중치로서 초기에는 임의의 값으로 시작되지만, 학습 과정에서 최적의 값으로 변화한다.
[그림 4] 합성곱층 처리 계산의 예
CNN에서는 특성을 추출하는 과정에서 입력 데이터가 특성맵의 크기로 한정되기 때문에 입력 데이터 중심부의 정보량보다 주변부의 정보량을 적게 전달하는 현상이 발생한다. 가령, 위의 그림에서 필터가 이동하며 데이터를 수집하면 중앙에 있는 4개의 셀 (0, 2, 2, 0)은 반복적으로 입력되는 반면 주변의 데이터는 상대적으로 적은 횟수로 입력된다. CNN은 이러한 문제를 해결하기 위해 입력 데이터 주변부의 행과 열을 추가적으로 0으로 채우는 제로 패딩 (Zero-Padding) 방식을 사용하기도 한다. 아래 [그림 11-6]에서 중앙의 4×4 (굵은 선으로 표시된) 영역이 원래의 입력 데이터 범위일 경우 3X3 크기의 필터가 이동하며 데이터를 수집하면 중앙의 2×2 영역 (0, 2, 2, 0) 부분만 4회 입력되는 반면, 그 주변부는 1~2회만 입력받게 되므로 제로 패딩 방식을 통해 원래 크기의 입력 데이터 주변부의 행과 열을 더 만들어 모두 0으로 채워 넣은 것을 볼 수 있다. 그렇게 되면 6×6 크기를 갖는 가상의 입력 데이터를 바탕으로 3×3 크기의 필터가 이동하며 모든 셀을 동일한 횟수로 입력받을 수 있게 되므로 왜곡 없는 데이터 인식이 가능하게 된다.
[그림 5] 제로 패딩을 이용한 합성곱 처리
(2) 풀링층
풀링층 (Pooling Layer)은 필요에 따라 추가할 수 있는 층으로서 합성곱층에서 얻은 특성맵을 더 작게 축소하여 인자 수를 줄이고 과잉적합 문제를 제어해 모형의 학습 성능을 개선할 수 있는 기능을 제공한다. 풀링층은 일종의 다운 샘플링 (Down Sampling) 역할을 하므로 어느 정도 정보량의 손실이 발생하지만, 대신 입력 데이터의 위치가 약간 달라지는 변화를 수용하는 장점도 있다. 가령, 이미지 인식에서 직선을 인식할 때 직선이 미세하게 흐트러져 있어도 직선이라고 판단할 수 있도록 해주는 역할을 담당한다. 풀링층의 축소 방법에는 각 특징의 최댓값을 사용하는 최대 풀링 (Max Pooling)과 평균값을 이용하는 평균 풀링 (Average Pooling) 방식이 있다.
[그림 6] 풀링의 유형
(3) 전결합층
전결합층 (Fully-Connected Layers)은 합성곱층과 풀링층의 결과인 2차원 특성맵을 1차원 데이터로 변환하여 출력층으로 전달하는 기능을 담당한다.
실습으로는 손글씨 숫자 이미지를 인식하여 해당이미지가 어떤 숫자를 나타내는지 판단하는것을 해보겠다.
마찬가지로 데이터 전처리 과정은 생략하겠다. 원핫인코딩을 진행하면 된다.
모형 학습 및 예측
#1. 모듈 및 함수 불러오기
from keras.layers import Conv2D, MaxPooling2D, Flatten
#2. 시드 값 설정
np.random.seed(0)
tf.random.set_seed(0)
#3. 모형 생성
model = Sequential()
model.add(Conv2D(4, (3, 3), input_shape=(28, 28, 1), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(10, activation='softmax'))
#4. 학습 과정 설정
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
#5. 모형 학습 및 예측
history= model.fit(X_train, Y_train, epochs=10, batch_size=128, verbose=0)
Y_pred = np.round(model.predict(X_test, verbose=0),3)
Y_classes = model.predict_classes(X_test, verbose=0)
print("평가용 데이터 세트에 대한 예측 확률\n", Y_pred[:5])
print(" ")
print("평가용 데이터 세트에 대한 예측 클래스\n",Y_classes[:5])
평가용 데이터 세트에 대해 모형이 예측 분류한 결과가 올바른지 확인하기 위해 실제 이미지를 출력해보겠다.
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
plt.imshow(X_test[0], cmap='Greys')
plt.show()
모형 평가
train_score = model.evaluate(X_train, Y_train, verbose=0)
test_score = model.evaluate(X_test, Y_test, verbose=0)
print("학습용 데이터 세트 오차와 정확도: {:.3f}, {:.3f}".format(train_score[0], train_score[1]))
print("평가용 데이터 세트 오차와 정확도: {:.3f}, {:.3f}".format(test_score[0], test_score[1]))
This post was written based on what I read and studied the book below.
http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9791195511747
댓글