사전 훈련된 모델(pretrained model): 대규모 이미지 분류 문제를 위해 대량의 데이터셋에서 미리 훈련된 모델
keras에서 사용할 수 있는 사전훈련모델
🔸 사용모델: VGG16
conv_base = applications.vgg16.VGG16(
weights="imagenet",
include_top=False,
input_shape=(180, 180, 3))
conv_base.summary()
🔸 밀집 연결층을 연결하는 방법 2가지
🔸 vgg16 특성추출 함수 적용
import numpy as np
def get_features_and_labels(dataset):
all_features = []
all_labels = []
for images, labels in dataset:
preprocessed_images = keras.applications.vgg16.preprocess_input(images)
features = conv_base.predict(preprocessed_images)
all_features.append(features)
all_labels.append(labels)
return np.concatenate(all_features), np.concatenate(all_labels)
train_features, train_labels = get_features_and_labels(train_dataset)
val_features, val_labels = get_features_and_labels(validation_dataset)
test_features, test_labels = get_features_and_labels(test_dataset)
이미지 데이터 전처리
conv_base.predict()
를 사용하여 특성 추출(넘파이 배열)
train_features.shape
>>>(2000,5,5,512)
🔸 밀집 연결 분류기 정의 및 훈련
inputs = keras.Input(shape=(5, 5, 512))
x = layers.Flatten()(inputs)
x = layers.Dense(256)(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inputs, outputs)
model.compile(loss="binary_crossentropy",
optimizer="rmsprop",
metrics=["accuracy"])
callbacks = [keras.callbacks.ModelCheckpoint(
filepath="feature_extraction.keras",
save_best_only=True,
monitor="val_loss")]
history = model.fit(train_features, train_labels,
epochs=20,
validation_data=(val_features, val_labels),
callbacks=callbacks)
🔸 그래프
import matplotlib.pyplot as plt
acc = history.history["accuracy"]
val_acc = history.history["val_accuracy"]
loss = history.history["loss"]
val_loss = history.history["val_loss"]
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, "bo", label="Training accuracy")
plt.plot(epochs, val_acc, "b", label="Validation accuracy")
plt.title("Training and validation accuracy")
plt.legend()
plt.figure()
plt.plot(epochs, loss, "bo", label="Training loss")
plt.plot(epochs, val_loss, "b", label="Validation loss")
plt.title("Training and validation loss")
plt.legend()
plt.show()
🔸 테스트 평가: feature_extraction.keras
test_model = keras.models.load_model('feature_extraction.keras')
test_loss, test_acc = test_model.evaluate(test_features, test_labels)
print(f'정확도: {test_acc:.3f}')
정확도: 0.974
🔸 데이터 증식
data_augmentation = keras.Sequential([
layers.RandomFlip("horizontal"),
layers.RandomRotation(0.1),
layers.RandomZoom(0.2),])
🔸 합성곱 기반층 동결
conv_base.trainable = False
훈련가능한 가중치 참고:
conv_base.trainable = True
일 경우 len(conv_base.trainable_weights)
>>>26
conv_base.trainable = False
일 경우len(conv_base.trainable_weights)
>>>0
🔸 데이터 증식과 밀집 분류기를 합성곱 층에 연결
inputs = keras.Input(shape=(180, 180, 3))
x = data_augmentation(inputs) # 데이터증식
x = keras.applications.vgg16.preprocess_input(x) # 이미지데이터 전처리
x = conv_base(x) # 합성곱연산
x = layers.Flatten()(x)
x = layers.Dense(256)(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inputs, outputs)
model.compile(loss="binary_crossentropy",
optimizer="rmsprop",
metrics=["accuracy"])
callbacks = [
keras.callbacks.ModelCheckpoint(
filepath="feature_extraction_with_data_augmentation.keras",
save_best_only=True,
monitor="val_loss")
]
history = model.fit(
train_dataset,
epochs=50,
validation_data=validation_dataset,
callbacks=callbacks)
🔸 그래프
import matplotlib.pyplot as plt
acc = history.history["accuracy"]
val_acc = history.history["val_accuracy"]
loss = history.history["loss"]
val_loss = history.history["val_loss"]
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, "bo", label="Training accuracy")
plt.plot(epochs, val_acc, "b", label="Validation accuracy")
plt.title("Training and validation accuracy")
plt.legend()
plt.figure()
plt.plot(epochs, loss, "bo", label="Training loss")
plt.plot(epochs, val_loss, "b", label="Validation loss")
plt.title("Training and validation loss")
plt.legend()
plt.show()
🔸 테스트 평가: feature_extraction_with_data_augmentation.keras
test_model = keras.models.load_model(
"feature_extraction_with_data_augmentation.keras")
test_loss, test_acc = test_model.evaluate(test_dataset)
print(f"Test accuracy: {test_acc:.3f}")
Test accuracy: 0.976
1. 사전 훈련된 기반 네트워크위에 새로운 네트워크 추가
2. 기반 네트워크 동결
3. 새로 추가한 네트워크 훈련
4. 기반 네트워크에서 일부 층 동결 해제
5. 동결을 해제한 층과 새로 추가한 층을 함께 훈련
🔸 1~3까지 '데이터증식을 사용한 특성추출'에서 이미 완료
🔸 4. 일부층 동결 해제
conv_base.trainable = True
for layer in conv_base.laters[:-4]:
layer.trainable = False
🔸 5. 동결을 해제한 층과 새로 추가한 층을 함께 훈련
model.compile(loss="binary_crossentropy",
optimizer=keras.optimizers.RMSprop(learning_rate=1e-5),
metrics=["accuracy"])
callbacks = [
keras.callbacks.ModelCheckpoint(
filepath="fine_tuning.keras",
save_best_only=True,
monitor="val_loss")
]
history = model.fit(
train_dataset,
epochs=30,
validation_data=validation_dataset,
callbacks=callbacks)
🔸 6. 테스트 평가:fine_tuning.keras
model = keras.models.load_model("fine_tuning.keras")
test_loss, test_acc = model.evaluate(test_dataset)
print(f"Test accuracy: {test_acc:.3f}")
Test accuracy: 0.979
** 이미지출처