PyTorch实现U-Net图像分割报错NameError: name 'val_iou' is not defined
问题现象
- 任务目标:基于U-Net网络对RUGD数据集执行图像分割任务
- 已完成前置工作:
- 安装
segmentation-models-pytorch等项目依赖 - 完成数据集加载、训练/验证集划分
- 配置数据增强策略
- 构建训练、验证集对应DataLoader
- 初始化以MobileNetV2为编码器的U-Net分割模型
- 定义像素准确率、mIoU两类分割评估指标
- 编写
fit训练循环核心函数
- 安装
- 报错表现:启动训练后,代码执行到
val_iou.append(val_iou_score/len(val_loader))语句时抛出NameError: name 'val_iou' is not defined,训练流程中断。
错误原因
该报错为Python变量作用域类基础错误,核心原因是执行append操作时,当前代码作用域内不存在名为val_iou的列表对象,常见诱因共三类:
- 编写指标存储逻辑时,仅初始化了训练集对应的
train_loss、train_acc、train_iou存储列表,漏写验证集IoU存储列表val_iou的初始化语句 val_iou初始化语句的缩进层级错误,比如写在了epoch循环内部、条件判断分支内,和append操作不在同一作用域- 存在变量名拼写错误,初始化时用了
val_ious、val_iou_list等其他命名,和append调用时的变量名不匹配
修复方案
- 定位到
fit函数内epoch循环启动前的指标初始化区块,和其余训练、验证指标的初始化保持同一缩进层级,补上val_iou的空列表初始化,参考实现如下:
def fit(model, train_loader, val_loader, criterion, optimizer, epochs, device): # 此处省略优化器、损失函数、设备挂载等前置初始化逻辑 # 所有epoch共用的指标存储列表统一在循环外初始化,注意缩进对齐 train_loss = [] train_acc = [] train_iou = [] val_loss = [] val_acc = [] val_iou = [] # 补上漏写的这行初始化即可解决未定义问题 for epoch in range(epochs): # 训练阶段逻辑 model.train() train_running_loss = 0.0 train_iou_score = 0.0 train_acc_score = 0.0 # 省略逐batch训练、指标累加代码 # 训练轮次结束后计算平均指标并存入列表 train_loss.append(train_running_loss/len(train_loader)) train_acc.append(train_acc_score/len(train_loader)) train_iou.append(train_iou_score/len(train_loader)) # 验证阶段逻辑 model.eval() val_running_loss = 0.0 val_iou_score = 0.0 val_acc_score = 0.0 # 省略逐batch验证、指标累加代码 # 验证轮次结束后计算平均指标并存入列表 val_loss.append(val_running_loss/len(val_loader)) val_acc.append(val_acc_score/len(val_loader)) val_iou.append(val_iou_score/len(val_loader)) # 该行不再抛出NameError
- 校验缩进层级:确保
val_iou = []的初始化位置在整个epoch循环的外部,不要写在for循环内部导致每轮重置列表,也不要写在if/else等可能不触发的分支内。 - 排查命名一致性:全局搜索
val_iou关键词,确保初始化、append调用、后续日志打印/绘图环节的变量名完全一致,避免拼写偏差。
内容的提问来源于stack exchange,提问作者Chris Kehl
相关产品推荐
相关产品推荐

