👩‍💻LEARN : ML&Data/Book Study

[모두의딥러닝] #5-20. 전이학습

쟈니유 2023. 2. 27. 23:02
728x90

이 책도 슬 끝나간다

 

깜박했다. 내가 쉽게 질리는 스타일이라는 것을...

초반에 새로운 지식을 받아들일 땐 즐겁고 재밌는데, 뒤로 갈수록 모델에 대한 설명은 적어지고 반복된 코딩만 하다보니 지루해졌다...

그래서 빨리 모두의 딥러닝을 끝내야한다. 오늘안에 끝낸다앜 

 


#5-20. 전이학습 

 

상당히 신기한 것이, 교육학에서 사용하는 단어들이 딥러닝에서도 종종 나타난다.

전이도... 학습전이라고들 많이 하는데... 신기방기동방신기! 

 

1. 소규모 데이터셋으로 만드는 학습 모델 

  • 데이터 수가 적을 땐, 해당 데이터를 반전시키거나 수평 수직으로 뒤집는 등 이미지 변형을 통해 데이터 학습양을 늘릴 수 있음 
  • 데이터부풀리기 시 이미지의 형태를 생각해서 변형을 취해야 함 
  • 데이터 부풀리기는 학습셋에만 적용해야 함 
ImageDataGenerator()함수를 사용해서 변형해주고  data.flow_from_directory()함수를 사용해서 폴더 내 데이터를 불러옴 
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Dropout, Flatten, Conv2D, MaxPooling2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras import optimizers

import numpy as np
import matplotlib.pyplot as plt

# 깃허브에 준비된 데이터를 가져옵니다.

# 학습셋의 변형을 설정하는 부분입니다.
train_datagen = ImageDataGenerator(rescale=1./255, #원본이미지 픽셀의 RGB값이 0~255이므로, 255로 나눠주면 0~1 사이의 값으로 정규화.
   horizontal_flip=True, # 수평 대칭 이미지를 50% 확률로 만들어 추가합니다.
   width_shift_range=0.1, # 전체 크기의 15% 범위에서 좌우로 이동합니다.
   height_shift_range=0.1 # 마찬가지로 위, 아래로 이동합니다.
#rotation_range=5, # 정해진 각도만큼 회전시킵니다.
#shear_range=0.7, # 좌표 하나를 고정시키고 나머지를 이동시킵니다.
#zoom_range=1.2, # 확대 또는 축소시킵니다.
#vertical_flip=True, # 수직 대칭 이미지를 만듭니다.
#fill_mode='nearest' # 빈 공간을 채우는 방법입니다. nearest 옵션은 가장 비슷한 색으로 채우게 됩니다.
)

train_generator = train_datagen.flow_from_directory(
   './data-ch20/train', # 학습셋이 있는 폴더의 위치입니다.
   target_size=(150, 150),
   batch_size=5,
   class_mode='binary')

# 테스트셋은 이미지 부풀리기 과정을 진행하지 않습니다.
test_datagen = ImageDataGenerator(rescale=1./255)

test_generator = test_datagen.flow_from_directory(
   './data-ch20/test', # 테스트셋이 있는 폴더의 위치입니다.
   target_size=(150, 150),
   batch_size=5,
   class_mode='binary')


# 앞서 배운 CNN 모델을 만들어 적용해 보겠습니다.
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), input_shape=(150,150,3))) #첫인자=커널의 수, input_shape=(행,열,색상)
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.summary()

# 모델 실행의 옵션을 설정합니다.
model.compile(loss='binary_crossentropy', optimizer=optimizers.Adam(learning_rate=0.0002), metrics=['accuracy'])

# 학습의 조기 중단을 설정합니다.
early_stopping_callback = EarlyStopping(monitor='val_loss', patience=5)

# 모델을 실행합니다
history = model.fit(
train_generator,
epochs=100,
validation_data=test_generator,
validation_steps=10,
callbacks=[early_stopping_callback])


사실 뒤에 그래프 그리면서 오차 차이 구분하는 거 있는데 귀찮아서 안함 ㅠ 

2. 전이학습 

전이학습이란 기존의 학습 결과를 가져와서 유사한 프로젝트에 사용하는 방법을 의미함 

좀 더 자세히 보자면 대용량 데이터를 이용해 학습한 가중치 정보를 가져와 내 모델에 적용하는 것을 의미 

 

사전에 학습된 모델 ---[전이 네트워크 / Conv * n] ---> (미세조정) ---> [내 컨볼루션 레이어] -> [분류기] 

 

[전이모델]

전이모델에서 분류기는 제외하고 가져올 것이므로 include_top = False 로 지정한다 

불러온 부분은 새로 학습하는 것이 아니므로 학습되지 않도록 transfer_model.trainable = False 로 지정한다 

transfer_model = VGG16(weights='imagenet', include_top=False, input_shape=(150, 150, 3))
transfer_model.trainable = False

[로컬모델]

처음 레이어에 기존 transfer_model을 불러와주면 끝끝

이 이전/이후엔 동일하게 데이터셋 불러오고 변형한 다음 컴파일 조건 맞춰서 실행해주면 된다. 

finetune_model = models.Sequential()
finetune_model.add(transfer_model)
finetune_model.add(Flatten())
finetune_model.add(Dense(64))
finetune_model.add(Activation('relu'))
finetune_model.add(Dropout(0.5))
finetune_model.add(Dense(1))
finetune_model.add(Activation('sigmoid'))