FCN:只有convolution layer的語意分割先驅
FCN將fully-connected layer轉換為等義的convolution layer,使模型能夠接收完整影像。作者另外提出upsampling方法並結合skip connection使最終預測層大小能與輸入影像大小相同,對每個影像位置做物體分類。
FCN:只有convolution layer的語意分割先驅
論文重點
- 將fully-connected layers轉換為convolutional layer形成fully convolutional network(FCN)。
- FCN加上upsampling使得網絡能夠對input image每個pixel位置進行物體分類,形成semantic segmentation maps。
論文原文:Fully Convolutional Networks for Semantic Segmentation
在介紹這篇文章之前必須承認我跟這篇論文有點不對頻,常常一段話看很久不知道他在講什麼或為什麼要講,尤其是圖示的部份讓我有點抓不到要點。但這篇也是最近難得讀到把所有成功或失敗的嘗試都寫出來的文章,從科學知識共享的角度來說是非常棒的事情。發完牢騷後就進入正式介紹。
語意分割(semantic segmentation)是在像素層次上進行物體分類,比起只針對整張影像或部分區域進行分類的影像分類(image classification)或物體偵測(object detection)更為困難,不只要能夠辨識物體類別,還要能夠精準定位到像素層次。
CNN的結構特性是隨著網絡深度越深,layer的語意層次越高,但空間位置精細度越低。換句話說,深層layer的output maps雖然可以用來得知影像中是否有物體存在,卻很難用來定位物體確切的位置。
另一方面,CNN模型因為後面的fully-connected layer需要固定大小的輸入影像,讓能分析的區域受限。此外,Fully-connected layer捨棄空間資訊,將結果化約為一串機率數值,與需要精確空間訊息的語意分割作業背道而馳。
對上面的問題,這篇論文提出應對的方法:
- 將fully-connected layers轉為對等的convolution layers,使模型能接受各種大小的輸入影像,且能輸出保留空間資訊的probability maps。
- 利用skip connections與up-sampling將隨深度變小的feature maps重建為大小與輸入影像相同的probability maps。
Fully convolutional network (FCN)
在SPPnet論文中提到convolution layer可以接受各種大小的影像並輸出長寬比相似的feature maps,但是最後的fully-connected layer在定義上需要大小固定的輸入向量,使得CNN只能輸入固定大小的影像。
SPPnet或Fast RCNN設計spatial pyramid pooling layer或RoI pooling layer令模型無論輸入影像大小都輸出固定大小的特徵向量,FCN則使用不同套路。
FCN的概念是將fully-connected layer轉換為kernel size等於feature map size的convolution layer。
假設CNN最後一層convolution layer輸出維度是W × H × C。如果fully-connected layer輸出N個單元,則需要估計的參數量為W × H × C × N。
如果最後一層convolution layer後面接的是kernel size等於feature map size(也就是W × H × C)的convolution layer,假設這樣的kernels共有N個,則需要估計的參數數量也是W × H × C × N,和fully-connected layers一樣。
看下圖更直觀,fully connected layer最常見的畫法是下圖左側,輸入和輸出單元都攤平成一維,輸出單元連接每一個輸入單元。由於輸出單元連接所有輸入單元,調整輸入單元的空間位置不影響輸出值。假設把輸入單元堆疊成下圖右,這樣的表現形式就是一個kernel size等於整個輸入大小的convolution。

利用這個概念,這篇論文將fully-connected layer轉換為convolution layer,形成從頭到尾都是convolution layers的fully convolutional network(FCN)。一旦轉換為FCN,模型就能輸入各種大小的影像。而且藉由convolution的特性,相對空間資訊將被保留。
下圖是作者以AlexNet為基礎的示意圖。原本最後面的convolution layer維度為13 × 13 × 256,後面接上兩個1 × 1 × 4096(fc6、fc7)與一個1 × 1 × 1000(fc8)的fully-connected layers。這些fully-connected layers可以轉換為convolution layers:

- fc6改為使用kernel size為13 × 13 × 256且輸出4096個channels的convolution layer;
- fc7改為kernel size為1× 1 × 4096且輸出4096個channels的convolution layer;
- fc8改為kernel size為1× 1 × 4096且輸出1000個channels的convolution layer。
我們可以看到轉換後的FCN能接受完整影像,而所有feature maps(包含轉換為convolution layers的原fully-connected layers)的空間大小會隨著變動。原本最後的分類層是1000個元素的一維向量,每個元素代表特定物體類別出現的機率,轉換為FCN後的分類層每一個channel變成二維probability map,每一個元素相當於對應空間區塊出現特定物體的機率。
Upsampling回復失去的空間資訊
接下來的問題是CNN中的subsampling讓深層convolution layers的feature maps變小,即便convolution layer保留相對空間關係,但深層layers的空間資訊過於粗糙。
從這裡開始的討論作者是用VGG16舉例,下圖是我畫的原VGG16與轉換為FCN的FCN-VGG16示意圖,用上面介紹的FCN概念,fc6相當於kernel size為7 × 7 × 512、輸出4096個channels的conv6;fc7相當於kernel size為1 × 1 × 4096、輸出4096個channels的conv7。
Feature maps經過總共五層pooling layers不斷縮小,如果要用後面的預測層建立與影像大小相同的probability maps,就必須把feature maps放大。

