[英]Transfer Learning model gives 0 accuracy regardless of architecture
I am trying to develop a model using Keras and transfer learning.我正在尝试使用 Keras 和迁移学习来开发 model。 The dataset I am using can be found here: https://github.com/faezetta/VMMRdb .我使用的数据集可以在这里找到: https://github.com/faezetta/VMMRdb 。
I have taken the 10 classes of car brands with the most samples and trained two models built upon the VGG16 architecture using transfer learning, as it can be seen in the code below.我选取了样本最多的 10 类汽车品牌,并使用迁移学习训练了两个基于 VGG16 架构的模型,如下面的代码所示。
samples_counts = utils.read_dictionary(utils.TOP10_BRANDS_COUNTS_NAME)
train_dataset = image_dataset_from_directory(
directory=utils.TRAIN_SET_LOCATION,
labels='inferred',
label_mode='categorical',
class_names=list(samples_counts.keys()),
color_mode='rgb',
batch_size=32,
image_size=(56, 56),
shuffle=True,
seed=utils.RANDOM_STATE,
validation_split=0.2,
subset='training',
interpolation='bilinear'
)
validation_dataset = image_dataset_from_directory(
directory=utils.TRAIN_SET_LOCATION,
labels='inferred',
label_mode='categorical',
class_names=list(samples_counts.keys()),
color_mode='rgb',
batch_size=32,
image_size=(56, 56),
shuffle=True,
seed=utils.RANDOM_STATE,
validation_split=0.2,
subset='validation',
interpolation='bilinear'
)
test_dataset = image_dataset_from_directory(
directory=utils.TEST_SET_LOCATION,
labels='inferred',
label_mode='categorical',
class_names=list(samples_counts.keys()),
color_mode='rgb',
batch_size=32,
image_size=(56, 56),
shuffle=True,
seed=utils.RANDOM_STATE,
interpolation='bilinear'
)
image_shape = (utils.RESIZE_HEIGHT, utils.RESIZE_WIDTH, 3)
base_model = apps.VGG16(include_top=False, weights='imagenet', input_shape=image_shape)
base_model.trainable = False
preprocess_input = apps.vgg16.preprocess_input
flatten_layer = layers.Flatten(name='flatten')
specialisation_layer = layers.Dense(1024, activation='relu', name='specialisation_layer')
avg_pooling_layer = layers.GlobalAveragePooling2D(name='pooling_layer')
dropout_layer = layers.Dropout(0.2, name='dropout_layer')
classification_layer = layers.Dense(10, activation='softmax', name='classification_layer')
inputs = tf.keras.Input(shape=(utils.RESIZE_HEIGHT, utils.RESIZE_WIDTH, 3))
x = preprocess_input(inputs)
x = base_model(x, training=False)
# First model
# x = flatten_layer(x)
# x = specialisation_layer(x)
# Second model
x = avg_pooling_layer(x)
x = dropout_layer(x)
outputs = classification_layer(x)
model = tf.keras.Model(inputs, outputs)
model.summary()
steps_per_epoch = len(train_dataset)
validation_steps = len(validation_dataset)
base_learning_rate = 0.0001
optimizer = optimizers.Adam(learning_rate=base_learning_rate)
loss_function = losses.CategoricalCrossentropy()
train_metrics = [metrics.Accuracy(), metrics.AUC(), metrics.Precision(), metrics.Recall()]
model.compile(optimizer=optimizer,
loss=loss_function,
metrics=train_metrics)
initial_results = model.evaluate(validation_dataset,
steps=validation_steps,
return_dict=True)
training_history = model.fit(train_dataset, epochs=10, verbose=0,
validation_data=validation_dataset,
callbacks=[TqdmCallback(verbose=2)],
steps_per_epoch=steps_per_epoch,
validation_steps=validation_steps)
history = training_history.history
final_results = model.evaluate(test_dataset,
return_dict=True,
callbacks=[TqdmCallback(verbose=2)])
I keep getting 0 accuracy and bad metrics in general.一般来说,我一直得到 0 的准确性和糟糕的指标。 I have tried the solutions mentioned in Transfer learning bad accuracy and MNIST and transfer learning with VGG16 in Keras- low validation accuracy , without success.我已经尝试过迁移学习差的准确率和MNIST 中提到的解决方案,以及在 Keras-low 验证准确度下使用 VGG16 进行迁移学习,但没有成功。
The summary and the results for the first model are:第一个 model 的总结和结果是:
Model: "functional_1"
input_2 (InputLayer) [(None, 56, 56, 3)] 0
tf_op_layer_strided_slice (T [(None, 56, 56, 3)] 0
tf_op_layer_BiasAdd (TensorF [(None, 56, 56, 3)] 0
vgg16 (Functional) (None, 1, 1, 512) 14714688
flatten (Flatten) (None, 512) 0
specialisation_layer (Dense) (None, 1024) 525312
classification_layer (Dense) (None, 10) 10250
Total params: 15,250,250
Trainable params: 535,562
Non-trainable params: 14,714,688
Initial results: loss = 9.01, accuracy = 0.0, auc = 0.53, precision = 0.13, recall = 0.12
Final results: loss = 2.5, accuracy = 0.0, auc = 0.71, precision = 0.31, recall = 0.14
The summary and the results for the second model are:第二个 model 的总结和结果是:
Model: "functional_1"
input_2 (InputLayer) [(None, 56, 56, 3)] 0
tf_op_layer_strided_slice (T [(None, 56, 56, 3)] 0
tf_op_layer_BiasAdd (TensorF [(None, 56, 56, 3)] 0
vgg16 (Functional) (None, 1, 1, 512) 14714688
pooling_layer (GlobalAverage (None, 512) 0
dropout_layer (Dropout) (None, 512) 0
classification_layer (Dense) (None, 10) 5130
Total params: 14,719,818
Trainable params: 5,130
Non-trainable params: 14,714,688
Initial Results: loss = 21.6, accuracy = 0, auc = 0.48, precision = 0.07, recall = 0.07
Final Results: loss = 2.02, accuracy = 0, auc = 0.72, precision = 0.44, recall = 0.009
in the code below在下面的代码中
# Second model
x = avg_pooling_layer(x)
x = dropout_layer(x)
outputs = classification_layer(x)
model = tf.keras.Model(inputs, outputs)
you need to add a Flatten layer after the avg_pooling_layer.您需要在 avg_pooling_layer 之后添加一个 Flatten 层。 Or alternatively change the ave_pooling_lay to a GlobalMaxPooling2D layer which is what I think is best.或者将 ave_pooling_lay 更改为 GlobalMaxPooling2D 层,这是我认为最好的。 so your second model would be所以你的第二个 model 将是
x=tf.keras.layers.GlobalMaxPooling2D()(x)
x = dropout_layer(x)
outputs = classification_layer(x)
model = tf.keras.Model(inputs, outputs)
Also in Vgg you can set the parameter pooling='average then the output is a 1 dimensional tensor so you don't need to flatten it and you don't need to add global average pooling.同样在 Vgg 中,您可以设置参数 pooling='average 然后 output 是一维张量,因此您不需要将其展平,也不需要添加全局平均池。 In your test_dataset and validation_dataset set shuffle=False and set seed=None.在您的 test_dataset 和 validation_dataset 中设置 shuffle=False 并设置 seed=None。 Your values for steps_per_epoch and validation steps are incorrect.您的 steps_per_epoch 和验证步骤的值不正确。 They are typically set to number of samples//batch_size.它们通常设置为样本数//batch_size。 You can leave these values as None in model.fit and it will determine these values internally, also set verbose=1 so you can see the results of training for each epoch.您可以在 model.fit 中将这些值保留为 None ,它将在内部确定这些值,还设置 verbose=1 以便您可以查看每个时期的训练结果。 Leave callbacks=None I don't even know what TqdmCallback(verbose=2) is.离开 callbacks=None 我什至不知道 TqdmCallback(verbose=2) 是什么。 Not listed in any documentation I could find.未在我能找到的任何文档中列出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.