neural-network - 神经网络收敛太快,预测空白结果
问题描述
我正在使用 UNet 模型来训练具有大约 1,000 个灰度医学图像和 1,000 个相应蒙版的分割算法,其中医学图像中感兴趣的部分是白色像素,背景是黑色。
我使用骰子损失和类似的骰子分数作为准确度指标,以说明我的白色像素通常比黑色背景像素的数量少。但是我在训练时仍然遇到一些问题
1)损失收敛太快。例如,如果我的 SGD 优化器的学习率为 0.01,则在大约 2 个 epoch 时,损失(训练和验证)将下降到 0.00009,并且准确率会上升并按比例稳定在 100%。对看不见的集合进行测试会给出空白图像。
假设 - 过拟合: 我认为这是由于过拟合造成的,所以我通过刚性变换(翻转和旋转)尽可能地扩充了数据集,但仍然没有帮助。此外,如果我根据我用来训练它的相同数据测试模型,它仍然会预测空白图像。那么这是否意味着它不是过度拟合的情况?
2)模型看起来不像是在训练。我能够在模型将所有测试数据还原为黑色之前检查模型,但即使这样,结果也会看起来像原始版本的模糊版本,而没有分割我的训练掩码突出显示的特征
3) loss vs epochs 和 accuracy vs epochs 输出图表非常平滑:它们没有呈现出我在进行语义分割时期望看到的振荡行为。根据这篇相关文章,当只有一个类时,通常会出现平滑图表。然而,我假设我的模型会看到训练掩码(白色像素与黑色像素)并将其视为两类问题。我在这个假设上错了吗?
4)根据这篇文章,骰子适用于不平衡的训练集。我也尝试按照他们的建议获得精度/召回/F1 结果,但无法做到这一点,并假设它可能与我的第三个问题有关,模型将我的分割任务视为单个类问题。
TLDR:如何修复我得到的黑色输出结果?您能否帮我澄清一下我的学习模型是否实际上将每个蒙版中的白色和黑色像素视为两个单独的类,如果不是,它实际上在做什么?
解决方案
由于类别不平衡,您的模型仅预测一个类别(背景/背面像素)。
损失收敛得太快。例如,如果我的 SGD 优化器的学习率为 0.01,则在大约 2 个 epoch 时,损失(训练和验证)将下降到 0.00009,并且准确率会上升并按比例稳定在 100%。对看不见的集合进行测试会给出空白图像。
降低你的学习率。0.01
真的很高,所以尝试一些类似3e-5
的东西来学习,看看你的模型表现如何。此外,具有 100% 的准确度(假设您使用的是骰子?)表明您仍在使用准确度,因此我相信您的模型无法识别您正在使用骰子/骰子损失进行训练和评估(代码片段将不胜感激)。
例子:
model.compile(optimizer=Adam(lr=TRAIN_SEG_LEARNING_RATE),
loss=dice_coef_loss,
metrics=[dice_coef])
此外,如果我根据我用来训练它的相同数据测试模型,它仍然会预测空白图像。那么这是否意味着它不是过度拟合的情况?
尝试使用model.evaluate(test_data, test_label)
. 如果评估的性能很好(如果您只预测 0,则骰子应该非常低),那么要么您的标签以某种方式弄乱了,要么您的管道有问题。
如果一切都失败了,可能的解决方案:
- 确保通过本文中的所有健全性检查
- 您可能没有足够的数据,因此请尝试对随机作物使用补丁方法。
- 添加更多正则化(dropout、BatchNormalization、InstanceNormalization、增加输入图像大小等)
推荐阅读
- c# - 处理无效演员表 - IList to List
- machine-learning - 期刊文章中报告了哪种准确性(培训或测试)?
- php - Laravel 使用键返回对象:值而不是对象数组
- c++14 - c++14中带有struct的模板特化
- c# - Visual Studio 项目安装程序未安装所有 dll
- vba - 无法从网页中收集不同属性的链接
- python - 在 Python 中,是否可以在另一个请求中模拟请求?
- python - 由其他数组索引numpy数组作为索引
- javascript - 不从 React 中的函数渲染 JSX
- python-3.x - 如何从 Python Matplotlib_venn 中的虚拟变量绘制维恩图?