新闻详情

新闻详情

首页 / 资讯中心 / 详情

动手学深度学习:Pascal VOC2012 语义分割数据集详解与 PyTorch/MXNet/Paddle 数据管线实战

发布时间:2026/9/30 1:59:24来源:尧图网络
动手学深度学习:Pascal VOC2012 语义分割数据集详解与 PyTorch/MXNet/Paddle 数据管线实战
人工智能深度学习机器学习教程【免费下载链接】d2l-zh《动手学深度学习》面向中文读者、能运行、可讨论。中英文版被70多个国家的500多所大学用于教学。项目地址https://gitcode.com/GitHub_Trending/d2/d2l-zh点击查看免费下载语义分割semantic segmentation是计算机视觉中像素级理解图像的关键任务与目标检测的“方形边界框”标注不同它对图像中每个像素都赋予一个语义类别标签。本文以《动手学深度学习》中文版仓库 chapter_computer-vision/semantic-segmentation-and-dataset.md 为主体系统讲解语义分割与图像分割、实例分割的区别并完整拆解最常用的Pascal VOC2012语义分割数据集的下载、解析、像素级标签映射、随机裁剪预处理以及如何自定义VOCSegDataset数据集类并构建 DataLoader 数据管线。读完本文你将掌握一套可直接复用的语义分割数据集加载与预处理方案为后续训练 FCN 等全卷积网络见 chapter_computer-vision/fcn.md打下数据基础。语义分割从边界框到像素级标注在 chapter_computer-vision/bounding-box.md 至 chapter_computer-vision/rcnn.md 讨论的目标检测问题中我们始终使用方形边界框来标注和预测图像中的目标。而语义分割重点关注如何将图像分割成属于不同语义类别的区域它不仅要知道“图中有狗”还要精确回答“哪些像素属于狗”。因此语义分割的标注和预测都是像素级的其语义区域边界远比边界框精细。下图为语义分割中图像关于狗、猫和背景的像素级标签示意图像分割与实例分割计算机视觉领域还有两个与语义分割相似的重要问题需要与语义分割区分开来图像分割image segmentation将图像划分为若干组成区域通常利用像素之间的相关性。它在训练时不需要图像像素的标签信息在预测时也无法保证分割出的区域具有我们希望的语义。例如对上面的图像图像分割可能将狗分成两个区域一个覆盖以黑色为主的嘴和眼睛另一个覆盖以黄色为主的其余身体。实例分割instance segmentation也叫同时检测并分割simultaneous detection and segmentation研究如何识别图像中各个目标实例的像素级区域。与语义分割不同实例分割不仅需要区分语义还要区分不同的目标实例。例如图像中有两条狗时实例分割必须判断某个像素属于哪一条狗。简而言之三者的粒度递进关系是图像分割无语义、仅区域→ 语义分割有语义、不分个体→ 实例分割有语义、且分个体。Pascal VOC2012 数据集概览与下载Pascal VOC2012 是最重要的语义分割数据集之一。其 tar 文件大约 2GB下载可能需要一段时间解压后的数据集位于../data/VOCdevkit/VOC2012相对工作目录的data/VOCdevkit/VOC2012。《动手学深度学习》仓库通过d2l.DATA_HUB统一管理数据集下载。在 d2l/torch.pyd2l/mxnet.py、d2l/paddle.py中亦有同款注册中可以看到d2l.DATA_HUB[voc2012] (d2l.DATA_URL VOCtrainval_11-May-2012.tar, 4e443f8a2eca6b1dac8a6c57641b67dd40621a49)其中DATA_URL指向http://d2l-data.s3-accelerate.amazonaws.com/元组第二项是文件的SHA-1 校验和用于在下载前校验缓存文件是否完整见 d2l/torch.py 中download函数的实现。随后一行代码即可完成下载与解压voc_dir d2l.download_extract(voc2012, VOCdevkit/VOC2012)download_extractd2l/torch.py先调用download下载再按扩展名解压 zip/tar 文件最后返回../data/VOCdevkit/VOC2012目录路径。数据集目录结构与读取函数进入VOCdevkit/VOC2012后可以看到数据集的不同组件目录/文件作用ImageSets/Segmentation/train.txt、val.txt列出用于训练和测试的样本文件名JPEGImages/存储每个样本的输入图像.jpgSegmentationClass/存储每个样本的像素级标签.png标签同样采用图像格式尺寸与其标注的输入图像相同标签中颜色相同的像素属于同一个语义类别。原文档定义了read_voc_images函数将所有输入图像和标签读入内存以 PyTorch 版本为例d2l/torch.py的 read_voc_images 中已收录同款实现def read_voc_images(voc_dir, is_trainTrue): 读取所有VOC图像并标注 txt_fname os.path.join(voc_dir, ImageSets, Segmentation, train.txt if is_train else val.txt) with open(txt_fname, r) as f: images f.read().split() features, labels [], [] for i, fname in enumerate(images): features.append(torchvision.io.read_image(os.path.join( voc_dir, JPEGImages, f{fname}.jpg))) labels.append(torchvision.io.read_image(os.path.join( voc_dir, SegmentationClass, f{fname}.png), torchvision.io.image.ImageReadMode.RGB)) return features, labels train_features, train_labels read_voc_images(voc_dir, True)该函数的要点is_trainTrue读取train.txt否则读取val.txt文本文件每行一个不带扩展名的样本名输入图像从JPEGImages以.jpg读取标签从SegmentationClass以.png读取PyTorch 版本使用torchvision.io.read_image得到(C, H, W)张量并用ImageReadMode.RGB强制标签按 RGB 三通道读取读取后用d2l.show_images可绘制前 5 个输入图像及其标签在标签图像中白色和黑色分别表示边框和背景其他颜色对应不同类别。像素级标签RGB 颜色映射与类别索引Pascal VOC2012 的标签图像使用 21 种 RGB 颜色值区分 21 个语义类别。原文档定义了VOC_COLORMAP与VOC_CLASSES两个常量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]] VOC_CLASSES [background, aeroplane, bicycle, bird, boat, bottle, bus, car, cat, chair, cow, diningtable, dog, horse, motorbike, person, potted plant, sheep, sofa, train, tv/monitor]两者按下标一一对应VOC_COLORMAP[i]的颜色代表VOC_CLASSES[i]类别。其中索引 0 的[0, 0, 0]纯黑是background索引 1 的[128, 0, 0]是aeroplane依此类推。为了把标签图像转换为逐像素的类别索引矩阵原文档定义了两个辅助函数PyTorch 版本见 d2l/torch.pydef voc_colormap2label(): 构建从RGB到VOC类别索引的映射 colormap2label torch.zeros(256 ** 3, dtypetorch.long) for i, colormap in enumerate(VOC_COLORMAP): colormap2label[ (colormap[0] * 256 colormap[1]) * 256 colormap[2]] i return colormap2label def voc_label_indices(colormap, colormap2label): 将VOC标签中的RGB值映射到它们的类别索引 colormap colormap.permute(1, 2, 0).numpy().astype(int32) idx ((colormap[:, :, 0] * 256 colormap[:, :, 1]) * 256 colormap[:, :, 2]) return colormap2label[idx]其原理是将 RGB 三通道值编码为一个 24 位整数(R * 256 G) * 256 B在一维长度为256^3的查找表中记录每个颜色对应的类别索引查询时同样编码像素的 RGB 值并索引查表即可一次性得到整张标签图的类别索引矩阵y。验证一下映射结果——在第一张样本图像中飞机头部区域的类别索引应为 1背景索引为 0y voc_label_indices(train_labels[0], voc_colormap2label()) y[105:115, 130:140], VOC_CLASSES[1]数据预处理固定尺寸随机裁剪而非缩放在之前的图像分类实验中如 AlexNet、GoogLeNet 章节通常通过再缩放图像使其符合模型的输入形状。但语义分割中这样做会带来问题预测的像素类别需要重新映射回原始尺寸的输入图像而这种映射在语义区域边界处可能不够精确。为避免该问题原文档采用将图像裁剪为固定尺寸的策略具体使用图像增广中的随机裁剪对输入图像和标签裁剪相同的区域。因为输入图像与标签在像素上一一对应只要用同一组裁剪参数两者的对齐关系就不会被破坏。voc_rand_crop函数实现了这一逻辑def voc_rand_crop(feature, label, height, width): 随机裁剪特征和标签图像 rect torchvision.transforms.RandomCrop.get_params( feature, (height, width)) feature torchvision.transforms.functional.crop(feature, *rect) label torchvision.transforms.functional.crop(label, *rect) return feature, label以 MXNet 版本d2l/mxnet.py 中有同款voc_rand_crop为例实现为image.random_crop得到裁剪矩形rect再用image.fixed_crop按同一矩形裁剪标签保证特征与标签严格对齐。对同一张图反复执行随机裁剪可观察到每次得到的区域都不同但特征与标签始终对应。自定义数据集类 VOCSegDataset原文档通过继承高级 API 提供的Dataset类自定义了语义分割数据集类VOCSegDataset。以 PyTorch 版本为例d2l/torch.py 中收录了同款实现class VOCSegDataset(torch.utils.data.Dataset): 一个用于加载VOC数据集的自定义数据集 def __init__(self, is_train, crop_size, voc_dir): self.transform torchvision.transforms.Normalize( mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) self.crop_size crop_size features, labels read_voc_images(voc_dir, is_trainis_train) self.features [self.normalize_image(feature) for feature in self.filter(features)] self.labels self.filter(labels) self.colormap2label voc_colormap2label() print(read str(len(self.features)) examples) def normalize_image(self, img): return self.transform(img.float() / 255) def filter(self, imgs): return [img for img in imgs if ( img.shape[1] self.crop_size[0] and img.shape[2] self.crop_size[1])] def __getitem__(self, idx): feature, label voc_rand_crop(self.features[idx], self.labels[idx], *self.crop_size) return (feature, voc_label_indices(label, self.colormap2label)) def __len__(self): return len(self.features)各组成部分的作用__init__构造时调用read_voc_images读取全部特征与标签对输入图像执行filter过滤与normalize_image标准化标签只过滤不标准化同时构建colormap2label映射表供__getitem__使用。normalize_image先将像素值从[0, 255]缩放到[0, 1]除以 255再用 ImageNet 的统计均值与标准差mean[0.485, 0.456, 0.406]、std[0.229, 0.224, 0.225]对 RGB 三个通道分别做标准化即(x / 255 - mean) / std。MXNet 与 Paddle 版本的实现思路相同只是img的通道排列略有差异。filter数据集中有些图像尺寸小于随机裁剪指定的输出尺寸这些样本无法被裁剪因此通过filter移除——只保留高和宽都不小于crop_size的图像PyTorch 版本中shape[1]、shape[2]对应 H、W。__getitem__返回索引idx对应的输入图像及其每个像素的类别索引。先对特征与标签执行同一组随机裁剪再对标签调用voc_label_indices完成 RGB→类别索引映射。__len__返回过滤后保留的样本数量。读取数据集构建 DataLoader 与整合函数指定随机裁剪输出形状为320 × 480高 × 宽即可分别创建训练集与测试集实例并看到各自保留的样本个数crop_size (320, 480) voc_train VOCSegDataset(True, crop_size, voc_dir) voc_test VOCSegDataset(False, crop_size, voc_dir)设批量大小为 64用高级 API 的 DataLoader 包装训练集。打印第一个小批量的形状会发现与图像分类或目标检测不同这里的标签是一个三维数组——因为语义分割的标签是像素级的类别索引图形状与输入图像一致只是通道上从 RGB 三通道变成了单通道类别索引batch_size 64 train_iter torch.utils.data.DataLoader(voc_train, batch_size, shuffleTrue, drop_lastTrue, num_workersd2l.get_dataloader_workers()) for X, Y in train_iter: print(X.shape) print(Y.shape) break这里的d2l.get_dataloader_workers()d2l/torch.py默认返回 4即使用 4 个进程并行读取数据MXNet 版本用last_batchdiscard丢弃不足一批的尾部样本PyTorch/Paddle 版本对应drop_lastTrue。最后原文档将上述所有组件整合为load_data_voc函数下载并读取数据集返回训练集与测试集两个迭代器def load_data_voc(batch_size, crop_size): 加载VOC语义分割数据集 voc_dir d2l.download_extract(voc2012, os.path.join( VOCdevkit, VOC2012)) num_workers d2l.get_dataloader_workers() train_iter torch.utils.data.DataLoader( VOCSegDataset(True, crop_size, voc_dir), batch_size, shuffleTrue, drop_lastTrue, num_workersnum_workers) test_iter torch.utils.data.DataLoader( VOCSegDataset(False, crop_size, voc_dir), batch_size, drop_lastTrue, num_workersnum_workers) return train_iter, test_iter在后续章节中的实际应用load_data_voc并非孤立存在——在 chapter_computer-vision/fcn.md 中训练全卷积网络FCN时直接复用了本节的数据管线指定batch_size32, crop_size(320, 480)高和宽都可被 32 整除便于 FCN 的下采样/上采样对齐随后调用train_iter, test_iter d2l.load_data_voc(batch_size, crop_size)即可开始训练。这也说明本节的随机裁剪方案正是为像素级预测任务量身设计的固定尺寸裁剪保证模型输入一致同时不破坏像素级标签的逐像素对齐关系。小结与练习小结语义分割通过将图像划分为属于不同语义类别的区域来识别并理解图像中像素级的内容语义分割最重要的数据集之一是 Pascal VOC2012由于语义分割的输入图像和标签在像素上一一对应输入图像会被随机裁剪为固定尺寸而不是缩放以保证逐像素对齐且无需反向重映射。练习如何在自动驾驶和医疗图像诊断中应用语义分割还能想到其他领域的应用吗回想图像增广见 chapter_computer-vision/image-augmentation.md中的描述图像分类中使用的哪种图像增强方法难以用于语义分割提示考虑哪些变换会破坏输入与标签的像素级对齐关系例如水平翻转之外的几何翻转类增广往往需要对标签施加完全相同的变换才能保持对齐。赞分享人工智能深度学习机器学习教程【免费下载链接】d2l-zh《动手学深度学习》面向中文读者、能运行、可讨论。中英文版被70多个国家的500多所大学用于教学。项目地址https://gitcode.com/GitHub_Trending/d2/d2l-zh点击查看免费下载相关推荐深入理解语义分割与Pascal VOC2012数据集深入理解语义分割与Pascal VOC2012数据集 什么是语义分割 语义分割Semantic Segmentation是计算机视觉领域的一项核心任务它人工智能深度学习机器学习教程深入理解语义分割与Pascal VOC2012数据集深入理解语义分割与Pascal VOC2012数据集 什么是语义分割 语义分割Semantic Segmentation是计算机视觉领域的一项重要任务它旨人工智能深度学习机器学习教程PaddlePaddle深度学习实战语义分割与数据集详解PaddlePaddle深度学习实战语义分割与数据集详解 引言 语义分割是计算机视觉领域的一项重要任务它能够对图像中的每个像素进行分类为图像理解提供了更精文档教程人工智能深度学习上一篇流媒体下载革命N_m3u8DL-RE如何重新定义你的数字内容保存体验下一篇如何将Lightning CSS与ESBuild完美结合前端构建工具链的终极优化指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

