语义分割 - SegNet / DeconvNet

这篇博客详细介绍了SegNet和DeconvNet两种深度学习语义分割模型。SegNet利用编码器-解码器结构,通过保存最大池化索引来实现反池化,减少信息损失。DeconvNet则采用VGG-16作为编码器,解码器结合反卷积和反池化,并加入全连接层。两者的实现细节在SegNet.py和DeconvNet.py中给出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

论文精读

先验知识

编码器 - 解码器结构(Encoder - Decoder frame)

编码器结构:
由普通卷积层和下采样层将特征图尺寸缩小

解码器结构:
由普通卷积、上采样层和融合层组成,用来逐渐恢复空间维度,在尽可能减少信息损失的前提下完成同尺寸输入输出

随机丢弃层(Dropout)

当一个复杂的前馈神经网络被训练在小数据集上时,容易造成过拟合。Dropout通过忽略特征检测器来减少过拟合现象。

在这里插入图片描述

反池化(unpooling)

解码器中每一个最大池化层的索引都存储起来,用于之后在解码器中进行反池化操作。

  • 有助于保持高频信息的完整性
  • 对低分辨率的特征图进行反池化时,会忽略临近的信息

SegNet

本文创新点

  • SegNet 核心的训练引擎包括一个 encoder 网络和一个对称的 decoder 网络,即编码器 - 解码器结构
  • decoder 中直接利用与之对应的 encoder 阶段中最大池化时保留的 pooling index 来反池化

算法架构

在这里插入图片描述

DeconvNet

本文创新点

  • 编码部分使用 VGG-16 卷积层
  • 解码部分使用反卷积和反池化
  • 特殊方法:将 object proposal 送入训练后的网络,整幅图像是由 proposal 分割结果的组合,解决了物体太大或太小带来的分割问题

算法架构

DeconvNet 与 SegNet 的不同之处主要在于

  • 反池化与反卷积结合来形成 decoder
  • encoder 和 decoder 之间加入了全连接

在这里插入图片描述

算法实现

除了模型以外,其他部分与FCN无异

SegNet.py

导入包

import torch
import torchvision.models as models
from torch import nn

解码器中的卷积部分的定义

def decoder(input_channel, output_channel, num=3):
    if num == 3:
        decoder_body = nn.Sequential(
            nn.Conv2d(input_channel, input_channel, 3, padding=1),
            nn.Conv2d(input_channel, input_channel, 
### 如何使用SegNet进行Cityscapes数据集上的语义分割 #### Cityscapes 数据集简介 Cityscapes 是一个广泛使用的城市场景语义理解数据集,包含来自50个不同城市的高质量城市街景图像。该数据集主要用于自动驾驶场景下的语义分割任务[^2]。 #### SegNet 的基本原理 SegNet 是一种基于卷积神经网络(CNN)的深度学习模型,专为图像语义分割设计。其核心架构由编码器-解码器组成,能够通过多层卷积池化操作提取图像的高层次特征,并利用解码器将这些特征重新映射到原始图像分辨率,从而完成像素级分类任务[^3]。 #### 使用 PyTorch 实现 SegNet 并应用到 Cityscapes 数据集上 以下是实现 SegNet 进行 Cityscapes 数据集语义分割的一个教程示例: 1. **安装依赖库** 需要先安装必要的 Python 库,例如 `torch` `torchvision`。 ```bash pip install torch torchvision matplotlib pillow ``` 2. **加载 Cityscapes 数据集** 可以通过 `torchvision.datasets.Cityscapes` 加载 Cityscapes 数据集。 ```python from torchvision import datasets, transforms transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) cityscapes_train = datasets.Cityscapes( root='./data', split='train', mode='fine', target_type='semantic', transform=transform ) cityscapes_val = datasets.Cityscapes( root='./data', split='val', mode='fine', target_type='semantic', transform=transform ) ``` 3. **定义 SegNet 架构** 下面是一个简单的 SegNet 定义: ```python import torch.nn as nn import torch.nn.functional as F class SegNet(nn.Module): def __init__(self, input_channels=3, output_channels=34): # 输出通道数对应 Cityscapes 类别数量 super(SegNet, self).__init__() self.encoder_1 = nn.Sequential( nn.Conv2d(input_channels, 64, kernel_size=3, padding=1), nn.BatchNorm2d(64), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=2, stride=2, return_indices=True) ) self.decoder_1 = nn.Sequential( nn.ConvTranspose2d(64, output_channels, kernel_size=3, padding=1), nn.BatchNorm2d(output_channels), nn.ReLU(inplace=True) ) # 更复杂的编码器解码器可以在此处扩展... def forward(self, x): indices_list = [] sizes = [] # Encoder x, indices = self.encoder_1(x) indices_list.append(indices) sizes.append(x.size()) # Decoder out = F.max_unpool2d(x, indices_list.pop(), 2, 2, output_size=sizes.pop()) out = self.decoder_1(out) return out ``` 4. **训练过程** 训练过程中需要定义损失函数、优化器以及评估指标。 ```python model = SegNet() criterion = nn.CrossEntropyLoss() # 对于语义分割任务通常使用交叉熵损失 optimizer = torch.optim.Adam(model.parameters(), lr=0.001) num_epochs = 10 for epoch in range(num_epochs): model.train() total_loss = 0 for images, labels in train_loader: outputs = model(images) loss = criterion(outputs, labels.squeeze(1)) # 去掉多余的维度 optimizer.zero_grad() loss.backward() optimizer.step() total_loss += loss.item() print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {total_loss:.4f}') ``` 5. **验证与测试** 在验证集或测试集上评估模型性能。 ```python model.eval() with torch.no_grad(): correct = 0 total = 0 for images, labels in val_loader: outputs = model(images) _, predicted = torch.max(outputs.data, 1) total += labels.numel() correct += (predicted == labels).sum().item() accuracy = 100 * correct / total print(f'Validation Accuracy: {accuracy:.2f}%') ``` #### 结论 上述代码展示了如何使用 PyTorch 实现 SegNet 并将其应用于 Cityscapes 数据集上的语义分割任务。此方法同样适用于其他类似的编码器-解码器架构,如 FCN 或 U-Net[^1]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值