我在一个包含植物病症图像的数据集上进行模型训练实验。
我从头开始训练了VGG16模型,并使用了迁移学习。
在迁移学习中,我移除了预训练在ImageNet数据集上的VGG16模型的头部。然后我连接了一个自定义头部到模型上。
from keras.layers.core import Dropoutfrom keras.layers.core import Flattenfrom keras.layers.core import Densehead_model = base_model.outputhead_model = Flatten(name='flatten')(head_model)head_model = Dense(256,activation='relu')(head_model)head_model = Dropout(0.5)(head_model)# Add a softmaxc layerhead_model = Dense(len(class_names),activation='softmax')(head_model)
我冻结了基础模型的所有层,并训练了头部大约25个周期。
然后我解冻了基础模型末端的一些层,并继续训练了100个周期。
这种方法比从头开始训练获得了更高的准确率。
我还想尝试使用ResNet50模型。
我的问题是如何确定要连接的合适头部部分?对于上述情况,我是从一个教程中获得了头部架构。但我并不真正理解其背后的原因。例如,那里没有使用CONV层。只有Dense、Flatten和Dropout。为什么没有使用CONV层呢?
我如何为ResNet决定一个合适的头部呢?
EDIT
每个类别有100到1500张图像。总共有10个类别。
ResNet的训练准确率
在预热之后。这里,我冻结了所有基础模型的层,只训练自定义头部25个周期。
[INFO] evaluating after initialization... precision recall f1-score support Tomato___Tomato_mosaic_virus 0.00 0.00 0.00 532 Tomato___Early_blight 0.00 0.00 0.00 239 Tomato___Late_blight 0.00 0.00 0.00 470 Tomato___Leaf_Mold 0.00 0.00 0.00 238 Tomato___Bacterial_spot 0.00 0.00 0.00 435 Tomato___Target_Spot 0.00 0.00 0.00 362Tomato___Tomato_Yellow_Leaf_Curl_Virus 0.30 1.00 0.46 1355 Tomato___healthy 0.00 0.00 0.00 98 Tomato___Septoria_leaf_spot 0.00 0.00 0.00 414 Tomato___Two-spotted_spider_mite 0.00 0.00 0.00 397 avg / total 0.09 0.30 0.14 4540
预热完成后,我尝试逐渐解冻一些层。这些是结果。
从第165层开始解冻。(运行了60个周期)
425/425 [==============================] - 233s 548ms/step - loss: 0.2656 - accuracy: 0.9201 - val_loss: 93.4192 - val_accuracy: 0.2998
从第161层开始解冻(运行了大约50个周期)
425/425 [==============================] - 221s 521ms/step - loss: 0.2627 - accuracy: 0.9235 - val_loss: 91.5139 - val_accuracy: 0.1066
从第168层开始解冻(运行了50个周期)val_accuracy = 0.30198
因此,验证准确率很少增加。而且还会下降。
相比之下,VGG16的准确率非常高。
回答:
任何定义好的CNN模型,如VGG16、ResNet、Inception等,都具有经过长时间训练和实验验证的架构。因此,通常不需要更改现有架构或添加更多的CONV层。唯一需要的变化是完全连接层的修改,或者简单地说就是“头部”。由于头部仅处理数字,在大多数情况下,最多两个密集层就足够了。我观察到如果使用超过两个密集层,模型会变得很重(训练时间和内存消耗增加)。