Xception NetのBlockを使ったStacked Hourgrass Netを公開しています。

# Xception NetのBlockを使ったStacked Hourgrass Netを公開しています。

![アーキテクチャ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595605/611da7f1-def9-0d1d-6e73-5132a35184e8.png)

[https://github.com/tanreinama/XceptionHourgrass---PyTorch](https://github.com/tanreinama/XceptionHourgrass---PyTorch)

# Stacked Hourgrass Networkとは

Hourgrass＝砂時計。
Hourgrass Networkとは、砂時計の形に似て、中間の層での解像度を絞って結合した畳み込みニューラルネットワークのことを言います。
日本語の解説だと、[こちらの方のブログ](http://yusuke-ujitoko.hatenablog.com/entry/2017/07/22/000523)が詳しいかな。
要するに、画像の局所的な情報だけで無く、全体として何が写っているのかという情報を使うために、一度畳み込み層のサイズを小さくして、その後元に戻した結果を使おう、というアイデアです。

そして、二つ以上のHourgrass Networkを積み重ねて、それぞれの出力を使って最終的な結果とするのが、Stacked Hourgrass Networkです。

<img width="584" alt="Hourgrass Networkの論文より" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595605/8cce0477-52b8-e010-3be3-5f1a3af12dc5.png">
(図は論文からの引用)


[論文](https://arxiv.org/abs/1603.06937)によると、Stackedにすることで、最終的な性能と学習の収束が良くなっているようです。
人体のポーズを推定するOpenPoseや、[CenterNet](https://arxiv.org/pdf/1904.07850.pdf)等で使われているようですね。
CenterNetの[論文](https://arxiv.org/pdf/1904.07850.pdf)では、Object Detectionタスクにおいて、DLAやResNetよりも優れた結果を出しています。

<img width="802" alt="CenterNetの論文より" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595605/977df82f-9744-b314-0789-db1775e3adb9.png">
(表は論文からの引用)

# Xception Networkとは

Xception Networkは、画像認識用のニューラルネットワークのモデルで、日本語の解説だと、[こちらの方のブログ](https://qiita.com/woody_egg/items/3adc613e7717b6b5a260)が詳しいかな。
畳み込みニューラルネットワークにおいて、チャンネル間のマスクを分離することで、パラメーター数を減らしてやる（その分層の数だとかを増やせる）。そうすることで、同じ程度のパラメーター数で作ったその他のネットワークよりも性能がよい、というものになります。

<img width="378" alt="Xceptionの論文より" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595605/d1a5e902-ffbe-73ba-1a66-ea0a97e41a3a.png">
(図は論文からの引用)

# XceptionHourgrassNetとは

そして、私が作った[こちら](https://github.com/tanreinama/XceptionHourgrass---PyTorch)のニューラルネットワークは、Stacked Hourgrass Networkを、Xceptionで使っているBlockを使って組み立てたものになります。
用途としては、画像からマスク画像やヒートマップ画像を作るためのニューラルネットワークになります。
こういった用途では、入力と出力の両方が画像データとなるため、ニューラルネットワークの中を流れるデータが大きくなってしまい、あまり凝ったネットワークを作ると、学習時にモデルがGPUメモリに乗り切らなくなってしまいます。
そこで、Xceptionで使っているBlockを使うことで、ネットワークのパラメーター数を削減してやろう、と言うのが主眼になります。
個人的に使おうと想定している、特定の用途が念頭にあり、それに対して最適化されています。
具体的には、層の数が深い割に、各層でのチャンネル数がそれほどでも無い（96チャンネル）ため、割とシーンが限定される画像データ向けです。
出力チャンネル数は幾つでも可ですが、中間のチャンネルが少ないので、あまり多いチャンネルは出力出来ません（なので、Image Segmentationみたいな多クラスの出力は苦手）。

![アーキテクチャ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595605/611da7f1-def9-0d1d-6e73-5132a35184e8.png)

# なぜこれを作ったか

なぜこのニューラルネットワークを作ったかというと、元はXceptionをBackboneにしたU-Netとかを作るつもりだったんですね。
ところが、オリジナルのXception Networkでは、比較的早い段階で解像度を低下させて（19×19ピクセル）、その後で大量の畳み込み処理を行うように設計されています。
これは、クラス分類タスクにおいては良い結果をもたらしますが、画像のディテールが早期に失われると言うことを意味してもおり、今回のようなタスクには向いていないと思われます。
そこでいろいろ試してみた結果、Hourgrass Networkの構造を取り入れた形になった、と言う訳です。（一応、同じ程度のパラメーター数で作った、XceptionNetのBlockを直線的に繋げたネットワークよりも性能が良いことは確認しています）

# テスト学習

GitHubのページは[こちら](https://github.com/tanreinama/XceptionHourgrass---PyTorch)。
テストとしてMS-COCOデータセットから猫の画像を集めて学習させるコードも付いています。
学習手順については[次回](https://qiita.com/tanreinama/items/f688583199b4020ce4f4)に書こうと思います。

# Reference

1. XceptionHourgrass - PyTorch https://github.com/tanreinama/XceptionHourgrass---PyTorch
2. Alejandro Newell, Kaiyu Yang, and Jia Deng "Stacked Hourglass Networks for Human Pose Estimation" https://arxiv.org/pdf/1603.06937.pdf
3. Franc ̧ois Chollet "Xception: Deep Learning with Depthwise Separable Convolutions" https://arxiv.org/pdf/1610.02357.pdf
4. Xingyi ZhouUT, WangUC, Kr ̈ahenb ̈uhlUT Austin "Objects as Points" https://arxiv.org/pdf/1904.07850.pdf