【问题标题】:Validation accuracy (val_acc) does not change over the epochs验证准确度 (val_acc) 不会随时期变化
【发布时间】:2020-06-09 18:15:47
【问题描述】:

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'))
    
  • 解锁密集层,将它们设置为可训练;

  • 在“training data”文件夹中获取位于两个不同文件夹中的数据,一个名为“malignant”,另一个名为“benign”;

    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 在验证生成器中;

  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]]

我做错了什么?

谢谢。

【问题讨论】:

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


    【解决方案1】:

    VGG16 在以 RGB 为中心的数据上进行了训练。但是,您的 ImageDataGenerator 没有启用 featurewise_center,因此您正在为网络提供原始 RGB 数据。 VGG 卷积基无法对其进行处理以提供任何有意义的信息,因此您的网络最终会普遍猜测更常见的类。

    一般来说,当您看到此类问题(您的网络专门猜测最常见的类)时,这意味着您的数据有问题,而不是网络有问题。它可能是由这样的预处理步骤引起的,也可能是由大量“中毒”的异常训练数据引起的,这些数据会积极损害训练过程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-28
      • 2020-12-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      • 1970-01-01
      • 2020-03-29
      相关资源
      最近更新 更多