训练准确度提高但验证准确度保持在 0.5,并且模型为每个验证样本预测几乎相同的类别

Posted

技术标签:

【中文标题】训练准确度提高但验证准确度保持在 0.5,并且模型为每个验证样本预测几乎相同的类别【英文标题】:Training accuracy improving but validation accuracy remain at 0.5, and model predicts nearly the same class for every validation sample 【发布时间】:2019-12-19 12:34:43 【问题描述】:

我正在使用 keras tensorflow 后端在时间流逝的 IVF 胚胎图像数据集上实现 ResNet50 + LSTM 和注意力模型。

数据集包含大约 220 个样本,我使用 85% - 15% 的训练/验证拆分(203 个用于训练,27 个用于验证)。

我的模型能够达到 0.80+ 的训练准确度,但验证准确度要么卡在 0.5 左右,要么仅停留在 0.5,验证损失几乎是训练损失的两倍。

这只是一个过拟合的问题吗?

如果没有,我该如何调试和提高验证集的性能?

#我尝试过的事情:

我尝试添加正则化(L1,0.01)/Dropout 层(0.5)/减少神经元(1024 到 512 到 256),但它们都不起作用)

我还通过减去平均值和除以标准差来标准化我的数据。

我正在使用一个学习率为 1e-5 且没有权重衰减的 Adam 优化器。图像在训练前被打乱。

#下面是我的模型和进度条的代码

#进度条:

Epoch 1/40

150/150 [==============================] - 28s 189ms/step - loss: 2.1318 - acc: 0.5267 - val_loss: 4.8806 - val_acc: 0.5556



Epoch 00001: val_loss improved from inf to 4.88055, saving model to result/resnetmodel.hdf5

Epoch 2/40

150/150 [==============================] - 14s 94ms/step - loss: 1.9957 - acc: 0.5867 - val_loss: 4.8210 - val_acc: 0.5000



Epoch 00002: val_loss improved from 4.88055 to 4.82100, saving model to result/resnetmodel.hdf5

Epoch 3/40

150/150 [==============================] - 14s 94ms/step - loss: 1.8062 - acc: 0.6200 - val_loss: 4.9689 - val_acc: 0.5000



Epoch 00003: val_loss did not improve from 4.82100

Epoch 4/40

150/150 [==============================] - 14s 91ms/step - loss: 1.7516 - acc: 0.6267 - val_loss: 5.0284 - val_acc: 0.5000



Epoch 00004: val_loss did not improve from 4.82100

Epoch 5/40

150/150 [==============================] - 14s 94ms/step - loss: 1.6508 - acc: 0.7000 - val_loss: 4.9873 - val_acc: 0.4444



Epoch 00005: val_loss did not improve from 4.82100

Epoch 6/40

150/150 [==============================] - 14s 92ms/step - loss: 1.5003 - acc: 0.7733 - val_loss: 4.9800 - val_acc: 0.4444



Epoch 00006: val_loss did not improve from 4.82100

Epoch 7/40

150/150 [==============================] - 14s 96ms/step - loss: 1.4614 - acc: 0.7667 - val_loss: 4.9435 - val_acc: 0.5000



Epoch 00007: val_loss did not improve from 4.82100

Epoch 8/40

150/150 [==============================] - 14s 90ms/step - loss: 1.5480 - acc: 0.6800 - val_loss: 4.9345 - val_acc: 0.5000



Epoch 00008: val_loss did not improve from 4.82100

Epoch 9/40

150/150 [==============================] - 14s 93ms/step - loss: 1.4334 - acc: 0.7667 - val_loss: 5.0452 - val_acc: 0.5000



Epoch 00009: val_loss did not improve from 4.82100

Epoch 10/40

150/150 [==============================] - 14s 94ms/step - loss: 1.4344 - acc: 0.7667 - val_loss: 5.1768 - val_acc: 0.4444



Epoch 00010: val_loss did not improve from 4.82100

Epoch 11/40

150/150 [==============================] - 15s 98ms/step - loss: 1.3369 - acc: 0.8533 - val_loss: 5.1331 - val_acc: 0.4444



Epoch 00011: val_loss did not improve from 4.82100

Epoch 12/40

150/150 [==============================] - 14s 93ms/step - loss: 1.2834 - acc: 0.8133 - val_loss: 5.1265 - val_acc: 0.4444



Epoch 00012: val_loss did not improve from 4.82100

Epoch 13/40

150/150 [==============================] - 14s 91ms/step - loss: 1.3007 - acc: 0.8200 - val_loss: 5.1941 - val_acc: 0.4444



Epoch 00013: val_loss did not improve from 4.82100

Epoch 14/40

150/150 [==============================] - 14s 94ms/step - loss: 1.2358 - acc: 0.8533 - val_loss: 5.3716 - val_acc: 0.4444



Epoch 00014: val_loss did not improve from 4.82100

