{"notes":[{"id":"classic-cnns/inception-v4","category":"classic-cnns","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"Inception-v4","subtitle":"ずっと速く、少し正確に","author":"Z. Yuan","paperDate":"2016-02-23","publishedOn":"2026-01-27","world":"external/inception-v4","paperTitle":"Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning","paperUrl":"https://arxiv.org/abs/1602.07261","bibliography":{"title":"Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning","authors":["Christian Szegedy","Sergey Ioffe","Vincent Vanhoucke","Alex Alemi"],"url":"https://arxiv.org/abs/1602.07261","pdfUrl":"https://arxiv.org/pdf/1602.07261v2","codeUrl":null,"preprint":{"id":"1602.07261","submittedOn":"2016-02-23","url":"https://arxiv.org/abs/1602.07261"},"publication":null,"citation":"@misc{classiccnnsinceptionv42016,\n  title = {{Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning}},\n  author = {Christian Szegedy and Sergey Ioffe and Vincent Vanhoucke and Alex Alemi},\n  year = {2016},\n  eprint = {1602.07261},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/1602.07261}\n}\n","citationPath":"/content/papers/citations/classic-cnns/inception-v4.ed8e0294ae0b.bib"},"thumbnail":{"src":"/content/papers/assets/cc8335c4ba4672514d3dd5e9953719d52b4f8fdd0af994c76722874543fcb864.png","width":666,"height":656},"locale":"ja","path":"/content/papers/ja/classic-cnns/inception-v4.8e5591b07579.md","headings":[{"id":"問題の定義","text":"問題の定義","depth":2},{"id":"問題の解決","text":"問題の解決","depth":2},{"id":"しがらみを下ろすinception-v4","text":"しがらみを下ろす：Inception-v4","depth":3},{"id":"入口の部分","text":"入口の部分","depth":3},{"id":"inceptionに残差を組み込む","text":"Inceptionに残差を組み込む","depth":3},{"id":"残差を縮めて学習を安定させる","text":"残差を縮めて、学習を安定させる","depth":3},{"id":"学習設定","text":"学習設定","depth":3},{"id":"考察","text":"考察","depth":2},{"id":"残差で学習がずっと速くなる","text":"残差で学習がずっと速くなる","depth":3},{"id":"単一モデルの成績","text":"単一モデルの成績","depth":3},{"id":"アンサンブル","text":"アンサンブル","depth":3},{"id":"残差接続は必須なのか","text":"残差接続は「必須」なのか？","depth":3},{"id":"結論","text":"結論","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"classic-cnns/resnet","relation":"referenced","topic":""},{"id":"classic-cnns/inception-v3","relation":"referenced","topic":""},{"id":"classic-cnns/resnet-v2","relation":"referenced","topic":""}]},{"id":"classic-cnns/resnet","category":"classic-cnns","legacyPath":"classic-cnns/1512-resnet","legacySlug":"1512-resnet","legacyPaths":[],"title":"ResNet","subtitle":"畳み込みネットワーク 100 層","author":"Z. Yuan","paperDate":"2015-12-10","publishedOn":"2024-08-08","paperTitle":"Deep Residual Learning for Image Recognition","paperUrl":"https://arxiv.org/abs/1512.03385","bibliography":{"title":"Deep Residual Learning for Image Recognition","authors":["Kaiming He","Xiangyu Zhang","Shaoqing Ren","Jian Sun"],"url":"https://arxiv.org/abs/1512.03385","pdfUrl":"https://arxiv.org/pdf/1512.03385","codeUrl":null,"preprint":{"id":"1512.03385","submittedOn":"2015-12-10","url":"https://arxiv.org/abs/1512.03385"},"publication":{"venue":"CVPR","year":2016,"kind":"conference","url":"https://doi.org/10.1109/cvpr.2016.90"},"citation":"@misc{classiccnnsresnet2015,\n  title = {{Deep Residual Learning for Image Recognition}},\n  author = {Kaiming He and Xiangyu Zhang and Shaoqing Ren and Jian Sun},\n  year = {2015},\n  eprint = {1512.03385},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/1512.03385}\n}\n","citationPath":"/content/papers/citations/classic-cnns/resnet.cf4014e8baae.bib"},"thumbnail":{"src":"/content/papers/assets/b8fe87fe757249ea6d7bb667fef3196754b9f80e28bf842a69b540ca94585d08.jpg","width":1224,"height":408},"locale":"ja","path":"/content/papers/ja/classic-cnns/resnet.c2822db52f83.md","headings":[{"id":"問題の定義","text":"問題の定義","depth":2},{"id":"問題解決","text":"問題解決","depth":2},{"id":"残差とは","text":"残差とは？","depth":3},{"id":"残差学習","text":"残差学習","depth":3},{"id":"残差モジュール","text":"残差モジュール","depth":3},{"id":"ネットワークアーキテクチャ","text":"ネットワークアーキテクチャ","depth":3},{"id":"構成と計算量","text":"構成と計算量","depth":3},{"id":"討論","text":"討論","depth":2},{"id":"resnet-18-vs-resnet-34","text":"ResNet-18 vs ResNet-34","depth":3},{"id":"より深いボトルネックアーキテクチャ","text":"より深いボトルネックアーキテクチャ","depth":3},{"id":"imagenet-でのパフォーマンス","text":"ImageNet でのパフォーマンス","depth":3},{"id":"結論","text":"結論","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"classic-cnns/vgg","relation":"background","topic":"深い畳み込みネットワークの学習"},{"id":"classic-cnns/densenet","relation":"next","topic":"深い畳み込みネットワークの学習"}]},{"id":"classic-cnns/inception-v3","category":"classic-cnns","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"Inception-v3","subtitle":"大きなカーネルの退場","author":"Z. Yuan","paperDate":"2015-12-02","publishedOn":"2025-12-16","world":"external/inception-v3","paperTitle":"Rethinking the Inception Architecture for Computer Vision","paperUrl":"https://arxiv.org/abs/1512.00567","bibliography":{"title":"Rethinking the Inception Architecture for Computer Vision","authors":["Christian Szegedy","Vincent Vanhoucke","Sergey Ioffe","Jonathon Shlens","Zbigniew Wojna"],"url":"https://arxiv.org/abs/1512.00567","pdfUrl":"https://arxiv.org/pdf/1512.00567v3","codeUrl":null,"preprint":{"id":"1512.00567","submittedOn":"2015-12-02","url":"https://arxiv.org/abs/1512.00567"},"publication":null,"citation":"@misc{classiccnnsinceptionv32015,\n  title = {{Rethinking the Inception Architecture for Computer Vision}},\n  author = {Christian Szegedy and Vincent Vanhoucke and Sergey Ioffe and Jonathon Shlens and Zbigniew Wojna},\n  year = {2015},\n  eprint = {1512.00567},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/1512.00567}\n}\n","citationPath":"/content/papers/citations/classic-cnns/inception-v3.5636c0bddf2d.bib"},"thumbnail":{"src":"/content/papers/assets/c87d3d6fa9ea76d954eba2570f702150eca32d62c7cdb3d724075a4be9a63080.png","width":419,"height":358},"locale":"ja","path":"/content/papers/ja/classic-cnns/inception-v3.1a1cc69c4ec2.md","headings":[{"id":"問題の定義","text":"問題の定義","depth":2},{"id":"問題の解決","text":"問題の解決","depth":2},{"id":"55を33の2層に分ける","text":"5×5を3×3の2層に分ける","depth":3},{"id":"さらに1nとn1に分ける","text":"さらに1×nとn×1に分ける","depth":3},{"id":"補助分類器の本当の役割","text":"補助分類器の本当の役割","depth":3},{"id":"特徴マップを縮めつつ情報をせき止めない","text":"特徴マップを縮めつつ、情報をせき止めない","depth":3},{"id":"部品を組み立てる","text":"部品を組み立てる","depth":3},{"id":"モデルに自信を持たせすぎない","text":"モデルに自信を持たせすぎない","depth":3},{"id":"学習設定","text":"学習設定","depth":3},{"id":"考察","text":"考察","depth":2},{"id":"一つずつ加えていく","text":"一つずつ加えていく","depth":3},{"id":"解像度を下げるとどれだけ違うか","text":"解像度を下げると、どれだけ違うか？","depth":3},{"id":"ほかのモデルと比べる","text":"ほかのモデルと比べる","depth":3},{"id":"結論","text":"結論","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"classic-cnns/inception-v1","relation":"referenced","topic":""},{"id":"normalization/batchnorm","relation":"referenced","topic":""},{"id":"classic-cnns/convnext","relation":"referenced","topic":""}]},{"id":"classic-cnns/resnet-v2","category":"classic-cnns","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"ResNet v2","subtitle":"ショートカットはきれいに","author":"Z. Yuan","paperDate":"2016-03-16","publishedOn":"2026-02-14","world":"external/resnet-v2","paperTitle":"Identity Mappings in Deep Residual Networks","paperUrl":"https://arxiv.org/abs/1603.05027","bibliography":{"title":"Identity Mappings in Deep Residual Networks","authors":["Kaiming He","Xiangyu Zhang","Shaoqing Ren","Jian Sun"],"url":"https://arxiv.org/abs/1603.05027","pdfUrl":"https://arxiv.org/pdf/1603.05027v3","codeUrl":null,"preprint":{"id":"1603.05027","submittedOn":"2016-03-16","url":"https://arxiv.org/abs/1603.05027"},"publication":null,"citation":"@misc{classiccnnsresnetv22016,\n  title = {{Identity Mappings in Deep Residual Networks}},\n  author = {Kaiming He and Xiangyu Zhang and Shaoqing Ren and Jian Sun},\n  year = {2016},\n  eprint = {1603.05027},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/1603.05027}\n}\n","citationPath":"/content/papers/citations/classic-cnns/resnet-v2.3d311a21e308.bib"},"thumbnail":{"src":"/content/papers/assets/7eda4acdde3019e92c5b44f59917b1e493a5b11b5b8a63280d03b15787934ef5.png","width":967,"height":469},"locale":"ja","path":"/content/papers/ja/classic-cnns/resnet-v2.2eccc1d938b8.md","headings":[{"id":"問題の定義","text":"問題の定義","depth":2},{"id":"問題の解決","text":"問題の解決","depth":2},{"id":"二つの恒等写像","text":"二つの恒等写像","depth":3},{"id":"ショートカットに何かを足すとどうなるか","text":"ショートカットに何かを足すとどうなるか？","depth":3},{"id":"加算の後のreluはどこに置くべきか","text":"加算の後のReLUはどこに置くべきか？","depth":3},{"id":"見方を変えるpre-activation","text":"見方を変える：pre-activation","depth":3},{"id":"考察","text":"考察","depth":2},{"id":"深いほど差は大きくなる","text":"深いほど差は大きくなる","depth":3},{"id":"ほかの手法と比べる","text":"ほかの手法と比べる","depth":3},{"id":"結論","text":"結論","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"classic-cnns/resnet","relation":"referenced","topic":""},{"id":"classic-cnns/highway-networks","relation":"referenced","topic":""},{"id":"classic-cnns/inception-v4","relation":"referenced","topic":""}]}],"text":"ILSVRC 2015の分類部門で優勝したのは、Microsoft ResearchのResNetでした。アーキテクチャはごく伝統的で、畳み込みを1層ずつ積み重ね、残差接続を加えただけです。単一モデルの成績は、Googleが発表したばかりのInception-v3とほぼ同じでした。\n\n二つの路線には、それぞれのやり方があります。Inceptionは多分岐のモジュールと緻密に計算したチャネル数で計算量を抑え、ResNetは残差接続によって、とても深いネットワークでも学習できるようにします。\n\nでは、二つを組み合わせたらどうなるでしょうか？\n\n2016年2月、GoogleのChristian Szegedy、Sergey Ioffe、Vincent Vanhoucke、Alex Alemiがこの論文を公開し、のちにAAAI 2017で発表しました。タイトルには三つのことがすべて書かれています。新しいInception-v4、残差接続を加えたInception-ResNet、そして残差接続が学習に実際どんな影響を与えるのか、です。\n\n\n> [!TIP]\n> \n> この論文の二つの前作は、先に私たちのノートで読めます。\n> \n> - **[[15.12] ResNet：畳み込みネットワーク 100 層](/blog/papers/classic-cnns/resnet)**\n> - **[[15.12] Inception-v3：大きなカーネルの退場](/blog/papers/classic-cnns/inception-v3)**\n\n\n## 問題の定義\n\nこの論文は、二つの問題を同時に扱っています。\n\n一つ目は残差接続です。ResNetの著者らは、残差接続は非常に深い畳み込みネットワークを学習させるうえで**本質的に必要**なものだと主張しました。Inceptionネットワークはもともと深いので、Inceptionモジュールの最後の「チャネルの連結」を「入力への加算」に置き換えるのは自然に見えます。問題は、そうすることに何の利点があるのか、です。利点は最終的な正解率にあるのか、それとも別のところにあるのか。\n\n二つ目はInception自身です。著者らは率直に、Inception-v3は多くの歴史的なしがらみを背負っていたと認めています。初期のモデルはDistBeliefで分散学習していて、各レプリカはいくつかのサブネットワークに分けないとメモリに収まりませんでした。各サブネットワークの計算量を釣り合わせるため、各層のフィルタ数は細かく調整されていました。TensorFlowに移ってからは、この制約はなくなりました。一方で、彼らはこれまでアーキテクチャの変更に慎重で、一度に一つの部品だけを動かしてほかはそのままにしてきたので、ネットワークはどんどん複雑になっていきました。\n\nしがらみを下ろせるようになった今、Inceptionをもっと単純に、もっと深く、もっと広くできないでしょうか？\n\n## 問題の解決\n\n### しがらみを下ろす：Inception-v4\n\n[![Inception-v4の全体アーキテクチャ。下から上へ：Input 299x299x3、Stem（出力35x35x384）、4 x Inception-A（35x35x384）、Reduction-A（17x17x1024）、7 x Inception-B（17x17x1024）、Reduction-B（8x8x1536）、3 x Inception-C（8x8x1536）、Average Pooling（1536）、Dropout（keep 0.8）、Softmax（1000）](/content/papers/assets/f491d08afae7d54b8ffcbd407c61918990579e762722f0424cf7813284d73873.png)](/content/papers/assets/f491d08afae7d54b8ffcbd407c61918990579e762722f0424cf7813284d73873.png)\n\n*原論文Figure 9。[**v2 PDFの5ページ**](https://arxiv.org/pdf/1602.07261v2#page=5)から抜粋。Inception-v4の全体アーキテクチャで、右側は各段の出力サイズです。*\n\nこの図はInception-v3のアーキテクチャ表によく似ています。三つの解像度（$35\\times35$、$17\\times17$、$8\\times8$）があり、各段でInceptionモジュールをいくつか重ね、そのあいだを縮小モジュールで次の解像度に切り替えます。違いは、Inception-v4では**一つの解像度に1種類のモジュールしか使わない**ことで、数も増えています。Inception-Aが4個、Inception-Bが7個、Inception-Cが3個です。\n\n3種類のモジュールは、Inception-v3の分解の方法を受け継いでいます。\n\n- **Inception-A**（$35\\times35$）：分岐は4本で、最も長い分岐は$5\\times5$の代わりに$3\\times3$を2層使います。各分岐が96チャネルを出力し、合わせて384です。\n- **Inception-B**（$17\\times17$）：$1\\times7$と$7\\times1$の非対称な畳み込みを使い、合わせて1024チャネルです。\n- **Inception-C**（$8\\times8$）：$1\\times3$と$3\\times1$を並列に出力し、合わせて1536チャネルです。\n\n図で「V」の付いた畳み込みはvalid paddingで、ゼロ埋めしないので出力が小さくなります。付いていないものはすべてsame paddingで、出力の大きさは入力と同じです。\n\n### 入口の部分\n\nInception-v3と比べて最も目立つ変化は、ネットワークの冒頭にあります。著者らはこれをstemと呼んでいます。\n\n[![Inception-v4のstem。下から上へ：Input 299x299x3。3x3 Conv（32 stride 2 V）で149x149x32。3x3 Conv（32 V）で147x147x32。3x3 Conv（64）で147x147x64。続いて3x3 MaxPool（stride 2 V）と3x3 Conv（96 stride 2 V）の2本に分かれ、Filter concatで73x73x160。さらに2本に分かれ、一方は1x1 Conv（64）の後に3x3 Conv（96 V）、もう一方は1x1 Conv（64）、7x1 Conv（64）、1x7 Conv（64）、3x3 Conv（96 V）を通り、Filter concatで71x71x192。最後に3x3 Conv（192 V）とMaxPool（stride=2 V）の2本に分かれ、Filter concatで35x35x384](/content/papers/assets/a8aa67238a41bcf306ee4cf1d7d45c7564e9b522e9f9ea4272cbda8e3c2787e8.png)](/content/papers/assets/a8aa67238a41bcf306ee4cf1d7d45c7564e9b522e9f9ea4272cbda8e3c2787e8.png)\n\n*原論文Figure 3。[**v2 PDFの3ページ**](https://arxiv.org/pdf/1602.07261v2#page=3)から抜粋。Inception-v4とInception-ResNet-v2が共通で使うstemです。*\n\n最初の3層はInception-v3と同じで、$299\\times299$から$147\\times147\\times64$まで進みます。その後「分かれて進み、また連結する」を3回続けます。毎回、一方の分岐が縮小を担当するか、二つの分岐がそれぞれ処理してから合流します。図のとおりにたどってみましょう。\n\n```python\nimport torch\nimport torch.nn as nn\n\ndef conv(cin, cout, k, stride=1, valid=False):\n    # Vの付いた畳み込みはパディングなし。ほかの畳み込みはパディングして、出力の大きさを入力と同じにする\n    pad = 0 if valid else (k[0] // 2, k[1] // 2) if isinstance(k, tuple) else k // 2\n    return nn.Sequential(nn.Conv2d(cin, cout, k, stride, pad), nn.ReLU())\n\nx = torch.randn(1, 3, 299, 299)\n\nx = conv(3, 32, 3, stride=2, valid=True)(x)\nx = conv(32, 32, 3, valid=True)(x)\nx = conv(32, 64, 3)(x)\nprint(\"畳み込み三層の後：\", tuple(x.shape[1:]))\n\n# 1回目の並列：最大プーリング | ストライド2の畳み込み\na = nn.MaxPool2d(3, 2)(x)\nb = conv(64, 96, 3, stride=2, valid=True)(x)\nx = torch.cat([a, b], dim=1)\nprint(\"プーリング\", tuple(a.shape[1:]), \"+ 畳み込み\", tuple(b.shape[1:]), \"→\", tuple(x.shape[1:]))\n\n# 2回目の並列：二つの畳み込み分岐\na = nn.Sequential(conv(160, 64, 1), conv(64, 96, 3, valid=True))(x)\nb = nn.Sequential(conv(160, 64, 1), conv(64, 64, (7, 1)), conv(64, 64, (1, 7)), conv(64, 96, 3, valid=True))(x)\nx = torch.cat([a, b], dim=1)\nprint(\"第一の分岐\", tuple(a.shape[1:]), \"+ 第二の分岐\", tuple(b.shape[1:]), \"→\", tuple(x.shape[1:]))\n\n# 3回目の並列：ストライド2の畳み込み | 最大プーリング\na = conv(192, 192, 3, stride=2, valid=True)(x)    # プーリングの35×35と連結するには、ストライドは2でなければならない\nb = nn.MaxPool2d(3, 2)(x)\nx = torch.cat([a, b], dim=1)\nprint(\"畳み込み\", tuple(a.shape[1:]), \"+ プーリング\", tuple(b.shape[1:]), \"→\", tuple(x.shape[1:]))\n```\n\n```text\n畳み込み三層の後： (64, 147, 147)\nプーリング (64, 73, 73) + 畳み込み (96, 73, 73) → (160, 73, 73)\n第一の分岐 (96, 71, 71) + 第二の分岐 (96, 71, 71) → (192, 71, 71)\n畳み込み (192, 35, 35) + プーリング (192, 35, 35) → (384, 35, 35)\n```\n\n出力の形は、図に書かれた$73\\times73\\times160$、$71\\times71\\times192$、$35\\times35\\times384$と一致します。プーリングはチャネル数を変えないので、1回目の合流は$64+96=160$、最後は$192+192=384$です。\n\n1回目と3回目の合流は、Inception-v3で特徴マップを縮めた方法そのものです。ストライド2の畳み込みとストライド2のプーリングを並列に置き、先にプーリングすることで生じる情報のボトルネックを避けます。今回は、ネットワークの冒頭でもこの方法を使っています。\n\n### Inceptionに残差を組み込む\n\n残差版のInceptionには、著者らは比較的安価なモジュールを使っています。Inception-ResNet-v2の$35\\times35$モジュールを例に見てみましょう。\n\n[![Inception-ResNet-Aモジュール：下のRelu activationから4本の経路に分かれる。最も左の1本は上の加算記号に直接つながる。残りの3本の分岐は、1x1 Conv（32）、1x1 Conv（32）の後に3x3 Conv（32）、1x1 Conv（32）の後に3x3 Conv（48）と3x3 Conv（64）。3本の分岐の出力はまとめて1x1 Conv（384 Linear）に入り、最も左の直通経路と加算され、最後にRelu activationを通る](/content/papers/assets/cc8335c4ba4672514d3dd5e9953719d52b4f8fdd0af994c76722874543fcb864.png)](/content/papers/assets/cc8335c4ba4672514d3dd5e9953719d52b4f8fdd0af994c76722874543fcb864.png)\n\n*原論文Figure 16。[**v2 PDFの8ページ**](https://arxiv.org/pdf/1602.07261v2#page=8)から抜粋。Inception-ResNet-v2の$35\\times35$モジュール（Inception-ResNet-A）です。*\n\n純粋なInceptionモジュールと比べると、違いは二つあります。\n\n1. 分岐が細い。3本の分岐は最後に$32+32+64=128$チャネルしかなく、入力の384よりずっと少なくなっています。\n2. 分岐を連結した後に、**活性化関数のない**$1\\times1$畳み込みが1層加わり、チャネル数を384に戻してから入力と加算します。著者らはこれをfilter-expansion layerと呼び、Inceptionモジュールによる次元削減を補うものとしています。\n\n```python\nimport torch\nimport torch.nn as nn\n\ndef conv(cin, cout, k):\n    return nn.Sequential(nn.Conv2d(cin, cout, k, padding=k // 2, bias=False), nn.BatchNorm2d(cout), nn.ReLU())\n\nclass InceptionResNetA(nn.Module):\n    def __init__(self, channels=384, scale=0.1):\n        super().__init__()\n        self.b1 = conv(channels, 32, 1)\n        self.b2 = nn.Sequential(conv(channels, 32, 1), conv(32, 32, 3))\n        self.b3 = nn.Sequential(conv(channels, 32, 1), conv(32, 48, 3), conv(48, 64, 3))\n        self.expand = nn.Conv2d(32 + 32 + 64, channels, 1)   # 1×1、活性化関数なし\n        self.scale = scale\n\n    def forward(self, x):\n        branches = torch.cat([self.b1(x), self.b2(x), self.b3(x)], dim=1)\n        residual = self.expand(branches)\n        print(\"分岐を連結：\", tuple(branches.shape[1:]), \"→ 1×1で戻す：\", tuple(residual.shape[1:]))\n        return torch.relu(x + self.scale * residual)\n\nx = torch.randn(2, 384, 35, 35)\nprint(\"出力：\", tuple(InceptionResNetA()(x).shape[1:]))\n```\n\n```text\n分岐を連結： (128, 35, 35) → 1×1で戻す： (384, 35, 35)\n出力： (384, 35, 35)\n```\n\nコードの`scale`は次の節の主役なので、ひとまず置いておきます。\n\n著者らは残差版をいくつも試しましたが、論文で詳しく示しているのは二つだけです。\n\n| ネットワーク | 計算量の比較対象 | Stem | 本体 |\n| --- | --- | --- | --- |\n| Inception-ResNet-v1 | Inception-v3とほぼ同じ | 独自のstem（Figure 14） | 5 × A、Reduction-A、10 × B、Reduction-B、5 × C |\n| Inception-ResNet-v2 | Inception-v4とほぼ同じ | Inception-v4と同じ（Figure 3） | 同上、モジュールが広い |\n\n*表：原論文第3.2節とFigure 15をもとに整理。二つのネットワークの全体構造は同じで、モジュールのチャネル数が異なります。*\n\nInception-ResNet-v2とInception-v4の計算量の数字そのものは同程度ですが、著者らは、Inception-v4は実際には学習の1ステップがずっと遅く、おそらく層の数が多いためだとも述べています。\n\nもう一つ細かい点があります。Inception-ResNetでは、batch normalizationは通常の層にだけ入れ、**加算の後には入れません**。著者らによれば、batch normalizationを全面的に使うほうが良いはずですが、活性化の大きな層では、batch normalizationが不釣り合いなほどGPUメモリを食います。各モデルのレプリカをGPU 1枚に収めるためにこれらのBNを外し、その代わりにモジュールをずっと多く重ねられるようにしました。\n\n### 残差を縮めて、学習を安定させる\n\n次に、著者らは厄介な問題にぶつかりました。フィルタ数が1000を超えると残差版が不安定になり、ネットワークが学習の初期に「死んで」しまうのです。具体的な症状は、数万回のイテレーションの後、平均プーリングの直前の最後の層が0しか出力しなくなることです。学習率を下げても、この層にbatch normalizationを追加しても、元に戻りませんでした。\n\n効果のあった方法は単純です。加算の前に、残差に小さな定数を掛けておくのです。\n\n[![残差スケーリングの模式図：下のRelu activationから2本の経路に分かれ、1本は上の加算記号に直接つながり、もう1本はInceptionブロック、次にActivation Scalingブロックを通ってから加算記号につながる。加算の後はRelu activation](/content/papers/assets/80acad99318e473fe9dab6f2b4d92977d9619ab66149982bd22ff1e8067a7917.png)](/content/papers/assets/80acad99318e473fe9dab6f2b4d92977d9619ab66149982bd22ff1e8067a7917.png)\n\n*原論文Figure 20。[**v2 PDFの9ページ**](https://arxiv.org/pdf/1602.07261v2#page=9)から抜粋。Inception-ResNetモジュールの中で残差をスケーリングします。定数は通常0.1前後です。*\n\n著者らは普通、0.1〜0.3の値を選んでいます。ResNetの論文では、とても深いネットワークが不安定になったとき、まずとても低い学習率で「ウォームアップ」してから学習率を上げる2段階の学習を使っていました。著者らは、フィルタが多いと0.00001という学習率でさえ不安定さを抑えられず、その後の高い学習率がウォームアップの効果を台無しにすることもあると気づきました。それに比べ、残差のスケーリングはずっと信頼できます。もともとスケーリングなしで学習できる場合でも、スケーリングを加えて最終的な正解率が損なわれることはなく、学習もより安定しました。\n\n論文は、なぜ「死ぬ」のかを分析していません。ただ、一つ簡単に見えることがあります。Inception-ResNetの分岐にはbatch normalizationがあるので、出力の大きさはおおむね一定です。主経路の加算の後にはbatch normalizationがないので、モジュールを一つ通るたびに積み重なっていきます。単純化したモデルで、主経路の信号がどう変わるかを見てみましょう。\n\n```python\nimport torch\n\ntorch.manual_seed(0)\nx0 = torch.randn(4096, 256)                     # 主経路の信号：4096か所の位置、256チャネル\n\nfor scale in (1.0, 0.3, 0.1):\n    x = x0.clone()\n    stds = []\n    for block in range(1, 41):\n        w = torch.randn(256, 256) / 16\n        r = torch.relu(x) @ w\n        r = (r - r.mean(0)) / r.std(0)          # 分岐にはBNがある：各チャネルの出力は標準偏差1に引き戻される\n        x = x + scale * r                       # 主経路の加算の後にはBNがない\n        if block in (10, 20, 40):\n            stds.append(f\"{x.std().item():5.2f}\")\n    print(f\"スケール{scale}：10、20、40ブロック目の後の主経路の標準偏差\", \" \".join(stds))\n```\n\n```text\nスケール1.0：10、20、40ブロック目の後の主経路の標準偏差  3.31  4.57  6.42\nスケール0.3：10、20、40ブロック目の後の主経路の標準偏差  1.37  1.67  2.15\nスケール0.1：10、20、40ブロック目の後の主経路の標準偏差  1.05  1.10  1.18\n```\n\nスケーリングしないと、各モジュールが主経路とほぼ同じ大きさの信号を足し込むので、40モジュールの後の標準偏差はおよそ$\\sqrt{41}\\approx6.4$になります。0.1でスケーリングすると、各モジュールは小さな修正を加えるだけで、主経路の信号は主に直通経路から伝わってきたものになります。これは初期化時の単純化した例にすぎず、学習途中で「死ぬ」理由の説明にはなりません。論文で確かなのは実験結果だけです。スケーリングすれば、幅の広い残差ネットワークを安定して学習できます。\n\n### 学習設定\n\nInception-v3とほぼ同じです。TensorFlowの分散学習で、今回は20個のレプリカをそれぞれNVIDIA Kepler GPU 1枚で動かします。最良のモデルはRMSProp（decay 0.9、$\\epsilon=1.0$）を使い、学習率は0.045で、2エポックごとに0.94を掛けます。評価ではパラメータの移動平均を使います。\n\n## 考察\n\n### 残差で学習がずっと速くなる\n\n[![折れ線グラフで、横軸はエポック（20〜200）、縦軸はtop-1誤り率（15%〜29%）。緑の破線がinception-v3、赤の実線がinception-resnet-v1。赤線はずっと速く下がり、約80エポックで22%近くに達する。緑線が追いつくのは160エポック前後。最後は2本とも21%を少し超えたところで止まる](/content/papers/assets/2c7a11bd8741d531c7a4888f1c2efee55cf3b7f27c1fb808e2f1da765a585065.png)](/content/papers/assets/2c7a11bd8741d531c7a4888f1c2efee55cf3b7f27c1fb808e2f1da765a585065.png)\n\n*原論文Figure 21。[**v2 PDFの9ページ**](https://arxiv.org/pdf/1602.07261v2#page=9)から抜粋。計算量の近いInception-v3とInception-ResNet-v1の、学習中のtop-1誤り率（シングルクロップ）です。*\n\n赤線は残差を加えたInception-ResNet-v1、緑線はInception-v3です。赤線はずっと速く下がりますが、2本の線は最後にほぼ同じところで止まります。top-1では残差版がわずかに悪く、top-5では残差版がわずかに良くなっています。Inception-v4とInception-ResNet-v2の組でも、残差版のほうが速く学習し、最終的な成績もわずかに良くなりました。\n\n四つのモデルを並べて比べた著者らの結論は、残差版のほうが速く収束するが、最終的な正解率は主にモデルの大きさで決まる、というものです。\n\n### 単一モデルの成績\n\n| ネットワーク | Top-1誤り率 | Top-5誤り率 |\n| --- | ---: | ---: |\n| BN-Inception | 25.2% | 7.8% |\n| Inception-v3 | 21.2% | 5.6% |\n| Inception-ResNet-v1 | 21.3% | 5.5% |\n| Inception-v4 | 20.0% | 5.0% |\n| **Inception-ResNet-v2** | **19.9%** | **4.9%** |\n\n*表：原論文Table 2から抜粋。単一モデル、シングルクロップで、検証セットはブラックリストの画像を除いています。*\n\n計算量の近いもの同士の組で見ると、Inception-v3とInception-ResNet-v1はほぼ互角で、Inception-v4とInception-ResNet-v2も0.1ポイントしか違いません。組と組のあいだの差は、組の中での残差の有無による差よりずっと大きくなっています。\n\nマルチクロップの結果も同じ傾向です。\n\n| ネットワーク | クロップ数 | Top-1誤り率 | Top-5誤り率 |\n| --- | ---: | ---: | ---: |\n| ResNet-152 | 10 | 21.4% | 5.7% |\n| Inception-v3 | 12 | 19.8% | 4.6% |\n| Inception-ResNet-v1 | 12 | 19.8% | 4.6% |\n| Inception-v4 | 12 | 18.7% | 4.2% |\n| Inception-ResNet-v2 | 12 | 18.7% | 4.1% |\n| ResNet-152 | dense | 19.4% | 4.5% |\n| Inception-v3 | 144 | 18.9% | 4.3% |\n| Inception-ResNet-v1 | 144 | 18.8% | 4.3% |\n| Inception-v4 | 144 | 17.7% | 3.8% |\n| Inception-ResNet-v2 | 144 | 17.8% | 3.7% |\n\n*表：原論文Table 3とTable 4から抜粋。50,000枚の検証セット全体での結果です。*\n\n### アンサンブル\n\n| ネットワーク | モデル数 | Top-1誤り率 | Top-5誤り率 |\n| --- | ---: | ---: | ---: |\n| ResNet-152 | 6 | – | 3.6% |\n| Inception-v3 | 4 | 17.3% | 3.6% |\n| **Inception-v4 + 3 × Inception-ResNet-v2** | **4** | **16.5%** | **3.1%** |\n\n*表：原論文Table 5から抜粋。50,000枚の検証セット全体での結果です。ResNetはdense評価、Inception系列は144クロップです。*\n\nInception-v4を1つとInception-ResNet-v2を3つ組み合わせると、検証セットのtop-5誤り率は3.1%です。このアンサンブルはテストサーバーにも送られ、3.08%を得ました。著者らは特に、この1年でテストサーバーに結果を送ったのはBN-Inceptionの論文のときとILSVRC 2015のCLSLOCコンペティションのときの2回だけなので、テストセットの数字は汎化能力の実際の推定値とみなせる、と説明しています。\n\n著者らは、単一モデルでの進歩がアンサンブルではそれほどはっきり現れないことにも気づいています。\n\n### 残差接続は「必須」なのか？\n\n冒頭の一つ目の問いに戻りましょう。著者らの答えは明快です。少なくとも画像認識では、彼らの結果は、ResNetの論文の「残差接続は本質的に必須」という主張を支持しません。Inception-v4は残差接続なしでも問題なく学習でき、成績もInception-ResNet-v2と同等です。\n\n一方で、彼らは含みも残しています。残差接続の利点の全体像を見極めるには、より深いアーキテクチャと、より多くの実験点が必要かもしれません。確かなのは、残差接続で学習がずっと速くなることで、それだけでも使う価値があります。\n\n## 結論\n\nこの論文が示したネットワークは三つです。純粋なInceptionのInception-v4と、計算量をそれぞれInception-v3、Inception-v4に合わせたInception-ResNet-v1、v2です。\n\n比較の条件を先にはっきりさせておきます。Inception-ResNetのモジュールは「いくぶん場当たり的に選んだ」もので（著者らの原文ではsomewhat ad hoc）、対応する純粋なInceptionモデルと計算量が近いことだけが条件でした。著者らはもっと大きく広い版も試しており、ImageNetでの成績はよく似ていました。この条件のもとで、残差接続がもたらしたのは主に学習速度です。本当に差をつけたのはモデルの大型化で、Inception-v4とInception-ResNet-v2はどちらも、v3クラスのモデルをはっきり上回っています。\n\nこの論文の結論は、モデルを使う側にとってとても実用的です。学習時間が気になるなら、残差接続を加える。最終的な正解率が気になるなら、残差の有無よりモデルの大きさが重要です。ネットワークがとても広いときは、残差に0.1〜0.3を掛けてから足し戻すのを忘れないでください。そうしないと、学習の途中で「死んで」しまうかもしれません。\n\n残差が深いネットワークの学習に欠かせないものなのかについては、ResNetとこの論文で言い分が分かれています。同じ時期に、ResNetの著者ら自身も、残差をどうつなぐのが正しいのかを研究していました。それが次の記事の[ResNet v2](/blog/papers/classic-cnns/resnet-v2)です。\n","imageSizes":{"/content/papers/assets/f491d08afae7d54b8ffcbd407c61918990579e762722f0424cf7813284d73873.png":{"width":335,"height":941},"/content/papers/assets/a8aa67238a41bcf306ee4cf1d7d45c7564e9b522e9f9ea4272cbda8e3c2787e8.png":{"width":431,"height":1189},"/content/papers/assets/cc8335c4ba4672514d3dd5e9953719d52b4f8fdd0af994c76722874543fcb864.png":{"width":666,"height":656},"/content/papers/assets/80acad99318e473fe9dab6f2b4d92977d9619ab66149982bd22ff1e8067a7917.png":{"width":277,"height":396},"/content/papers/assets/2c7a11bd8741d531c7a4888f1c2efee55cf3b7f27c1fb808e2f1da765a585065.png":{"width":565,"height":356}}}
