python - 验证准确性 (val_acc) 不会随时间变化

标签 python machine-learning keras conv-neural-network vgg-net

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 和较低的学习率对其进行微调,将最后一个卷积层设置为可训练。

我尝试过很多事情,例如:

  1. 更改优化器(RMSprop、Adam 和 SGD);
  2. 删除预训练 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')) 
    
  3. Shuffle=True在validation_generator中;

  4. 更改批量大小;

  5. 改变学习率 ( 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/

相关文章:

python - TensorFlow 优化器中的 _get_hyper 和 _set_hyper 是什么?

python - Keras - on_batch_end 方法很慢,但我只有回调是检查点

python - 使用 matplotlib 和 ipywidget 的交互式图形

encoding - 回归分析中如何区分分类变量和序数变量?

java - 设置 Encog EarlyStoppingStrategy 参数的正确方法

tensorflow - 为什么在 Google Cloud ML 上训练的 TensorFlow 模型比本地训练的模型更准确?

python - ENIGMA 催化剂 - 警告 : Loader: Refusing to download new treasury data because a download succeeded

python - 考虑 Pandas 中的几个属性,删除重复项

python - 多处理 "OSError: [Errno 24] Too many open files": How to clean up jobs and queues?

python - 如何使用 Tensorflow(python) 为 keras model.fit() 创建我自己的数据集?