val_acc 的值在历元内不会改变。
摘要:
我使用的是来自 Keras 的预训练 (ImageNet) VGG16;
from keras.applications import VGG16 conv_base = VGG16(weights='imagenet', include_top=True, input_shape=(224, 224, 3))
来自 ISBI 2016 (ISIC) 的数据库 - 这是一组 900 张皮肤病变图像,用于训练和验证的二元分类(恶性或良性),以及 379 张图像用于测试 -;
里>我使用 VGG16 的顶部密集层(除了最后一个层(对 1000 多个类别进行分类)),并使用带有 sigmoid 函数激活的二进制输出;
conv_base.layers.pop() # Remove last one conv_base.trainable = False model = models.Sequential() model.add(conv_base) model.add(layers.Dense(1, activation='sigmoid'))
解锁密集层,将其设置为可训练;
获取“训练数据”文件夹中两个不同文件夹中的数据,一个名为“恶性”,另一个名为“良性”;
from keras.preprocessing.image import ImageDataGenerator from keras import optimizers folder = 'ISBI2016_ISIC_Part3_Training_Data' batch_size = 20 full_datagen = ImageDataGenerator( rescale=1./255, #rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, validation_split = 0.2, # 20% validation horizontal_flip=True) train_generator = full_datagen.flow_from_directory( # Found 721 images belonging to 2 classes. folder, target_size=(224, 224), batch_size=batch_size, subset = 'training', class_mode='binary') validation_generator = full_datagen.flow_from_directory( # Found 179 images belonging to 2 classes. folder, target_size=(224, 224), batch_size=batch_size, subset = 'validation', shuffle=False, class_mode='binary') model.compile(loss='binary_crossentropy', optimizer=optimizers.SGD(lr=0.001), # High learning rate metrics=['accuracy']) history = model.fit_generator( train_generator, steps_per_epoch=721 // batch_size+1, epochs=20, validation_data=validation_generator, validation_steps=180 // batch_size+1, )
然后我用 100 个以上的 epoch 和较低的学习率对其进行微调,将最后一个卷积层设置为可训练。
我尝试过很多事情,例如:
- 更改优化器(RMSprop、Adam 和 SGD);
删除预训练 VGG16 的顶部密集层并添加我的;
model.add(layers.Flatten()) model.add(layers.Dense(128, activation='relu')) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(1, activation='sigmoid'))
Shuffle=True
在validation_generator中;更改批量大小;
改变学习率 (
0.001, 0.0001, 2e-5
)。
结果类似于以下内容:
Epoch 1/100
37/37 [==============================] - 33s 900ms/step - loss: 0.6394 - acc: 0.7857 - val_loss: 0.6343 - val_acc: 0.8101
Epoch 2/100
37/37 [==============================] - 30s 819ms/step - loss: 0.6342 - acc: 0.8107 - val_loss: 0.6342 - val_acc: 0.8101
Epoch 3/100
37/37 [==============================] - 30s 822ms/step - loss: 0.6324 - acc: 0.8188 - val_loss: 0.6341 - val_acc: 0.8101
Epoch 4/100
37/37 [==============================] - 31s 840ms/step - loss: 0.6346 - acc: 0.8080 - val_loss: 0.6341 - val_acc: 0.8101
Epoch 5/100
37/37 [==============================] - 31s 833ms/step - loss: 0.6395 - acc: 0.7843 - val_loss: 0.6341 - val_acc: 0.8101
Epoch 6/100
37/37 [==============================] - 31s 829ms/step - loss: 0.6334 - acc: 0.8134 - val_loss: 0.6340 - val_acc: 0.8101
Epoch 7/100
37/37 [==============================] - 31s 834ms/step - loss: 0.6334 - acc: 0.8134 - val_loss: 0.6340 - val_acc: 0.8101
Epoch 8/100
37/37 [==============================] - 31s 829ms/step - loss: 0.6342 - acc: 0.8093 - val_loss: 0.6339 - val_acc: 0.8101
Epoch 9/100
37/37 [==============================] - 31s 849ms/step - loss: 0.6330 - acc: 0.8147 - val_loss: 0.6339 - val_acc: 0.8101
Epoch 10/100
37/37 [==============================] - 30s 812ms/step - loss: 0.6332 - acc: 0.8134 - val_loss: 0.6338 - val_acc: 0.8101
Epoch 11/100
37/37 [==============================] - 31s 839ms/step - loss: 0.6338 - acc: 0.8107 - val_loss: 0.6338 - val_acc: 0.8101
Epoch 12/100
37/37 [==============================] - 30s 807ms/step - loss: 0.6334 - acc: 0.8120 - val_loss: 0.6337 - val_acc: 0.8101
Epoch 13/100
37/37 [==============================] - 32s 852ms/step - loss: 0.6334 - acc: 0.8120 - val_loss: 0.6337 - val_acc: 0.8101
Epoch 14/100
37/37 [==============================] - 31s 826ms/step - loss: 0.6330 - acc: 0.8134 - val_loss: 0.6336 - val_acc: 0.8101
Epoch 15/100
37/37 [==============================] - 32s 854ms/step - loss: 0.6335 - acc: 0.8107 - val_loss: 0.6336 - val_acc: 0.8101
以同样的方式进行,常数为 val_acc = 0.8101
.
当我完成训练后使用测试集时,混淆矩阵对良性病变 (304) 的正确率是 100%,对恶性病变的正确率是 0%,如下所示:
Confusion Matrix
[[304 0]
[ 75 0]]
我可能做错了什么?
谢谢。
最佳答案
VGG16 在以 RGB 为中心的数据上进行训练。但是,您的 ImageDataGenerator
未启用 featurewise_center
,因此您需要向网络提供原始 RGB 数据。 VGG 卷积基无法处理此信息以提供任何有意义的信息,因此您的网络最终会普遍猜测更常见的类别。
一般来说,当您看到此类问题(您的网络专门猜测最常见的类)时,这意味着您的数据有问题,而不是网络有问题。它可能是由这样的预处理步骤引起的,也可能是由很大一部分“中毒”的异常训练数据引起的,这些数据会严重损害训练过程。
关于python - 验证准确性 (val_acc) 不会随时间变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60404341/