CNN 이론과 실습
Convolutional Neural Network의 핵심 개념인 Convolution, ReLU, Pooling, Flattening부터 TensorFlow로 직접 구현까지.
#CNN 이론 요약
- Convolution Operation
- ReLU Layer
- Pooling
- Flattening
- Full Connection
- Softmax & Cross-Entropy
CNN의 대가 Yann Lecun 논문 참고.
Feature Detector = Kernel = Filter
결과 메트릭스에 값이 적기 때문에 당연히 어떤 정보는 잃어버리게 된다. 그러나 특징을 감지하는 것이 중요하다. 가장 높은 숫자가 의미하는 것은 특징이 완벽하게 일치할 때 나온다.
특징은 우리가 사물을 보는 방식이자 인식하는 방식이다. 우리가 이미지를 보거나 실생활을 하면서 모든 픽셀을 살펴보는 것이 아니라 특징들을 찾는다.
#ReLU Layer
Rectifier를 사용하는 이유는 비선형을 높이기 위해서이다.
비선형을 높이려는 이유는 이미지 자체는 굉장히 비선형적이기 때문이다.
그러나 Convolution 연산을 하게 되면 선형을 만들 위험이 생긴다. 그래서 선형성을 끊어야 한다.
#Max Pooling
신경망은 공간적 불변성이라는 특성이 있는지 확인해야 한다.
특징이 이미지의 어디에 있는지는 중요하지 않다는 것이다.
특징이 약간 기울어져 있다든지, 질감이 좀 다르다든지 조금 더 가깝거나 서로 더 떨어져 있는지는 상관없다.
특징 자체가 약간 왜곡되었다면 신경망이 그 특징을 찾을 수 있을 정도의 융통성을 가지고 있어야 한다.
이것이 Pooling이다.
2x2 Matrix로 이 안에 있는 최댓값을 저장한다. 최대 숫자가 특징과의 최대 유사성을 의미하기에 여전히 특징을 보존할 수 있다. 게다가 이 특징들을 풀링하면서 특징이 아닌 정보를 75% 제거하게 되었다.
또 다른 풀링의 장점으로는:
- 크기가 줄어든다
- 매개 변수의 수가 줄어들어 과적합을 방지한다.
#Full Connection
Flatten의 과정까지 끝난 값은 이렇게 신경망에 연결된다.
여기서 Hidden Layer는 Fully Connected Layer라고 불린다.
역전파 과정에서 가중치가 조정되는 것뿐만 아니라 Feature Detector도 조정된다. Dog, Cat 뉴런도 학습을 통해 그 전 Layer에서의 뉴런에 가중치를 부여한다.
#Softmax & Cross Entropy
결과를 출력했을 때 두 개의 최종 뉴런이 서로 연결되어 있지 않은데, 어떻게 상대 뉴런의 값을 알고 총합이 1이 되게 했을까?
유일한 방법은 Softmax라는 함수를 제공하는 것이다.
또 소프트맥스 함수는 Cross-entropy 함수와 함께 제공된다.
CNN에서는 손실함수로 MSE보다 소프트맥스 함수를 적용하고 크로스 엔트로피 함수가 더 나은 선택지이다.
- 출력값이 아주 작아서 경사 하강법의 경사도 낮을거라 올바른 방향으로 나아가기 어려울 것이다.
- 반면에 크로스 엔트로피를 사용하면 안에 로그가 있어서 이런 작은 오류도 평가해서 조치할 수 있다.
크로스 엔트로피는 분류할 때만 선호하는 방법이다. 회귀 같은 것은 MSE 평균 제곱 오차가 낫다.
#CNN 실습
0. Importing the libraries
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator1. Data processing
Preprocessing the Training set
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True
)
training_set = train_datagen.flow_from_directory(
'dataset/training_set',
target_size=(64,64),
batch_size=32,
class_mode='binary'
)rescale은 RGB의 값이 0255의 값을 가지므로, 01까지의 값을 갖도록 변환하는 것이다.
shear_range, zoom_range, horizontal_flip은 이미지를 변환하는 것으로, 이미지를 변환하는 과정을 통해 과적합을 피할 수 있다.
CNN은 약한 수준의 위치 불변성만을 자동으로 학습해낼 수 있고, 크고 복잡한 변형에는 불변하지 않는다. 그래서 학습 데이터의 다양화를 위해서 데이터를 변형하고 이것을 데이터 증강이라고 부른다.
| class_mode | 출력층 설정 | 출력 형태 | 손실 함수 |
|---|---|---|---|
| binary | activation=sigmoid | 0~1 사이 실수 | binary_crossentropy |
| categorical | activation=softmax | [1, 0] 또는 [0, 1] | categorical_crossentropy |
categorical은 가능하지만 비효율적이다.
Preprocessing the Test set
test_datagen = ImageDataGenerator(rescale=1./255)
test_set = test_datagen.flow_from_directory(
'dataset/test_set',
target_size=(64,64),
batch_size=32,
class_mode='binary'
)2. Building the CNN
Initialize the CNN
cnn = tf.keras.models.Sequential()Convolution
cnn.add(tf.keras.layers.Conv2D(filters=32, kernel_size=3, activation='relu', input_shape=[64, 64, 3]))CNN 필터는 처음엔 랜덤한 값으로 초기화 된다. 그러나 학습을 반복하면서 유용한 형태로 변형된다.
Pooling
cnn.add(tf.keras.layers.MaxPool2D(pool_size=2, strides=2, padding='valid'))Adding a second convolutional layer
cnn.add(tf.keras.layers.Conv2D(filters=32, kernel_size=3, activation='relu'))
cnn.add(tf.keras.layers.MaxPool2D(pool_size=2, strides=2, padding='valid'))Flattening
cnn.add(tf.keras.layers.Flatten())Full connection
cnn.add(tf.keras.layers.Dense(units=128, activation='relu'))Output Layer
cnn.add(tf.keras.layers.Dense(units=1, activation='sigmoid'))3. Training the CNN
Compiling the CNN
cnn.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])Training the CNN on the Training set and evaluating it on the Test set
cnn.fit(x = training_set, validation_data= test_set, epochs = 25)4. Making a single prediction
import numpy as np
from keras.preprocessing import image
test_image = image.load_img('dataset/single_prediction/cat_or_dog_1.jpg', target_size = (64, 64))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis = 0)
result = cnn.predict(test_image)
training_set.class_indices
if result[0][0] == 1:
prediction = 'dog'
else:
prediction = 'cat'