Create a Network and Transfer Weights
전송된 가중치로 새로운 신경망을 만든다. 이미지넷에 대해 학습된 가중치가 포함된 Xception 신경망에서 가중치를 전송한다. 기존 Xception 신경망에 keras.applications을 로드한다. base_model의 로딩에는 상당히 많은 작업이 진행된다.
기본 Xception 신경망은 299x299의 이미지를 받아들인다. 표준화한 150x150을 사용해야 하지만 그 차이를 극복하는 것이 비교적 쉽다는 것이 밝혀졌다. 컨볼루션 신경망은 스캔할 때 이미지 텐서에서 커널을 이동한다. Keras는 커널이 스캔하는 이미지가 아니라 레이어의 커널 크기에 따라 가중치의 수를 정의한다. 따라서, 이전 입력 레이어를 폐기하고 원하는 이미지 크기에 맞는 입력 레이어를 다시 만들 수 있다. include_top을 false로 지정하고 입력 모양을 지정한다.
학습이 진행될 때 모델이 기존 가중치를 업데이트하지 않도록 기본 모델을 고정한다. 150x150×3 RGB 색상 구성 요소로 구성된 새 입력 레이어를 생성한다. 이 RGB 구성 요소는 0에서 255 사이의 정수이다. 신경망은 부동 소수점 숫자를 0을 중심으로 분포할 때 더 잘 처리한다. 이러한 신경망의 이점을 얻기 위해 각 RGB 구성 요소를 -1에서 1 사이로 정규화한다.
일괄 정규화 레이어는 특별한 고려가 필요하다. 미세 조정을 위해 기본 모델을 고정 해제할 때 이러한 레이어를 추론 (inference) 모드로 유지해야 한다. 이를 위해 여기에서 기본 모델이 추론 모드로 실행되고 있는지 확인다.
base_model = keras.applications.Xception(
weights="imagenet", # Load weights pre-trained on ImageNet.
input_shape=(150, 150, 3),
include_top=False,
) # Do not include the ImageNet classifier at the top.
# Freeze the base_model
base_model.trainable = False
# Create new model on top
inputs = keras.Input(shape=(150, 150, 3))
x = data_augmentation(inputs) # Apply random data augmentation
# Pre-trained Xception weights require that input be scaled
# from (0, 255) to a range of (-1., +1.), the rescaling layer
# outputs: `(inputs * scale) + offset`
scale_layer = keras.layers.Rescaling(scale=1/127.5, offset=-1)
x = scale_layer(x)
# The base model contains batchnorm layers.
# We want to keep them in inference mode
# when we unfreeze the base model for fine-tuning,
# so we make sure that the
# base_model is running in inference mode here.
x = base_model(x, training=False)
x = keras.layers.GlobalAveragePooling2D()(x)
x = keras.layers.Dropout(0.2)(x) # Regularize with dropout
outputs = keras.layers.Dense(1)(x)
model = keras.Model(inputs, outputs)
model.summary()
Model: "model"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_2 (InputLayer) [(None, 150, 150, 3)] 0
sequential_3 (Sequential) (None, 150, 150, 3) 0
rescaling (Rescaling) (None, 150, 150, 3) 0
xception (Functional) (None, 5, 5, 2048) 20861480
global_average_pooling2d ( (None, 2048) 0
GlobalAveragePooling2D)
dropout (Dropout) (None, 2048) 0
dense_4 (Dense) (None, 1) 2049
=================================================================
Total params: 20863529 (79.59 MB)
Trainable params: 2049 (8.00 KB)
Non-trainable params: 20861480 (79.58 MB)
_________________________________________________________________
다음으로 모델을 컴파일하고 맞춘다. 피팅은 Adam 최적화 프로그램을 사용하며, 이진 분류를 수행하기 때문에 이전과 마찬가지로 이진 교차 엔트로피 손실 함수를 사용한다.
model.compile(
optimizer=keras.optimizers.Adam(),
loss=keras.losses.BinaryCrossentropy(from_logits=True),
metrics=[keras.metrics.BinaryAccuracy()],
)
epochs = 20
model.fit(train_ds, epochs=epochs, validation_data=validation_ds)
90% 정도의 정확도는 양호한 수준이지만 더 개선할 수 있다.
Fine-Tune the Model
마지막으로 모델을 미세 조정한다. 먼저 모든 가중치를 훈련 가능으로 설정한 다음 낮은 학습률 (1e-5)로 신경망을 훈련한다. 이 미세 조정을 통해 정확도가 90% 이상 범위로 향상된다. 미세 조정을 통해 신경망의 모든 가중치를 약간 조정하여 개/고양이 데이터에 최적화할 수 있다.
# base_model의 동결을 해제합니다. training=False로 호출했기 때문에 추론 모드로 유지된다.
# 이는 batchnorm 레이어가 배치 통계를 업데이트하지 않음을 의미한다.
# 이로 인해 batchnorm 레이어가 지금까지 수행한 모든 훈련을 무효화하는 것을 방지한다.
base_model.trainable = True
model.summary()
model.compile(
optimizer=keras.optimizers.Adam(1e-5), # 낮은 학습률
loss=keras.losses.BinaryCrossentropy(from_logits=True),
metrics=[keras.metrics.BinaryAccuracy()],
)
epochs = 10
model.fit(train_ds, epochs=epochs, validation_data=validation_ds)
'DNN with Keras > Transfer Learning' 카테고리의 다른 글
조기 중지의 이점 (0) | 2024.02.13 |
---|---|
Transfer Learning for NLP with Keras (0) | 2024.02.13 |
Keras Transfer Learning for Computer Vision (0) | 2024.02.13 |
회귀 네트워크 전송 (0) | 2024.02.13 |
전이 학습 (Transfer Learning) (0) | 2024.02.13 |