합성곱 딥러닝 아키텍처
합성곱(Convolution) 이란?
합성곱(Convolution)은 행렬의 합, 곱 연산을 하는데 사용되며, 다시말해 선형 함수(Linear Function)이다. (머신 러닝에 필요한 선형대수 기초 지식)
합성곱은 딥러닝에서 주로 픽셀 이미지(행렬)의 특징 맵(feature map)을 만드는데 사용된다.
합성곱 예시
각종 이미지 프로그램들의 필터링 기능들
경계 검출 필터 (미분 원리)
패딩(Padding)
패딩 사이즈가 1인 경우 콘볼루션 연산을 하더라도 원본 행렬의 크기를 유지한다.
합성곱을 딥러닝에 왜 사용하는가?
합성곱은 선형 함수이기 때문에 이미지 본래의 성질을 유지한 채 중요한 부분(특징)만 찾아낼 수 있어 학습의 정확도를 높일 수 있다.
합성곱 신경망에 활성화 함수(activation function)를 왜 사용하는가?
선형 함수나 아핀 함수는 활성화 함수를 사용하지 않으면 다층 신경망을 구성하는 의미가 없다.
선형 레이어는 아무리 중첩해도 선형 레이어가 되기 때문이다.
풀링 (pooling)
풀링은 입력 데이터를 압축하여 연산량을 줄이는 작업이다.
최대 풀링(max pooling)은 가장 큰 값을 선택하는 것이다.
콘볼루션 연산 출력 데이터 크기
피처 맵 높이 H: 입력 높이, W: 입력 폭, P: 패딩 폭, 스트라이드: S
$$ OH = \frac{H+2P-FH}{S} + 1 $$
피처 맵 폭 $$ OW = \frac{W+2P-FW}{S} + 1 $$
풀링(Pooling)을 이용한 서브 샘플링
풀링은 샘플의 크기를 줄이기 위하여 사용하는 방식이다.
드롭아웃(dropout)으로 신경망 규제
크기가 큰 네트워크에서 ‘과대적합’을 피하기 위해 일부 데이터 셋을 일부러 버리는 것이다.
과대적합(overfitting)이란 모델을 학습할 때 학습 데이터셋에 지나치게 최적화하여 발생하는 문제이다.
CNN을 이용한 MNIST 손글씨 검증
텐서 차원
입력: [batchsize x 28 x 28 x 1]
합성곱 1: [batchsize x 28 x 28 x 32]
풀링 1: [batchsize x 14 x 14 x 32]
합성곱 2: [batchsize x 14 x 14 x 64]
풀링 2: [batchsize x 7 x 7 x 46]
완전 연결 1: [batchsize x 1024]
완전 연결과 소프트맥스 층: [batchsize x 10]
합성곱 포맷
batch N, channels C, depth D, height H, width W
NHWC Format (batch, height, width, channels)
NCHW Format (batch, channels, height, width)
이번 네트워크에서는 NHWC
포맷을 사용할 것이다. (data_format=’channel_last’)
학습 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 import tensorflow as tfimport numpy as npfrom tensorflow.keras.datasets import mnistfrom tensorflow.keras import Sequentialfrom tensorflow.keras.layers import Flatten, Dense, Conv2D, MaxPool2D, Dropout(x_train_orig, y_train_orig), (x_test, y_test) = mnist.load_data() x_train_orig = x_train_orig / 255. x_test = x_test / 255. x_train = x_train_orig[:30000 ] y_train = y_train_orig[:30000 ] x_valid = x_train_orig[30000 :] y_valid = y_train_orig[30000 :] tf.random.set_seed(1 ) model = Sequential() model.add(Conv2D( input_shape=(28 , 28 , 1 ), filters=32 , kernel_size=(5 ,5 ), strides=(1 ,1 ), padding='same' , data_format='channels_last' , activation='relu' , name='conv_1' )) model.add(MaxPool2D( pool_size=(2 ,2 ), name='pool_1' )) model.add(Conv2D( filters=64 , kernel_size=(5 ,5 ), strides=(1 ,1 ), padding='same' , activation='relu' , name='conv_2' )) model.add(MaxPool2D( pool_size=(2 ,2 ), name='pool_2' )) model.add(Flatten()) model.add(Dense( units=1024 , activation='relu' , name='fc_1' )) model.add(Dropout( rate=0.5 )) model.add(Dense( units=10 , activation='softmax' , name='fc_2' )) model.compile ( optimizer='adam' , loss='SparseCategoricalCrossentropy' , metrics=['accuracy' ] ) history = model.fit(x_train, y_train, epochs=10 , batch_size=64 , validation_data=(x_valid, y_valid))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Epoch 1/10 469/469 [==============================] - 106s 224ms/step - loss: 0.1883 - accuracy: 0.9422 - val_loss: 0.0629 - val_accuracy: 0.9809 Epoch 2/10 469/469 [==============================] - 105s 224ms/step - loss: 0.0571 - accuracy: 0.9820 - val_loss: 0.0518 - val_accuracy: 0.9842 Epoch 3/10 469/469 [==============================] - 105s 224ms/step - loss: 0.0384 - accuracy: 0.9871 - val_loss: 0.0410 - val_accuracy: 0.9874 Epoch 4/10 469/469 [==============================] - 105s 224ms/step - loss: 0.0249 - accuracy: 0.9923 - val_loss: 0.0419 - val_accuracy: 0.9887 Epoch 5/10 469/469 [==============================] - 105s 224ms/step - loss: 0.0200 - accuracy: 0.9933 - val_loss: 0.0469 - val_accuracy: 0.9876 Epoch 6/10 469/469 [==============================] - 105s 224ms/step - loss: 0.0192 - accuracy: 0.9935 - val_loss: 0.0438 - val_accuracy: 0.9880 Epoch 7/10 469/469 [==============================] - 105s 223ms/step - loss: 0.0173 - accuracy: 0.9943 - val_loss: 0.0395 - val_accuracy: 0.9893 Epoch 8/10 469/469 [==============================] - 105s 224ms/step - loss: 0.0106 - accuracy: 0.9964 - val_loss: 0.0539 - val_accuracy: 0.9865 Epoch 9/10 469/469 [==============================] - 105s 223ms/step - loss: 0.0114 - accuracy: 0.9965 - val_loss: 0.0442 - val_accuracy: 0.9894 Epoch 10/10 469/469 [==============================] - 104s 222ms/step - loss: 0.0099 - accuracy: 0.9966 - val_loss: 0.0475 - val_accuracy: 0.9898
히스토리 분석
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import matplotlib.pyplot as pltimport numpy as npdef draw_history (hist, figsize=None ): if figsize: fig = plt.figure(figsize=figsize) else : fig = plt.figure() x_arr = np.arange(len (hist['loss' ])) + 1 loss_ax = fig.add_subplot(1 , 2 , 1 ) acc_ax = fig.add_subplot(1 , 2 , 2 ) loss_ax.plot(x_arr, hist['loss' ], '-o' , label='Train Loss' ) loss_ax.plot(x_arr, hist['val_loss' ], '--<' , label='Validation Loss' ) acc_ax.plot(x_arr, hist['accuracy' ], '-o' , label='Train acc.' ) acc_ax.plot(x_arr, hist['val_accuracy' ], '--<' , label='Validation acc.' ) loss_ax.legend(fontsize=15 ) acc_ax.legend(fontsize=15 ) draw_history(history.history, figsize=(12 , 4 ))
테스트 데이터 예측 결과 시각화
1 2 3 test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2 ) predicted = model.predict(x_test)
1 313/313 - 8s - loss: 0.0318 - accuracy: 0.9903 - 8s/epoch - 24ms/step
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import matplotlib.pyplot as pltimport numpy as npdef show_predicted_with_img (predicted, x_img, y_label, grid, figsize=None ): if figsize: fig = plt.figure(figsize=figsize) else : fig = plt.figure() for i, pred in enumerate (predicted): p_label = np.argmax(pred) if p_label == y_label[i]: color = 'green' else : color = 'red' ax = fig.add_subplot(grid[0 ], grid[1 ], i+1 ) ax.set_xticks([]) ax.set_yticks([]) ax.text(0.85 , 0.1 , f'{p_label} ({y_label[i]} )' , size=15 , color=color, horizontalalignment='center' , verticalalignment='center' , transform=ax.transAxes) ax.imshow(x_img[i], cmap='gray_r' ) plt.show() show_predicted_with_img(predicted[:18 ], x_test[:18 ], y_test[:18 ], grid=(3 , 6 ), figsize=(12 , 6 ))
참고 사항
머신 러닝을 위한 파이썬 한조각
머신 러닝 교과서 with 파이썬, 사이킷런, 텐서플로
바이오메디컬비전 및 응용 (숭실대학교)
Author:
JeHwanYoo
License:
Copyright (c) 2022 CC-BY-NC-4.0 LICENSE