DL - CNN

Jungmin·2023년 1월 30일
1

딥러닝

목록 보기
4/7

⏹ CNN

CNN (Convolutional Neural Networks) : 딥러닝에서 주로 이미지나 영상 데이터를 처리할 때 쓰이며, Convolution이라는 전처리 작업이 들어가는 Neural Network 모델.

이미지, 영상 인식의 혁명같은 CNN

❔ CNN을 사용하는 이유 :

일반 DNN은 기본적으로 1차원 형태의 데이터를 사용한다. 이미지(예를들면 1028x1028같은 2차원 형태의)가 입력값이 되는 경우, 이것을 flatten시켜서 한줄 데이터로 만들어야 하는데, 이 과정에서 이미지의 공간적/지역적 정보가 손실되게 된다. 또 추상화과정 없이 바로 연산과정으로 넘어가 버리기 때문에 학습시간과 능률의 효율성이 떨어진다.

이러한 문제점에서부터 고안한 해결책이 CNN. CNN은 이미지를 날것 그대로 받음으로써 공간적/지역적 정보를 유지한 채 특성(feature)들의 계층을 빌드업한다. CNN의 중요 포인트는 이미지 전체보다는 부분을 보는 것, 그리고 이미지의 한 픽셀과 주변 픽셀들의 연관성을 살리는 것.

미분은 변화율을 측정하기 때문에, 변화되는 부분을 따서 이미지의 경계를 인식.

원래 Convolutional Filter를 통해 필터를 만들고, 이 필터를 사용해서 이미지 변환하는 과정을 거쳤는데, CNN은 딥러닝을 사용해서 필터 특징을 검출하고, 찾은 특징을 가지고 분류를 하는 영역으로 나뉨.

💡 Convolutional Filter 예시

✔ Conv 필터 의미

Convolutional : 특정 패턴이 있는지 박스로 훑으며 마킹
Conv 박스로 밀고나면, 숫자가 출력. 그 숫자를 Activation(주로 ReLU)에 넣어 나온 값을 이미지 지도를 그림.

풀링 레이어

풀링 layer를 지나면 이미지가 줄어든다.
사진을 1cm 거리만 두고 너무 가까이서 확대된 이미지를 보면 인식이 더 어려워 지기 때문에, 멀리에서 보는 것과 비슷.

풀링 필요성의 예

Pooling 종류 중 Maxpooling

💡 stride 옵션은 몇칸 이동하며 훑을 지

conv layer

흰 박스가 pooling layer, 파란 박스가 convolutional layer.

  • conv : 점점 패턴을 쌓아가며 복잡한 패턴을 인식한다.
  • maxpooling : 사이즈를 줄여가며, 추상화 해나간다.

1) 예를 들어 MNIST 데이터 28*28 사이즈 이미지를 다루고 싶다면
2) 첫번째 Convolutional layer는 필터는 5*5로 잡고, activ function은 ReLU, Stride 1 로 해서 한칸씩 밀고나가며 인식하도록 설정. 채널 32개는 사진 크기를 바꾸지 않은 상태로, 32개의 특성을 찾겠다는 것과 비슷. 한 채널안에 필터를 통해 인식된 하나의 특성을 모아 총 32개 특성.
3) pooling layer 만나서 사이즈 줄여준다.
4) 다시 Convolutional layer를 만나 64개 채널로 확장. 그림을 멀리서 크게 보며 특성을 더 찾게 함.
5) 이 과정에서 나온 결과 (7*7) * 64 갯수를 flatten으로 펼침.

input_shape에 (28,28)이나 (28,28,1)이나 같은데 굳이 (28,28,1)로 한 이유는 채널때문.
두번째가 28*28*32로 3차원. 연산 시 여기에 맞춰서 데이터를 설정해줘야 하기 때문에 위와 같이 표기.

💡 padding='same' 옵션

💡 dropout?

융통성 / 과적합 방지 --> 응용력을 주는 것

과적합을 방지하기 위해 학습에 방해를 줘서 일부 노드를 꺼버리는 것.


CNN 실습

import tensorflow as tf

mnist = tf.keras.datasets.mnist

