当前位置: 首页 > article >正文

用PyTorch和ResNet-18复现FCN语义分割:从预训练模型到像素级预测的完整流程

用PyTorch和ResNet-18构建FCN语义分割实战指南语义分割作为计算机视觉领域的核心技术正在自动驾驶、医疗影像分析等领域发挥越来越重要的作用。全卷积网络FCN作为语义分割的开山之作通过将传统CNN的全连接层替换为卷积层实现了端到端的像素级预测。本文将带您从零开始基于PyTorch框架和ResNet-18预训练模型构建一个完整的FCN语义分割系统。1. 环境准备与数据加载在开始之前我们需要准备好开发环境。推荐使用Python 3.8和PyTorch 1.10版本这些组合在稳定性和性能方面都有良好表现。以下是创建conda环境的命令conda create -n fcn python3.8 conda activate fcn pip install torch torchvision pillow matplotlib对于语义分割任务Pascal VOC2012是一个经典的数据集选择。它包含20个物体类别和1个背景类别共计21类。数据集中的每张图片都有对应的像素级标注。我们可以使用以下代码加载和预处理数据from torchvision.datasets import VOCSegmentation import torchvision.transforms as T transform T.Compose([ T.Resize((320, 480)), T.ToTensor(), T.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) target_transform T.Compose([ T.Resize((320, 480), interpolationT.InterpolationMode.NEAREST), T.PILToTensor() ]) train_dataset VOCSegmentation( root./data, year2012, image_settrain, downloadTrue, transformtransform, target_transformtarget_transform )注意在数据加载过程中确保图像和标注的尺寸完全一致这是语义分割任务的基本要求。同时对图像进行归一化处理时使用ImageNet的均值和标准差可以更好地利用预训练模型的优势。2. 模型架构设计FCN的核心思想是将传统CNN的全连接层替换为卷积层使网络能够接受任意尺寸的输入并输出对应尺寸的分割图。基于ResNet-18构建FCN时我们需要特别注意以下几点移除原始ResNet-18的最后两层全局平均池化和全连接层添加1×1卷积层将特征通道数调整为类别数使用转置卷积反卷积进行上采样恢复原始图像尺寸以下是模型构建的关键代码import torch import torch.nn as nn import torchvision.models as models class FCNResNet18(nn.Module): def __init__(self, num_classes21): super().__init__() # 加载预训练ResNet-18 resnet18 models.resnet18(pretrainedTrue) # 移除最后两层 self.feature_extractor nn.Sequential(*list(resnet18.children())[:-2]) # 1x1卷积调整通道数 self.classifier nn.Conv2d(512, num_classes, kernel_size1) # 转置卷积上采样 self.upsample nn.ConvTranspose2d( num_classes, num_classes, kernel_size64, padding16, stride32 ) # 初始化转置卷积为双线性插值 self._init_upsample() def _init_upsample(self): # 双线性插值核函数 factor (64 1) // 2 center factor - 1 og torch.arange(64).float() filt (1 - torch.abs(og - center) / factor).unsqueeze(1) kernel filt filt.t() # 应用到转置卷积权重 self.upsample.weight.data.copy_( kernel.expand(21, 21, 64, 64) ) def forward(self, x): x self.feature_extractor(x) x self.classifier(x) x self.upsample(x) return x提示转置卷积层的初始化对模型性能有重要影响。使用双线性插值初始化可以提供合理的起始点有助于模型更快收敛。3. 训练策略与技巧训练FCN模型时有几个关键点需要特别注意损失函数选择由于是像素级分类任务使用交叉熵损失函数学习率设置预训练部分使用较小学习率新增部分使用较大学习率评估指标除了整体准确率还应关注各类别的IoU交并比以下是训练过程的实现代码def train_model(model, train_loader, val_loader, num_epochs20): # 分离参数用于不同学习率 pretrained_params [] new_params [] for name, param in model.named_parameters(): if feature_extractor in name: pretrained_params.append(param) else: new_params.append(param) # 优化器设置 optimizer torch.optim.SGD([ {params: pretrained_params, lr: 1e-4}, {params: new_params, lr: 1e-3} ], momentum0.9, weight_decay1e-4) # 损失函数 criterion nn.CrossEntropyLoss(ignore_index255) for epoch in range(num_epochs): model.train() for images, masks in train_loader: images images.to(device) masks masks.to(device) # 前向传播 outputs model(images) loss criterion(outputs, masks.squeeze(1)) # 反向传播 optimizer.zero_grad() loss.backward() optimizer.step() # 验证阶段 model.eval() with torch.no_grad(): total_pixels 0 correct_pixels 0 for images, masks in val_loader: images images.to(device) masks masks.to(device) outputs model(images) _, preds torch.max(outputs, 1) # 计算准确率 correct_pixels (preds masks.squeeze(1)).sum().item() total_pixels preds.numel() accuracy correct_pixels / total_pixels print(fEpoch {epoch1}, Accuracy: {accuracy:.4f})在实际训练中我们可能会遇到以下常见问题及解决方案问题现象可能原因解决方案训练损失不下降学习率设置不当调整学习率或使用学习率预热验证准确率波动大批量大小不合适增大批量大小或使用梯度累积模型过拟合训练数据不足使用数据增强或正则化技术显存不足输入尺寸过大减小批量大小或使用混合精度训练4. 预测与结果可视化训练完成后我们需要对模型进行测试并将预测结果可视化。语义分割的结果通常以彩色掩码形式展示不同颜色代表不同类别。以下是预测和可视化的完整代码import matplotlib.pyplot as plt import numpy as np # VOC数据集颜色映射 VOC_COLORMAP [ [0, 0, 0], [128, 0, 0], [0, 128, 0], [128, 128, 0], [0, 0, 128], [128, 0, 128], [0, 128, 128], [128, 128, 128], [64, 0, 0], [192, 0, 0], [64, 128, 0], [192, 128, 0], [64, 0, 128], [192, 0, 128], [64, 128, 128], [192, 128, 128], [0, 64, 0], [128, 64, 0], [0, 192, 0], [128, 192, 0], [0, 64, 128] ] def predict_and_visualize(model, image_path): # 加载并预处理图像 image Image.open(image_path).convert(RGB) transform T.Compose([ T.Resize((320, 480)), T.ToTensor(), T.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) input_tensor transform(image).unsqueeze(0).to(device) # 预测 model.eval() with torch.no_grad(): output model(input_tensor) pred output.argmax(dim1).squeeze().cpu().numpy() # 转换为彩色掩码 h, w pred.shape mask np.zeros((h, w, 3), dtypenp.uint8) for i in range(h): for j in range(w): mask[i, j] VOC_COLORMAP[pred[i, j]] # 可视化 plt.figure(figsize(12, 6)) plt.subplot(1, 2, 1) plt.imshow(image) plt.title(Original Image) plt.axis(off) plt.subplot(1, 2, 2) plt.imshow(mask) plt.title(Segmentation Mask) plt.axis(off) plt.show()在实际项目中我们还需要考虑以下几点优化方向多尺度预测结合不同层次的特征图进行预测提升小物体检测效果条件随机场CRF后处理优化分割边界使结果更加精细注意力机制引入注意力模块让模型更关注重要区域数据增强使用更丰富的数据增强策略提升模型泛化能力5. 模型优化与部署当基础模型训练完成后我们可以进一步优化性能并考虑实际部署。以下是几个关键的优化方向模型量化通过减少模型参数的数值精度来减小模型大小和加速推理。PyTorch提供了简单的量化API# 动态量化 quantized_model torch.quantization.quantize_dynamic( model, {nn.Conv2d, nn.ConvTranspose2d}, dtypetorch.qint8 ) # 保存量化模型 torch.save(quantized_model.state_dict(), fcn_resnet18_quantized.pth)剪枝技术移除对模型输出影响较小的连接或通道减少计算量from torch.nn.utils import prune # 对卷积层进行L1非结构化剪枝 parameters_to_prune [ (model.feature_extractor[0], weight), (model.classifier, weight) ] prune.global_unstructured( parameters_to_prune, pruning_methodprune.L1Unstructured, amount0.2 # 剪枝20%的连接 )ONNX导出将模型转换为ONNX格式便于跨平台部署dummy_input torch.randn(1, 3, 320, 480).to(device) torch.onnx.export( model, dummy_input, fcn_resnet18.onnx, input_names[input], output_names[output], dynamic_axes{ input: {0: batch_size}, output: {0: batch_size} } )在实际部署时还需要考虑以下性能指标指标说明优化方向推理速度单张图片处理时间模型量化、剪枝内存占用模型运行时内存消耗减小输入尺寸、精简模型准确率mIoU指标模型结构调整、数据增强功耗设备运行功耗降低计算复杂度6. 进阶技巧与实战经验在多个实际项目中应用FCN后我总结出以下几点宝贵经验输入尺寸选择虽然FCN理论上可以处理任意尺寸输入但实际使用中建议保持训练和推理尺寸一致。常见的尺寸包括512×512、320×480等选择时需考虑显存限制和细节保留的平衡。类别不平衡处理语义分割数据集中经常出现严重的类别不平衡问题。可以通过以下方法缓解使用加权交叉熵损失函数在数据增强时针对少数类进行过采样采用Dice Loss或Focal Loss等特殊损失函数学习率调度策略相比固定学习率使用余弦退火或带热重启的学习率调度通常能获得更好效果from torch.optim.lr_scheduler import CosineAnnealingWarmRestarts scheduler CosineAnnealingWarmRestarts( optimizer, T_010, # 初始周期长度 T_mult2, # 周期倍增因子 eta_min1e-5 # 最小学习率 )混合精度训练使用AMP自动混合精度可以显著减少显存占用并加速训练from torch.cuda.amp import GradScaler, autocast scaler GradScaler() for inputs, labels in train_loader: optimizer.zero_grad() with autocast(): outputs model(inputs) loss criterion(outputs, labels) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()模型集成将多个FCN模型的预测结果进行集成可以进一步提升性能。常用的集成方法包括平均多个模型的预测概率投票法选择最可能类别使用不同结构的模型进行互补在医疗影像分割项目中我们通过调整FCN的转置卷积初始化策略将肝脏分割的Dice系数从0.82提升到了0.87。关键改进是采用了更适合医学图像特性的上采样初始化方式而非标准的双线性插值。

相关文章:

用PyTorch和ResNet-18复现FCN语义分割:从预训练模型到像素级预测的完整流程

用PyTorch和ResNet-18构建FCN语义分割实战指南 语义分割作为计算机视觉领域的核心技术,正在自动驾驶、医疗影像分析等领域发挥越来越重要的作用。全卷积网络(FCN)作为语义分割的开山之作,通过将传统CNN的全连接层替换为卷积层&…...

长时运行智能体的5种设计模式

两年来,“AI 代理"的主导形象一直是一个里面装着聪明循环的聊天窗口。你输入目标,代理调用一些工具,你看着 token 流式输出,当工作耗尽耐心或上下文窗口填满时你停止观看。这个范式带我们走了很远,但它有天花板。…...

孤舟笔记 并发篇三十 CompletableFuture到底是个啥?为什么说它是异步编程的王者

文章目录一、先说结论:CompletableFuture vs Future二、从 Future 的痛点说起三、链式回调:异步流水线四、任务组合:11>2五、异常处理:别让流水线崩盘CompletableFuture 全景回答技巧与点评标准回答加分回答面试官点评个人网站…...

PaddleOCR-VL-1.5:端到端文档解析与文本识别技术解析

1. 项目背景与技术定位PaddleOCR-VL-1.5是百度飞桨团队推出的新一代文档解析与文本识别解决方案。作为工业级OCR技术的集大成者,这个版本在传统文字识别能力基础上,重点强化了复杂版式文档的结构化解析能力。我在处理金融票据和医疗档案数字化项目时&…...

轻量化视频理解:自回归预训练框架实践

1. 项目概述:当视频理解遇上轻量化预训练在视频分析领域,传统方法往往需要消耗大量计算资源来处理时序信息。我们团队最近实现的这个轻量级框架,核心思路是通过自回归方式对视频历史信息进行高效嵌入,仅用单块消费级显卡就能完成预…...

Rolling Forcing算法在实时视频处理中的应用与优化

1. 项目背景与核心价值在实时视频处理领域,传统帧生成技术往往面临计算延迟与画面流畅度难以兼顾的困境。Rolling Forcing算法最初源于流体动力学仿真领域,其核心思想是通过动态权重分配实现计算资源的精准调度。2022年NVIDIA研究院首次将该算法引入视频…...

AI集成终端mediar-ai/terminator:下一代命令行智能辅助工具

1. 项目概述:一个面向未来的终端模拟器如果你和我一样,每天有超过一半的工作时间是在终端(Terminal)里度过的,那么你对终端模拟器的挑剔程度,可能不亚于程序员对键盘的选择。从早年经典的xterm、gnome-term…...

Nacrith:基于预训练语言模型的高效无损数据压缩方案

1. 项目背景与核心价值在数据爆炸式增长的时代,存储和传输成本已成为企业的重要负担。传统压缩算法如ZIP、GZIP等虽然成熟,但面对文本类数据的压缩率已接近理论极限。Nacrith项目的出现,正是为了解决这一痛点——它创新性地将预训练语言模型&…...

爬虫进阶必修课:从正则表达式到re.sub实战,手把手教你打造智能文本清洗引擎

目录 第一章:一个脏数据引发的血案 1.1 典型的“脏”长啥样 1.2 re.sub的初印象 第二章:re.sub的四种进阶用法(附真实案例) 2.1 基础版:批量干掉控制字符 2.2 进阶版:用回调函数实现动态替换 2.3 高阶版:使用分组引用反向构建 2.4 性能优化版:编译正则 + 批量替…...

从课后题到实战:手把手教你用Docker和Kubernetes搭建自己的第一个私有云环境

从课后题到实战:手把手教你用Docker和Kubernetes搭建自己的第一个私有云环境 当你在ICT课程中第一次听到"云计算"这个词时,脑海中浮现的可能是那些漂浮在天空中的服务器集群,或者是某个遥远数据中心里闪烁的机器。但云计算的核心概…...

TDD + DDD 双剑合璧:我是如何用测试驱动出清晰领域模型的

TDD DDD 双剑合璧:我是如何用测试驱动出清晰领域模型的 当业务需求像一团迷雾般模糊不清时,我们往往陷入两难:要么过早陷入技术实现细节,导致模型偏离业务本质;要么在抽象讨论中原地打转,迟迟无法产出可验…...

5.3小记1

现在已经爬取了猫途鹰上九寨沟风景区和澳门所有评论数量大于两百的景点的评论了,筛选条件是总评论数量大于两百,爬取数据是中文简体内容,所以数量实际并不多。而且九寨沟景区的景点并不仅仅有九寨沟风景区,这只是一个总的&#xf…...

[特殊字符]️ 从零到一:手把手教你用 re.findall() 打造智能爬虫(2026最新实战)

目录 一、前言:为什么 2026 年我还要写一篇关于 re.findall() 的爬虫文章? 二、 re.findall() 到底是什么? 2.1 一句话解释 2.2 re.findall() 三大返回值陷阱(90% 的新手都踩过) 陷阱一:有分组时,返回元组列表 陷阱二:嵌套分组,只捕获最内层 陷阱三:(?...) 非…...

DLSS Swapper终极指南:3步完成游戏性能优化,告别手动替换烦恼

DLSS Swapper终极指南:3步完成游戏性能优化,告别手动替换烦恼 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper 你是否曾在《赛博朋克2077》中为了提升几帧而翻遍游戏目录?是否在《控制…...

【RT-DETR涨点改进】TGRS 2026 |独家创新首发、下采样涨点改进篇| 引入MWHL最大池化-小波下采样,同时融合最大池化与小波变换的优势,助力红外小目标检测,遥感目标检测有效涨点

一、本文介绍 🔥本文给大家介绍使用 MWHL最大池化-小波下采样 改进RT-DETR网络模型,在下采样阶段同时融合最大池化与小波变换的优势,在保留强响应语义信息的同时有效维持特征的结构细节,从而缓解传统下采样过程中小目标特征易丢失的问题。该模块通过频域与空间域信息的协…...

多核处理器内存分区技术解析与工程实践

1. 多核处理器系统分区的核心挑战与设计哲学在嵌入式系统领域,我们正面临一个有趣的矛盾:一方面,现代设备的功能复杂度呈指数级增长,导致单个子系统规模不断扩大;另一方面,这些子系统又需要更紧密的集成协作…...

通过Python快速编写第一个调用Taotoken多模型聊天补全的程序

通过Python快速编写第一个调用Taotoken多模型聊天补全的程序 1. 准备工作 在开始编写Python程序调用Taotoken多模型聊天补全之前,需要确保已经完成以下准备工作。首先需要注册Taotoken账号并获取API Key。登录Taotoken控制台后,可以在API Key管理页面创…...

【RT-DETR涨点改进】TGRS 2026 |独家创新首发、特征融合改进篇| 引入HEWL小波特征融合模块,通道-空间-频域交互联合高频增强,助力红外小目标检测,多模态目标检测有效涨点

一、本文介绍 🔥本文给大家介绍使用 HEWL小波特征融合模块 改进RT-DETR网络模型,作用在于在特征融合与上采样阶段引入频域高频信息指导特征重建,使模型在检测过程中不仅关注语义信息,还能够有效保留目标的边缘与细节结构,从而提升对小目标和弱目标的表达能力。通过小波分…...

Cursor规则集:用AI代码助手实现团队编码规范自动化

1. 项目概述:当你的代码编辑器开始“思考”如果你是一名开发者,最近可能频繁听到一个词:Cursor。它不再仅仅是一个光标,而是一款正在悄然改变许多程序员工作流的AI代码编辑器。而今天要聊的,不是Cursor本身&#xff0c…...

基于强化学习的层次化知识检索系统设计与优化

1. 项目背景与核心挑战 大型语言模型(LLM)在知识检索任务中常面临层次化数据结构处理的困境。传统检索方式依赖静态索引和固定匹配模式,难以适应知识图谱、文档树等嵌套层级场景。我在实际项目中发现,当用户查询涉及"计算机科…...

XIAO双通道Wi-Fi电能表:家庭能源监控利器

1. 项目概述:XIAO双通道Wi-Fi交流电能表最近在折腾家庭能源监控系统时,发现Seeed Studio新推出的XIAO双通道Wi-Fi交流电能表是个很有意思的设备。这款基于ESP32-C6模组的电能表配备了两个100A电流互感器(CT钳),可以直接接入Home Assistant实现…...

稀疏计算优化LLM预训练:原理、技术与硬件加速

1. 稀疏计算在LLM预训练中的核心价值大型语言模型(LLM)预训练的计算瓶颈主要来自矩阵乘法运算。在Transformer架构中,前馈网络(FFN)模块占据了大部分计算量——随着模型规模增大,FFN的计算占比可高达总预训练浮点运算的50%以上。传统密集矩阵乘法需要处理…...

Agent 一接骨架屏页面就开始误判完成态:从 Readiness Signal 到 DOM Stabilization 的工程实战

浏览器 Agent 一进企业后台,最容易踩的坑往往不是页面太慢,而是页面看起来已经“加载好了”,实际仍停留在骨架屏、占位卡片和半成品 DOM。⚠️ 人类会等列表真实出现再点,Agent 如果只看到按钮可见、节点已挂载,就可能…...

A11y Bridge:为AI Agent实现毫秒级Android自动化交互

1. 项目概述:为AI Agent赋予“实时视觉”与“触手”在移动应用自动化测试和AI智能体交互领域,我们常常面临一个核心瓶颈:如何让运行在电脑上的程序“看见”并“操作”手机屏幕?传统的方法,无论是基于adb shell screenc…...

Flutter 跨平台实战:OpenHarmony 健康管理应用 Day3|页面路由跳转与多表单联动实现

🎯 Flutter 跨平台实战:OpenHarmony 健康管理应用 Day3|页面路由跳转与多表单联动实现 欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net 🚀 前言 大家好!本篇是我真实完成 Flutte…...

Agent 一接富文本编辑器就开始改错块:从 Selection Grounding 到 Undo Fence 的工程实战

很多团队以为 Agent 接上富文本编辑器后,剩下只是“把字打进去”。真到生产环境,事故常出在另一层:模型知道要改哪一句,人却只看到整篇文档被误覆盖。最常见的现象不是不会写,而是改错块、删错段、撤销失控。这类问题一…...

Agent 一接浏览器本地存储就开始串租户:从 Storage Namespace 到 Session Snapshot 的工程实战

很多浏览器 Agent 在演示环境里很稳,一进多租户后台就开始出现“登的是 B 账号,提交的却是 A 组织草稿”的事故。⚠️ 问题不在 DOM 识别,而在浏览器本地状态没跟任务边界一起清空。Cookie 已刷新,页面却仍会从旧的 localStorage、…...

2026年企业网站建设趋势:为什么说“移动优先”不再是可选项而是必选项?

2026年企业网站建设趋势:为什么说“移动优先”不再是可选项而是必选项?如果你今天还在问“我的网站需要适配手机吗”,你可能已经错过了两年的窗口期。2026年,超过65%的网站流量来自移动设备。谷歌早已全面采用移动优先索引——这意…...

如何在Windows上快速安装安卓应用:APK Installer完整免费指南

如何在Windows上快速安装安卓应用:APK Installer完整免费指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 想在Windows电脑上轻松运行安卓应用&#xff…...

5个理由告诉你为什么LyricsX是macOS上最智能的歌词伴侣

5个理由告诉你为什么LyricsX是macOS上最智能的歌词伴侣 【免费下载链接】LyricsX 🎶 Ultimate lyrics app for macOS. 项目地址: https://gitcode.com/gh_mirrors/ly/LyricsX 还在为找不到合适的歌词软件而烦恼吗?LyricsX作为一款专为macOS设计的…...