MobileNet, Mnasnet, EfficientNetの比較


概要:

モデル構造を並べた時、MobileNetV2, MobileNetV3, Mnasnet, EfficientNetは非常によく似ていた。
MobileNetV3はMnasnetを参考にしているようだった。
EfficientNetとMnasnetは作者が同じで係数もよく似ている。
そしてMnasnetはMobileNetV2を参考にしているようだった。
つまり、モデルの血脈はMobileNetV2=>Mnasnet=>MobileNetV3, EfficientNetと流れていた。
その事を示してみる。

Conv2D(3x3)のstride=2の解釈

Conv2D(3x3)のstride=2の場合、入力が224x224、出力が112x112であるから、Conv2D(stride=1)=>pooling(stride=2)を実行するとここでは解釈するとします。
そして、MBConv(3x3,stride=2)×3のようにstride=2の畳み込みが複数ある場合、stride=2が掛けられるのは最初だけで以降はstride=1になります。MBConv(3x3,stride=2)×3

MBConv(3x3,stride=2)×3=\begin{bmatrix}
MBConv(3\times 3,stride=2)\\
MBConv(3\times 3,stride=1)\\
MBConv(3\times 3,stride=1)
\end{bmatrix}

と書かれます。

一方、Conv2D(stride=2)の場合、Conv2D(stride=1)=>pooling(stride=2)と置き換えれるから

\begin{bmatrix}
MBConv(3\times 3,stride=1)\\
pooling(stride=2)\\ 
MBConv(3\times 3,stride=1)\\
MBConv(3\times 3,stride=1)
\end{bmatrix}

ここで、自分は最初の畳み込みと2,3回目の畳み込みは適用する画像サイズが異なるにもかかわらず、まとめて書かれていることを奇妙に感じました。そこで同じ画像サイズに適用される3x3畳み込みの数を整理してみることにしました。

VGG,ResNet,Xception,MobileNetV1の比較

:VGG
:ResNet
:Xception
:MobileNetV1

これを整理すると以下の表になる。
Conv2D(stride=2)での複数畳み込みは最初のだけ1つだけ上の解像度での畳み込みになる。
(ただし、Xceptionの入力は本来299x299だが224x224入力の場合で考えた)

ここでResNet50は以下の様な$Bottleneck$ブロックが使われます。

Bottleneck=\begin{bmatrix}
(1 \times 1), 64 \\
(3 \times 3), 64 \\
(1 \times 1), 256
\end{bmatrix}

一方、$Separable Conv$ブロックは以下の様に書かれます。

Separable Conv=\begin{bmatrix}
dw(3 \times 3), 256 \\
(1 \times 1), 256
\end{bmatrix}

最後に$MBConv$ブロックは以下の様に書かれます。これはDepthwiseを使った$Bottleneck$ブロックです。$MB$が何の略かと聞かれるとおそらく$Mobile Bottleneck$であると思われます。(Depthwiseを使った$Bottleneck$ブロックはMobileNetV2よりも前にShuffleNetで既出であるけれど…)

MBConv=\begin{bmatrix}
(1 \times 1), 64 \\
dw(3 \times 3), 64 \\
(1 \times 1), 256
\end{bmatrix}

5x5の畳み込みを3x3の畳み込み2回とみなし、7x7の畳み込みを3x3の畳み込み3回とみなして各解像度における3x3畳み込みの数を数えると以下の様になる。

input size VGG16 VGG19 ResNet
50
ResNet
101
ResNet
150
Xception MobileV1
224 2 2 3 3 3 1 1
112 2 2 0 0 0 2 2
56 3 4 4 4 4 2 2
28 3 4 4 4 8 2 2
14 3 4 6 23 36 5 6
7 - - 2 2 2 2 1

・ResNetの3x3畳み込みの数を俯瞰すると14x14の解像度に入れる3x3畳み込みの数が認識に重要であることが分かります。
・MobileNetV1やXceptionの示唆によれば14x14以外の解像度における畳み込みは2個となっており、ResNet系よりも少ない数になっている。
・ResNetは最初に7x7の畳み込みが入っている一方で112x112の解像度では一つも畳み込みが入っていない。若干アンバランスを感じる。

