PyTorch作为当前最流行的深度学习框架之一,其torchvision库为计算机视觉任务提供了强大的支持。今天我们要探讨的是torchvision中语义分割(Semantic Segmentation)功能的实践应用,特别适合刚接触PyTorch的开发者。语义分割作为计算机视觉的基础任务,在自动驾驶、医疗影像分析、遥感图像处理等领域都有广泛应用。
与分类任务不同,语义分割需要对图像中的每个像素进行分类,这使其成为理解图像内容的重要技术手段。torchvision提供的预训练模型和标准化接口,让初学者能够快速搭建和训练自己的分割模型,而不必从零开始实现复杂的网络结构。
开始之前,我们需要准备以下环境:
安装核心依赖的最简命令如下:
bash复制pip install torch torchvision
对于希望使用GPU加速的用户,需要额外安装对应版本的CUDA和cuDNN。建议访问PyTorch官网获取与您系统匹配的安装命令。
torchvision支持多种标准数据集,对于语义分割任务,常用的有:
以PASCAL VOC为例,可以通过torchvision直接下载:
python复制from torchvision.datasets import VOCSegmentation
dataset = VOCSegmentation('./data', year='2012', image_set='train', download=True)
torchvision提供了多种语义分割模型,主要包括:
这些模型都在COCO或PASCAL VOC数据集上进行了预训练,可以直接用于迁移学习。
以DeepLabV3为例,这是目前性能较好的分割模型之一。其核心特点包括:
加载预训练DeepLabV3模型的代码如下:
python复制from torchvision.models.segmentation import deeplabv3_resnet50
model = deeplabv3_resnet50(pretrained=True, progress=True)
语义分割任务需要同时对图像和掩码进行变换。torchvision提供了Compose工具来组合多个变换:
python复制from torchvision import transforms
transform = transforms.Compose([
transforms.Resize((256, 256)),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])
对于掩码需要特别注意:
一个基础的训练循环包含以下关键步骤:
python复制import torch.optim as optim
criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
for epoch in range(num_epochs):
for images, masks in train_loader:
optimizer.zero_grad()
outputs = model(images)['out']
loss = criterion(outputs, masks)
loss.backward()
optimizer.step()
语义分割常用的评估指标包括:
实现Mean IoU的示例:
python复制def compute_iou(pred, target, n_classes):
ious = []
for cls in range(n_classes):
pred_inds = pred == cls
target_inds = target == cls
intersection = (pred_inds & target_inds).sum()
union = (pred_inds | target_inds).sum()
ious.append(float(intersection) / float(max(union, 1)))
return np.mean(ious)
语义分割任务通常需要精细调整学习率:
示例学习率调度器:
python复制scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
optimizer, T_max=num_epochs, eta_min=1e-5)
除了标准的交叉熵损失,还可以考虑:
组合使用多种损失的示例:
python复制loss = 0.5 * cross_entropy_loss(outputs, masks) + 0.5 * dice_loss(outputs, masks)
为了提升推理速度,可以对模型进行量化:
python复制quantized_model = torch.quantization.quantize_dynamic(
model, {torch.nn.Conv2d}, dtype=torch.qint8)
将模型导出为ONNX格式以便跨平台部署:
python复制torch.onnx.export(model, dummy_input, "model.onnx",
input_names=["input"], output_names=["output"])
当遇到GPU内存不足时,可以尝试:
对于某些类别样本极少的情况:
出现"破碎"的预测结果时:
掌握了基础语义分割后,可以进一步探索:
对于希望深入研究的开发者,建议从修改模型架构开始,例如尝试不同的backbone网络,或者设计自定义的decoder模块。