在上一篇文章中,介绍了如何在不使用 torchvision 模块的情况下,创建卫星图像的多通道数据集。现在,我们将继续创建一个简单的深度学习模型,用于卫星图像的语义分割。
下图来自 "卷积神经网络实现了从高分辨率无人机图像中高效、准确、精细地分割植物物种和群落 "的论文,我们要创建的U-Net模型与其类似,其中我们有 3 个压缩块contracting blocks和 3 个上采样块(也叫扩展块)upsampling blocks。让我们来详细了解一下。
U-Net 架构的第一部分是一组具有池化功能的卷积,它可以缩小图像分辨率(因此被称为压缩块),并创建额外的层来从原始图像中提取 "特征"。
如果我们放大第一和第二个收缩块(下图),就会发现每个块都由 2 个卷积(如蓝色箭头所示,在本例中内核大小为 3x3)和一个跨距为 2x2 的最大池化组成,从而将输入图像的大小减半(在本例中从 128x128 减小到 64x64)。此外,我们还可以看到在第一次卷积时(第一个蓝色箭头),层数从 3 增加到 64,这表明在第一次卷积时使用的内核数量是经过设计决定的。
为了建立一个更灵活的模型,我们将从定义一个表示这些收缩块的函数开始我们的代码, 如下所示。每次卷积后都会有一个批量归一化和一个非线性函数。最后,还有一个最大池化函数(stride=2),用于将输出分辨率减半。
def contract_block(in_channels, out_channels, kernel_size, padding):
contract = nn.Sequential(
torch.nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, stride=1, padding=padding),
torch.nn.BatchNorm2d(out_channels),
torch.nn.ReLU(),
torch.nn.Conv2d(out_channels, out_channels, kernel_size=kernel_size, stride=1, padding=padding),
torch.nn.BatchNorm2d(out_channels),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
)
return contract
contract_block 函数将接收输入信息,包括输入通道数(或层数)、输出通道数、内核大小和填充(如有必要)。为了在卷积阶段保持原始图像的分辨率(图下图),不丢失任何像素,填充是必要的。