如第 14.9 節(jié)所述,語(yǔ)義分割在像素級(jí)別對(duì)圖像進(jìn)行分類。全卷積網(wǎng)絡(luò) (FCN) 使用卷積神經(jīng)網(wǎng)絡(luò)將圖像像素轉(zhuǎn)換為像素類( Long et al. , 2015 )。與我們之前在圖像分類或目標(biāo)檢測(cè)中遇到的 CNN 不同,全卷積網(wǎng)絡(luò)將中間特征圖的高度和寬度轉(zhuǎn)換回輸入圖像的高度和寬度:這是通過(guò) 14.10 節(jié)介紹的轉(zhuǎn)置卷積層實(shí)現(xiàn) 的. 因此,分類輸出和輸入圖像在像素級(jí)別具有一一對(duì)應(yīng)關(guān)系:任何輸出像素的通道維度都包含相同空間位置的輸入像素的分類結(jié)果。
%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。該模型
在這里,我們描述了全卷積網(wǎng)絡(luò)模型的基本設(shè)計(jì)。如圖 14.11.1所示,該模型首先使用 CNN 提取圖像特征,然后通過(guò)1×1卷積層,最后通過(guò) 14.10 節(jié)介紹的轉(zhuǎn)置卷積將特征圖的高度和寬度轉(zhuǎn)換為輸入圖像的高度和寬度。因此,模型輸出與輸入圖像具有相同的高度和寬度,其中輸出通道包含相同空間位置的輸入像素的預(yù)測(cè)類別。
下面,我們使用在 ImageNet 數(shù)據(jù)集上預(yù)訓(xùn)練的 ResNet-18 模型來(lái)提取圖像特征并將模型實(shí)例表示為 pretrained_net
。該模型的最后幾層包括全局平均池化層和全連接層:全卷積網(wǎng)絡(luò)不需要它們。
[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))
接下來(lái),我們創(chuàng)建全卷積網(wǎng)絡(luò)實(shí)例net
。它復(fù)制了 ResNet-18 中的所有預(yù)訓(xùn)練層,除了最終的全局平均池化層和最接近輸出的全連接層。
net = nn.HybridSequential()
for layer in pretrained_net.features[:-2]:
net.add(layer)
給定高度和寬度分別為 320 和 480 的輸入,正向傳播將net
輸入高度和寬度減小到原始的 1/32,即 10 和 15。
接下來(lái),我們使用一個(gè)1×1卷積層將輸出通道的數(shù)量轉(zhuǎn)換為 Pascal VOC2012 數(shù)據(jù)集的類數(shù) (21)。最后,我們需要將特征圖的高度和寬度增加 32 倍,以將它們變回輸入圖像的高度和寬度。回想一下7.3 節(jié)中如何計(jì)算卷積層的輸出形狀。自從 (320?64+16×2+32)/32=10和 (480?64+16×2+32)/32=15,我們構(gòu)造一個(gè)轉(zhuǎn)置卷積層,步幅為32,將內(nèi)核的高度和寬度設(shè)置為64,填充到16. 一般來(lái)說(shuō),我們可以看到對(duì)于 strides, 填充s/2 (假設(shè)s/2是一個(gè)整數(shù)),內(nèi)核的高和寬2s,轉(zhuǎn)置卷積將使輸入的高度和寬度增加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<
評(píng)論
查看更多