【问题标题】:Constant validation accuracy in binary classification using ResNet50使用 ResNet50 进行二进制分类的恒定验证精度
【发布时间】:2020-09-18 11:39:52
【问题描述】:

我正在训练一个深度学习网络来对甲状腺结节进行分类(二进制分类为 0 或 1)。因此,我意识到我的模型具有恒定的验证准确性。我尝试了一切,更改了学习率,如果损失没有增加,则进行一些回调。所以,我需要帮助,一些想法来处理它。我会给你一个 10 个 epoch 的例子,但是,即使我改为 100 个 epoch,它仍然具有相同的行为。这是架构的网络代码:

callbacks = [
    EarlyStopping(patience=20, verbose=1),
    ReduceLROnPlateau(factor=0.1, patience=5, min_lr=0.0001, verbose=1),
]

epochs=10
model = Sequential()
model.add(tf.keras.applications.ResNet50( include_top=False, pooling='avg', weights='imagenet'))
model.add(BatchNormalization())
model.add(Dropout(0.4))
model.add(Dense(2, activation='sigmoid'))
model.layers[0].trainable = False
weights=class_weight.compute_class_weight('balanced', np.unique(y_train), y_train)
opt =Adam(learning_rate=0.001)
model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
tf.random.set_seed(2)
rede=model.fit(X_train, y_train_2d, epochs=epochs, batch_size=18, class_weight=weights, callbacks=callbacks,\
               validation_data=(X_valid, y_valid_2d))

Train on 360 samples, validate on 46 samples
Epoch 1/10
342/360 [===========================>..] - ETA: 1s - loss: 0.7582 - accuracy: 0.5673
Epoch 00001: val_loss did not improve from 0.16301
360/360 [==============================] - 44s 123ms/sample - loss: 0.7706 - accuracy: 0.5583 - val_loss: 0.5528 - val_accuracy: 0.8043
Epoch 2/10
342/360 [===========================>..] - ETA: 1s - loss: 0.5604 - accuracy: 0.7135
Epoch 00002: val_loss did not improve from 0.16301
360/360 [==============================] - 41s 114ms/sample - loss: 0.5525 - accuracy: 0.7222 - val_loss: 0.5047 - val_accuracy: 0.8043
Epoch 3/10
342/360 [===========================>..] - ETA: 1s - loss: 0.5056 - accuracy: 0.7485
Epoch 00003: val_loss did not improve from 0.16301
360/360 [==============================] - 41s 114ms/sample - loss: 0.4993 - accuracy: 0.7500 - val_loss: 0.4946 - val_accuracy: 0.8043
Epoch 4/10
342/360 [===========================>..] - ETA: 1s - loss: 0.5004 - accuracy: 0.7661
Epoch 00004: val_loss did not improve from 0.16301
360/360 [==============================] - 41s 114ms/sample - loss: 0.5019 - accuracy: 0.7667 - val_loss: 0.4942 - val_accuracy: 0.8043
Epoch 5/10
342/360 [===========================>..] - ETA: 1s - loss: 0.4967 - accuracy: 0.8070
Epoch 00005: val_loss did not improve from 0.16301
360/360 [==============================] - 41s 114ms/sample - loss: 0.4897 - accuracy: 0.8083 - val_loss: 0.4952 - val_accuracy: 0.8043
Epoch 6/10
342/360 [===========================>..] - ETA: 1s - loss: 0.4615 - accuracy: 0.7427
Epoch 00006: val_loss did not improve from 0.16301
360/360 [==============================] - 41s 114ms/sample - loss: 0.4750 - accuracy: 0.7361 - val_loss: 0.4985 - val_accuracy: 0.8043
Epoch 7/10
342/360 [===========================>..] - ETA: 1s - loss: 0.4119 - accuracy: 0.7924
Epoch 00007: val_loss did not improve from 0.16301
360/360 [==============================] - 40s 111ms/sample - loss: 0.4164 - accuracy: 0.7944 - val_loss: 0.4953 - val_accuracy: 0.8043
Epoch 8/10
342/360 [===========================>..] - ETA: 0s - loss: 0.4182 - accuracy: 0.8158
Epoch 00008: val_loss did not improve from 0.16301
360/360 [==============================] - 20s 55ms/sample - loss: 0.4155 - accuracy: 0.8194 - val_loss: 0.4957 - val_accuracy: 0.8043
Epoch 9/10
342/360 [===========================>..] - ETA: 0s - loss: 0.3892 - accuracy: 0.8304
Epoch 00009: ReduceLROnPlateau reducing learning rate to 0.00010000000474974513.

Epoch 00009: val_loss did not improve from 0.16301
360/360 [==============================] - 21s 57ms/sample - loss: 0.3853 - accuracy: 0.8278 - val_loss: 0.4997 - val_accuracy: 0.8043
Epoch 10/10
342/360 [===========================>..] - ETA: 0s - loss: 0.3395 - accuracy: 0.8333
Epoch 00010: val_loss did not improve from 0.16301
360/360 [==============================] - 21s 58ms/sample - loss: 0.3375 - accuracy: 0.8333 - val_loss: 0.5003 - val_accuracy: 0.8043

