リーダブルコードまとめ

1章

優れたコードとは

  • コードは、他の人が最短時間で理解できるように書かなければいけない
    • 短ければいいというわけではない(リスト内包表記等)
    • 読みやすいコードを書くことは、処理速度や設計等の他の目的とは競合しない

2章 名前に情報を詰め込む

  • 明確な単語を選ぶ
    • stopではなく、kill, resume, pause等のニュアンスが含まれる単語を選ぶ
    • ↑やりすぎないこと
  • 汎用的な名前は避ける
    • retval, util, tmp等(使う場合のは相応の理由がある場合のみ)
    • ループの際の単語もi, jではなくci, mi(ここではclub_i, members_iの意)等にする

抽象的な名前より具体的な名前を使う

  • ServerCanStart()
  • CanListenOnPort()

名前に情報を追加する

  • 値の単位を追加する(start_ms 等)
  • バグやセキュリティリスクになりそうな部分には属性を追加する(password->plaintext_password)

名前の長さ

  • スコープが小さければ短い名前でも良い(一眼でわかるから)
  • スコープが数画面に及ぶ変数には長くてもわかりやすい名前をつける)
  • 省略形を使う(プロジェクト固有の省略は避ける)
  • 不要な単語を消す(ConvertToString->ToString)

名前のフォーマットで情報を伝える

  • スネークーケース、キャメルケースの使い分け
  • クラス変数に""をつける(stats

3章 誤解されない名前

  • 名前が他の意味と間違えて捉えられる可能性がないか、を考える
  • filter()では()内の要素を残すのか切り捨てるのかわからない
    • select, excludeの方が良い
  • 限界値を含めるときはmin, maxを使う(too_bigとかはだめ)
  • 範囲を指定するときはfirst, lastを使う(最後がstopだと含まれるかどうかわからない)
  • bool値にはis, has, can, shouldなどをつけるとわかりやすい
  • bool値は否定形にしない(disable_ssl->use_ssl
  • ユーザの期待に合わせる
    • get()は軽量なものへのアクセスを想起させるため、全データの平均を取得する際などはcompute()を使う
    • size()は計算量N(1)を想起させるので、そうではない場合はcountSize()等にする

4章 美しさ

  • コードのシルエットを統一する
  • 列を揃える
  • 意味のある順序で並べる
  • 空行でブロック毎に分ける
  • 間違ったスタイルでコーディングしている既存のプロジェクトは既存のスタイルを踏襲する
    • 一貫性の方が大事

5章 コメントするべきことを知る

  • すぐ読んでわかる処理の説明を書かない
  • ファイルやクラスは全体像のコメントを書く
    • 何をしているか
    • なぜこの処理をしているか
    • 問題点はあるか
  • 処理に違和感のある部分はコメントを残す
  • 他の人が間違いをおかしそうな部分にコメントを残す

6章 コメントを正確かつ簡潔に書く

  • 曖昧な代名詞を避ける
  • 名前付き引数を活用する
  • 多くの意味が込められた言葉や表現を使う
    • 正規化など

7章 制御フローを読みやすくする

  • if文では調査対象を左側に置く
    • if 調査対象の値 < 閾値
  • 条件の優劣->状況によって使い分ける
    • 単純な条件を先に書く
    • 目立つ条件を先に書く
  • list内包表記などの省略形のコードはわかりやすい時だけ使う

8章 巨大な式を分割する

  • 条件を変数に代入する
  • 条件が複雑になる場合は、反対を考えてみる
  • 「頭が良い」コードで1行にまとめて書くよりも、複数行に分割して書いたほうが何がしたいのかわかりやすい

9章 変数と読みやすさ

  • 変数のスコープを制限する
  • 変数は使われる場所の近くで定義する

10章 無関係の下位問題を抽出する

  • 本質的な処理の目的を考える
  • 本質的な処理の目的に関係のない処理を関数化する
  • 処理が汚い部分はラッパーを作って覆い隠す
  • プロジェクト固有のコードから汎用コードを分離する

11章 1度に1つのことをする

  • 1つの処理を同時並行で行わない
  • 異なる処理は分割して領域毎に区切る

12章 コードに思いを込める(?)

  • コードを簡単な言葉で説明する

13章 短いコードを書く

  • 最も綺麗なコードは何も書かれていないコードである
  • 無駄な機能は実装しない
  • 不要なコードは削除する
  • ライブラリに親しむ(短くかけるから)
    • 標準ライブラリのドキュメントに目を通してできることのイメージを持っておく

14章 テストと読みやすさ

  • コードは似たコードが多くなるので、可読性や保守性を高めやすい
    • 同じ処理はヘルパーメソッド等を作って活用する
  • 一度に全てをテストしない
  • エラーメッセージを読みやすく自作する
  • テスト関数は、テスト対象がわかるようにする

15章 「分/時間カウンタ」を設計・実装する

  • 上記手法の実践

「オブジェクト指向でなぜつくるのか」まとめ

第1章 オブジェクト指向はソフトウエア開発を楽にする技術

第2章 オブジェクト指向と現実世界は似て非なるもの

  • オブジェクト指向を現実世界になぞらえた説明はあくまでも比喩として割り切った上で、「プログラミングのための仕組み」として理解するのがおすすめ

クラスとインスタンス

メソッド

  • メソッドの呼び出し方も現実とは異異なっている
  • オブジェクト指向では、メソッドは指示通りに動く
  • 一方現実世界のモノは、自らの意思で動くこともあれば指示を受けてもその通りに動かないこともある

第3章 OOPを理解する近道はプログラミング言語の歴史にあり

  • プログラミング言語の進化の過程
  • プログラミング言語の表現力は向上したものの、1960年代後半に宣言されたソフトウエア危機を救うことはできなかった
    • ソフトウェア危機->将来的にソフトウェアの供給が需要を満たせなくなるという考え方
  • ソフトウエア危機を乗り越えるため、保守性を向上させることが重要となった
  • また、間違いを起こさないよう「品質の向上」も重視するようになった
    • 複雑なコードは避ける、等

第4章 OOPは無駄を省いて整理整頓するプログラミング技術

OOPの三大要素

クラス

  1. サブルーチンと変数をまとめる
  2. クラス内部だけで使う変数やサブルーチンを隠す
  3. 1つのクラスからインスタンスをたくさん作る

ポリモーフィズム

  • サブルーチンを呼び出す側のインターフェースを統一する
    • 共通のメインルーチンを作る仕組みのこと

継承

  • クラスの共通部分を別クラスにまとめる仕組みのこと
    • これによりコードの重複を削除でき、保守性を上げることができる

クラスを型として利用する

  • 型チェック
  • 静的な型付け
  • 動的な型付け
    • プログラムの実行時にエラーを検出する

進化したOOPの仕組み

  • 現在主流のプログラミング言語JavaC#PythonRubyPHP等)にはさらに進んだ機能がある
    • パッケージ
      • クラスをさらにまとめる
    • 例外
      • メソッドから特別なエラーを返す仕組み、バグを見つけやすくする
      • 無駄を省くことができる
      • 間違いを防止できる
    • ガベージコレクション
      • メモリ利用の効率化

第5章 メモリの仕組みの理解はプログラマのたしなみ

  • プログラムの実行方式
  • スレッド
    • プログラムの実行単位
    • プロセスよりも小さい単位で、1つのプロセスの中に複数存在する
  • メモリ領域
    • 静的領域
      • アプリケーション開始時に確保する
      • グローバル変数、実行コードが格納される
    • ヒープ領域
      • 開始時に一定領域を確保し、必要の都度アプリケーションに割り当てる
    • スタック領域
      • 後入れ先出し方式(LIFO
      • 呼び出したサブルーチンの引数、ローカル変数等

第6章 OOPがもたらしたソフトウエアとアイデアの再利用

第7章 汎用の整理術に化けたオブジェクト指向

上流工程におけるオブジェクト指向の利用

集合論

役割分担

  • オブジェクト指向における「メッセージパッシング」は、インスタンスを指定してそのクラスのメソッドを呼び出す
  • これは、特定の役割を持つもの同士が決められた方法で連絡し合う、役割分担に応用されることになった

この集合論と役割分担は、非常に強力なコンセプトとなった.
これによりオブジェクト指向は、物事を分類して整理する仕組みと役割分担を表現する仕組みを備えた汎用の整理術となった

第8章 UMLは形のないソフトウエアを見る道具

UML:Unified Modeling Language

  • プログラム構造や動作を表現する
  • 汎用の整理術の成果物を表現する
  • オブジェクト指向を表現する

第9章 現実世界とソフトウエアのギャップを埋めるモデリング

  • 業務分析・要件定義・設計の3ステップにより、現実世界とソフトウエアのギャップを埋めるモデリングを行う
  • モデリングとは、「UMLを使ってソフトウエアの機能や内部構造を2次元の図で表現すること」を指す

第10章 擬人化して役割分担させるオブジェクト指向設計

ソフトウェア設計の目標

  • 重複を排除する
    • 機能が重複すると規模が大きくなり修正漏れが増える
  • 部品の独立性を高める
    • 独立性を高めることで保守性や再利用性が高くなる
  • 依存関係を循環させない
    • AがBに、BがCに、CがDに依存している...と言う状態を避ける

第11章 オブジェクト指向から生まれたアジャイル開発

ウォーターフォール開発プロセス

  • 要件定義/設計/プログラミング/テストの作業を1回ずつ実施する
  • 現在よりも開発環境が整っていなかった時代の「ソフトウェアの変更に大きなコストがかかる」ことを前提としている

反復型開発プロセス

  • 要件定義→設計→プログラミング→テストを繰り返し行うことによって、段階的にソフトウエアを作っていく

第12章 オブジェクト指向を使いこなそう

オブジェクト指向の利用自体が目的になってはいけない

DeepLab v3

この記事では、DeepLab v3の論文について解説を行う。
※記事中に登場する図表は全て論文からの引用です

DeepLab v3

概要

  • atrous convolutionを何層も重ねるMulti-grid Methodを採用
  • deeplab v2にて提案したASPPにて、rate=24のケースで周辺情報をほとんど取得できていないことを発見し、高レートのatrous convolutionを削除した
  • 高レートのatrous convolutionの代わりにGlobal Average Poolingを採用し、大局的なコンテクストを取得できるようにした
  • PASCAL VOC 2012データセットのsemantic segmentationタスクにて当時のSOTAを達成した

各手法

1. Multi-grid method

FCNはsemantic segmentationに有効だが、畳み込みを何度も行うことで空間解像度を落としてしまう。その課題に対処するため、Deconvolutionによって空間的解像度を元に戻す方法があるが、Deeplab v3ではatrous convolutionを使うことでその問題を対処している。atrous convolutionは通常のconvolutionのカーネルの要素の間にr-1個(rはrate)の0を埋め込むことで、周辺の情報を効率的に収集できる畳み込みの手法である。atrous convolutionを使うことで、どの程度密に特徴量を計算するかを明示的に調節することができる。

f:id:deep21:20211206234122p:plain
atrous convolution

2. Atrous Spatial Pyramid Pooling

ASPPは、特徴量マップに対して異なるrateのatrous convolutionを適用する手法である。Spatial Pyramid Poolingという手法の論文において、異なるスケールで特徴量をリサンプリングすることが、精度も計算効率も高めるということが証明されている。その仕組みを参考にしてatrous convolutionと組み合わせたものがASPPである。

ASPPでは、マルチスケールの情報を獲得することができる。しかし、rateが大きくなるにつれて、有効なフィルターのweightsの数が小さくなっていくことを発見した。例えば、rateの値が特徴量マップのサイズに近づいた場合、有効なフィルタが中心のフィルタのみとなってしまうため、画像全体のコンテキストを獲得できずシンプルな1×1のフィルターと同じような働きになってしまう。

この問題に対処するため、この論文ではrateの大きなatrous convolutionを削除し、Grobal Average Poolingを導入している。Grobal Average Poolingの後に256枚のフィルターを持つ1×1のconvolution層(およびbatch normalization層)を通し、その後upsamplingにより任意のサイズに特徴マップを拡大する。これにより、モデルが大局的なコンテキスト情報を獲得することを可能にしている。

f:id:deep21:20211206144156p:plain
ASPP

検証結果

Image Netで事前学習したResNetを使用し、PASCAL VOC 2012データセットにて検証を行なった。

1. Atrous Convolutionの検証

output_strideサイズ(atrous convolutionの数)

ResNet-50にて、output_stride(出力特徴量マップの入力画像サイズに対する割合)を小さくしていくにつれて精度が向上し、層を重ねて行く場合にはatrous convolutionが不可欠であることが確認できた。

f:id:deep21:20211206144844p:plain

2. ResNet-50 vs. ResNet-101:

モデルをResNet-101に変更し、カスケード接続する層の数を変更して検証したところ、層を深くするにつれて精度が向上することを確認した。しかし、層を重ねるにつれて精度の上昇幅は小さくなり、ResNet-50ではblock7まで層を重ねた場合、精度に若干の低下が見られた。

f:id:deep21:20211206144511p:plain

3. Multi-grid

ResNet-101にいくつか層をカスケード接続してMulti-Gridの検証を行った。図表の通り、通常の構成(1,1,1)に比べ、Multi-Gridを導入した場合精度が向上することが確認できた。単純に各要素を2倍しただけのrate(2,2,2)もあまり効果はなく、(1,2,1)のケースが最も精度が向上した。

f:id:deep21:20211207002305p:plain
Multi-Grid検証結果

ASPPの検証

DeepLab v1との違いはbatch normalzationのパラメータがfine tuningされていることとimage-levelの特徴量(Global average poolingの部分)が追加されていることである。

Multi-Gridとの併用で精度が向上するかどうかを検証した。まずはASPPのレートを(6,12,18)に固定して実験を行った結果、(1,1,1)より(1,2,1)の方が良い結果であり、さらに(1,2,4)はより高い精度を記録した。 また、ASPPのレートについてr=24を追加した場合、0.12%という若干の精度低下が見られた。一方、image-levelの特徴を追加することで精度が 77.21%まで向上した。

f:id:deep21:20211207234544p:plain
Multi-GridとASPPの併用

その他

上記の検証のほか、学習時と推論時のoutput_strideを変更したり、TTAのような処理を追加した結果、79.77%という精度を達成した。

結論

実験の結果、提案モデルは以前のDeepLabバージョンよりも大幅に精度が改善され、PASCAL VOC 2012セマンティックセグメンテーションベンチマークにおいて、他のSOTAモデルと同等の性能を達成した。

参考

Detection手法まとめ

本記事では、深層学習を利用したdetection用のモデル概要の解説を行う。
※記事中に登場する図表は全て論文からの引用です

SSD

登場時期:2015年

SSD自体は2015年ごろに登場した手法で新しいものではないが、近年でも利用されている。SSDでは、当時主流だったR-CNNで行われるようなバウンディングボックスをスライドさせてCNNの演算を行う手法を使わず、一度の演算で領域候補の検出とクラス分類を行うことが特徴。

f:id:deep21:20211206161859p:plain
SSDモデル構造

デフォルトボックスという異なるアスペクト比の枠を複数用意し、各デフォルトボックスごとに位置特徴と各クラスの予測値を計算する。そして算出された予測値、位置特徴をもとに候補となるボックスを絞っていき、最終的に物体に対する予測を算出する。なお、学習時にはボックスの位置特徴の誤差と予測値の誤差の2つを組み合わせた損失関数を用いる。

また、様々なスケールの物体を検出できるよう、サイズの異なる特徴量マップにおいて各予測値を計算するのも特徴である。

RefineDet

登場時期:2017年

物体検出タスクにおいては、2-stageのアプローチが高精度な結果を残している一方、one-stageのアプローチ(例:SSD)が効率よく学習を進めることができるという状況だった。これらの両方のメリットを受け継ぎ、高精度で効率の良いモデルを提案したのがこのモデルであり、SSDとの類似していることからSSDの発展版と言われている。SSDの発展版と言われているだけあり、このモデル自体もone-stageの構成となっている。

f:id:deep21:20211206165632p:plain
RefineDetモデル構成
transfer connection block

RefineDetはanchor refinement moduleとobject detection moduleというモジュールで構成されている。anchor refinement moduleでは分類対象を絞るために確率の低いボックスを除外し、アンカーの位置とサイズを大まかに調整し、object detection moduleに渡す特徴を洗練させる。そして、object detection moduleではanchor refinement moduleからのoutputをinputとして受け取り、より高精度な予測を算出する。 また、anchor refinement moduleの特徴量をobject detection moduleでの予測に役立てるため、transfer connection blockにて特徴の受け渡しを行なっている。

RetinaNet

登場時期:2018年

one-stageモデルではtwo-stageのモデルほどの精度を出すことが難しいという問題に対して、目的関数を改良するアプローチを取ることで精度の向上を図った手法。提案された誤差関数はFocal Lossと呼ばれており、以下の計算式で表される。

f:id:deep21:20211206173521p:plain
Focal Loss

式中のγ(ガンマ)は論文中では「Focusing parameter」と呼ばれており、ハイパーパラメーターとなっている。γは0以上の値に設定する必要があり、γの値を大きくするにつれて予測が簡単なサンプルのウェイトを下げて予測が難しいサンプルに対する学習を進みやすくするような挙動をと。なお、γ=0の時は(1-pt)**γの部分が1となり、クロスエントロピー誤差と同じものになる。

論文中の以下の図からも、予測確率が高くなるにつれて誤差が小さくなっており、またγの値が大きくなるにつれて総計高が大きくなっていることが見て取れる。

f:id:deep21:20211206174535p:plain
γの値によるFocal Lossの挙動の違い

なお、Focal LossはKaggleでも頻繁に登場しており、不均衡データに対する手法の1つとして広く利用されている(印象)。

M2 Det

登場時期:2018年後半

国際的なカンファレンスAAAI-19(The Thirty-Third AAAI Conference on Artificial Intelligence 2019)で北京大学、アリババ、テンプル大学の合同チームにより発表された物体検出手法。多くの物体検出タスクにてFeaturePyramidが活用されていることを背景に、より効率的なfeature pyramidを構成するため、Multi-Level Feature Pyramid Networkという手法が提案された。

f:id:deep21:20211206185110p:plain
M2 Detモデル構成

手法としては、まずbackboneのネットワークの各層から抽出された異なるスケールの特徴量をFeature Fusion Module (FFM)にて(convolutionやupsampling等を挟んで各特徴量のサイズを統一させて)融合させる。論文内ではこの特徴量をbase featureと呼んでいる。なお、backboneのネットワークはただの特徴量抽出器であるため、任意のアーキテクチャを利用できる。

次に、生成されたbase featureをThinned U-shape Module (TUM)にインプットする。TUMはエンコーダ・デコーダ構成のピラミッドになっており、デコーダの各層からの出力をアップサンプリングしてエンコーダ側の対応する層の出力と結合し、最後に1×1のconvolutionを適用する。これらの各層の出力は次のブロックのSFAMへ受け渡される。また、TUMは多段に構成されており、TUMの最終的な出力(一番解像度の高い出力)のみが次のTUMへ受け渡され、同じ処理を繰り返す。

最後にTUMから得られる特徴ピラミッドをScale-wise Feature Aggregation Module(SFAM)にて結合する。SFAMでは各TUMから得られるそれぞれの特徴ピラミッドから同じ解像度の特徴マップを取り出してチャネル方向にconcatする。さらに、その特徴マップをGlobal Average Poolingと前結合層を通して重み係数に変換し、元の特徴マップと掛け合わせる(attentionの仕組みを導入)。

最後にSFAMから得られる特徴ピラミッドに対してconvolution層を適用し、物体の位置とクラスの予測を行う。

https://qiita.com/kzykmyzw/items/1831f70dcade04db2210

EfficientDet

登場時期:2019年

マルチスケールの特徴量を簡単かつ高速に融合するために、bi-directional feature pyramid network (BiFPN)を提案した手法。Kaggleのコンペティションで利用されることも多い。提案されている中で最も大きなEfficientDet-D7は、MS COCOデータセットで51.0mAPを達成し、当時のSOTAを達成した。

f:id:deep21:20211206194801p:plain
EfficientDet モデル構成

まず、backboneのモデルから得られた特徴マップにpooling処理を施しサイズを小さくしていき、各pooling層からの出力を上記のBiFPNへインプットする。BiFPNでは特徴マップを混合することになるが、混合の方法には他の論文でも様々な手法が提案されている。BiFPNでは下記のようにスキップコネクションを用いることで、計算を効率化している。

f:id:deep21:20211208135243p:plain
特徴マップの混合パターン

SWIN-transformer

登場時期:2021年

Segmentationのまとめにて解説

参考

Segmentation手法まとめ

本記事では、深層学習を利用したsegmentation用のモデルの簡単な解説を行う。
※記事中に登場する図表は全て論文からの引用です

UNet

登場時期:2015年

古いモデルではあるが、今でもKaggleで(主にベースラインとして)利用されることが多い。

f:id:deep21:20211207184227p:plain
UNetモデル構成

input画像を畳み込み処理とpooling処理で特徴マップを縮小させたのち(Encoder)、up convolutionで特徴マップのサイズを復元してゆく(Decoder)。Encoder、Decoder間でサイズの等しい特徴マップ同士を接続しConcat処理を行うことで、モデルの序盤にしか保持していない特徴をモデルの後半に共有し、活用させる仕組みを導入している(スキップ接続)。

PSPNet

登場時期:2017年

当時提案されていたモデルでは広範囲のコンテキスト情報を抽出できておらず、類似したクラスの分類ミスが発生していた。そこで、様々な解像度、スケールの特徴を抽出できる空間ピラミッドプーリングを採用した手法を提案した。

f:id:deep21:20211207183909p:plain
PSPNetモデル構成

input画像から抽出した特徴マップに対してpooling処理を施し、様々なサイズの特徴マップを取得する。その後、各特徴マップに対して畳み込みおよびup sampling処理を行なって特徴マップのサイズを統一させ、Concatする。Concatした特徴マップに畳み込み処理を行い、最終的な出力とする。

RefineNet

登場時期:2017年

CVPR2017で発表された手法。Encoder–Decoder構造になっており、EncoderにはRes Net101が使われている。

f:id:deep21:20211207115250p:plain
RefineNetモデル構成

まず、異なる4段階のサイズの特徴マップをResidual Conv Unit (上図b)へ渡し、畳み込みを行う。このユニットでは、ImageNetで事前学習されたResNetの重みをsegmentationタスク用にFineTuningすることが主な目的となっている。

次に、Residual Conv Unitから出力された特徴マップをMulti -Resolution Fusion(上図c)へ入力する。MRFでは、入力された特徴マップと、1段階下のサイズの特徴マップのRefineNetからの出力を合計する。 このように、最小サイズである1/32のサイズの特徴マップを除き、一段下のサイズの特徴マップ(RefineNetからの出力)と融合させながら次の特徴マップへ受け渡していく部分がMulti-Pathという名前の由来である。↓

f:id:deep21:20211207122101p:plain
Multi-Path Refinement

次に、MRFで融合された特徴マップをChained Residual Pooling(上図d)へインプットする。CRPでは、階層構造となったpooling層の結果を足し合わせていき、出力を生成する。

そして、最終的に生成された特徴マップにバイリニア補間を適用してマップサイズを元画像と同じサイズに復元することで最終的な出力を完成させる。

DeepLab v3+

登場時期:2018年

DeepLab v3に対して、Segmentation用モデルで利用されることの多いEncoder-Decoderモジュールを追加することで、atrous convolutionとEncoder-Decoderモジュールの両方のメリットを享受しモデルの精度を向上させた手法。また、Xceptionモデルを採用し、depthwise separable convolutionをASPP、Decoderモジュールの両方に適用することで、早く精度の高いモデルを作り上げた。

f:id:deep21:20211208104056p:plain
DeepLab v3

DeepLab v3+では、通常の畳み込み処理とは異なるDepthwise separable convolutionという手法と、それをさらに拡張したatrous separable convolutionという畳み込み処理を用いる。具体的には、Depthwise separable convolutionはチャネルごとに異なるフィルタでDepthwise(空間方向)の畳み込みを行なったのち、Pointwise(チャネル方向)の畳み込みを行う方法であり、通常の畳み込みに比べて計算量が削減される。atrous separable convolutionはDepthwiseの畳み込みにatrous convolutionを用いた手法であり、DeepLab v3では通常の畳み込み、atrous畳み込みのそれぞれに上記の手法を適用している。

f:id:deep21:20211208115211p:plain
Depthwise separable convolution

次に、Encoder層においてはDecoder層の出力がバイリニア補間により4倍にup samplingされ、同じサイズのDCNNからの特徴マップとconcatされる(CNNからの特徴マップはconcat前にチャネル数を削減するため1×1の畳み込みを行っている)。その後、3×3の畳み込みを行ない、最後に再度バイリニア補間で4倍にup samplingする。なお、Encoderからの出力はoutput stride=16にするとスピードと精度のトレードオフが最適であり、output stride=8にすると精度が最も高かったとのこと。

さらにDeepLab v3からの変更点として、ネットワークのバックボーンとしてXceptionを採用している。詳細は割愛するが、Xceptionを修正したモデルで物体検出で高精度を記録した論文を受けて、その手法に少し変化を加えたXceptionモデルを採用している。

上記の構成により、PASCAL VOC 2012データセットおよびCityscapesデータセットにて当時のSOTAを記録している。

HRNet(v1, v2)

登場時期:2019年

最初の論文(v1)では2D姿勢推定用のモデルとして提案され、続く論文(v2)にてアーキテクチャに工夫が加えられ、他のタスク(segmentationや物体検出)にも適用できるようになったモデルである。

f:id:deep21:20211207161725p:plain
HRNetモデル構成

高い解像度を維持するため、解像度の高いままの特徴マップをそのままモデルの後半へ受け渡して行くのが特徴。また、解像度を下げたマルチスケールの特徴マップをサブネットワークとしてパラレルに構成し、高解像度の特徴マップへ結合していくことで低解像度の特徴マップが持つ情報も取得できるようになってる。

元の論文では高解像度の特徴マップのみを出力していたが(下図a)、セグメンテーションに利用するために低解像度の特徴マップをアップサンプリングしてConcatしたものを出力している(下図b)。ちなみに、下図cは物体検出用のfeature pyramid形式の構成である。

f:id:deep21:20211207163226p:plain
HRNet 構成比較

なお、HRNetはCityscapesデータセット(道路のシーンを記録しラベル付けされたデータセット)を利用したベンチマークテストにて執筆時点でSOTAを記録しているモデルに使われている。本職である姿勢推定タスクにおいても、元のモデルから拡張はされているものの、COCO test-dev、OCHumanデータセット等のベンチマークテストで上位に入っている。

Swin Transformer

登場時期:2021年前半

近年流行のTransformerベースのモデルであり、segmentationタスクのみならず様々なタスクにおいて高い性能を示している。

f:id:deep21:20211207175810p:plain
Swin Transformerモデル構成

transformerベースのモデルの基本となっているVision transformerでは、入力画像をパッチに分割し、Transformerへ入力している。ただし、画像内の全てのパッチに対してAttentionの計算を行うため、計算コストが非常に大きくなってしまう。

Swin Transformerでは、画像をパッチに分割した後、パッチの集合であるウィンドウを定義する。そして、Window内のパッチに対してのみSelf -Attentionを計算することで、計算コストを抑えている(W-MSA)。さらに、別の層ではそのウィンドウをシフトさせて様々なサイズのパッチ集合を作り出すことで、ウインドウ間の関係性をモデリングすることができるようになっている(SW-MSA)。

なお、SwinTransformerはADE20Kデータセット(多様なシーン画像にセマンティックセグメンテーションのアノテーションを行ったデータセット)のベンチマークテストで執筆時点のSOTAを記録している。

参考

<論文>Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition

[1406.4729] Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition

概要

当時のCNNの手法は決められた画像サイズにスケールすることで一部の情報を失ったり歪めたりしているため精度に影響していた。そこで、任意の画像を入力できるPSSnetを考案することで入力画像のスケーリングが不要となり、精度が向上した。

解決したい課題

CNNはinputする画像を決められたサイズに前処理する必要があり精度を悪化させてしまっているため任意の画像サイズを入力できるようにしたい。

実現するための手法

特徴マップに対してマルチスケールのプーリング処理を施し、その出力を1次元で結合して前結合層へ受け渡すPSS-layerおよびそれを実装したPSSnetを考案した。PSSnetは任意の画像サイズ(特徴量マップ)を入力として固定長のベクトルへ変換できることから、入力画像のスケーリングが不要となった。

結論

PSS- layerを導入することで入力画像のスケーリングが不要となり、精度が向上した。

参考文献

https://www.slideshare.net/DeepLearningJP2016/dlencoderdecoder-with-atrous-separable-convolution-for-semantic-image-segmentation

関連論文

[1406.4729] Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition