尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

FCN 全卷积语义分割网络实战:基于 PyTorch 的 fcn_resnet50 训练、多 GPU 加速与 mIoU 评估指南(deep-learning-for-image-processing)

发布时间:2026/9/30 1:49:26

资讯中心
01
ARTICLE

FCN 全卷积语义分割网络实战:基于 PyTorch 的 fcn_resnet50 训练、多 GPU 加速与 mIoU 评估指南(deep-learning-for-image-processing)

FCN 全卷积语义分割网络实战:基于 PyTorch 的 fcn_resnet50 训练、多 GPU 加速与 mIoU 评估指南(deep-learning-for-image-processing)
示例工程【免费下载链接】deep-learning-for-image-processingdeep learning for image processing including classification and object-detection etc.项目地址https://gitcode.com/gh_mirrors/de/deep-learning-for-image-processing点击查看免费下载本指南围绕 deep-learning-for-image-processing 仓库中 fcn 目录 的完整实现展开该目录基于 PyTorch 官方 torchvision 的 segmentation 模块源码整理可用于在 PASCAL VOC2012 上端到端完成 FCNFully Convolutional Networks语义分割模型的训练、多 GPU 分布式加速、验证评估与单图预测。读完本文你将掌握 FCN 的 ResNet 骨干 全卷积分类头 空洞卷积的核心原理、整套脚本的参数含义以及如何复现 70 mIoU 级别的 VOC 分割结果。一、项目概述与文件结构1.1 项目定位FCNFully Convolutional Networks for Semantic Segmentation是首个将端到端全卷积思想引入语义分割的经典工作其核心贡献是将分类网络末端的全连接层替换为卷积层从而对任意尺寸输入输出逐像素的稠密预测。本目录代码主要来自 PyTorch 官方 torchvision 模块中torchvision/models/segmentation的源码并在此基础上补齐了完整的 VOC 数据读取、训练、验证、预测流程。1.2 文件结构总览pytorch_segmentation/fcn/ ├── src/ # 模型 backbone 与 FCN 的搭建 │ ├── backbone.py # ResNet50/ResNet101支持 replace_stride_with_dilation │ ├── fcn_model.py # FCN 网络主体、FCNHead、IntermediateLayerGetter │ └── __init__.py # 导出 fcn_resnet50 / fcn_resnet101 ├── train_utils/ # 训练、验证及多 GPU 训练相关模块 │ ├── train_and_eval.py # train_one_epoch、evaluate、create_lr_scheduler、criterion │ └── distributed_utils.py# 分布式初始化、ConfusionMatrix 混淆矩阵、MetricLogger ├── my_dataset.py # 自定义 dataset 读取 VOC 数据集VOCSegmentation ├── train.py # 单 GPU/CPU 训练脚本默认 fcn_resnet50 Dilated/Atrous Convolution ├── train_multi_GPU.py # 针对使用多 GPU 用户的训练脚本 ├── predict.py # 简易预测脚本使用训练好的权重进行预测测试 ├── validation.py # 利用训练好的权重验证/测试数据的 mIoU 等指标 ├── get_palette.py # 从 mask 标签中提取调色板并生成 palette.json ├── transforms.py # 语义分割专用的数据增强RandomResize/Crop/Flip 等 ├── requirements.txt # 依赖环境 ├── pascal_voc_classes.json # PASCAL VOC 20 个类别标签文件 ├── palette.json # 预测时用于上色的调色板 ├── torch_fcn.png # Pytorch 官方实现的 FCN 网络框架图 └── results20210918-122740.txt # 示例训练日志含 mIoU 曲线数据1.3 运行环境配置README 明确建议的环境如下也可直接参考 requirements.txt项目要求Python3.6 / 3.7 / 3.8PyTorch1.10仓库实测环境为 torch1.13.1 torchvision0.11.1操作系统Ubuntu 或 CentOSWindows 暂不支持多 GPU 训练硬件最好使用 GPU 训练# requirements.txt 内容 numpy1.22.0 torch1.13.1 torchvision0.11.1 Pillow二、FCN 网络结构源码级解析2.1 网络组装fcn_resnet50 / fcn_resnet101src/fcn_model.py 中提供了两个模型构造函数二者仅在 backbone 深度上不同def fcn_resnet50(aux, num_classes21, pretrain_backboneFalse): backbone resnet50(replace_stride_with_dilation[False, True, True]) out_inplanes 2048 # layer4 输出通道 aux_inplanes 1024 # layer3 输出通道 return_layers {layer4: out} if aux: return_layers[layer3] aux backbone IntermediateLayerGetter(backbone, return_layersreturn_layers) aux_classifier None if aux: aux_classifier FCNHead(aux_inplanes, num_classes) classifier FCNHead(out_inplanes, num_classes) model FCN(backbone, classifier, aux_classifier) return model核心要点replace_stride_with_dilation[False, True, True]分别作用于 ResNet 的 layer2/layer3/layer4。前两个 stage 保持 stride2 下采样后两个 stage 用空洞卷积替换 stride从而在不额外降低分辨率的前提下扩大感受野这正是 FCN 常用 Dilated/Atrous Convolution 的由来详见 backbone.py 中_make_layer的dilate分支当dilateTrue时self.dilation * stride; stride 1即把下采样步长转嫁给 dilation 参数。return_layers{layer4: out, layer3: aux}通过IntermediateLayerGetter只保留 backbone 中需要的子模块并返回中间特征图。FCNHead(2048, num_classes)作为主分类头FCNHead(1024, num_classes)作为辅助分类头aux仅训练时使用。2.2 IntermediateLayerGetter特征图抽取器src/fcn_model.py 中的IntermediateLayerGetter是 torchvision 风格的模块包装器它按return_layers指定的映射从 backbone 中按注册顺序截取子模块并只保留到最后一个目标层为止前向时返回OrderedDictkey 为out/aux。注释中特别强调由于它依赖模块注册顺序同一个nn.Module不应在 forward 中被复用两次且只能直接获取model.layer4这类直接子模块。2.3 FCN 主体与 FCNHeadclass FCN(nn.Module): def forward(self, x): input_shape x.shape[-2:] features self.backbone(x) result OrderedDict() x features[out] x self.classifier(x) # 原论文中使用 ConvTranspose2d但权重是冻结的等价于 bilinear 插值 x F.interpolate(x, sizeinput_shape, modebilinear, align_cornersFalse) result[out] x # aux 分支同理 return resultFCNHead结构为3x3 卷积(降维到 in_channels//4) - BN - ReLU - Dropout(0.1) - 1x1 卷积其中 1x1 卷积将特征映射到num_classes通道实现逐像素分类。源码注释明确FCN 原始论文虽然使用 ConvTranspose2d 上采样但权重是冻结的实际等价于双线性插值因此这里直接用F.interpolate(..., modebilinear, align_cornersFalse)把分割图恢复到输入尺寸。2.4 网络框架图上图展示了 Pytorch 官方实现的 FCN 网络框架ResNet 骨干layer3/layer4 采用空洞卷积 FCNHead 全卷积分类头 双线性插值上采样恢复原分辨率是理解整个网络数据流的最佳直观材料。三、数据集准备PASCAL VOC2012本教程使用PASCAL VOC2012数据集包含 20 个前景类别 1 个背景类别共 21 类num_classes 1。下载地址http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tarREADME 提供需解压得到VOCdevkit目录。数据目录结构约定my_dataset.py 中硬编码的路径拼接VOCdevkit/ └── VOC2012/ ├── JPEGImages/ # 原图 .jpg ├── SegmentationClass/ # 语义分割标签 .png带调色板的索引图 └── ImageSets/ └── Segmentation/ ├── train.txt # 训练样本名列表 └── val.txt # 验证样本名列表3.1 VOCSegmentation 数据读取my_dataset.py 中的VOCSegmentation继承torch.utils.data.Dataset__getitem__读取 RGB 原图与 mask 标签二者均作为 PIL Image 返回交由 transforms 处理collate_fn通过cat_list将 batch 内不同尺寸的图 padding 到统一尺寸图像填充值为 0mask 填充值为 255255 在后续 loss 中被忽略详见下文year参数仅支持2007与2012对应VOCdevkit/VOC{year}目录结构。3.2 标签与调色板pascal_voc_classes.json 记录 20 个类别名与索引aeroplane1 ... tvmonitor20类别从 1 开始索引 0 保留给背景get_palette.py 从一张 VOC mask 中读取调色板转换为{索引: [R,G,B]}字典写入 palette.json供 predict.py 预测时对分割结果上色。四、训练实战4.1 训练前准备确保--data-path指向存放VOCdevkit文件夹所在的根目录注意不是 VOCdevkit 本身也不是 VOC2012确保预训练权重已就位。官方权重在 COCO 上预训练且只针对与 PASCAL VOC 相同的类别训练过因此类别数为 21含背景fcn_resnet50fcn_resnet50_coco-1167a1af.pthfcn_resnet101fcn_resnet101_coco-7ecb50ca.pth下载后务必重命名例如 train.py 中torch.load(./fcn_resnet50_coco.pth)读取的是fcn_resnet50_coco.pth而不是带哈希后缀的原文件名。4.2 单 GPU / CPU 训练直接运行 train.pypython train.py --data-path /你的/VOCdevkit/根目录parse_args 中完整命令行参数如下参数默认值说明--data-path/data/VOCdevkit 根目录--num-classes20前景类别数脚本内部自动 1 得到总类别数--auxTrue是否使用辅助分类器auxilier loss--devicecuda训练设备无 GPU 时自动回退 CPU-b/--batch-size4batch size--epochs30总训练轮数--lr0.0001初始学习率--momentum0.9SGD 动量--wd/--weight-decay1e-4权重衰减--print-freq10打印频率--resume断点续训权重路径--start-epoch0起始 epoch--ampFalse是否使用 torch.cuda.amp 混合精度训练4.3 训练主流程细节main 的执行链路数据VOCSegmentation(args.data_path, year2012, txt_nametrain.txt/val.txt)分别构建训练集与验证集num_workers min([os.cpu_count(), batch_size if batch_size 1 else 0, 8])自动限制并行加载线程数验证集固定batch_size1。模型与预训练create_model中若num_classes ! 21会删除所有包含classifier.4的权重键即 FCNHead 末端 1x1 分类卷积防止类别数不一致时load_state_dict报 shape 错误随后以strictFalse加载并打印 missing/unexpected keys。优化器分组backbone 与 classifier 两组参数使用基础lr若开启 auxaux_classifier参数使用lr * 10辅助分支学习率放大这是 train.py 中的常见做法。学习率调度create_lr_scheduler(optimizer, len(train_loader), args.epochs, warmupTrue)在 train_utils/train_and_eval.py 中实现——每个 step 更新一次而非每个 epoch先 warmup倍率因子从warmup_factor1e-3线性升到 1再按多项式策略(1 - progress) ** 0.9衰减到 0参考 deeplab_v2 的 Learning rate policy。损失函数criterion对 out 与 aux 两个输出分别计算cross_entropy(x, target, ignore_index255)最终loss out 0.5 * auxtrain_and_eval.py。ignore_index255用于忽略 padding 填充区域collate 时 mask 填 255。训练循环train_one_epoch内部每 step 调用lr_scheduler.step()若开启--amp则用torch.cuda.amp.autocastGradScaler做混合精度反向传播train_and_eval.py。日志与权重每个 epoch 将train_loss、lr及验证指标写入results{时间戳}.txt并在save_weights/目录保存model_{epoch}.pth包含 model、optimizer、lr_scheduler、epoch、argsamp 时还包含 scaler支持--resume断点续训。4.4 多 GPU 分布式训练对多 GPU 用户使用 train_multi_GPU.py# 使用 8 块 GPU torchrun --nproc_per_node8 train_multi_GPU.py # 指定 GPU 设备如只使用第 1 块和第 4 块 GPU CUDA_VISIBLE_DEVICES0,3 torchrun --nproc_per_node2 train_multi_GPU.pynproc_per_node为使用 GPU 数量CUDA_VISIBLE_DEVICES在指令前限定可见设备。该脚本在单机版基础上增加了以下能力对照 train_multi_GPU.py 源码新增参数默认值说明--sync_bnFalse是否开启跨卡同步 BatchNorm开启后训练速度变慢-j/--workers4数据加载线程数--output-dir./multi_train权重保存目录--world-size1分布式进程数--dist-urlenv://分布式初始化方式--test-onlyFalse仅测试不训练关键差异调用init_distributed_mode(args)初始化分布式环境使用DistributedSampler切分数据每 epoch 需train_sampler.set_epoch(epoch)打乱顺序DataLoader设置drop_lastTrue模型经DistributedDataParallel包装sync_bnTrue时先执行convert_sync_batchnorm日志写入与权重保存仅在主进程args.rank in [-1, 0]执行通过save_on_master保证多进程下只落盘一份优化器、学习率、amp、resume 逻辑与单机版一致其中--lr仍是单卡学习率总 batch size 为NGPU × batch_size。五、模型验证与指标评估5.1 使用 validation.py 计算 mIoUvalidation.py 基于验证集计算混淆矩阵与各指标。README 特别提示使用前务必保证验证集或测试集中包含每个类别的目标并且只需要修改--num-classes、--aux、--data-path和--weights其他代码尽量不要改动。python validation.py \ --data-path /你的/VOCdevkit/根目录 \ --weights ./save_weights/model_29.pth \ --num-classes 20 \ --aux True脚本加载fcn_resnet50(auxargs.aux, num_classesnum_classes)与权重取 checkpoint 中的[model]字段对验证集逐个样本前向输出格式化的混淆矩阵结果。5.2 ConfusionMatrix 指标计算原理distributed_utils.py 中的ConfusionMatrix用向量化方式统计像素级混淆矩阵k (a 0) (a n) # 只统计合法类别像素 inds n * a[k].to(torch.int64) b[k] # 将 (gt, pred) 编码为唯一索引 self.mat torch.bincount(inds, minlengthn**2).reshape(n, n)随后计算acc_global全局正确率 对角线像素和 / 总像素acc每类别准确率 对角线 / 行和真实像素数iu每类别 IoU 对角线 / (行和 列和 - 对角线)mean IoU全部类别 IoU 的均值。reduce_from_all_processes通过all_reduce汇总多卡统计结果。仓库自带的 results20210918-122740.txt 展示了示例训练日志随着 epoch 推进mean IoU从 epoch0 的 70.6 逐步爬升到 71global correct稳定在 93.4~93.6说明该配置可以在 VOC2012 验证集上稳定复现约 70 的 mIoU。六、单图预测与可视化predict.py 提供简易预测流程需要把weights_path设置为训练生成的权重路径aux False # 推理时不需要 aux_classifier classes 20 weights_path ./save_weights/model_29.pth img_path ./test.jpg palette_path ./palette.json预测主流程读取 palette.json 生成调色板列表构建fcn_resnet50(auxFalse, num_classes21)并从 checkpoint 中删除所有含aux的权重键后load_state_dict因为推理模型没有 aux 分支图像预处理Resize(520) - ToTensor - Normalize(mean(0.485,0.456,0.406), std(0.229,0.224,0.225))与训练/验证的均值方差一致并unsqueeze(0)扩出 batch 维model.eval()下先用一张全零图调用model(init_img)完成一次预热触发 BN 与 graph 初始化、避免首帧计时偏差再用time_synchronized()统计真实推理耗时取output[out].argmax(1)得到每像素类别索引转为 uint8 数组后mask.putpalette(palette)上色保存为test_result.png。七、数据增强细节transforms.py语义分割的数据增强必须同步作用于图像与 masktransforms.py 实现了这一点变换行为关键实现RandomResize(min,max)将图像最小边长随机缩放到[min,max]区间mask 用InterpolationMode.NEAREST最近邻插值防止类别值被插值污染RandomHorizontalFlip(p)按概率水平翻转图像与 mask 同步hflipRandomCrop(size)随机裁剪size×sizepad_if_smaller先对小于裁剪尺寸的图 padding图像填 0mask 填 255配合 loss 的ignore_index255忽略ToTensor图像转 float 张量、归一化到 [0,1]mask 转 int64 张量mask 不归一化Normalize(mean,std)按 ImageNet 统计量标准化图像仅作用于图像不作用于 maskget_transform 约定训练用base_size520, crop_size480先 RandomResize(260~1040) 再随机裁剪到 480×480验证用固定Resize(520,520)。八、常见问题与注意事项汇总预训练权重命名fcn_resnet50_coco.pth无哈希后缀训练脚本硬编码读取该文件名--data-path语义必须指向包含VOCdevkit文件夹的根目录脚本内部会拼接VOCdevkit/VOC2012/...自定义数据集若训练非 21 类任务create_model会自动删除classifier.4相关权重键避免 shape 冲突类别数传num_classes 1含背景推理与训练模型结构差异预测时auxFalse并剔除 aux 权重因此训练时建议保留--aux True以提升精度推理时无需辅助分支Windows 限制多 GPU 训练不支持 Windows仅支持 Ubuntu/CentOSmask 的 255 像素crop padding 与 collate padding 都会引入 255 值loss 通过ignore_index255忽略评估时ConfusionMatrix也只统计0 a n的像素指标解读global correct为全局像素准确率average row correct为逐类召回率IoU为逐类交并比mean IoU为最终汇总指标训练日志会逐 epoch 打印。结语通过本文你可以完整复现一条 FCN 语义分割的实战链路从 src/fcn_model.py 的空洞卷积 ResNet 骨干与全卷积分类头原理到 my_dataset.py 的 VOC 数据读取与 transforms.py 的同步增强再到 train.py / train_multi_GPU.py 的单机与分布式训练、validation.py 的 mIoU 评估以及 predict.py 的推理可视化。仓库中的 results20210918-122740.txt 日志可作为复现进度的对照基准。若想进一步深入理解 FCN 原理或代码细节README 也提供了对应的视频讲解详见 fcn/README.md 原文。赞分享示例工程【免费下载链接】deep-learning-for-image-processingdeep learning for image processing including classification and object-detection etc.项目地址https://gitcode.com/gh_mirrors/de/deep-learning-for-image-processing点击查看免费下载相关推荐U-Net 图像分割实战基于 deep-learning-for-image-processing 仓库的 DRIVE 视网膜血管分割与 PyTorch 训练部署指南U Net 图像分割实战基于 deep learning for image processing 仓库的 DRIVE 视网膜血管分割与 PyTorch 训练示例工程MXNet FCN-xs 语义分割实战基于 VGG16 的全卷积网络训练、参数初始化与推理全解析MXNet FCN xs 语义分割实战基于 VGG16 的全卷积网络训练、参数初始化与推理全解析 本文以 Apache MXNet 仓库中的 fcn xs 示深度学习机器学习人工智能Mask R-CNN 实例分割实战基于 deep-learning-for-image-processing 仓库的 COCO / Pascal VOC 训练、验证与部署指南Mask R CNN 实例分割实战基于 deep learning for image processing 仓库的 COCO / Pascal VOC 训练示例工程上一篇VoiceStudio 引擎验收指南TTS/ASR 新引擎从提案到合并的完整准入流程下一篇Lottery 分布式抽奖系统用简单工厂搭建发奖领域服务创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。