FCNを深く理解する

# この記事の対象者
- FCNとCNNの違いが分からない人
- どうしてU-Netのようなオートエンコーダでセマンティック・セグメンテーションできるのか分からない人

# 全結合層の問題
- 全結合層は、2次元以上あったデータを1次元(1列のデータ)に並び替えている
- 全てのデータを同じものとして捉えていた
- 画像は2次元の形状であり、1次元にしてしまうと2次元ならではの位置情報が抽出できない

**モチベーション : 1次元に並び替える全結合層を使いたくない！！**
これがのちの**「CNN」**という技術である

## CNNは生物学的過程から発想を得た！
人間の視覚がどのように畳み込みネットワークとしてモデル化されるか
> - 人間が物体を見る際に生じる経過を追ってみると、最初に物体から反射された光が目の奥の網膜に像を結ぶ。その後、視神経を通じて脳に刺激が達し、物体が何であるかを認識する。そのとき、**物体の像全体を一度に把握するのではなく、ある限定された領域ごとに像をスキャンするように認識する。この限定された領域を「局所受容野」と呼ぶ。**
- 局所受容野の光の刺激は、電気信号に変換されて脳に達し、そこで視覚認識に関係するニューロンが反応する。このニューロンには2種類あることが知られており、それぞれ**「単純型細胞」「複雑型細胞」**と名づけられている。
- **単純型細胞は、ある特定の形状に反応する細胞である。**さまざまな形状に反応する単純型細胞があり、それらが連携して活動することで複雑な形状の物体を認識する。
- 一方の**複雑型細胞は、形状の空間的なずれを吸収するような働きをする。**単純型細胞だけだと、ある形状の位置がずれると別の形状と見なすが、複雑型細胞は空間的な位置ずれを吸収し、同一形状と見なせるように働く。
 
