ひとことで言うと
セマンティックセグメンテーションは、入力画像の各画素 に対してクラス を予測するタスクです。画像全体を1ラベルに潰す分類や、矩形を返す検出とは異なり、出力は画像と同じ空間に並ぶクラス分布です。同じクラスの領域に属する画素は同じクラスとして扱い、個体までは区別しません。
画像を一枚の書類として判定するのではなく、地図の各マスに「道路」「建物」「空」の印を置いていく作業です。深い特徴は「何があるか」を読み、浅い特徴は「境界がどこか」を補います。
なぜ必要か
通常の画像分類器は、全結合層で空間の座標をまとめてしまい、最後に画像全体のクラスを出します。これでは「どの画素がそのクラスか」という密な出力を直接作れません。画素ごとに小窓を切り出して分類する方法も考えられますが、重なった小窓で同じ畳み込みを何度も計算します。
FCN(Fully Convolutional Network)は、全結合層を畳み込み層として読み替えます。すると固定サイズのベクトルではなく空間的なスコアマップになり、任意サイズの入力に対応した密な推論が可能になります。重なった受容野を画像全体でまとめて計算できるため、画素単位の学習・推論を効率よく行えます。
ただし、プーリングやストライドによるダウンサンプリングは計算量を抑える一方、出力マップの解像度を入力より粗くします。分類器をFCN化しただけでは、クラスは当たっても境界が大まかになる。この解像度の不足を埋めるのが、アップサンプリングと浅い層の情報です。
| 方式 | 出力の性質 | ボトルネック |
|---|---|---|
| 画像分類 | 画像全体のクラス | 画素の位置がない |
| 小窓分類 | 局所ごとのクラス | 重複計算が多い |
| FCN | 空間的な密な予測 | 粗い解像度の回復が必要 |
仕組み
画像を 、クラス数を 、画素 の正解クラスを とします。FCNの最終出力を (画素 における各クラスのスコア)とすれば、画素ごとの損失を足し合わせる定式化は次のように書けます。
はネットワークの学習パラメータ、 は画素 でのクラス のスコアです。重要なのは、損失が空間位置ごとの項の和になっていることです。全結合の単一出力ではなく、最終特徴マップの各セルに正解を対応させるので、順伝播も逆伝播も画像全体の密な計算になります。
全結合層は、入力領域全体を覆うカーネルを持つ畳み込みと見なせます。これを畳み込みへ置き換えると、入力が大きくなってもカーネルを空間方向へスライドさせて、複数位置のスコアを同時に出せます。これがFCN化で得られる「分類器をヒートマップ生成器に変える」効果です。
ダウンサンプリングで出力が 倍粗くなったとします。ここで は入力上の隣接画素が、粗い特徴マップでは何セルおきに対応するかを表すストライドです。粗いスコアを画素密度へ戻すには、転置畳み込み(原論文の呼称では deconvolution)を使えます。これは固定の補間に限らず、学習可能なフィルタとしてアップサンプリングを学習できます。
しかし、粗い特徴だけを大きく拡大しても、失われた細い境界は復元できません。そこで深い層の粗く意味的な情報と、浅い層の細かい見た目の情報をスキップ接続で融合します。深い予測をアップサンプリングし、同じ解像度にそろえた浅い層の予測を足し合わせる構造です。深い層は「何か」を、浅い層は「どこまでか」を担当するため、単純な一段アップサンプリングより空間精度を上げられます。
| 段階 | 空間解像度 | 役割 |
|---|---|---|
| 深い特徴 | 粗い | 広い受容野でクラスの意味を決める |
| 浅い特徴 | 細かい | 局所的な境界や位置を補う |
| 転置畳み込み | 拡大 | 粗い予測を画素密度へ写像する |
試験でどう問われるか
| 問われ方 | 正解に寄る条件 | 引っかけ |
|---|---|---|
| セマンティックセグメンテーションの出力 | 各画素のクラスを予測する | 画像全体の1クラスだけを返す |
| FCN化の意味 | 全結合層を畳み込みとして扱い、空間的な出力マップを得る | 全結合層を増やして画素数を直接出力する |
| ダウンサンプリング後の回復 | 転置畳み込みなどでアップサンプリングする | 粗い特徴をそのまま画素ラベルとみなす |
| スキップ接続の目的 | 深い意味情報と浅い細部情報を融合する | 深い層だけを使って境界を復元する |
| 定義上の限界 | 同じクラスの個体を区別しない | 個体ごとに別マスクを返すとする |
実装で確かめる
転置畳み込みの細かな実装はパディング規則にも左右されます。まずは、ストライドで粗くなったスコアマップを、画素ごとのクラススコアへ戻す形を配列の寸法で確認します。次のコードは、 クラスの粗い予測を 倍に最近傍拡大し、画素ごとの予測クラスを得る最小例です。学習可能な重みを持たせれば、これが転置畳み込みによる復元へ発展します。
import numpy as np
coarse = np.array([
[[2.0, 0.1, -1.0], [0.2, 1.5, 0.0]],
[[0.0, 0.4, 1.2], [1.1, 0.2, 0.0]],
]) # (粗いH, 粗いW, K)
r = 2
dense = np.repeat(np.repeat(coarse, r, axis=0), r, axis=1)
pred = dense.argmax(axis=-1)
print("coarse:", coarse.shape, "dense:", dense.shape)
print(pred)
この例の dense は補間の確認用で、境界の情報を新たに生みません。転置畳み込みではアップサンプリングのフィルタを学習し、画素単位の損失から逆伝播できます。さらに浅い特徴を加えるスキップ接続を置くと、拡大だけに頼らず、細部の予測を補正できます。
取り違えやすいもの
| 用語 | セマンティックセグメンテーションとの切り分け |
|---|---|
| 画像分類 | 画像全体にクラスを付ける。画素ごとの位置は出力しない |
| 物体検出 | 物体の存在と矩形などを出す。画素単位の領域は直接出さない |
| インスタンス分割 | クラスだけでなく個体ごとにマスクを分ける。Mask R-CNNはこちら側 |
| FCN | セマンティックセグメンテーションを密に解くためのネットワーク構成 |
| 転置畳み込み | 粗い特徴マップを空間方向に拡大する演算。タスク名ではない |
| スキップ接続 | 浅い層と深い層を結ぶ経路。アップサンプリングそのものではない |
想起チェック
セマンティックセグメンテーションは何を予測するか
各画素 のクラス を予測します。同じクラスの個体同士は区別しません。
全結合層を畳み込みに置き換えると何が変わるか
固定長の単一ベクトルではなく空間的なスコアマップを出せるため、任意サイズ入力に対する密な予測が可能になります。
転置畳み込みとスキップ接続の役割を分けると
転置畳み込みは粗いマップを拡大し、スキップ接続は深い層の意味情報へ浅い層の細部情報を融合します。前者だけでは、ダウンサンプリングで失った境界情報を十分に補えません。
インスタンスを区別しないことから生じる限界は
同じクラスの隣接する物体が別個体でも、セマンティックセグメンテーションの出力では同じクラス領域として扱われます。