PyTorch : FCN によるセマンティック・セグメンテーション
作成 : (株)クラスキャット セールスインフォメーション
日時 : 07/24/2017
先に TensorFlow : FCN によるセグメンテーション で FCN (Fully Convolutional Network) モデルによるセマンティック・セグメンテーションの実験をしましたが、同様に PASCAL VOC2012 を題材として PyTorch 実装でも試してみます。
今回は FCN のスキップ・アーキテクチャの有無という視点ではなく、原論文どおりに FCN-8s, FCN-16s, そして FCN-32s それぞれのモデル実装を比較してみます。FCN-8s をベースとしてこれらの違いは decoder でスキップを行なう際の位置と数です。
また損失グラフと予想画像の表示のために visdom も使用します。
念のため PASCAL VOC 2012 について再度説明しておきますと、このデータセットは物体検出やセグメンテーション目的で標準的に利用されるデータセットです。セグメンテーションについては訓練セットが 1464 画像、検証セットが 1449 画像用意されていて総計 2,913 枚あります。クラスは以下の 20 ありますが (背景をカウントすれば 21) :
1=aeroplane, 2=bicycle, 3=bird, 4=boat, 5=bottle, 6=bus, 7=car , 8=cat, 9=chair, 10=cow, 11=diningtable, 12=dog, 13=horse, 14=motorbike, 15=person, 16=potted plant, 17=sheep, 18=sofa, 19=train, 20=tv/monitor
クラスの詳細については以下を参照してください :
以下は FCN-8s のケースのトレーニングによる予想画像の推移を示した例です。表示は PASCAL のラベル風にしてあります :
モデルとトレーニング
モデル
FCN の原論文 – Fully Convolutional Networks for Semantic Segmentation – では FCN-8s, FCN-16s, そして FCN-32s のサブモデルに分けられています。基本構造は共通で便宜上 encoder/decoder で分けて考えると、encoder は分類器として (完全結合層ではなく) 畳み込み層を使用した VGG-16 をベースとしており、decoder では upsampling を反復します。
この時 decoder でスキップ・アーキテクチャを導入して (encoder の) 浅い層の出力が反映されるようにするわけですが、ここでサブモデル間で違いがあります。FCN-8s では (VGG の) ブロック 3 と 4 の出力も反映し、FCN-16s ではブロック 4 の出力も反映します。FCN-32s では最終出力のみを使用します。その結果、最終ステップで upsampling する際のストライドが 8, 16, 32 になるためにそれぞれ FCN-8s, FCN-16s そして FCN-32s と呼称するようです。当然、FCN-32s が粗い結果になります。
トレーニング
トレーニングは訓練データセット (train) 上、各サブモデルについて 100 epochs 実行しました。以下の図は FCN-8s のトレーニングについて 1 epoch ずつ visdom でグラフ表示したものですが他のサブモデルの場合も殆ど変わりません。
0 epoch; y-軸区間 : [0, 6] | 10 epochs; y-軸区間 : [0, 0.8] |
![]() | ![]() |
50 epochs; y-軸区間 : [0, 0.5] | 100 epochs; y-軸区間 : [0, 0.4] |
![]() | ![]() |
1 epoch ずつのグラフだと直感的に分かりにくいので、まとめてグラフ化したものが以下です :
FCN-16s も同様です :
結果
val データセットからの検証用画像 (飛行機、電車、ボート) を使用して予想画像の推移を見てみます。
FCN-8s
最初に FCN-8s について推移を細かく確認しましたが、上の損失グラフからも分かるように 20 epochs 程度で原型ができて 50 epochs 程度からは大きくは変化しません。
入力画像 | GT (正解ラベル) | 10 epochs |
![]() | ![]() | ![]() |
20 epochs | 50 epochs | 100 epochs |
![]() | ![]() | ![]() |
入力画像 | GT | 10 epochs |
![]() | ![]() | ![]() |
20 epochs | 50 epochs | 100 epochs |
![]() | ![]() | ![]() |
入力画像 | GT | 10 epochs |
![]() | ![]() | ![]() |
20 epochs | 50 epochs | 100 epochs |
![]() | ![]() | ![]() |
FCN-16s
続いて FCN-16s。20 epochs と 100 epochs の予想画像のみを示します。
GT | 20 epochs | 100 epochs |
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
FCN-32s
そして FCN-32s。粗いです。
GT | 20 epochs | 100 epochs |
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
まとめ
まとめとして、FCN-8s, FCN-16s, そして FCN-32s の 100 epochs における予想出力結果を比較してみます。
PASCAL VOC2012 の画像については明らかに FCN-8s が良いようです。
GT | FCN-8s | FCN-16s | FCN-32s |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
以上