У меня очень маленький набор данных изображений (747 изображений для тренировок и 250 для тестирования, когда размеры изображений уменьшены до 256 x 256). Задача - классификация по нескольким меткам (между двумя инфекциями, которые возможны вместе, но в моих данных об обучении такой ситуации нет).
Поскольку мой набор данных очень мал, я решил использовать трансферное обучение с использованием VGG16. и Начало V3. Когда я тренирую VGG16, все следует теории, например, потери при обучении и потери при проверке продолжают уменьшаться и не сильно отличаются друг от друга, как показано на рисунке 1
![VGG16: batch_size=32, learning_rate=0.00001](https://i.stack.imgur.com/kwe2p.png)
Когда я тренирую InceptionV3, кажется, что модель переоснащена, но я не уверен в этом, потому что потери при обучении составляют около 0,6, тогда как потери при проверке в 10 раз превышают потери при обучении, как показано на рисунке 2
В обе модели были добавлены 3 плотных слоя. Я приложил код для справки. Я не смог найти объяснения, почему модель намного большего размера (VGG) не подходит для этого набора данных, а InceptionV3. Могу ли я предложить, что пошло не так с InceptionV3?
def xvgg16(self, height, width, depth, num_class, hparams):
"""
This function defines transfer learning for vgg16
Parameters
----------
height : Integer
Image height (pixel)
width : Integer
Image width (pixel)
depth : Integer
Image channel
num_class : Integer
Number of class labels
hparams: Dictionary
Hyperparameters
Returns
-------
model : Keras model object
The transfer model
"""
input_tensor = Input(shape=(height, width, depth))
pretrain = VGG16(weights="imagenet", include_top=False, input_tensor=input_tensor)
conv1_1 = pretrain.layers[1]
conv1_2 = pretrain.layers[2]
pool1 = pretrain.layers[3]
conv2_1 = pretrain.layers[4]
conv2_2 = pretrain.layers[5]
pool2 = pretrain.layers[6]
conv3_1 = pretrain.layers[7]
conv3_2 = pretrain.layers[8]
conv3_3 = pretrain.layers[9]
pool3 = pretrain.layers[10]
conv4_1 = pretrain.layers[11]
conv4_2 = pretrain.layers[12]
conv4_3 = pretrain.layers[13]
pool4 = pretrain.layers[14]
conv5_1 = pretrain.layers[15]
conv5_2 = pretrain.layers[16]
conv5_3 = pretrain.layers[17]
pool5 = pretrain.layers[18]
x = BatchNormalization(axis=-1)(conv1_1.output)
x = conv1_2(x)
x = BatchNormalization(axis=-1)(x)
x = pool1(x)
x = conv2_1(x)
x = BatchNormalization(axis=-1)(x)
x = conv2_2(x)
x = BatchNormalization(axis=-1)(x)
x = pool2(x)
x = conv3_1(x)
x = BatchNormalization(axis=-1)(x)
x = conv3_2(x)
x = BatchNormalization(axis=-1)(x)
x = conv3_3(x)
x = BatchNormalization(axis=-1)(x)
x = pool3(x)
x = conv4_1(x)
x = BatchNormalization(axis=-1)(x)
x = conv4_2(x)
x = BatchNormalization(axis=-1)(x)
x = conv4_3(x)
x = BatchNormalization(axis=-1)(x)
x = pool4(x)
x = conv5_1(x)
x = BatchNormalization(axis=-1)(x)
x = conv5_2(x)
x = BatchNormalization(axis=-1)(x)
x = conv5_3(x)
x = BatchNormalization(axis=-1)(x)
x = pool5(x)
x = Flatten()(x)
x = Dense(64, use_bias=False)(x)
x = Dropout(0.25)(x)
x = BatchNormalization(axis=-1)(x)
x = Activation("relu")(x)
x = Dense(64, use_bias=False)(x)
x = Dropout(0.25)(x)
x = BatchNormalization(axis=-1)(x)
x = Activation("relu")(x)
x = Dense(64, use_bias=False)(x)
x = Dropout(0.25)(x)
x = BatchNormalization(axis=-1)(x)
x = Activation("relu")(x)
x = Dense(num_class)(x)
x = Activation("sigmoid")(x)
model = Model(inputs=pretrain.layers[0].input, outputs=x)
for layer in model.layers:
if "conv" in layer.name:
layer.trainable = False
model.compile(loss="binary_crossentropy", optimizer=Adam(lr=hparams["learning_rate"]), metrics=["binary_accuracy"])
return model
def inception3(self, height, width, depth, num_class, hparams):
"""
This function defines transfer learning for densenet
Parameters
----------
height : Integer
Image height (pixel)
width : Integer
Image width (pixel)
depth : Integer
Image channel
num_class : Integer
Number of class labels
hparams: Dictionary
Hyperparameters
Returns
-------
model : Keras model object
The transfer model
"""
input_tensor = Input(shape=(height, width, depth))
pretrain = InceptionV3(weights="imagenet", include_top=False, input_tensor=input_tensor)
x = pretrain.output
x = GlobalAveragePooling2D()(x)
x = Dense(64, use_bias=False)(x)
x = Dropout(0.25)(x)
x = BatchNormalization(axis=-1)(x)
x = Activation("relu")(x)
x = Dense(64, use_bias=False)(x)
x = Dropout(0.25)(x)
x = BatchNormalization(axis=-1)(x)
x = Activation("relu")(x)
x = Dense(64, use_bias=False)(x)
x = Dropout(0.25)(x)
x = BatchNormalization(axis=-1)(x)
x = Activation("relu")(x)
x = Dense(num_class)(x)
x = Activation("sigmoid")(x)
model = Model(inputs=pretrain.input, outputs=x)
for layer in pretrain.layers:
layer.trainable = False
model.compile(loss="binary_crossentropy", optimizer=Adam(lr=hparams["learning_rate"]), metrics=["binary_accuracy"])
return model