MATLAB SSD ResNet50迁移学习中小批量与验证损失为NaN问题求助
SSD ResNet50训练首轮损失为NaN问题排查方案
1 优先排查标注数据集问题
- 检查所有标注框是否存在无效值:比如宽/高为0、坐标为负、边界超出原始图像尺寸的标注,
boxLabelDatastore读取这类框时会在计算损失时触发除0/溢出,直接返回NaN - 检查单类别标注的标签名是否规范:不要使用特殊字符、空格,确认所有标注的类别ID都对应唯一的单类别,不存在漏标、空标样本
- 调用
countEachLabel(bldsTrain)检查训练集标注分布,确认没有样本的标注框为空
2 数据预处理逻辑校验
代码中用到的自定义augmentData和preprocessData函数是问题高发区:
- 确认
preprocessData中图像归一化逻辑是否正确:如果误将像素值缩放到了过大/过小范围(比如没有除以255,直接传入0-255的整数值给预训练网络),会导致激活值爆炸 - 确认预处理后的标注框是否还符合要求:图像缩放、裁剪后标注框有没有被截断为0值,坐标有没有和输入尺寸[300,300]匹配
- 可以运行以下代码校验预处理后的数据有效性:
for i=1:100 data = read(preprocessedTrainingData); bbox = data{2}; % 检查框是否有效 if any(bbox(:,3)<=0 | bbox(:,4)<=0 | bbox<0) disp(['第',num2str(i),'个样本存在无效标注框']); break end reset(preprocessedTrainingData); end
3 网络参数与训练配置修正
- 手动设置的第一层卷积权重为
1e-15的量级,权重过小会导致梯度消失,和梯度爆炸一样会触发NaN,删除自定义的权重初始化代码,直接用ssdLayers默认的预训练权重初始化即可 - 初始学习率1e-1对于ResNet50迁移学习来说过大,默认用1e-3即可,同时可以在trainingOptions中加上
'GradientThreshold',1,梯度超过1就截断,避免溢出 - 确认没有误改ssdLayers生成的默认锚框参数:如果锚框尺寸和数据集中的目标尺寸完全不匹配,会导致IOU计算出现极端值,触发损失NaN
4 运行环境校验
- 如果使用GPU训练,先切换成CPU跑2轮试试,部分老旧显卡的浮点计算精度问题会偶发NaN
- 确认MATLAB版本和Computer Vision Toolbox版本匹配,预训练ResNet50权重下载完整,没有损坏
内容的提问来源于stack exchange,提问作者KamalLagh
相关产品推荐
相关产品推荐