(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train, X_test = X_train / 255, X_test / 255

X_train = X_train.reshape((60000, 28, 28, 1))
X_test = X_test.reshape((10000, 28, 28, 1))
from tensorflow.keras import layers, models

model = models.Sequential([
    layers.Conv2D(32, kernel_size=(5, 5), strides=(1, 1),
                  padding='same', activation='relu', input_shape=(28, 28, 1)),
    layers.MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
    layers.Conv2D(64, (2, 2), activation='relu', padding='same'),
    layers.MaxPooling2D(pool_size=(2, 2)),
    layers.Dropout(0.25), 
    layers.Flatten(),
    layers.Dense(1000, activation='relu'),
    layers.Dense(10, activation='softmax')
])

model.summary()
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 28, 28, 32)        832       
                                                                 
 max_pooling2d (MaxPooling2D  (None, 14, 14, 32)       0         
 )                                                               
                                                                 
 conv2d_1 (Conv2D)           (None, 14, 14, 64)        8256      
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 7, 7, 64)         0         
 2D)                                                             
                                                                 
 dropout (Dropout)           (None, 7, 7, 64)          0         
                                                                 
 flatten (Flatten)           (None, 3136)              0         
                                                                 
 dense (Dense)               (None, 1000)              3137000   
                                                                 
 dense_1 (Dense)             (None, 10)                10010     
                                                                 
=================================================================
Total params: 3,156,098
Trainable params: 3,156,098
Non-trainable params: 0
_________________________________________________________________
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
hist = model.fit(X_train, y_train, epochs=5, verbose=1,
                 validation_data=(X_test, y_test))
Epoch 1/5
1875/1875 [==============================] - 38s 20ms/step - loss: 0.1172 - accuracy: 0.9630 - val_loss: 0.0541 - val_accuracy: 0.9819
Epoch 2/5
1875/1875 [==============================] - 43s 23ms/step - loss: 0.0442 - accuracy: 0.9862 - val_loss: 0.0345 - val_accuracy: 0.9881
Epoch 3/5
1875/1875 [==============================] - 56s 30ms/step - loss: 0.0355 - accuracy: 0.9890 - val_loss: 0.0359 - val_accuracy: 0.9889
Epoch 4/5
1875/1875 [==============================] - 75s 40ms/step - loss: 0.0254 - accuracy: 0.9918 - val_loss: 0.0313 - val_accuracy: 0.9906
Epoch 5/5
1875/1875 [==============================] - 53s 28ms/step - loss: 0.0206 - accuracy: 0.9935 - val_loss: 0.0277 - val_accuracy: 0.9902

🤔모델 결과 확인

import matplotlib.pyplot as plt

plot_target = ['loss', 'val_loss', 'accuracy', 'val_accuracy']

plt.figure(figsize=(12, 8))
for each in plot_target:
    plt.plot(hist.history[each], label= each)
plt.legend()
plt.grid()
plt.show()

score = model.evaluate(X_test, y_test)
print("Test loss : " + str(score[0]))
print("Test accuracy : " + str(score[1]))
313/313 [==============================] - 2s 5ms/step - loss: 0.0277 - accuracy: 0.9902
Test loss : 0.027657995000481606
Test accuracy : 0.9901999831199646
# 틀린 결과 확인 -> 전체 데이터 인덱스 확인
import numpy as np

predicted_result = model.predict(X_test)
predicted_labels = np.argmax(predicted_result, axis=1)
predicted_labels[:10]
array([7, 2, 1, 0, 4, 1, 4, 9, 5, 9], dtype=int64)
wrong_result = []

for n in range(0, len(y_test)):
    if predicted_labels[n] != y_test[n]:
        wrong_result.append(n)

len(wrong_result)
98
#틀린 데이터 중 랜덤 16개 선택
import random

samples = random.choices(population=wrong_result, k=16)
samples[:3]
[1260, 4078, 2939]
# 틀린 데이터 확인
plt.figure(figsize=(14, 12))
for idx, n in enumerate(samples):
    plt.subplot(4, 4, idx+1)
    plt.imshow(X_test[n].reshape(28, 28), cmap='Greys', interpolation='nearest')
    plt.title('Label : '+str(y_test[n]) + " | Predict : " + str(predicted_labels[n]))
    plt.axis('off')
plt.show()

모델 저장

모델은 훈련 중 및 훈련 후에 저장할 수 있다.
모델이 중단된 위치에서 다시 시작하고 긴 훈련 시간을 피할 수 있다.

model.save('./MNIST_CNN_model.h5')
from tensorflow.keras import models

test_model = models.load_model('./MNIST_CNN_model.h5')
profile
데이터분석 스터디노트🧐✍️

0개의 댓글