平常如果使用stride為s的convolution layer(s為正整數),feature map大小會縮小約s倍。
如果要藉由convolution layer將feature map放大s倍,就像是使用stride為1/s的fractionally strided convolution,這種convolution又被稱為deconvolution。
Deconvolution這個名稱有點誤導,因為它只是將輸出層回復為輸入層大小,而不是去除convolution的效果。比較好的名稱是transposed convolution,把convolution看為矩陣乘法,回復大小相當於乘上轉置矩陣,之後有機會再細談。
相對於down-sampling縮小feature map,放大feature map可以利用up-sampling, deconvolution是一種up-sampling方法。
既然deconvolution是一種convolution,它的權重就可以經由網絡學習。然而作者實測發現有沒有讓網絡學習參數對結果影響不大,所以在FCN中的deconvolution只用bilinear kernel初始化,並沒有讓網絡學習更新參數值。用bilinear kernel初始化相當於對feature map用內插法進行up-sampling。
Skip connections結合淺層空間訊息
內插法雖然可以放大影像,但是產生的結果非常粗糙。對此,作者利用skip connections結合前一層、空間精細度比較高的feature maps,藉此產生同時具備深層語意資訊與淺層空間資訊的預測層。

結合淺層資訊示意圖。
依循這個想法,作者測試三種模型:
- FCN-32s
把最後conv7輸出的feature maps直接用stride為32的deconvolution放大後作為預測層。
- FCN-16s
在pool4後接上1 × 1 convolution轉換為預測層,將conv7的feature maps用stride為2的deconvolution放大後與前者相加,最後再用stride為16的deconvolution放大作為最終預測層。
- FCN-8s
在pool3後接上1 × 1 convolution轉換為預測層,將FCN-16的預測層用stride為2的deconvolution放大後與前者相加,最後以stride為8的deconvolution放大作為最終預測層。
作者有測試再結合更淺層layers的模型但是表現無法繼續提升。
下圖是三種模型的segmentation map,可以看到結合淺層資訊的FCN-16和FCN-8預測的結果都比FCN-32細緻,FCN-8又比FCN-16看起來更精確。

模型最終產出的segmentation map。
你可能跟我有同樣的疑惑
conv6是對pool5使用kernel size 為7的convolution layer,大小應該更小,和原始影像的關係不是32倍。
我一開始一直把FCN-32s等命名想成預測層放大32倍後是原始影像大小,且作者圖三也是這樣畫(雖然很巧妙地把沒有把convolution layer畫清楚),還寫著32 x。但這個命名的重點是32s後面的「s」,這個s是stride的意思,FCN-32s應該視作「使用stride為32的deconvolution的FCN」。這兩者有點差異,因為feature maps的大小會受到其他設定如padding影響。Deconvolution除了stride以外也要選擇對應的padding才能將結果回復為輸入大小。
FCN中作者沒有仔細計算padding,相對地,他們設定conv1第一個convolution layer的padding為100。這個設定使經過deconvolution放大的預測層不會剛好等於影像大小,而會稍微大一些。作者在預測層後面加上裁切層,把多出來的像素捨棄,使最終預測層與影像大小相同。
相同的邏輯,FCN-16s、FCN-8s是指「使用stride 為16或8的deconvolution的FCNs」。另外,裁切層也被用在pool4、pool3經過1 × 1 convolution後的feature maps,讓他們能夠和經過stride為2的deconvolution放大的預測層大小相同。
메타데이터
- post_id
- 6089d6e1343a
- slug
- fcn-只有convolution-layer的語意分割先驅-6089d6e1343a
- url
- https://medium.com/@lee.kevin.lin/fcn-%E5%8F%AA%E6%9C%89convolution-layer%E7%9A%84%E8%AA%9E%E6%84%8F%E5%88%86%E5%89%B2%E5%85%88%E9%A9%85-6089d6e1343a
- canonical_url
- https://medium.com/@lee.kevin.lin/fcn-%E5%8F%AA%E6%9C%89convolution-layer%E7%9A%84%E8%AA%9E%E6%84%8F%E5%88%86%E5%89%B2%E5%85%88%E9%A9%85-6089d6e1343a
- author_url
- https://medium.com/@lee.kevin.lin
- status
- ok
- fetched_at
- 2026-06-29 22:44:20