코딩 개발일지

머신러닝 기초 - CNN 실습 / 전이학습 실습 본문

AI 본 교육/AI 10주차

머신러닝 기초 - CNN 실습 / 전이학습 실습

호기호 2023. 10. 19. 18:24

CNN 사용할땐 import 해줄게 좀 더 많아진다. Conv2D, MaxPooling2D, Flatten, Dropout 를 추가로 해줬다.

from tensorflow.keras.layers import Input, Dense, Conv2D, MaxPooling2D, Flatten, Dropout

reshape 부분이 CNN을 쓸 때, 약간 달라진다. 기존 것들보다 차원이 높아진다라고 생각하면 된다.

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))
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

아래에서 CNN 네트워크 구성의 예시를 보자. hidden layer가 상당히 많은 것을 볼 수 있다.

filter 갯수가 다른것을 볼 수 있고, pooling 한 후 flatten하는것도 보인다. 그 후 dropout도 하는것을 볼 수 있다.

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

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

hidden = Conv2D(filters=64, kernel_size=3, strides=1, padding='same', activation='relu')(hidden)
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)

hidden = Dense(512, activation='relu')(hidden)

hidden = Dropout(rate=0.3)(hidden)

output = Dense(24, activation='softmax')(hidden)

model = Model(inputs=input, outputs=output)

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

model.summary()

<실행 결과>


전이학습

아래 코드에서는 InceptionV3 를 사용했다. 전이학습을 시킬때는 base_model 을 정의해줘야한다.

from tensorflow.keras.applications.inception_v3 import InceptionV3

input = Input(shape=(224, 224, 3))

base_model = InceptionV3(weights='imagenet', include_top=False, input_tensor=input, pooling='max')

x = base_model.output
x = Dropout(rate=0.25)(x)
x = Dense(256, activation='relu')(x)
output = Dense(131, activation='softmax')(x)

model = Model(inputs=base_model.input, outputs=output)

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

model.summary()

기존의 CNN과 callback만 다르다.

callback의 ModelCheckpoint를 통해 저장(백업)할 수 있다.

from tensorflow.keras.callbacks import ModelCheckpoint

history = model.fit(
    train_gen,
    validation_data=test_gen, # 검증 데이터를 넣어주면 한 epoch이 끝날때마다 자동으로 검증
    epochs=20, # epochs 복수형으로 쓰기!
    callbacks=[
      ModelCheckpoint('model.h5', monitor='val_acc', verbose=1, save_best_only=True)
    ]
)

ImageDataGenerator

training 과정에서 랜덤하게 '회전, 확대, 이동, 뒤집기 등' 의 과정을 해서 training 시키는것을 볼 수 있다.

그 후, test 할때에는 일반화만 시켜서 test를 진행한다.

 

이 과정을 거치면, acc(정확도)가 더 늘어난다. 이미지를 학습시킬 때, 아주 좋은 방법 !!!!!!

실무에서 CNN을 사용할때 많이 쓸 것으로 보인다. 당연하게도 전이학습 시킬때도 쓰면 좋겠쥬?

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

test_datagen = ImageDataGenerator(
  rescale=1./255 # 일반화
)

train_gen = train_datagen.flow_from_directory(
  'fruits-360_dataset/fruits-360/Training',
  target_size=(224, 224), # (height, width)
  batch_size=32,
  seed=2021,
  class_mode='categorical',
  shuffle=True
)

test_gen = test_datagen.flow_from_directory(
  'fruits-360_dataset/fruits-360/Test',
  target_size=(224, 224), # (height, width)
  batch_size=32,
  seed=2021,
  class_mode='categorical',
  shuffle=False
)