미세 조정(fine-tuning)
- 사전 학습(pre-training)
- 많은 시간과 자원을 사용하여 방대한 양의 학습 데이터를 이용해서 모델의 파라미터(가중치)를 처음부터 학습시키는 과정
- 전이 학습(transfer learning)
- 사전 학습된 모델을 사용자가 원하는 새로운 과제에 적용하는 과정
- 미세 조정(fine-tuning)
- 사전 학습 모델이 가지고 있는 파라미터(가중치)를 사용자가 해결하고자 하는 과제에 대한 학습 데이터를 이용해서 추가적으로 학습하는 방법
- 사전 학습 모델이 가지고 있는 파라미터(가중치)를 초기값으로 사용해서 추가적인 학습을 통해 사용자가 가지고 있는 학습 데이터에 더 적합한 파라미터(가중치)를 얻는 것
- 추가적인 학습 + 사전 학습된 모델을 사용자의 과제 목적에 맞게 수정해서 학습을 진행하는 방식
사전 학습된 모델 재구성 + 미세 조정(fine-tuning)
- 특성 추출(feature extractor) 부분은 학습을 시키지 않고 사전 학습된 모델(가중치)을 이용하여 입력 이미지로부터 특성만 추출
- 분류(classifier) 부분을 수정하고 집중적으로 학습
- 적은 양의 데이터와 짧은 학습 시간으로 분류 성능 향상
재구성 모델
# 사전 학습된 모델 생성하기
pretrained_model = tf.keras.applications.VGG16(
include_top=False,
weights='imagenet',
input_shape=(224,224,3)
)
# pretrained_model 구조 확인하기
pretrained_model.summary()
# 사전 학습된 모델의 전체 가중치 동결(freezing) --> 가중치 업데이트(X)
for layer in pretrained_model.layers:
layer.trainable=False
# 미세 조정 모델 정의하기
# 출력 units 설정
units=2
# 모델 생성
finetuned_model = tf.keras.Sequential()
finetuned_model.add(pretrained_model)
finetuned_model.add(tf.keras.layers.Flatten())
finetuned_model.add(tf.keras.layers.Dense(units=256, activation='relu'))
finetuned_model.add(tf.keras.layers.Dense(units=units, activation='softmax'))
# 추가 사항
finetuned_model.build(input_shape=(None,224,224,3))
# 모델 구조 확인
finetuned_model.summary()
# 모델 컴파일
# optimizer 재설정
optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001)
# 컴파일
finetuned_model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
# ImageDataGenerator() 함수 --> 데이터 증식 조건 설정
# 학습용 이미지 증식 조건 설정
train_datagen3 = tf.keras.preprocessing.image.ImageDataGenerator(
rescale=1/255,
rotation_range=30,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
vertical_flip=True
)
# 검증용 이미지 생성 조건 --> 증식(X) + scaling(normalization)
val_datagen3 = tf.keras.preprocessing.image.ImageDataGenerator(
rescale=1/255
)
# 평가용 이미지 생성 조건 --> 증식(X) + scaling(normalization)
test_datagen3 = tf.keras.preprocessing.image.ImageDataGenerator(
rescale=1/255
)
# ImageDataGenerator() 함수와 flow_from_directory() 함수를 사용, 데이터 증식시키기
# 이미지 폴더 경로 설정
train_path = '/content/drive/MyDrive/CV/cats_and_dogs/train'
val_path = '/content/drive/MyDrive/CV/cats_and_dogs/val'
test_path = '/content/drive/MyDrive/CV/cats_and_dogs/test'
# 학습용 데이터 생성
train_generator3 = train_datagen3.flow_from_directory(directory=train_path,
batch_size=60,
target_size=(224,224),
class_mode='categorical')
# 검증용 데이터 생성
val_generator3 = val_datagen3.flow_from_directory(directory=val_path,
batch_size=60,
target_size=(224,224),
class_mode='categorical')
# 평가용 데이터 생성
test_generator3 = test_datagen3.flow_from_directory(directory=test_path,
batch_size=10,
target_size=(224,224),
class_mode='categorical')
# 조기 종료 설정
early_stop = tf.keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=3
)
# 학습 진행
finetuned_model.fit(train_generator3,
validation_data=val_generator3,
epochs=100,
callbacks=[early_stop])
# model.evaluate() 함수 사용
score = finetuned_model.evaluate(test_generator3)
# 결과 확인
print(f'평가용 데이터에 대한 손실 : {score[0]}')
print('-'*80)
print(f'평가용 데이터에 대한 정확도 : {score[1]}')
# 사전 학습된 모델 생성하기
pretrained_model2 = tf.keras.applications.VGG16(
include_top=False,
weights='imagenet',
input_shape=(224,224,3)
)
# 사전 학습된 모델의 전체 계층의 인덱스와 이름 확인하기
for idx, layer in enumerate(pretrained_model2.layers):
print(f'layer의 인덱스 : {idx}, layer의 이름 : {layer.name}')
# 사전 학습된 모델의 전체 계층의 가중치 동결(freezing)하기
for layer in pretrained_model2.layers:
layer.trainable=False
# 재구성 모델 정의하기 --> 함수식
# 입력층 생성
input = pretrained_model2.inputs
# 특성 추출의 결과물 생성 --> feature map : (7, 7, 512)
x = pretrained_model2.get_layer(index=18).output
# 출력층 생성
x = tf.keras.layers.GlobalAveragePooling2D()(x)
prediction = tf.keras.layers.Dense(units=2, activation='softmax')(x)
# 모델 재구성
finetuned_model2 = tf.keras.Model(inputs=input, outputs=prediction)
# 모델 구조 확인
finetuned_model2.summary()
# 모델 컴파일
# optimizer 재설정
optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001)
# 컴파일
finetuned_model2.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
# ImageDataGenerator() 함수 --> 데이터 증식 조건 설정
# 학습용 이미지 증식 조건 설정
train_datagen3 = tf.keras.preprocessing.image.ImageDataGenerator(
rescale=1/255,
rotation_range=30,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
vertical_flip=True
)
# 검증용 이미지 생성 조건 --> 증식(X) + scaling(normalization)
val_datagen3 = tf.keras.preprocessing.image.ImageDataGenerator(
rescale=1/255
)
# 평가용 이미지 생성 조건 --> 증식(X) + scaling(normalization)
test_datagen3 = tf.keras.preprocessing.image.ImageDataGenerator(
rescale=1/255
)
# ImageDataGenerator() 함수와 flow_from_directory() 함수를 사용, 데이터 증식시키기
# 이미지 폴더 경로 설정
train_path = '/content/drive/MyDrive/CV/cats_and_dogs/train'
val_path = '/content/drive/MyDrive/CV/cats_and_dogs/val'
test_path = '/content/drive/MyDrive/CV/cats_and_dogs/test'
# 학습용 데이터 생성
train_generator3 = train_datagen3.flow_from_directory(directory=train_path,
batch_size=60,
target_size=(224,224),
class_mode='categorical')
# 검증용 데이터 생성
val_generator3 = val_datagen3.flow_from_directory(directory=val_path,
batch_size=60,
target_size=(224,224),
class_mode='categorical')
# 평가용 데이터 생성
test_generator3 = test_datagen3.flow_from_directory(directory=test_path,
batch_size=10,
target_size=(224,224),
class_mode='categorical')
# 조기 종료 설정
early_stop = tf.keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=3
)
# 최적의 학습 결과를 저장하기 위한 ModelCheckpoint 설정
checkpoint = tf.keras.callbacks.ModelCheckpoint(
filepath='/content/drive/MyDrive/CV/vgg16.keras',
monitor='val_loss',
save_best_only=True
)
# 학습 진행
finetuned_model2.fit(
train_generator3,
validation_data=val_generator3,
epochs=20,
callbacks=[early_stop, checkpoint]
)
# 저장된 모델 불러오기
# 파일 경로 설정
file_path='/content/drive/MyDrive/CV/vgg16.keras'
# 모델 불러오기
loaded_model = tf.keras.models.load_model(file_path)
# 모델 구조 확인하기
loaded_model.summary()
# model.evaluate() 함수 사용
score = loaded_model.evaluate(test_generator3)
# 결과 확인
print(f'평가용 데이터에 대한 손실 : {score[0]}')
print('-'*80)
print(f'평가용 데이터에 대한 정확도 : {score[1]}')
모델 요약 및 비교
- model1
- 학습되지않은 VGG16모델 사용 (weights=None)
- 증식시키지 않은 데이터로 학습
- model2
- 학습되지않은 VGG16모델 사용 (weights=None)
- 증식시킨 데이터로 학습
- finetuned_model
- 사전학습 (weights='imagenet')된 VGG16모델 사용
- 증식시킨 데이터로 학습
- finetuned_model2
- 사전학습 (weights='imagenet')된 VGG16모델 사용
- 모델 layer 재구성
- 증식시킨 데이터로 학습
참고 자료