Epoch 15/40

150/150 [==============================] - 14s 92ms/step - loss: 1.2823 - acc: 0.8000 - val_loss: 5.3877 - val_acc: 0.4444

Epoch 00015:val_loss 没有从 4.82100 改进

Epoch 00015:提前停止

评估:----加载数据

----prediction_on_eval-----

事实=[1。 0.],预测=[0.03809702 0.96190304]

事实=[1。 0.],预测=[0.9803326 0.0196674]

事实=[1。 0.],预测=[9.9986279e-01 1.3717638e-04]

事实=[1。 0.],预测=[0.98158103 0.01841903]

事实=[1。 0.],预测=[0.99492776 0.00507224]

事实=[1。 0.],预测=[0.70435154 0.29564843]

事实=[1。 0.],预测=[4.1277369e-04 9.9958724e-01]

事实=[1。 0.],预测=[0.9818978 0.01810225]

事实=[1。 0.],预测=[0.91195923 0.08804072]

事实=[0. 1.],预测=[0.986312 0.013688]

事实=[0. 1.],预测=[0.9985434 0.00145668]

事实=[0. 1.],预测=[0.80424094 0.195759]

事实=[0. 1.],预测=[0.9214819 0.07851809]

事实=[0. 1.],预测=[0.03754392 0.96245605]

事实=[0. 1.],预测=[9.9976009e-01 2.3989924e-04]

事实=[0. 1.],预测=[0.98681134 0.01318868]

事实=[0. 1.],预测=[0.9984666 0.0015334]

事实=[0. 1.],预测=[0.7229417 0.27705824]

#这是我的模型:


x =Input(shape = (40, config.img_shape, config.img_shape, config.img_channel))

if config.base_model == "inception_v3":

    cnn = InceptionV3(weights = None, include_top=False, pooling = "avg")

elif config.base_model == 'ResNet50':

    cnn = ResNet50(weights = None, include_top=False, pooling = "avg")
    
cnn.load_weights(config.pretrained_path)

for layer in cnn.layers:

    layer.trainable = False


extracted_features = TimeDistributed(cnn)(x)

activations = Bidirectional(LSTM(config.num_units_lstm, return_sequences=True,                              recurrent_activation = 'relu', recurrent_initializer = 'glorot_uniform', name='Bidirectional_LSTM'))(extracted_features)

activations = Dropout(0.5)(activations)

attention = TimeDistributed(Dense(1, activation='tanh'),name = "context_vector")(activations)

attention = Flatten()(attention)

attention = Activation('softmax', name = "conext_weights")(attention)

attention = RepeatVector(config.num_units_lstm*2)(attention)

attention = Permute([2, 1])(attention)

sent_representation = merge.multiply([activations, attention])

sent_representation = Lambda(lambda xin: K.sum(xin, axis=1))(sent_representation)

sent_representation = BatchNormalization()(sent_representation)

prediction = Dense(config.num_classes, activation = 'softmax')(sent_representation)

model =  Model(inputs = x, outputs = prediction)

【问题讨论】:

【参考方案1】:

数据集包含大约 220 个样本,我使用 85% - 15% 的训练/验证拆分(203 个用于训练,27 个用于验证)。

这只是一个过拟合的问题吗?

听起来很有可能,是的。对于这样一个深度网络,220 个样本是非常非常小的数据集。真的不太可能从这么少的一组数据中学会很好地概括。

如果没有,我该如何调试和提高验证集的性能?

在理想情况下,再获取大约 100,000 个样本并将它们添加到您的数据集中!

接受这一点可能是不切实际的,您可以尝试以下策略之一或组合:

使用image augmentation 人为地增加数据集的大小 而不是尝试从头开始训练深度网络。使用 tensorflow_hub 进行调查,以便仅训练最后一层(和/或微调)预训练网络 (link)。

【讨论】:

【参考方案2】:

我遇到了同样的问题:

使用ImageDataGenerator from keras.preprocessing.image 动态执行图像增强 使用了带有预训练权重的迁移学习、VGG16 和 MobileNetV2 等

我仍然得到 0.5 val_loss。 这解决了我的情况,希望对您有所帮助:

替换model = Model(inputs = x, outputs = prediction)model = Model(inputs = x.inputs, outputs = prediction)

【讨论】:

以上是关于训练准确度提高但验证准确度保持在 0.5,并且模型为每个验证样本预测几乎相同的类别的主要内容,如果未能解决你的问题,请参考以下文章

带有keras的CNN,准确性保持不变并且没有提高

Keras DNN 预测模型准确率没有提高

训练多个epoch来提高训练模型的准确率

我的图像分割模型在训练和验证上提供了非常高的准确性,但输出空白掩码

CNN 训练准确率在训练期间变得更好,但测试准确率保持在 40% 左右

Keras图像分类验证准确率更高