[畳み込みネットワークの「基礎の基礎」を理解する　～ディープラーニング入門｜第2回](https://www.imagazine.co.jp/%E7%95%B3%E3%81%BF%E8%BE%BC%E3%81%BF%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AE%E3%80%8C%E5%9F%BA%E7%A4%8E%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%80%8D%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99/)の長い引用になってしまったが、これがめちゃくちゃイメージしやすかった。
要するに、ここでいう**「単純型細胞」が畳み込み層であり「複雑型細胞」がプーリング層である。**この2つの用語はこの後詳しく説明する。

# CNNの登場人物
- Convolutional Layer
    - 畳み込み層は画像処理や、自然言語処理などでよく見られる処理層で、役割は周辺情報を考慮した特徴抽出です。
    - 画像処理であれば、注目ピクセルの周囲1ピクセル、計3×3の情報を取り込むことによって位置情報や周囲のピクセルとの関係性を特徴として捉えることができます。
    - 畳み込み層によって出来た沢山の画像は、特徴マップ(feature map)と呼ばれます。
- Pooling Layer
    - 畳み込み層によって出来た特徴マップのサイズを削減する役割を持ちます。
    - 単に削減するだけなので、重みパラメータはありません。
    - プーリング層では、畳み込み層と同じようにフィルタが決められています。
    - 例えば、よく使われるMax Poolingであれば、そのフィルタが当てられている中から大きい値のみを抽出します。
    - つまり、3×3のプーリングであれば、サイズは1/9になる。
    - プーリングのメリットは、入力画像のズレに強くなることである。
    - 大きい値が多少ズレても、抽出される値はその大きい値なので結果に変わりはない。
- Fully Connected Layer
    - **Fully Convolutional Networkとは全くの別物です！！**
    - 全結合層とは、その名の通り前層と後層のニューロンが全て接続されている層のことを言います。 
    - o = Wi+b (iは入力、oは出力、Wは重み、bはバイアス項)
    - 「o」も「W」も「i」も行列データである
    - Wiの部分は「W」と「i」の内積（ドット積）
    - bは、Wiの結果が極端に小さな値でエラーになるとかを防ぐための保険みたいなもの
    - 行列同士の「Wi+b」みたいな演算のことを「Affine変換」という
    - **ただの(2行,2列)・(2行,2列)のような計算だと全結合とは言えない(答えも(2行,2列だから))**
    - **実際の全結合層では、１次元にして計算します。**
    - 例えば、(28,28,1)＝幅28×高さ28×1チャンネルのデータなら、一旦　28×28×1＝＞784のサイズの１次元・・以下のようなイメージにするわけです。
    - ここで、1次元になった1列のデータを重み(W)と内積するわけだが、その結果には2次元情報は失われている(先ほども紹介したが、だから全結合層を使いたくない)

## 全結合層には様々な言い方がある
- Fully Connected Layer
- FC Layer
- FC層
- Affine Layer (アフィン空間、アフィン写像から由来)
- Dense Layer (kerasなどで使われる)

# CNNの基本原理を細かく見ていく
- 一般的なDNN (例)
    - 入力、全結合層、ReLU、全結合層、ReLU、全結合層、ReLU、全結合層、SoftMax、出力
- CNN (例)
    - 入力、Conv、ReLU、Pooling、Conv、ReLU、Pooling、Conv、ReLU、全結合、ReLU、全結合、SoftMax、出力

CNNは最初の全結合層がなくなっている！一方で最後の方には全結合層(Affine層)が何回か出てくる。
CNNでは、畳み込み層(Convolutionレイヤ)で形状を維持するため、**画像などの形状を有したデータを正しく理解できる可能性が高まる。**

## Convolutional Layer
- 入力データにフィルタ（＝カーネルとも呼ばれる）を利用して畳み込み演算を行う。
- **入力画像とフィルタが似たような配置だった場合、乗算によってより数値が高くなり、画像の特徴として抽出できる仕組み。**
- **様々なフィルタを適用することで、各画像の様々な場所の特徴を捉えたフィルタ群が完成していく。**
- フィルタのサイズに厳密な決まりごとはないが、奇数かつ小さいサイズの方が精度が出るため、３×３や５×５がよく利用される。
- **ストライドを1から2や3に増やすことで、大雑把に畳み込み演算することになるため、出力サイズが小さくなり、処理が短時間になる一方で、画像の特徴を取りこぼす可能性がある。**
- 入力データの周りに固定データを合わせることで入力のサイズを大きくし、出力サイズを調整することができる。
-  これをパディングと呼び、**画像のはじの特徴も捉えることができる**、出力サイズが小さくなって演算ができなくなることを避けられる、といったメリットがある。
-  周辺を0で埋める**「ゼロパディング」**がよく利用されるが、この場合、**周辺が暗くなってしまう**。それを回避するために、周辺の画素数をそのまま外挿するパディング方法なども存在する。
-  入力時のデータ形状は [縦×横×チャネル数(色の数)] になる。
    -  **28×28のサイズのRGB画像であれば、 28 × 28 × 3　になる。**
-  3×3のフィルタを32枚、ストライド1、パディング1
を設定した場合、畳み込み処理後のデータのサイズは　**28 × 28 × 32**　となる。
- **畳み込み層の出力は、 [縦×横×フィルタ数] となる。**
- フィルタサイズ、ストライド、パディングの設定値によっては計算ができない場合もあるため、注意する。
- 10*10の入力画像に対してフィルタが３＊３でストライドを3にした場合だと割り切れないため、場合によってはエラーになる（ライブラリによっては自動で可能な部分だけ計算してくれるものもある）。
- 畳み込み層を2つ連続で続けるなど、レイヤーを増やすと、**１つ目に適用した結果に対して２回目の畳み込みをするため、より小さい特徴を捉えられるようになる。**
- ネットワークを深くして精度が上がった有名なネットワークもある（AlexNet,VGGなど）。
- **深くしすぎると勾配消失問題**が起きたり、過学習したりするという別の問題が発生するため、別途対処が必要になる。

### Conv層の後にReLUを使うことで…
**ReLUは正の値をそのまま出力し、マイナスの値は0にしてしまう関数。** 
**畳み込み処理後のデータは特徴が正の大きな値となって現れてくる。**
**そもそもマイナスの値である部分は特徴としてフィルタリングされなかった部分であるため、0にしてしまっても問題ない。**

## Pooling Layer
**汎化能力アップ**
プーリング層の出力には活性化関数を適用しない。活性化関数を使うと特徴を際立たせることになってしまい、ぼやかした意味がなくなってしまう。
プーリングの手法は、最大プーリングや平均プーリングが代表的。ただし、効果の違いなどまだ不明なことも残されている。

## その他
> 全結合とは違い、特的のユニット同士のみが結合されるため、局所的な特徴を学習できる。また、データの形状も特徴として捉えることができる。
1種類の画像(縦-横-チャネル)に対しては同一の重みとバイアスを共有し適用するため、似た特徴を捉えやすい。どこにあってもきちんと特徴を抽出できるようになる。また、パラメタが減り全結合層よりも計算時間が短縮できる。どちらも学習効率が良くなる効果が得られる。

参考 : [CNN（Convolutional Neural Network）を理解する](http://sagantaf.hatenablog.com/entry/2019/05/26/160401)


# CNNとFCNの違いってなに？
## Q1.Fully Convolutional Networkとは何か？
- **Semantic Segmentationにディープラーニングを使った最初の手法がFCN (Fully Convolutional Network)**
- **Semantic Segmentation**は画像をpixel単位でどのクラスに属するか分類する。そのため**Pixel-labeling**とも呼ばれる。
- 一般物体認識を行うニューラルネットワークでは、**入力ユニット数が入力画像のサイズ、出力ユニット数は分類するクラス数**だった
- Semantic Segmentationでは**出力ユニット数は画像サイズ×分類クラス数**(入力ユニット数は同様に画像サイズ)
- pixelごとにラベル付けされた教師データを与えて学習することで、**入力画像の各pixelがどのクラスに分類されるかの確率**を出力できるようになる。
- FCN (Fully Convolutional Network)は、CVPR 2015, PAMI 2016で発表された Fully Convolutional Networks for Semantic Segmentationで提案されたSemantic Segmentation手法。
- **FCNの大きな特長は、全結合層を持たず、ネットワークが畳み込み層のみで構成されていること。**
- つまり、**一般物体認識用のCNNをSemantic Segmentation用に改良したということ**
- 一般物体認識の畳み込みニューラルネットワークの**全結合層を1×1の畳み込み層に置き換えている。**
    - 本来だったら、全結合(Affine層)によって1次元のデータ列になるところを、FCNは**画像サイズが1×1(1pixcel)になるように無理やり畳み込んでいる**(=これすなわち、**フィルタの数分の特徴を示す値が抽出された**ということ=(フィルタの数だけ特徴量が取れた))
- 全結合層では、全pixelに対して接続しているノードごとに重みをかける処理を行っていた。これはつまり、**ノードの数だけ1×1の畳み込みを行う処理と同等である。**(参考: [全結合層（Affine）の仕組を、数式なしでざっくり整理してみた／ディープラーニング](https://arakan-pgm-ai.hatenablog.com/entry/2018/11/05/090000))
    - 要するに全結合層でやっていた計算と全く同じことをやっている、ただし、1×1の畳み込み層になるということは全結合層で出力されるのが(行列計算から導き出された)**数値**であるのに対して、FCNでは**畳み込まれた画像**(もはや1×1なら数値だが…)である。
- 特徴マップのサイズはMaxプーリングを経て小さくなっているため、入力画像H×Wに対して特徴マップのサイズはH/32×W/32になっている。

**結論 : FCNは一般物体認識用のCNNをSemantic Segmentation用に改良したものである。詳しくは、全結合層が1×1の畳み込み層になっただけである。(やっていることは同じ)**

## Q2.なぜオートエンコーダでセマンティック・セグメンテーションができるのか？
- U-Netの構造(skip-conectionを除いた大体の順番)
    - Conv層、Conv層、Conv層、Pooling層、Conv層、Conv層、Conv層、Pooling層、Conv層、Conv層、Conv層、Pooling層、Conv層、Conv層、Conv層、Pooling層、Conv層、Conv層、Conv層、up-conv層、Conv層、Conv層、Conv層、up-conv層、Conv層、Conv層、Conv層、up-conv層、Conv層、Conv層、Conv層、up-conv層、Conv層、Conv層、Conv層
- 旧知の通り、Affine層が一つもない
- 代わりにConv層になっている
- **FCNで畳み込みをしまくって最終的に1×1の畳み込み層になった(小さい特徴マップ)**
- この小さくなった特徴マップを**入力画像と同サイズにアップサンプリングしてpixel単位のクラス分類を行う。(アップサンプリング)**
- **アップサンプリングには逆畳み込み(up convolution/transposed convolution)という処理を施す。**
- 逆畳み込みのパラメータは畳み込みと似ており、kernel size, padding, strideにそれぞれpixel数を指定する。
- 逆畳み込みで実際に行われるのは、以下のように特徴マップを拡大してから畳み込む処理。
    - 特徴マップの各pixelをstrideで指定したpixel数ずつ空けて配置し
kernel size-1だけ特徴マップの周囲に余白を取り
paddingで指定されたpixel数だけ余白を削り
畳み込み処理を行う(**無理やり余白を作った状態で畳み込みをするから結果的に元の特徴マップよりも大きな特徴マップになる**)
- 各pooling層の特徴マップを足し合わせる
    - 特徴マップをアップサンプリングで入力画像と同サイズに拡大するだけでは**semantic segmentationの結果は物体の境界がぼやけたものとなる。**
    - 特徴抽出の最終層だけでなく、**途中のpooling層で出力される大きいサイズの特徴マップも活用する。**
    - **特徴マップのサイズは各層で異なる**ので、最終層の特徴マップから順にアップサンプリングで前の層と同サイズに拡大し、チャンネルごとに足し算する。

# 数学の用語確認
- 幾何学
    - 幾何学は、**図形や空間の性質について研究する数学の分野**である。
    - 人間に認識できる図形に関する様々な性質を研究する数学の分野としてとくに古代ギリシャにて独自に発達し、これらのおもな成果は紀元前300年ごろ**ユークリッド**によってユークリッド原論にまとめられた。
    - **三角形の合同定理，三平方の定理，円周角,線の方程式，円の方程式など**
    - **幾何学（ジオメトリー）の語源は「土地測量」であり**、起源は古代エジプトにまで遡ることができる。
    - 古代ギリシャの歴史家ヘロドトスの記録では、エジプトでは毎年春になるとナイル川が氾濫し、エジプトの砂漠に農耕を可能にする河土を運んでくるが、**去年の畑の境界線はすべて流れてしまう。古代エジプト人は死ぬと神前で「私は、隣人の土地を盗んだことはない」と誓わなければ冥界行きが許されなかったので、土地境界の正確な決定は重大問題であった。**そのため、印をつけた縄で**まっ平らになった土地を元どおり区割りする「縄張り師」と呼ばれた測量専門家集団**が現れ、土地測量術が発達した。現在、ピタゴラスの定理として知られている数学定理が、古代エジプトではすでに5000年前に経験則として知られ、縄張り師たちは3:4:5の比率で印をつけた縄を張って、畑の角の直角を取ったという。
- ユークリッド空間
    - **いつも数学で使っている1次関数、2次関数、3次関数の世界のこと**
    - 幾何学（ユークリッド幾何学）の場となる平面や空間、およびその高次元への一般化である。
    - 「ユークリッド的」という修飾辞は、これらの空間が非ユークリッド幾何やアインシュタインの相対性理論に出てくるような**曲がった空間ではない**ことを示唆している。
    - 現代的な観点では、ユークリッド空間は各次元に本質的に一つだけ存在すると考えられる。
    - **ユークリッド空間の「点」は実数からなる組**であり、**二点間の距離は二点間の距離の公式に従う**ものとして定まる。
    - **三次元ユークリッド空間の各点は三つの成分の座標で決定される。**
- 線形結合
    - **ベクトルの定数倍**と**その足し算**のことである。一次結合あるいは線型和とも呼ぶ。
    - いくつかのベクトルを組み合わせると他のベクトルを作ることができる。
    - 。例えば、2次元数ベクトルを例にとれば、**ベクトル v = (2, 3) と w = (1, 2) を用いて 2v + 3w のようにすれば、(7, 12) というベクトルを作ることができる。**
    - いくつかのベクトルを何倍かしたものを足し合わせたものを、それらのベクトルの線型結合というのである。
- アフィン空間
    - ユークリッド空間から絶対的な原点・座標と標準的な長さや角度などといった**計量の概念を取り除いたアフィン構造を抽象化した幾何学的構造**である。
    - ベクトル空間からどの点が原点であるかを忘れたものと考えることもできる。
    - 1次元のアフィン空間はアフィン直線、2次元のアフィン空間はアフィン平面と呼ばれる。
    - アフィン空間では点の差としてベクトルを得たり、点にベクトルを加えて他の点を得たりすることはできるが、点をくわえることはできない。また特に、どの点が原点を与えるのかを認識することができない。
    - 太郎さんは本当の原点 O が何処なのか知っていて、権兵衛さんは別の P と呼ばれる点が原点だと思っているという状況を想像してみよう。
    - 権兵衛さんは自分の思う a + b を求めるために、P から A へ矢印を引き、P から B へ別の矢印を引いてできる平行四辺形の対角線を考えることになる
    - 同様に、a と b（あるいはもっと多くの有限個のベクトルの集合）の任意の線型結合について評価を行ったとき、太郎さんと権兵衛さんは一般には異なる答えを導き出すことになる
    - その線型結合の係数の和が 1 であるような場合には、太郎さんと権兵衛さんの答えは一致する
    - 権兵衛さんは「アフィン構造」（つまり係数の和が 1 の線型結合として定義されるアフィン結合の値）しか知らないが、太郎さんは「線型構造」と「アフィン構造」の両方を知っているということにある。(詳しくは[アフィン空間](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%95%E3%82%A3%E3%83%B3%E7%A9%BA%E9%96%93))
- アフィン結合
    - ベクトル空間における線型結合の特別の場合であって、主に（ユークリッド空間などの）アフィン空間に対して用いられ、したがってこの概念はユークリッド幾何学において重要となる。
    - 与えられた体 K 上のベクトル空間 V において、その元 x1, …, xn の α1, …, αn を係数とする**アフィン結合とは、係数和が 1, つまり ∑n
i=1 αi = 1 を満たすような線型結合のこと**である。
- アフィン写像
    - 幾何学におけるアフィン写像（アフィンしゃぞう、英語: affine map）はベクトル空間（厳密にはアフィン空間）の間で定義される、**平行移動を伴う線型写像**である。
    - アフィン (affine) は**ラテン語で「類似・関連」を意味する** affinis に由来する。
- アフィン変換
    - **始域と終域が同じであるようなアフィン写像**はアフィン変換（アフィンへんかん、英語: affine transformation）と呼ばれる。
    - アフィン変換は線型変換（回転、拡大縮小、剪断（せん断））と平行移動の組み合わせである。
    - 有限次元の場合には、アフィン変換は適当な性質を満たす**行列 A とベクトル b を用いて表すことができる。**
    - ユークリッド空間内のアフィン変換は以下のような構造を保つ。
        - 共線性: （任意の）同一直線上にある3点のアフィン変換による像は、やはり同一直線上にある3点となる。
        - 線分比: 同一直線上にある3点 p1, p2, p3 に対して、比は変換後も変わらない。
    - 「アフィン変換とは平行移動と線形変換を組み合わせた変換」のこと。

## 【おまけ】行列の出力サイズは外×外
行列の出力サイズは、「2行3列」×「3行2列」なら「2行2列」になるみたいに、外側の数で決まります。

# 参考
- [CNN（Convolutional Neural Network）を理解する](http://sagantaf.hatenablog.com/entry/2019/05/26/160401)
- [畳み込みネットワークの「基礎の基礎」を理解する　～ディープラーニング入門｜第2回](https://www.imagazine.co.jp/%E7%95%B3%E3%81%BF%E8%BE%BC%E3%81%BF%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AE%E3%80%8C%E5%9F%BA%E7%A4%8E%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%80%8D%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99/)
- [畳み込みニューラルネットワーク](https://ja.wikipedia.org/wiki/%E7%95%B3%E3%81%BF%E8%BE%BC%E3%81%BF%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%A9%E3%83%AB%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF)
- [人工知能・機械学習でよく使われるワード徹底まとめ！](https://rightcode.co.jp/blog/information-technology/artificial-intelligence-machine-learning-word)
- [全結合層（Affine）の仕組を、数式なしでざっくり整理してみた／ディープラーニング](https://arakan-pgm-ai.hatenablog.com/entry/2018/11/05/090000)
- [幾何学](https://ja.wikipedia.org/wiki/%E5%B9%BE%E4%BD%95%E5%AD%A6#:~:text=%E5%B9%BE%E4%BD%95%E5%AD%A6%EF%BC%88%E3%81%8D%E3%81%8B%E3%81%8C%E3%81%8F%E3%80%81%E5%8F%A4%E4%BB%A3,%E6%95%B0%E5%AD%A6%E3%81%AE%E5%88%86%E9%87%8E%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82)
- [ユークリッド空間](https://ja.wikipedia.org/wiki/%E3%83%A6%E3%83%BC%E3%82%AF%E3%83%AA%E3%83%83%E3%83%89%E7%A9%BA%E9%96%93)
- [線型結合](https://ja.wikipedia.org/wiki/%E7%B7%9A%E5%9E%8B%E7%B5%90%E5%90%88)
- [アフィン空間](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%95%E3%82%A3%E3%83%B3%E7%A9%BA%E9%96%93)
- [アフィン結合](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%95%E3%82%A3%E3%83%B3%E7%B5%90%E5%90%88)
- [アフィン写像](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%95%E3%82%A3%E3%83%B3%E5%86%99%E5%83%8F#%E3%82%A2%E3%83%95%E3%82%A3%E3%83%B3%E5%A4%89%E6%8F%9B%E3%81%AE%E6%80%A7%E8%B3%AA)
- [ディープラーニングを基本から学ぶ　Part5 畳み込みニューラルネットワーク](https://qiita.com/nvtomo1029/items/601af18f82d8ffab551e)
- [FCN (Fully Convolutional Network)：ディープラーニングによるSemantic Segmentation手法](https://blog.negativemind.com/2019/03/11/semantic-segmentation-by-fully-convolutional-network/)