SpringBoot+SSM健身房管理系统实战:从架构设计到部署全解析 2026/9/30 3:59:57

SpringBoot+SSM健身房管理系统实战:从架构设计到部署全解析

最近把一套基于 Java SpringBoot SSM 的健身房管理系统重新整理了一遍,从数据库设计、后端接口到前端页面全部过了一遍,顺便把调试过程中踩到的坑都记录了下来。这套系统虽然叫“SpringBoot SSM”,但只要按模块拆开看,其实就是…

阅读更多 →
Model-Optimizer:AI模型瘦身三把刀——剪枝、量化、蒸馏协同优化实战 2026/9/30 3:59:56

Model-Optimizer:AI模型瘦身三把刀——剪枝、量化、蒸馏协同优化实战

1. 项目概述:这不是一个“安装驱动”的工具,而是一套模型瘦身手术刀“Model-Optimizer”这个名字乍一听容易让人联想到NVIDIA控制面板里那个被反复搜索却总也找不到的“优化选项”,或是Win10系统里消失的nvidia控制面板文件夹位置——但恰恰相…

阅读更多 →
SpringBoot+SSM健身房管理系统:从需求、表设计到核心代码全解析 2026/9/30 3:59:55

SpringBoot+SSM健身房管理系统:从需求、表设计到核心代码全解析

