AI 웹 개발 과정/실전 머신러닝

08. 4주차 실습 - CNN / 이미지 증강 / 전이학습

만 기 2022. 5. 17. 15:40

 

 

CNN 실습

 

- 패키지
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense, Conv2D, MaxPooling2D, Flatten, Dropout  # Conv2D convolution 연산, MaxPooling2D maxpooling사용, Flatten 2차원->1차원, Dropout
from tensorflow.keras.optimizers import Adam, SGD
from tensorflow.keras.preprocessing.image import ImageDataGenerator   # data agmentation
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import OneHotEncoder

 

- 데이터셋 로드

train_df = pd.read_csv('sign_mnist_train.csv')

train_df.head()

test_df = pd.read_csv('sign_mnist_test.csv')

test_df.head()

 

- 전처리 : 입력과 출력 나누기

train_df = train_df.astype(np.float32)
x_train = train_df.drop(columns=['label'], axis=1).values
x_train = x_train.reshape((-1, 28, 28, 1))    # convolution 연산하려면 2차원으로 할거니까  3차원 데이터로 만든다. 마지막1은 그레이스케일이미지
y_train = train_df[['label']].values

test_df = test_df.astype(np.float32)
x_test = test_df.drop(columns=['label'], axis=1).values
x_test = x_test.reshape((-1, 28, 28, 1))
y_test = test_df[['label']].values

print(x_train.shape, y_train.shape)
print(x_test.shape, y_test.shape)

 

- 데이터 미리보기

index = 1
plt.title(str(y_train[index]))
plt.imshow(x_train[index].reshape((28, 28)), cmap='gray')
plt.show()

 

- One-hot encoding

encoder = OneHotEncoder()
y_train = encoder.fit_transform(y_train).toarray()
y_test = encoder.fit_transform(y_test).toarray()

print(y_train.shape)

 

- 일반화

train_image_datagen = ImageDataGenerator(
  rescale=1./255, # 일반화  # rescale argument : 각 픽셀에 곱해준다.
)

train_datagen = train_image_datagen.flow(   # train data generator, flow method
    x=x_train,
    y=y_train,
    batch_size=256,   # 256개씩 학습
    shuffle=True      # 데이터를 섞는다.
)

test_image_datagen = ImageDataGenerator(
  rescale=1./255
)

test_datagen = test_image_datagen.flow(
    x=x_test,
    y=y_test,
    batch_size=256,
    shuffle=False
)

index = 1

preview_img = train_datagen.__getitem__(0)[0][index]    # __getitem__ static method 모델에 데이터를 피딩
preview_label = train_datagen.__getitem__(0)[1][index]

plt.imshow(preview_img.reshape((28, 28)))
plt.title(str(preview_label))
plt.show()

 

- 네트워크 구성

input = Input(shape=(28, 28, 1))

hidden = Conv2D(filters=32, kernel_size=3, strides=1, padding='same', activation='relu')(input)   # convolution, filter 32개, 크기 3x3, 1칸씩 옮겨가고, padding이 같으면 인풋아웃풋 똑같이, relu 활성화함수사용 
hidden = MaxPooling2D(pool_size=2, strides=2)(hidden)   # 차원 반으로 줄임

hidden = Conv2D(filters=64, kernel_size=3, strides=1, padding='same', activation='relu')(hidden)  # filter 갯수는 튜닝하며 맞춰가야된다.
hidden = MaxPooling2D(pool_size=2, strides=2)(hidden)

hidden = Conv2D(filters=32, kernel_size=3, strides=1, padding='same', activation='relu')(hidden)
hidden = MaxPooling2D(pool_size=2, strides=2)(hidden)

hidden = Flatten()(hidden)    # 1차원으로 펼치지 (Dense연산 하려고)

hidden = Dense(512, activation='relu')(hidden)  # 512개 노드

hidden = Dropout(rate=0.3)(hidden)  # 0.3 = 30%노드를 랜덤으로 탈락시킨다.

output = Dense(24, activation='softmax')(hidden)  # j,z 뺀 알파뱃 24개

model = Model(inputs=input, outputs=output)   # 모델 정의

model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=0.001), metrics=['acc'])

model.summary()

 

- 학습

history = model.fit(
    train_datagen,
    validation_data=test_datagen, # 검증 데이터를 넣어주면 한 epoch이 끝날때마다 자동으로 검증
    epochs=20 # epochs 복수형으로 쓰기!
)

 

- 결과 그래프 출력

fig, axes = plt.subplots(1, 2, figsize=(20, 6))
axes[0].plot(history.history['loss'])
axes[0].plot(history.history['val_loss'])
axes[1].plot(history.history['acc'])
axes[1].plot(history.history['val_acc'])

 

- 이미지 증강 기법 => image augmentation을 쉽게 할 수있다.

train_image_datagen = ImageDataGenerator(
  rescale=1./255, # 일반화
  rotation_range=10,  # 랜덤하게 이미지를 회전 (단위: 도, 0-180)
  zoom_range=0.1, # 랜덤하게 이미지 확대 (%)
  width_shift_range=0.1,  # 랜덤하게 이미지를 수평으로 이동 (%)
  height_shift_range=0.1,  # 랜덤하게 이미지를 수직으로 이동 (%)
)

train_datagen = train_image_datagen.flow(
    x=x_train,
    y=y_train,
    batch_size=256,
    shuffle=True
)

test_image_datagen = ImageDataGenerator(
  rescale=1./255
)

test_datagen = test_image_datagen.flow(
    x=x_test,
    y=y_test,
    batch_size=256,
    shuffle=False
)

index = 1

preview_img = train_datagen.__getitem__(0)[0][index]
preview_label = train_datagen.__getitem__(0)[1][index]

plt.imshow(preview_img.reshape((28, 28)))
plt.title(str(preview_label))
plt.show()