CNN(Convolutional Neural Network)

2024. 7. 5. 09:10Deep Learning

 

✅ CNN(Convolutional Neural Network)

 

https://setosa.io/ev/image-kernels/

 

Image Kernels explained visually

An image kernel is a small matrix used to apply effects like the ones you might find in Photoshop or Gimp, such as blurring, sharpening, outlining or embossing. They're also used in machine learning for 'feature extraction', a technique for determining the

setosa.io

 

CNN의 오차 역전파 (Error Backpropagation)

 

 

✅ 학습 목표

  • CNN으로 특성을 추출해서 손 글씨 숫자 데이터 분류
  • 📌 CNN 층
    • Cond2D() : 특성 추출기
    • MaxPooling2D() : 크기 축소
    • Flatten() : 특성 이미지를 1차원으로 변환
  • 📌 손글씨 숫자 가져오기
from tensorflow.keras.datasets import mnist

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

X_train.shape, X_test.shape

import numpy as np
import tensorflow as tf

seed = 0

np.random.seed(seed)
tf.random.set_seed(seed)
  • 📌 데이터 전처리
# 스케일링

X_train = X_train / 255.0
X_test = X_test / 255.0
X_train.shape, X_test.shape

# CNN에 입력으로 할려면 색상 차원이 필요 (흑백 1, 칼라 3)

X_train = X_train.reshape(-1, 28, 28, 1)
X_test = X_test.reshape(-1, 28, 28, 1)

X_train.shape, X_test.shape

  • 📌 샘플링 : 일부 데이터만 이용해서 학습
    • 중요 특성만 뽑기 때문에 데이터도 수가 적어서 잘 분류하는지 확인
X_train = X_train[:1000]
y_train = y_train[:1000]

X_test = X_test[:300]
y_test = y_test[:300]

X_train.shape, X_test.shape

  • 📌 라벨 원핫 인코딩
from tensorflow.keras.utils import to_categorical

y_train_en = to_categorical(y_train)
y_test_en = to_categorical(y_test)

y_train_en.shape, y_test_en.shape

  • 📌 특성 추출기 (CNN) + 분류기 (Dense) 신경망 설계
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense

model1 = Sequential()

# 특성 추출기

model1.add(Conv2D(filters = 32, kernel_size = (3, 3), activation='relu', input_shape=(28, 28, 1)))

# 특성 이미지 축소

model1.add(MaxPooling2D(pool_size=(2, 2)))

# 특성 이미지를 1차원으로 변환 

model1.add(Flatten())

# 분류기

model1.add(Dense(units = 64, activation='relu'))
model1.add(Dense(units = 10, activation='softmax'))

model1.summary()

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense

model1 = Sequential()

# 특성 추출기
model1.add(Conv2D(filters = 32, kernel_size = (3, 3), activation='relu', input_shape=(28, 28, 1)))
model1.add(Conv2D(filters = 64, kernel_size = (3, 3), activation='relu'))

# 특성 이미지 축소
model1.add(MaxPooling2D(pool_size=(2, 2)))

# 특성 이미지를 1차원으로 변환
model1.add(Flatten())

# 분류기
model1.add(Dense(units = 512, activation='relu'))
model1.add(Dense(units = 10, activation = 'softmax'))

model1.summary()

model1.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
  • 📌 베스트 모델 저장, 학습 중단 기능 추가
from google.colab import drive

drive.mount('/content/drive')

%cd /content/drive/MyDrive/Colab Notebooks/Deep Learning

from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping

file_name = "./model/model_cnn_{epoch:02d}_{loss:.3f}_{val_loss:.3f}.hdf5"

mc = ModelCheckpoint(file_name, monitor='val_loss', verbose=1, save_best_only=True)

es = EarlyStopping(monitor='val_loss', patience=5)

h1 = model1.fit(X_train, y_train_en, epochs=30, batch_size = 32, validation_data=(X_test, y_test_en), callbacks=[mc, es])

import matplotlib.pyplot as plt

plt.plot(h1.history['accuracy'], label="train")
plt.plot(h1.history['val_accuracy'], label="test")

plt.legend()
plt.show()

plt.plot(h1.history['loss'], label="train")
plt.plot(h1.history['val_loss'], label="test")

plt.legend()
plt.show()

X_train = X_train[:3000]
y_train = y_train[:3000]

X_test = X_test[:300]
y_test = y_test[:300]

X_train.shape, X_test.shape

from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping

file_name = "./model/model_cnn_{epoch:02d}_{loss:.3f}_{val_loss:.3f}.hdf5"

mc = ModelCheckpoint(file_name, monitor='val_loss', verbose=1, save_best_only=True)

es = EarlyStopping(monitor='val_loss', patience=5)

h1 = model1.fit(X_train, y_train_en, epochs=30, batch_size = 32, validation_data=(X_test, y_test_en), callbacks=[mc, es])

import matplotlib.pyplot as plt

plt.plot(h1.history['accuracy'], label="train")
plt.plot(h1.history['val_accuracy'], label="test")

plt.legend()
plt.show()

plt.plot(h1.history['loss'], label="train")
plt.plot(h1.history['val_loss'], label="test")

plt.legend()
plt.show()

# 이미지 불러오기

import PIL.Image as pimg
import numpy as np
import matplotlib.pyplot as plt

img = pimg.open('./data/2.png').convert('L')
# convert('L') : 컬러 -> 흑백 이미지로 변환

plt.imshow(img, cmap = "gray")
plt.show()

img = np.array(img)

img.shape

# testimg = img.reshape(-1, 28*28)

testimg = img.reshape(-1, 28, 28, 1)

testimg.shape

testimg = testimg / 255.0
testimg

pred = model1.predict(testimg)

print(pred)
print(pred.argmax())

 

신경망 성능 개선

✅ CNN : 합성곱 신경망

  • 📌 MLP가 이미지 데이터를 학습 시킬 때 픽셀의 위치 정보도 포함
    • 위치 정보가 조금만 틀어져도 신경망의 성능은 저하
    • 픽셀의 위치 정보 영향은 줄이고, 이미지가 가지고 있는 특성을 이용해보자
    • CNN 등장!

✅ Sampling : 일부 데이터만 이용해서 학습

✅ 학성곱 신경망의 구조

  • 📌 Conv2D - 컨볼루션 층
    • 우리가 이미지 분석을 진행할 때 -> 이미지의 특성(데이터가 가지고 있는 특징점)
    • 특성을 도드라지게 만들어 준다! -> 합성곱 연산을 통해서 중요한 특성을 강조 
    • 규남쌤의 그림에는 돋보기가 붙음! 왜? 돋보기를 붙여뒀을까?
      • 돋보기는 물체를 확대 시켜 볼 때 사용
      • 이 개념을 CNN으로 가져온다면?
        • 중요한 특성은 돋보기를 가져다 대서 크게 보이도록 만들어보자 라고 정할 수 있음

✅ pooling : 중요한 특성을 뽑아 오자(중요하지 않은 특성은 걸러 내자.)

  • 📌 MaxPolling : 풀링 영역 내에 최대값을 뽑아오는 방법
  • 📌 AveragePooling : 풀링 영역 내에 평균값을 뽑아오는 방법

✅ Kernel : filter

✅ model checkpoint

✅ EarlyStopping

✅ Dropout