多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

AI For Beginners 课程:用语义分割实现像素级图像分类(Segmentation 实战指南)

AI For Beginners 课程:用语义分割实现像素级图像分类(Segmentation 实战指南) 教程人工智能机器学习深度学习【免费下载链接】AI-For-Beginners12 Weeks, 24 Lessons, AI for All!项目地址https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners点击查看免费下载本指南基于 AI For Beginners 课程第 12 课「分割Segmentierung」展开完整讲解语义分割与实例分割的概念区别、编码器-解码器网络架构、分割任务特有的损失函数设计并带领读者基于 PH² 皮肤镜图像数据集训练真实的分割网络PyTorch 与 TensorFlow 双版本最后延伸到人体分割实战练习。读完本文你将理解分割网络输入图像 → 输出逐像素掩码的工作原理并能直接运行仓库中的 Notebook 复现训练流程。从目标检测到像素级分类为什么需要分割在 目标检测 任务中我们通过预测边界框bounding box来定位图像中的物体。但许多场景需要远比边界框精确得多的定位医学影像中需要标出病灶的精确轮廓自动驾驶需要区分道路与行人的每个像素。这种对图像中每个像素赋予语义标签的任务就是分割Segmentation。分割可以看作一种像素级分类Pixel Classification对于图像的每一个像素都要预测它的类别背景本身就是其中一类。根据输出粒度的不同分割算法分为两大类类别说明语义分割Semantic Segmentation只给出每个像素的类别不区分同一类中的不同个体。例如图片里有 10 只羊语义分割把所有羊都标成羊这一类。实例分割Instance Segmentation在像素分类的基础上把同一类别进一步拆分为不同实例。同样 10 只羊实例分割会区分出 10 个不同的对象。分割网络的统一结构Encoder-Decoder虽然存在多种分割神经网络架构但它们都遵循同一种结构。从某种意义上说这与你在自编码器课程中学到的结构非常相似——区别在于自编码器的目标是重构原始图像而分割网络的目标是重构一张掩码Mask图像。一个分割网络由两个部分组成编码器Encoder从输入图像中提取特征。通常由一系列卷积层与池化层构成逐级压缩空间尺寸、加深通道数。解码器Decoder将编码器提取的特征逐步上采样还原为与输入同尺寸的掩码图像其通道数等于类别数多类分割输出 one-hot 编码的多通道图二值分割输出单通道图。分割专用的损失函数交叉熵与 BCE在经典自编码器中我们用均方误差MSE衡量两张图像像素之间的相似度但在分割任务中目标掩码图像的每个像素代表的是类别编号沿第三维进行 one-hot 编码因此需要采用专门面向分类问题的损失函数——交叉熵损失Cross-Entropy Loss并对所有像素取平均。当掩码是二值的例如我们的痣分割案例只有病灶/背景两类则使用二值交叉熵损失BCEBinary Cross-Entropy Loss。✅ 补充知识one-hot 编码是一种把类别标签编码成长度等于类别数的向量的方法其中只有对应类别的位置为 1其余为 0。在分割任务中每个像素的类别标签都会被编码成这样的向量网络输出因此也自然地采用多通道表示。实战医学影像中的痣分割本课将训练一个网络从医学图像中识别人类色素痣Nävi即俗话说的痣。我们使用PH² 皮肤镜图像数据库PH² Database of dermoscopy images作为数据源共200 张图像分属三类典型痣typical nevus、非典型痣atypical nevus与黑色素瘤melanoma每张图像都配有对应的掩码精确勾勒出痣的轮廓我们要训练模型把任意一颗痣从背景中分割出来。这类技术尤其适合医学影像场景。除了皮肤病变分割你还能联想到哪些现实世界的应用例如遥感图像中的地物分割、自动驾驶场景解析、卫星云图分析等。动手实验两种主流分割架构仓库中提供了两个可直接运行的 Jupyter Notebook分别使用 PyTorch 与 TensorFlow 实现用于学习不同语义分割架构并观察它们的实际效果Semantic Segmentation PytorchSemantic Segmentation TensorFlow源码级解析一SegNet——最朴素的编码器-解码器SegNet是最简单的编码器-解码器架构编码器使用带卷积与池化的标准 CNN 逐级提取特征解码器使用带卷积与上采样的反卷积 CNN逐步还原分辨率同时依靠批归一化Batch Normalization来保证多层网络可以成功训练。从 PyTorch 实现 的代码可以看到它的完整结构class SegNet(nn.Module): def __init__(self): super().__init__() # Encoder: 3→16→32→64→128每级 ConvReLUBNMaxPool(2x2) self.enc_conv0 nn.Conv2d(in_channels3, out_channels16, kernel_size(3,3), padding1) ... self.pool0 nn.MaxPool2d(kernel_size(2,2)) # ... enc_conv1(16→32)、enc_conv2(32→64)、enc_conv3(64→128) # 瓶颈层128→256 self.bottleneck_conv nn.Conv2d(in_channels128, out_channels256, kernel_size(3,3), padding1) # Decoder: 双线性上采样 卷积256→128→64→32→1 self.upsample0 nn.UpsamplingBilinear2d(scale_factor2) ... self.dec_conv3 nn.Conv2d(in_channels32, out_channels1, kernel_size(1,1)) self.sigmoid nn.Sigmoid()PyTorch 版本的训练配置来自 Notebook 代码为device cuda:0 if torch.cuda.is_available() else cpu train_size 0.9 # 90% 用于训练 lr 1e-3 # Adam 学习率 weight_decay 1e-6 # 权重衰减 batch_size 32 epochs 30 model SegNet().to(device) optimizer optim.Adam(model.parameters(), lrlr, weight_decayweight_decay) loss_fn nn.BCEWithLogitsLoss()由于是二值掩码病灶/背景损失函数使用nn.BCEWithLogitsLoss()。训练循环按常规方式定义每个 epoch 中把图像与标签送入device计算损失后zero_grad → backward → step再用测试集在torch.no_grad()下评估 loss。Notebook 中 30 个 epoch 训练完成后train loss 约为 0.593、test loss 约为 0.577随后用(model(img) 0.5)的阈值化方式将网络输出转成二值掩码并可视化。TensorFlow 版本SemanticSegmentationTF.ipynb的 SegNet 是同样的思路用 Keras API 表达编码器为Conv2D BatchNormalization Activation(relu) MaxPool2D解码器为UpSampling2D(interpolationbilinear) Conv2D最终输出 1 通道超参数略有不同train_size 0.8 lr 3e-4 weight_decay 8e-9 batch_size 64 epochs 100 loss_fn losses.BinaryCrossentropy(from_logitsTrue) model.compile(lossloss_fn, optimizeroptimizer)训练日志显示 SegNet 的 val_loss 从第 1 个 epoch 的 0.696 逐步下降到第 100 个 epoch 的 0.445。源码级解析二U-Net——跳连带来的精度提升SegNet 结构很自然但它不是最精确的金字塔式 CNN 在压缩特征空间分辨率的同时丢失了空间精度导致重建时难以准确还原像素位置。这引出了在编码器与解码器卷积层之间建立跳连Skip Connections的思想即著名的U-Net架构。跳连在每个卷积层级把编码器提取的特征直接拼接到对应层级的解码器上帮助网络不丢失该层级来自原始输入的细节信息。仓库中的 U-Net 实现印证了这一点——解码器的输入通道数包含了拼接torch.cat进来的编码器特征# U-Net 解码器384 256(上采样后) 128(编码器第4层特征 cat3) self.dec_conv0 nn.Conv2d(in_channels384, out_channels128, kernel_size(3,3), padding1) ... # 前向传播中把上采样结果与同层级编码器输出拼接 d0 self.dec_bn0(self.dec_act0(self.dec_conv0(torch.cat((self.upsample0(b), cat3), dim1)))) d1 self.dec_bn1(self.dec_act1(self.dec_conv1(torch.cat((self.upsample1(d0), cat2), dim1))))在 PyTorch 版本中U-Net 与 SegNet 共用同一训练函数和 BCE 损失30 个 epoch 后 train loss ≈ 0.595、test loss ≈ 0.572。而在 TensorFlow 版本中100 个 epoch 后 U-Net 的 val_loss 降至0.1525远低于 SegNet 的 0.445直观体现了跳连对分割精度的提升。提示本课为了教学清晰使用了较简单的 CNN 编码器实际应用中 U-Net 的编码器也可以替换为更强的特征提取骨干例如 ResNet-50。更正式的评估指标Pixel Accuracy除了可视化对比目标掩码与预测掩码分割模型还有正式的量化评估指标。其中最容易理解的是像素准确率Pixel Accuracy——被正确分类的像素所占的百分比即预测掩码与真实掩码逐像素比对后的正确率。作业挑战人体分割实战分割在视频制作中有典型应用例如天气预报节目经常需要把人像从摄像头画面中抠出来叠加到其他背景素材上。传统做法使用色度键chroma key技术——让被摄者站在纯色背景前拍摄再移除背景色。而在本课程的 lab 作业 中我们将改用神经网络模型直接切出人体剪影从 Kaggle 手动下载并解压Segmentation Full Body MADS Dataset包含 1192 张图像及其掩码打开启动 Notebook BodySegmentation.ipynb其代码展示了数据组织方式数据集目录下images/与masks/两个子目录存放同名文件plt.imread同时读取图像与掩码进行可视化示例输出为 512×384 的图像-掩码对复用本课学到的分割网络SegNet / U-Net完成训练与推理。人体分割只是面向人像图像的常见任务之一。另一类重要任务是骨架检测skeleton detection与姿态识别pose detection你可以尝试使用 OpenPose 库来观察姿态识别是如何实现的。总结分割是一种非常强大的图像分类技术它超越了边界框实现了像素级分类在医学影像等领域有着广泛应用。本课的核心要点可归纳为分割 逐像素分类语义分割不区分同类实例实例分割进一步拆分实例主流分割网络 编码器提特征 解码器生成掩码分割的损失函数是逐像素平均的交叉熵二值场景用 BCE而非 MSESegNet 是最简基线U-Net 通过跳连显著提升分割精度使用 PH² 数据集可完整复现皮肤病变分割训练流程并使用像素准确率评估效果。如需进一步探索可查看本课架构参考图 segnet.png 与 unet.png以及课程目录 4-ComputerVision 下的其他视觉任务章节。更完整的课件与练习题可参阅仓库根目录 README.md。赞分享教程人工智能机器学习深度学习【免费下载链接】AI-For-Beginners12 Weeks, 24 Lessons, AI for All!项目地址https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners点击查看免费下载相关推荐AI-For-Beginners 语义分割实战指南从像素级分类到医学图像分割SegNet 与 U-Net 完整实现AI For Beginners 语义分割实战指南从像素级分类到医学图像分割SegNet 与 U Net 完整实现 本篇技术指南基于 AI For Beg教程人工智能机器学习深度学习语义分割实战指南用PyTorch实现像素级图像分类语义分割实战指南用PyTorch实现像素级图像分类 语义分割是计算机视觉中一种重要的像素级图像分类技术它能将图像中的每个像素分配到特定的类别。在深度学习领域示例工程教程AI-For-Beginners 图像分割实战指南从像素级分类到医学影像病变分割AI For Beginners 图像分割实战指南从像素级分类到医学影像病变分割 图像分割Segmentation是计算机视觉中比目标检测更进一步的任务教程人工智能机器学习深度学习上一篇终极指南5步使用Warp框架构建高性能社交媒体API下一篇Python 定时任务一行代码搞定schedule 库 repeat 装饰器完整教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表