如第 14.9 節所述,語義分割在像素級別對圖像進行分類。全卷積網絡 (FCN) 使用卷積神經網絡將圖像像素轉換為像素類( Long et al. , 2015 )。與我們之前在圖像分類或目標檢測中遇到的 CNN 不同,全卷積網絡將中間特征圖的高度和寬度轉換回輸入圖像的高度和寬度:這是通過 14.10 節介紹的轉置卷積層實現 的. 因此,分類輸出和輸入圖像在像素級別具有一一對應關系:任何輸出像素的通道維度都包含相同空間位置的輸入像素的分類結果。
%matplotlib inline
import torch
import torchvision
from torch import nn
from torch.nn import functional as F
from d2l import torch as d2l
14.11.1。該模型
在這里,我們描述了全卷積網絡模型的基本設計。如圖 14.11.1所示,該模型首先使用 CNN 提取圖像特征,然后通過1×1卷積層,最后通過 14.10 節介紹的轉置卷積將特征圖的高度和寬度轉換為輸入圖像的高度和寬度。因此,模型輸出與輸入圖像具有相同的高度和寬度,其中輸出通道包含相同空間位置的輸入像素的預測類別。
圖 14.11.1全卷積網絡。
下面,我們使用在 ImageNet 數據集上預訓練的 ResNet-18 模型來提取圖像特征并將模型實例表示為 pretrained_net
。該模型的最后幾層包括全局平均池化層和全連接層:全卷積網絡不需要它們。
[Sequential(
(0): BasicBlock(
(conv1): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(downsample): Sequential(
(0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(1): BasicBlock(
(conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
),
AdaptiveAvgPool2d(output_size=(1, 1)),
Linear(in_features=512, out_features=1000, bias=True)]
(HybridSequential(
(0): Activation(relu)
(1): GlobalAvgPool2D(size=(1, 1), stride=(1, 1), padding=(0, 0), ceil_mode=True, global_pool=True, pool_type=avg, layout=NCHW)
(2): Flatten
),
Dense(512 -> 1000, linear))
接下來,我們創建全卷積網絡實例net
。它復制了 ResNet-18 中的所有預訓練層,除了最終的全局平均池化層和最接近輸出的全連接層。
net = nn.HybridSequential()
for layer in pretrained_net.features[:-2]:
net.add(layer)
給定高度和寬度分別為 320 和 480 的輸入,正向傳播將net
輸入高度和寬度減小到原始的 1/32,即 10 和 15。
接下來,我們使用一個1×1卷積層將輸出通道的數量轉換為 Pascal VOC2012 數據集的類數 (21)。最后,我們需要將特征圖的高度和寬度增加 32 倍,以將它們變回輸入圖像的高度和寬度。回想一下7.3 節中如何計算卷積層的輸出形狀。自從 (320?64+16×2+32)/32=10和 (480?64+16×2+32)/32=15,我們構造一個轉置卷積層,步幅為32,將內核的高度和寬度設置為64,填充到16. 一般來說,我們可以看到對于 strides, 填充s/2 (假設s/2是一個整數),內核的高和寬2s,轉置卷積將使輸入的高度和寬度增加s次。
num_classes = 21
net.add_module('final_conv', nn.Conv2d(512, num_classes, kernel_size=1))
net.add_module('transpose_conv', nn.ConvTranspose2d(num_classes, num_classes,
kernel_size<
評論