做过Java Web开发的人应该对SpringBoot加SSM这套组合不陌生,它在国内项目里出现的频率高到几乎成了标配。单看"健身房管理系统"这个名字,感觉就是一个普通的后台CRUD,但真正从需求捋到落地,涉及的业务细节和编码细节一点…

阅读更多 →
鉴相器相位提取:arctan与arctan2的工程区别与选择指南 2026/9/30 3:59:49

鉴相器相位提取:arctan与arctan2的工程区别与选择指南

最近在调试一个X波段的FMCW雷达前端,数字下变频之后用反正切函数提相位,结果在目标跨过零频的瞬间,相位曲线出现了离谱的跳变,数据直接没法看。排查了一晚上,最后定位到问题根源:我用的是一元反正切atan(Q/…

阅读更多 →
SpringBoot学生公寓管理系统源码拆解:从表结构到部署排错全攻略 2026/9/30 3:59:49

SpringBoot学生公寓管理系统源码拆解:从表结构到部署排错全攻略

学生公寓管理系统算得上Java Web里最经典的一类练手项目,需求清晰、角色分明、业务闭环完整,特别适合毕业设计和课程设计。配合SpringBoot来写,开发效率比过去SSH时代高出一大截,一个学生从零搭起来也就两三周的事。这个“springb…

阅读更多 →
Thrift跨语言RPC实战:从IDL设计到服务端选型与踩坑记录 2026/9/30 3:59:49

Thrift跨语言RPC实战:从IDL设计到服务端选型与踩坑记录

你们有没有遇到过这种场景:一个服务端用 Java 写得好好的,客户端突然来了个 Python 脚本要对接,后来又冒出个 Go 服务要调同一个接口。刚开始还能靠 RESTful 接口硬扛,JSON 来 JSON 去也能跑,可一旦接口字段多起来、调…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