【问题讨论】:

    标签: tensorflow keras deep-learning resnet


    【解决方案1】:

    对于二元分类,您应该将输出密集层更改为 1 个单元,并将损失更改为 binary_crossentropy。

    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
    

    还要确保您的目标数组 (y_train,y_valid) 具有正确的形状和数据。它们应该包含二进制标签,0 或 1

    【讨论】:

    • 验证损失似乎不是严格恒定的——从 0.55 下降到 ~0.5 的高原是显着的。我认为如果 OP 对您描述的层进行更改,他可能会看到改进
    • 好的,但是对于 y_train 和 y_valid,哪个形状是正确的?我更改了 y_train_2d 和 y_valid_2d,条目如下:良性:[0,1] 恶性:[1,0]
    • 应该是良性的:[0],恶性的:[1],反之亦然
    【解决方案2】:

    @AlexM4 是对的,对于二进制分类,您应该使用带有 sigmoid 分类的单个输出单元。

    还值得指出的是,for multi-class classification, you shouldn't use a sigmoid activation 而是 softmax,它产生了可能类的概率分布(sigmoid 理论上可以为所有类产生 1.0 的概率,这是没有意义的)。这可能会阻碍您的网络在此处的性能。

    解决更大的问题(移动到单个输出单元)将消除解决我刚才描述的问题的需要,但在未来的实验中值得牢记。

    【讨论】:

      【解决方案3】:

      我尝试将输出密集度更改为 1,而不是 2。准确度仍然具有相同的行为。

      epochs=10
      model = Sequential()
      model.add(tf.keras.applications.ResNet50( include_top=False, pooling='avg', weights='imagenet'))
      model.add(BatchNormalization())
      model.add(Dropout(0.4))
      model.add(Dense(1, activation='sigmoid'))
      model.layers[0].trainable = False
      weights=class_weight.compute_class_weight('balanced', np.unique(y_train), y_train)
      opt =Adam(learning_rate=0.001)
      model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
      tf.random.set_seed(2)
      rede=model.fit(X_train, y_train, epochs=epochs, batch_size=18, class_weight=weights, callbacks=callbacks,\
                     validation_data=(X_valid, y_valid))
      Train on 360 samples, validate on 46 samples
      Epoch 1/10
      360/360 [==============================] - 17s 48ms/sample - loss: 0.8778 - accuracy: 0.5639 - val_loss: 0.3967 - val_accuracy: 0.8696
      Epoch 2/10
      360/360 [==============================] - 9s 24ms/sample - loss: 0.6527 - accuracy: 0.7028 - val_loss: 0.3973 - val_accuracy: 0.8696
      Epoch 3/10
      360/360 [==============================] - 9s 26ms/sample - loss: 0.6054 - accuracy: 0.7222 - val_loss: 0.4171 - val_accuracy: 0.8696
      Epoch 4/10
      360/360 [==============================] - 10s 28ms/sample - loss: 0.5388 - accuracy: 0.7500 - val_loss: 0.4211 - val_accuracy: 0.8696
      Epoch 5/10
      360/360 [==============================] - 11s 30ms/sample - loss: 0.4830 - accuracy: 0.7694 - val_loss: 0.4367 - val_accuracy: 0.8696
      Epoch 6/10
      342/360 [===========================>..] - ETA: 0s - loss: 0.4986 - accuracy: 0.8070
      Epoch 00006: ReduceLROnPlateau reducing learning rate to 0.00010000000474974513.
      360/360 [==============================] - 11s 29ms/sample - loss: 0.4952 - accuracy: 0.8056 - val_loss: 0.4576 - val_accuracy: 0.8696
      Epoch 7/10
      360/360 [==============================] - 11s 30ms/sample - loss: 0.4257 - accuracy: 0.8306 - val_loss: 0.4661 - val_accuracy: 0.8696
      Epoch 8/10
      360/360 [==============================] - 17s 46ms/sample - loss: 0.4054 - accuracy: 0.8250 - val_loss: 0.4722 - val_accuracy: 0.8696
      Epoch 9/10
      360/360 [==============================] - 17s 48ms/sample - loss: 0.4484 - accuracy: 0.7917 - val_loss: 0.4761 - val_accuracy: 0.8696
      Epoch 10/10
      360/360 [==============================] - 16s 44ms/sample - loss: 0.3844 - accuracy: 0.8472 - val_loss: 0.4785 - val_accuracy: 0.8696
      

      【讨论】:

      • 第一层是什么——你能打印一个模型摘要吗?也许您冻结的模型比您预期的要多。我从来没有在 Keras 中使用过 ResNet 骨干网,所以这只是我的一个疯狂的预感。
      猜你喜欢
      • 2021-01-31
      • 2020-12-20
      • 2017-05-30
      • 1970-01-01
      • 2018-01-29
      • 2021-05-09
      • 1970-01-01
      • 2017-07-25
      • 2017-06-02
      相关资源
      最近更新 更多