【導語】
本文基於動手深度學習專案講解了FCN進行自然影象語義分割的流程,並對U-Net和Deeplab網路進行了實驗,在Github和谷歌網盤上開源了程式碼和預訓練模型,訓練和預測的指令碼已經做好封裝,讀者可以自行下載使用。
1 前言
使用的VOC資料集連結開放在文章中,預訓練模型已上傳Github,環境我使用,大家下載模型做預測即可。
程式碼連結:
https://github。com/lixiang007666/segmentation-learning-experiment-pytorch
使用方法:
下載VOC資料集,將 兩個資料夾放入到data資料夾下。
終端切換到目標目錄,執行檢視訓練
(torch) qust116-jq@qustx-X299-WU8:~/語義分割$ python train。py -h
usage: train。py [-h] [-m ] [-g GPU]
choose the model
optional arguments:
-h, ——help show this help message and exit
-m , ——model
輸入模型名字
-g GPU, ——gpu GPU 輸入所需GPU
選擇模型和GPU編號進行訓練,例如執行
預測需要手動修改中的模型
如果對FCN非常瞭解的,可以直接跳過(動手學深度學習)的講解到最後一部分。
2 資料集
VOC資料集一般是用來做目標檢測,在2012版本中,加入了語義分割任務。
基礎資料集中包括:含有1464張圖片的訓練集,1449的驗證集和1456的測試集。一共有21類物體。
PASCAL VOC分割任務中,共有20個類別的物件,其他內容作為背景類,其中紅色代表飛機類,黑色是背景,飛機邊界部分用米黃色(看著像白色)線條描繪,表示分割模糊區。
其中,分割標籤都是png格式的影象,該影象其實是單通道的顏色索引影象,該影象除了有一個單通道和影象大小一樣的索引影象外,還儲存了256個顏色值列表(調色盤),每一個索引值對應調色盤裡一個RGB顏色值,因此,一個單通道的索引圖+調色盤就能表示彩色圖。
原圖:
在這裡插入圖片描述
標籤:
在這裡插入圖片描述
挑選一張影象可以發現,單張影象分割類別不只兩類,且每張影象類別不固定。
3 全卷積神經網路
語義分割能對影象中的每個畫素分類。全卷積網路 (fully convolutional network,FCN) 採用卷積神經網路實現了從影象畫素到畫素類別的變換 。與我們之前在影象分類或目標檢測部分介紹的卷積神經網路不同,:這是透過中引入的轉置卷積(transposed convolution)層實現的。因此,輸出的類別預測與輸入影象在畫素級別上具有一一對應關係:給定空間維上的位置,通道維的輸出即該位置對應畫素的類別預測。
%matplotlib inline
import torch
import torchvision
from torch import nn
from torch。nn import functional as F
from d2l import torch as d2l
3。1 網路結構
全卷積網路先使用卷積神經網路抽取影象特徵,然後透過
卷積層將通道數變換為類別個數,最後再透過轉置卷積層將特徵圖的高和寬變換為輸入影象的尺寸。因此,模型輸出與輸入影象的高和寬相同,且最終輸出的通道包含了該空間位置畫素的類別預測。
下面,我們使用在ImageNet資料集上預訓練的ResNet-18模型來提取影象特徵,並將該網路例項記為。該模型的最後幾層包括全域性平均匯聚層和全連線層,然而全卷積網路中不需要它們。
建立一個全卷積網路例項。它複製了Resnet-18中大部分的預訓練層,但除去最終的全域性平均匯聚層和最接近輸出的全連線層。
net = nn。Sequential(*list(pretrained_net。children())[:-2])
給定高度和寬度分別為320和480的輸入,的前向計算將輸入的高和寬減小至原來的
,即10和15。
X = torch。rand(size=(1, 3, 320, 480))
net(X)。shape
使用
卷積層將輸出通道數轉換為Pascal VOC2012資料集的類數(21類)。最後,我們需要將要素地圖的高度和寬度增加32倍,從而將其變回輸入影象的高和寬。
回想一下卷積層輸出形狀的計算方法:
由於
且
,我們構造一個步幅為
的轉置卷積層,並將卷積核的高和寬設為
,填充為
。
我們可以看到如果步幅為
,填充為
(假設
是整數)且卷積核的高和寬為
,轉置卷積核會將輸入的高和寬分別放大
倍。
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=64, padding=16, stride=32))
3。2 初始化轉置卷積層
將影象放大通常使用上取樣(upsampling)方法。雙線性插值(bilinear interpolation) 是常用的上取樣方法之一,它也經常用於初始化轉置卷積層。
為了解釋雙線性插值,假設給定輸入影象,我們想要計算上取樣輸出影象上的每個畫素。
首先,將輸出影象的座標 (,) 對映到輸入影象的座標 (′,′) 上。例如,根據輸入與輸出的尺寸之比來對映。請注意,對映後的 ′ 和 ′ 是實數。
然後,在輸入影象上找到離座標 (′,′) 最近的4個畫素。
最後,輸出影象在座標 (,) 上的畫素依據輸入影象上這4個畫素及其與 (′,′) 的相對距離來計算。
雙線性插值的上取樣可以透過轉置卷積層實現,核心由以下bilinear_kernel函式構造。限於篇幅,我們只給出bilinear_kernel函式的實現,不討論演算法的原理。
def bilinear_kernel(in_channels, out_channels, kernel_size):
factor = (kernel_size + 1) // 2
if kernel_size % 2 == 1:
center = factor - 1
else:
center = factor - 0。5
og = (torch。arange(kernel_size)。reshape(-1, 1),
torch。arange(kernel_size)。reshape(1, -1))
filt = (1 - torch。abs(og[] - center) / factor) * \
(1 - torch。abs(og[1] - center) / factor)
weight = torch。zeros((in_channels, out_channels,
kernel_size, kernel_size))
weight[range(in_channels), range(out_channels), :, :] = filt
return weight
用雙線性插值的上取樣實驗它由轉置卷積層實現。我們構造一個將輸入的高和寬放大2倍的轉置卷積層,並將其卷積核用bilinear_kernel函式初始化。
在全卷積網路中,我們用雙線性插值的上取樣初始化轉置卷積層。對於 1×1卷積層,我們使用Xavier初始化引數。
3。3 訓練
損失函式和準確率計算與影象分類中的並沒有本質上的不同,因為我們使用轉置卷積層的通道來預測畫素的類別,所以在損失計算中通道維是指定的。此外,模型基於每個畫素的預測類別是否正確來計算準確率。
def loss(inputs, targets):
return F。cross_entropy(inputs, targets, reduction=‘none’)。mean(1)。mean(1)
num_epochs, lr, wd, devices = 5, 0。001, 1e-3, d2l。try_all_gpus()
trainer = torch。optim。SGD(net。parameters(), lr=lr, weight_decay=wd)
d2l。train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs, devices)
4 開原始碼和Dataset
資料集下載地址:http://host。robots。ox。ac。uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012。tar
輸入樣本:
輸出樣本:
執行Segmentat_pytorch.ipynp:
訓練:
!python3 train。py -m Unet -g
預測:
模型程式碼包括FCN、U-Net和Deeplab的實現,大家可以更方便的更換模型訓練和預測。
DeeplabV3分割結果:
FCN分割結果:
在這裡插入圖片描述
U-Net分割結果:
記得點個Star哦!
5 總結
透過與分割標準影象的對比,可以發現該模型的輸出分割影象與分割標準影象幾乎一致,同時模型的輸出分割影象與原圖也較好的融合,說明該模型具有較好的準確性。
此外,從輸入影象大小來看,該模型可以輸入任意大小的影象,並輸出相同大小的已經標籤好的分割影象。由於是針對PASCAL VOC資料集影象進行的分割,PASCAL VOC資料集中只支援20個類別(背景為第21個類別),所以在分割時,遇到不在20個類別中的事物都將其標為背景。
但總體來說,該模型對PASCAL VOC資料集的影象分割達到了較高準確率。
6 參考
[1]。https://zh-v2。d2l。ai/index。html
個人簡介:李響Superb,CSDN百萬訪問量博主,普普通通男大學生,深度學習演算法、醫學影象處理專攻,偶爾也搞全棧開發,沒事就寫文章。
本文僅做學術分享,如有侵權,請聯絡刪文。