MobileNetV2,V3, Mnasnet, EfficientNetの比較

:MobileNetV2
:MobileNetV3
:Mnasnet
:EfficientNet
:NFNet

MobileNetV2,V3のDepthwiseを使ったBottleneckブロックはMnasnetのMBConvと等しい。
Bottleneckブロックという名称はResNetのBottleneckブロックと混合するのでここではMBConvという呼称の方を用いる。また、MobileNetV3はexpandチャンネルサイズが出力チャンネルサイズの整数倍ではないので値を両方併記する。
MB3x3, 80, 480は出力チャンネル80でexpandチャンネルが480、拡大比率6倍である。

この表を見ていただければ、MobileNetV2,V3, Mnasnet, EfficientNetが非常によく似ていることに同意していただけると思う。MobileNetV2の3x3の一部を5x5に置き換えたのがMnasnetであり、更にMnasnetを改良したのがMobileNetV3,EfficientNetである。
一方、NFNetはBottleneckに二回3x3畳み込みを入れるような形でありMobileNetV2よりはResNet系を参考にしているように見える。

5x5の畳み込みを3x3の畳み込み2回とみなし、各解像度における3x3畳み込みを数えると以下の様になる。

input size ResNet
50
Mobile
V1
Mobile
V2
Mobile
V3
Mnasnet EfficientV1 EfficientV2
224 3 1 1 1 1 1 1
112 0 2 2 2 2 2 3
56 4 2 2 3 3 3 4
28 4 2 2 5 5 3 4
14 6 6 7 7 7 9 15
7 2 1 3 4 5 7 14

・MobileNetV2=>Mnasnetでは14x14の解像度での畳み込みの数は増えていない。それ以外の解像度での畳み込みの数が増えている。これはResNet50=>ResNet101での畳み込みの増え方とは異なる。
・Mnasnet=>MobileNetV3では7x7解像度での最後の3x3畳み込みを一つ減らしている。
・Mnasnet=>EfficientNetでは14x14解像度と7x7解像度で畳み込みの数が増えているが、逆に28x28解像度では畳み込みの数が減っている。
・EfficientNetにおける入力の解像度を上げるという操作はこのテーブルの畳み込みを上にずらす操作になるからそれが7x7の解像度での畳み込みの数を予め増やす理由になるのかもしれない。

まとめ:

MobileNetV2, MobileNetV3, Mnasnet, EfficientNetが似ていることを示した。
EfficientNetは論文で深さを1.2倍、チャンネル幅を1.1倍、入力解像度を1.15倍に増やしていくと効率的なモデル構造を維持したままFLOPsが2倍ずつ増えていくという事が示されているがそのベースモデルの由来は従来よく分からなかった。
EfficientNetの論文中には同じ検索空間を使用しているためEfficientNetはMnasNetに似ているとある。最適化の検索結果の違いは対象となるFLOPsでMnasNetA1は312Mに対してEfficientNetB0は400Mとなるように検索している。(…というかMnasNetA3がのちのEfficientNetB0なのでは?)

MnasnetとEfficientNetの作者は同じだが、ベースとなるEfficientNetB0の由来に関する説明はMnasnetに託しており、このMnasnetの日本語での解説は少ないように感じた。
Mnasnetの正体はMobileNetV2の3x3畳み込みの一部を5x5畳み込みに置き換えたものである。

その他:

最近の傾向は実行速度が優先されがちのように感じる。
FLOPsは理論演算量であるがこれは現実の実行速度とは乖離していて、特にDepthwiseが相対的に理論演算量よりも掛かってしまうという現実があるが、将来的にCUDAのアルゴリズムが見直されDepthwiseの復権もないわけではない。(理論演算量では優秀なので)
一方、1x1Convの方は特に何もない。ずっと前にShuffleNetで2回の1x1グループConvとチャンネルシャッフルを使うというアイデアがあった(これは$(batch,H,W,64)$を$(batch,H,W,8,8)$と変形して4次元目と5次元目でそれぞれ全結合を実行することである。チャンネルシャッフルは4次元目と5次元目を入れ替える処理)が、その後の音沙汰はない。