{"notes":[{"id":"classic-cnns/cam","category":"classic-cnns","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"CAM","subtitle":"モデルはどこを見ている？","author":"Z. Yuan","paperDate":"2015-12-14","publishedOn":"2026-01-05","world":"external/cam","paperTitle":"Learning Deep Features for Discriminative Localization","paperUrl":"https://arxiv.org/abs/1512.04150","bibliography":{"title":"Learning Deep Features for Discriminative Localization","authors":["Bolei Zhou","Aditya Khosla","Agata Lapedriza","Aude Oliva","Antonio Torralba"],"url":"https://arxiv.org/abs/1512.04150","pdfUrl":"https://arxiv.org/pdf/1512.04150v1","codeUrl":null,"preprint":{"id":"1512.04150","submittedOn":"2015-12-14","url":"https://arxiv.org/abs/1512.04150"},"publication":null,"citation":"@misc{classiccnnscam2015,\n  title = {{Learning Deep Features for Discriminative Localization}},\n  author = {Bolei Zhou and Aditya Khosla and Agata Lapedriza and Aude Oliva and Antonio Torralba},\n  year = {2015},\n  eprint = {1512.04150},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/1512.04150}\n}\n","citationPath":"/content/papers/citations/classic-cnns/cam.2ce837236f9d.bib"},"thumbnail":{"src":"/content/papers/assets/c3c6af7f1943634784331ca03a55efc3e68a7714d936d953a14f11b0828d9cf8.png","width":1372,"height":615},"locale":"ja","path":"/content/papers/ja/classic-cnns/cam.26e443086c3a.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":2},{"id":"全結合層を外すと分類はどれだけ悪くなるか","text":"全結合層を外すと、分類はどれだけ悪くなるか？","depth":3},{"id":"弱教師あり位置特定","text":"弱教師あり位置特定","depth":3},{"id":"ほかのタスクに移す","text":"ほかのタスクに移す","depth":3},{"id":"結論","text":"結論","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"classic-cnns/nin","relation":"referenced","topic":""},{"id":"classic-cnns/zfnet","relation":"referenced","topic":""},{"id":"classic-cnns/resnet","relation":"referenced","topic":""}]},{"id":"classic-cnns/nin","category":"classic-cnns","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"NiN","subtitle":"1×1の伏線","author":"Z. Yuan","paperDate":"2013-12-16","publishedOn":"2025-09-24","world":"external/network-in-network","paperTitle":"Network In Network","paperUrl":"https://arxiv.org/abs/1312.4400","bibliography":{"title":"Network In Network","authors":["Min Lin","Qiang Chen","Shuicheng Yan"],"url":"https://arxiv.org/abs/1312.4400","pdfUrl":"https://arxiv.org/pdf/1312.4400v3","codeUrl":null,"preprint":{"id":"1312.4400","submittedOn":"2013-12-16","url":"https://arxiv.org/abs/1312.4400"},"publication":null,"citation":"@misc{classiccnnsnin2013,\n  title = {{Network In Network}},\n  author = {Min Lin and Qiang Chen and Shuicheng Yan},\n  year = {2013},\n  eprint = {1312.4400},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/1312.4400}\n}\n","citationPath":"/content/papers/citations/classic-cnns/nin.db58639ac47c.bib"},"thumbnail":{"src":"/content/papers/assets/8024fc245eb852a2c0cd34b59c18c680b92766c33d621b934dbf102c1cacda13.png","width":896,"height":330},"locale":"ja","path":"/content/papers/ja/classic-cnns/nin.05b02df5157b.md","headings":[{"id":"問題の定義","text":"問題の定義","depth":2},{"id":"問題の解決","text":"問題の解決","depth":2},{"id":"パッチごとに小さなmlpを動かす","text":"パッチごとに小さなMLPを動かす","depth":3},{"id":"全結合層を平均に置き換える","text":"全結合層を平均に置き換える","depth":3},{"id":"ネットワーク全体","text":"ネットワーク全体","depth":3},{"id":"考察","text":"考察","depth":2},{"id":"cifar-10とcifar-100","text":"CIFAR-10とCIFAR-100","depth":3},{"id":"svhnとmnist","text":"SVHNとMNIST","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":"classic-cnns/resnet","relation":"referenced","topic":""},{"id":"classic-cnns/cam","relation":"referenced","topic":""}]},{"id":"classic-cnns/zfnet","category":"classic-cnns","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"ZFNet","subtitle":"ブラックボックスの中の景色","author":"Z. Yuan","paperDate":"2013-11-12","publishedOn":"2025-09-06","world":"external/zfnet","paperTitle":"Visualizing and Understanding Convolutional Networks","paperUrl":"https://arxiv.org/abs/1311.2901","bibliography":{"title":"Visualizing and Understanding Convolutional Networks","authors":["Matthew D Zeiler","Rob Fergus"],"url":"https://arxiv.org/abs/1311.2901","pdfUrl":"https://arxiv.org/pdf/1311.2901v3","codeUrl":null,"preprint":{"id":"1311.2901","submittedOn":"2013-11-12","url":"https://arxiv.org/abs/1311.2901"},"publication":null,"citation":"@misc{classiccnnszfnet2013,\n  title = {{Visualizing and Understanding Convolutional Networks}},\n  author = {Matthew D Zeiler and Rob Fergus},\n  year = {2013},\n  eprint = {1311.2901},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/1311.2901}\n}\n","citationPath":"/content/papers/citations/classic-cnns/zfnet.6d4dd35e9f91.bib"},"thumbnail":{"src":"/content/papers/assets/6c45d745e8a2f4b60cc45bea1029353e303d5e3bbee1e62f438c71874fddf883.png","width":1200,"height":1329},"locale":"ja","path":"/content/papers/ja/classic-cnns/zfnet.4e09cca79696.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":3},{"id":"異なる画像のあいだの対応","text":"異なる画像のあいだの対応","depth":3},{"id":"考察","text":"考察","depth":2},{"id":"imagenet-2012","text":"ImageNet 2012","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/alexnet","relation":"referenced","topic":""},{"id":"classic-cnns/vgg","relation":"referenced","topic":""},{"id":"classic-cnns/resnet","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":"深い畳み込みネットワークの学習"}]}],"text":"クラスラベルしか見たことのない分類ネットワークは、物体がどこにあるかを知っているのでしょうか？\n\nMITのBolei Zhouらは前年の研究で、答えはおおむね「はい」だと気づきました。シーン分類で学習した畳み込みネットワークでは、各層の畳み込みユニットが物体検出器のように振る舞っていたのです。学習中に物体の位置を教えた人は誰もいないのに、です。ところが、この能力は全結合層に入ると消えてしまいます。畳み込み層の出力には空間的な位置がまだ残っていますが、平らにして全結合層に送ると、「どこ」と「何」が混ざり合い、切り離せなくなります。\n\n2015年12月、同じグループ（Bolei Zhou、Aditya Khosla、Agata Lapedriza、Aude Oliva、Antonio Torralba）がこの論文を公開し、のちにCVPR 2016で発表しました。彼らが目を向けたのは、すでにある部品でした。NiNが提案し、GoogLeNetも使っていたグローバル平均プーリングです。\n\n\n> [!TIP]\n> \n> グローバル平均プーリングの由来と、NiNの最後の層の特徴マップの様子は、先に私たちのノートで確認できます。\n> \n> - **[[13.12] NiN：1×1の伏線](/blog/papers/classic-cnns/nin)**\n\n\n## 問題の定義\n\nこの論文が扱うのは**弱教師あり物体位置特定**です。学習時には画像単位のクラスラベルしかないのに、テスト時には物体の位置をボックスで示さなければなりません。\n\n当時、すでにいくつかの方法がありました。画像を一部ずつ隠し、どこを隠したときに反応が最も落ちるかを見る方法。マルチインスタンス学習と畳み込み特徴を組み合わせる方法。大量に重なり合う小さなパッチのそれぞれでネットワークを実行する方法。どれもエンドツーエンドの学習ではなく、順伝播を何度も実行する必要があるので、大規模なデータには使いにくいものでした。\n\n最も近いのはOquabらの方法で、グローバル**最大**プーリングで物体の位置を特定します。ただ、見つけられるのは物体の境界上の1点だけで、物体の範囲は示せません。\n\nもう一つ関連する研究が、畳み込みネットワークの可視化です。[ZFNet](/blog/papers/classic-cnns/zfnet)はdeconvnetで各ユニットが探しているパターンを調べ、Zhouら自身の前作は、シーンを認識するネットワークの中に物体検出器があることを見つけました。これらの研究が分析しているのは畳み込み層だけで、全結合層は飛ばしています。\n\n著者らが目指したのは、ネットワークを1回順伝播させるだけで、画像のどの領域を根拠にそのクラスだと判断したのかを示せるようにすることです。\n\n## 問題の解決\n\n### スコアを空間に分解し直す\n\n著者らが使うネットワーク構造は、NiNやGoogLeNetに似ています。前半はほとんどが畳み込み層で、最後の畳み込み層の後にグローバル平均プーリングを行い、全結合層を1層つないで、softmaxに続きます。\n\n$f_k(x, y)$を、最後の畳み込み層の$k$番目のユニットの位置$(x, y)$での活性化とします。グローバル平均プーリングは、各特徴マップを1つの数に押しつぶします。\n\n$$\nF_k = \\sum_{x,y} f_k(x, y)\n$$\n\n論文はここで単純に総和として書いていて、位置の数で割る部分を省いています。違いは定数倍だけなので、この後の導出には影響しません。\n\nクラス$c$のスコアは、これらの数の重み付き和です。\n\n$$\nS_c = \\sum_k w_k^c F_k\n$$\n\n$w_k^c$は全結合層の重みで、$k$番目の特徴マップがクラス$c$にとってどれだけ重要かを表します。著者らはsoftmaxのバイアスを0にしていて、分類にはほとんど影響しないと述べています。\n\nここからが論文全体の鍵です。$F_k$を代入し、二つの総和の順序を入れ替えます。\n\n$$\nS_c = \\sum_k w_k^c \\sum_{x,y} f_k(x, y) = \\sum_{x,y} \\sum_k w_k^c f_k(x, y)\n$$\n\n内側の$\\sum_k w_k^c f_k(x, y)$には、まだ位置$(x, y)$が残っています。著者らはこれを、クラス$c$の**クラス活性化マップ**（class activation map、CAM）と定義しました。\n\n$$\nM_c(x, y) = \\sum_k w_k^c f_k(x, y)\n$$\n\nすると$S_c = \\sum_{x,y} M_c(x, y)$です。クラスのスコアはCAM上のすべての位置の総和そのものであり、$M_c(x, y)$は、位置$(x, y)$がこのスコアにどれだけ寄与しているかを直接示しています。\n\n言い換えると、分類では先に平均してから重み付けします。CAMはその順序を逆にして、先に重み付けし、空間は平均せずに残します。小さな例で確かめてみましょう。\n\n```python\nimport torch\n\ntorch.manual_seed(0)\nK, C = 4, 3                                   # 特徴マップ4枚、クラス3個\nf = torch.relu(torch.randn(K, 7, 7))          # 最後の畳み込み層の出力：4 × 7 × 7\nw = torch.randn(C, K)                         # GAPの後の全結合層：クラスごとに4個の重みが1組\n\n# 分類：先に平均し、それから重み付け\nscores = w @ f.mean(dim=(1, 2))               # [3]\n\n# CAM：先に重み付けし、空間を残す\ncams = torch.einsum('ck,khw->chw', w, f)      # [3, 7, 7]\n\nprint(\"分類スコア： \", scores)\nprint(\"各CAMの平均：\", cams.mean(dim=(1, 2)))\nprint(cams.shape)\n```\n\n```text\n分類スコア：  tensor([-1.0399, -0.8521, -0.5210])\n各CAMの平均： tensor([-1.0399, -0.8521, -0.5210])\ntorch.Size([3, 7, 7])\n```\n\n二組の数字はまったく同じです。CAMは新しいパラメータを一つも使わず、ネットワークをもう一度実行する必要もありません。学習済みの全結合層の重みを、最後の畳み込み層の特徴マップへ「投影」し直しているだけです。\n\n[![上半分はネットワーク：犬を抱いた男の子の写真が一連の畳み込み層を通り、最後の畳み込み層の複数の特徴マップがGAPを通って、重みw1、w2からwnでAustralian terrierというクラスにつながる。下半分のタイトルはClass Activation Mapping：w1、w2、wnをそれぞれ対応する特徴マップに掛けて足し合わせ、元の画像に重ねたヒートマップを得る。最も明るい位置は犬の体の上にある](/content/papers/assets/c3c6af7f1943634784331ca03a55efc3e68a7714d936d953a14f11b0828d9cf8.png)](/content/papers/assets/c3c6af7f1943634784331ca03a55efc3e68a7714d936d953a14f11b0828d9cf8.png)\n\n*原論文Figure 2。[**v1 PDFの3ページ**](https://arxiv.org/pdf/1512.04150v1#page=3)から抜粋。予測されたクラスのスコアが一つ前の畳み込み層へ写し戻され、クラス活性化マップが生成されます。*\n\n図の下半分が$M_c$の計算です。各特徴マップは、それぞれある種の視覚パターンを検出しています。犬の頭で明るくなるものもあれば、下の胴体で明るくなるものもあります。「Australian terrier」というクラスの重みを掛けて足し合わせたものが、このクラスのヒートマップです。最後の畳み込み層の解像度はとても低い（論文では$13\\times13$か$14\\times14$）ので、CAMを入力画像の大きさまで拡大すると、画像のどの領域がこのクラスと最も関係しているかが見えてきます。\n\n同じ画像でもクラスを替えれば重みの組も替わり、CAMもそれに応じて変わります。\n\n[![左上はドームのある建物の夜景写真で、タイトルはdome。残りの5マスは予測上位5クラスのCAMとスコア：palace 0.459は下側に横に広がる宮殿の本体で明るい。dome 0.195は上側のドームで明るい。church 0.146、altar 0.091、monastery 0.051の明るい点は、建物の左下と尖塔のあたりに集まっている](/content/papers/assets/5feae5d21639fe423e9457b6eee11d7c4357e0fab4014dac2dd2482a810f0c45.png)](/content/papers/assets/5feae5d21639fe423e9457b6eee11d7c4357e0fab4014dac2dd2482a810f0c45.png)\n\n*原論文Figure 4。[**v1 PDFの4ページ**](https://arxiv.org/pdf/1512.04150v1#page=4)から抜粋。正解クラスはdome（ドーム）で、残りの5マスは予測上位5クラスのCAMです。各マスの上にクラスとスコアがあります。*\n\npalace（宮殿）は下側の平たい建物本体で明るく、domeは上側のドームで明るくなっています。二つのクラスを判断するとき、ネットワークは同じ画像の別々の場所を見ているのです。\n\n### 平均と最大の違い\n\nOquabらがグローバル最大プーリングを使っていたので、著者らは平均を使う理由を特に説明しています。\n\n彼らの直観はこうです。平均をとる場合、スコアを高くするには、物体の識別に役立つ部分を**すべて**見つけるのが一番です。どこか1か所でも活性化が低ければ、平均が下がるからです。最大値をとる場合は、最も強い1か所だけが効き、ほかの位置の高低は影響しません。\n\nこの違いは、逆伝播のときに最もはっきり見えます。\n\n```python\nimport torch\n\ntorch.manual_seed(0)\nx = torch.rand(1, 1, 4, 4, requires_grad=True)\n\nx.mean().backward()                           # グローバル平均プーリング\nprint(\"GAPの勾配：\\n\", x.grad[0, 0])\n\nx.grad = None\nx.amax().backward()                           # グローバル最大プーリング\nprint(\"GMPの勾配：\\n\", x.grad[0, 0])\n```\n\n```text\nGAPの勾配：\n tensor([[0.0625, 0.0625, 0.0625, 0.0625],\n        [0.0625, 0.0625, 0.0625, 0.0625],\n        [0.0625, 0.0625, 0.0625, 0.0625],\n        [0.0625, 0.0625, 0.0625, 0.0625]])\nGMPの勾配：\n tensor([[0., 0., 0., 0.],\n        [0., 0., 0., 1.],\n        [0., 0., 0., 0.],\n        [0., 0., 0., 0.]])\n```\n\n平均プーリングは勾配を16か所に均等に配るので、どの位置も学習されます。最大プーリングは最大の1マスにしか勾配を送らず、ほかの15マスはこのステップで何も学べません。この直観が位置特定で成り立つかは、後の実験で確かめます。\n\n### 最後の層の解像度を少し上げる\n\n著者らはAlexNet、VGGnet、GoogLeNetの三つのネットワークを改造しました。最後の全結合層を取り除いてGAPに置き換え、全結合のsoftmax層を1層つなぎます。\n\n彼らは、GAPの直前の最後の畳み込み層の空間解像度が高いほど、位置特定の能力が高くなることに気づきました。著者らはこの解像度をmapping resolutionと呼んでいます。これを上げるために、さらにいくつかの層を削りました。\n\n- **AlexNet**：conv5以降の層をすべて削り、$13\\times13$を得ます。\n- **VGGnet**：conv5-3以降の層をすべて削り、$14\\times14$を得ます。\n- **GoogLeNet**：inception4e以降の層をすべて削り、$14\\times14$を得ます。\n\n各ネットワークに、$3\\times3$、ストライド1、パディング1、1024ユニットの畳み込み層を1層加え、GAPとsoftmaxをつないでから、ILSVRCの130万枚の学習画像で1000クラス分類のファインチューニングを行います。得られたネットワークを、それぞれAlexNet-GAP、VGGnet-GAP、GoogLeNet-GAPと呼びます。著者らは脚注で、ゼロから学習しても結果はほぼ同じだったと述べています。\n\n### ヒートマップからボックスへ\n\nILSVRCの位置特定の評価で求められるのはボックスです。著者らの方法は単純です。\n\n1. CAMを画像の大きさまで拡大します。\n2. 値が最大値の20%を超える領域を残します。\n3. 最大の連結領域をとり、その外接矩形を描きます。\n\n作り物の$14\\times14$のCAMで一度たどってみましょう。左側に大きな反応が一つ、右上に小さな反応が一つあります。\n\n```python\nimport torch\nimport torch.nn.functional as F\nfrom scipy import ndimage\n\n# 14×14のCAM：左側に大きな反応、右上に小さな反応\nyy, xx = torch.meshgrid(torch.arange(14.), torch.arange(14.), indexing='ij')\ncam = 1.0 * torch.exp(-((yy - 8) ** 2 / 6 + (xx - 4) ** 2 / 4)) \\\n    + 0.6 * torch.exp(-((yy - 2) ** 2 + (xx - 11) ** 2) / 1.5)\n\n# 1. 入力画像の大きさまで拡大する\ncam = F.interpolate(cam[None, None], size=(224, 224), mode='bilinear', align_corners=False)[0, 0]\n\n# 2. 最大値の20%を超える領域を残す\nmask = (cam > 0.2 * cam.max()).numpy()\n\n# 3. 最大の連結領域を見つけ、外接矩形をとる\nlabels, n = ndimage.label(mask)\nsizes = ndimage.sum(mask, labels, range(1, n + 1))\nlargest = labels == (sizes.argmax() + 1)\nrows, cols = largest.any(axis=1).nonzero()[0], largest.any(axis=0).nonzero()[0]\n\nprint(\"連結領域の数：\", n, \"、それぞれの画素数：\", sizes.astype(int).tolist())\nprint(\"ボックス（x0, y0, x1, y1）：\", cols[0], rows[0], cols[-1], rows[-1])\n```\n\n```text\n連結領域の数： 2 、それぞれの画素数： [1344, 6552]\nボックス（x0, y0, x1, y1）： 30 85 113 186\n```\n\n右上の塊もしきい値を超えていますが、面積が小さいので、最終的なボックスは左側の大きな領域だけを囲みます。ここからこの方法の限界も見えます。同じ画像に物体が二つあっても、囲めるのはそのうち一つだけです。top-5の位置特定の評価では、予測上位5クラスのそれぞれについて、これを1回ずつ行います。\n\n## 考察\n\n### 全結合層を外すと、分類はどれだけ悪くなるか？\n\n| ネットワーク | Top-1誤り率 | Top-5誤り率 |\n| --- | ---: | ---: |\n| AlexNet | 42.6 | 19.5 |\n| AlexNet-GAP | 51.1 | 26.3 |\n| AlexNet\\*-GAP | 44.9 | 20.9 |\n| VGGnet | 31.2 | 11.4 |\n| VGGnet-GAP | 33.4 | 12.2 |\n| GoogLeNet | 31.9 | 11.3 |\n| GoogLeNet-GAP | 35.0 | 13.2 |\n| GoogLeNet-GMP | 35.6 | 13.9 |\n| NIN | 41.9 | 19.6 |\n\n*表：原論文Table 1から抜粋。ILSVRC検証セット、単位はパーセントです。元のネットワークと比べやすいよう、行の順序を並べ替えています。*\n\nVGGnetとGoogLeNetは、いくつかの層を外すと、top-1誤り率がそれぞれ2.2ポイントと3.1ポイント増え、top-5はどちらも増加が2ポイント未満でした。AlexNetが最も大きな影響を受け、top-1誤り率は42.6%から51.1%まで悪化しました。著者らがGAPの前に畳み込み層を2層追加したAlexNet\\*-GAPでは、元のAlexNetとほぼ同じになります。GAPとGMPの分類性能も近く、これは予想どおりです。\n\n分類の性能が落ちすぎては困ります。位置特定の評価では、クラスとボックスの両方が正しくなければならないからです。\n\n### 弱教師あり位置特定\n\n| 手法 | Top-1誤り率 | Top-5誤り率 |\n| --- | ---: | ---: |\n| **GoogLeNet-GAP** | **56.40** | **43.00** |\n| VGGnet-GAP | 57.20 | 45.14 |\n| GoogLeNet-GMP | 57.78 | 45.26 |\n| GoogLeNet | 60.09 | 49.34 |\n| AlexNet\\*-GAP | 63.75 | 49.53 |\n| Backprop on GoogLeNet | 61.31 | 50.55 |\n| Backprop on VGGnet | 61.12 | 51.46 |\n| AlexNet-GAP | 67.19 | 52.16 |\n| Backprop on AlexNet | 65.17 | 52.64 |\n| NIN | 65.47 | 54.19 |\n\n*表：原論文Table 2から抜粋。ILSVRC検証セットでの位置特定の誤り率で、top-5の順に並べています。Backpropは、CAMの代わりにSimonyanらの逆伝播による顕著性マップを使ったものです。*\n\nいくつか比べてみます。\n\n- **CAM対逆伝播**：GoogLeNetとVGGnetでは、CAMのtop-5誤り率は逆伝播より6ポイント以上低くなっています。AlexNetでは両者は近く（52.16対52.64）、top-1ではむしろ逆伝播のほうが少し良い結果です。\n- **GoogLeNet-GAP対GoogLeNet**：元のGoogLeNetのほうが分類は良いのに、位置特定では層を削ったGoogLeNet-GAPに負けています。著者らは、元のGoogLeNetの最後の層が$7\\times7$しかなく、解像度が低すぎるためだと考えています。\n- **GAP対GMP**：分類はほぼ同じですが、位置特定ではGAPのtop-5誤り率が2.26ポイント低く、先ほどの平均プーリングの直観を裏づけています。\n\n[![左右2組。a)4つの例で、それぞれ元の画像とCAMが1枚ずつある：アメリカアリゲーター、迷路、シェットランド・シープドッグ、バッタ。元の画像の緑がアノテーションのボックス、赤がCAMから推定したボックスで、両者はおおむね重なる。b)上段の2例はGoogLeNet-GAPによるスノーモービルとエプロンの位置特定で、ヒートマップは物体に集中している。下段の2例はAlexNetの逆伝播の結果で、ヒートマップは散らばった点になり、推定したボックスは大きすぎる](/content/papers/assets/dce42d560109e416d7229359699d2bca63f7ec9a74374b2d62fce387c9bbed22.png)](/content/papers/assets/dce42d560109e416d7229359699d2bca63f7ec9a74374b2d62fce387c9bbed22.png)\n\n*原論文Figure 6。[**v1 PDFの6ページ**](https://arxiv.org/pdf/1512.04150v1#page=6)から抜粋。a)GoogLeNet-GAPの位置特定の例。b)上段の2例はGoogLeNet-GAP、下段の2例はAlexNetの逆伝播。緑のボックスがアノテーション、赤のボックスがヒートマップから推定したボックスです。*\n\n右側の比較は直観的です。逆伝播の顕著性マップは散らばった明るい点の集まりで、しきい値で切るとボックスが大きくなりすぎます。CAMは強く反応する領域がまとまっていて、ボックスも物体に比較的ぴったり合っています。\n\nテストセットでは、著者らはボックスの選び方を変えました。予測1位と2位のクラスからはそれぞれきついボックスとゆるいボックスを1つずつ、3位のクラスからはゆるいボックスを1つとります。このヒューリスティックは、検証セットで調整したものです。\n\n| 手法 | 教師の種類 | Top-5テスト誤り率 |\n| --- | --- | ---: |\n| GoogLeNet-GAP（ヒューリスティックでボックスを選択） | 弱教師あり | **37.1** |\n| GoogLeNet-GAP | 弱教師あり | 42.9 |\n| Backprop | 弱教師あり | 46.4 |\n| GoogLeNet | 全教師あり | 26.7 |\n| OverFeat | 全教師あり | 29.9 |\n| AlexNet | 全教師あり | 34.2 |\n\n*表：原論文Table 3から抜粋。ILSVRCテストセット。*\n\n37.1%は、全教師ありのAlexNet（34.2%）にすでに迫っています。しかもGoogLeNet-GAPは、学習中にボックスを一つも見ていません。それでも差はまだ大きいと著者らも認めています。同じGoogLeNetのアーキテクチャでも、全教師ありなら26.7%に届きます。\n\n### ほかのタスクに移す\n\n著者らは、この位置特定のできる特徴を、そのままほかのデータセットに使えるかも調べました。GoogLeNet-GAPを固定し、GAPの出力の上で線形SVMを学習させ、SVMの重みを元のsoftmaxの重みの代わりに使ってCAMを計算します。\n\n汎用の画像特徴として使うと、GoogLeNet-GAPはSUN397、MIT Indoor67、Caltech256など八つのデータセットで、元のGoogLeNetの平均プーリング層の特徴と同程度の性能を示し、大半のデータセットでAlexNetのfc7をはっきり上回りました。\n\n細粒度分類のCUB-200-2011鳥類データセットでの結果は、より興味深いものです。200種の鳥、5,994枚の学習画像、5,794枚のテスト画像があり、鳥のボックスも付いています。\n\n| 手法 | 学習・テストで使うアノテーション | 正解率 |\n| --- | --- | ---: |\n| GoogLeNet-GAP、画像全体 | なし | 63.0% |\n| GoogLeNet-GAP、CAMから推定したボックス | なし | 67.8% |\n| GoogLeNet-GAP、アノテーションのボックス | ボックス | 70.5% |\n| PANDA R-CNN | ボックス＋部位 | 76.4% |\n\n*表：原論文Table 4の一部の行を抜粋。*\n\nCAMでまず鳥をボックスで囲み、ボックスの中から特徴を抽出し直すと、アノテーションを一切使わずに、正解率は63.0%から67.8%に上がります。CAMから推定したボックスは、IoU 0.5の基準で41.0%が正解で、ランダムに当てた場合は5.5%です。細粒度分類では違いがわずかな細部にしかないことが多く、まず注意を鳥に集中させることの効果ははっきりしています。\n\n最後の実験群は「パターンの発見」です。共通の概念を持つ画像群を与え、CAMがその概念の上で明るくなるかを見ます。その一つが、文字の検出に関わる例です。\n\n[![上段は店先を写した6枚の街の写真、下段は対応するCAM。強く反応する領域はどれも店の看板の文字の上にある。たとえば日よけに書かれた店名や、入口の上の看板](/content/papers/assets/89c6a4410389b611bdcc7e40a414223d52106f89494e17ede86188b4552d73a0.png)](/content/papers/assets/89c6a4410389b611bdcc7e40a414223d52106f89494e17ede86188b4552d73a0.png)\n\n*原論文Figure 11。[**v1 PDFの8ページ**](https://arxiv.org/pdf/1512.04150v1#page=8)から抜粋。弱教師ありの文字検出器：ネットワークは文字やボックスを一切使わずに学習していますが、CAMはそれでも文字の上で明るくなります。*\n\n正例はSVTデータセットの、文字を含むGoogleストリートビュー画像350枚、負例はSUNデータセットからランダムに選んだ屋外シーンです。「この画像に文字があるか」という二値のラベルだけで、CAMは看板の文字の上に現れます。論文ではほかにも、シーン内の重要な物体、フレーズで表される概念の位置特定、視覚的質問応答モデルの答えの説明を試しています。\n\n著者らはもう一つ試しています。GAPの後の重みを使い、最後の畳み込み層のユニットを、あるクラスにとっての重要度の順に並べ、そのクラスを判断するうえでどのユニットが最も重要かを直接見るのです。たとえばlakeland terrierというテリアにとって重要なユニットは犬の顔と体毛を検出し、リビングルームにとって重要なユニットはソファ、テーブル、暖炉を検出しています。\n\n## 結論\n\nCAMそのものは1行の式にすぎません。分類層の重みを最後の層の特徴マップに掛け戻すだけです。これが成り立つのは、GAPの後に線形層が1層しかなく、クラスのスコアを各位置に分解し直せるからです。それがCAMの前提でもあります。ネットワークは「畳み込み、GAP、全結合1層」という構造でなければならず、ほかのネットワークは先にアーキテクチャを変えてファインチューニングし直す必要があり、そのせいで分類の正解率が下がることもあります。\n\n実験では、CAMはILSVRCの弱教師あり位置特定でtop-5誤り率37.1%を出し、全教師ありのAlexNetに近づきましたが、同じアーキテクチャの全教師ありGoogLeNetとはまだ距離があります。1枚の画像で最大の連結領域のボックスしかとらないので、主要な物体が1つだけの画像に向いています。\n\nCAMのアーキテクチャ上の制約には、すぐに手が打たれました。2016年10月の[Grad-CAM](https://arxiv.org/abs/1610.02391)は、勾配を使って各特徴マップの重みを決めるので、GAPのアーキテクチャに変える必要も、学習し直す必要もありません。\n\nCAMを使うハードルはとても低く、ネットワークの末端がGAPと全結合1層なら、数行のコードで計算できます。今よく使われる[ResNet](/blog/papers/classic-cnns/resnet)はちょうどこの構造なので、モデルがどこを見ているかを知りたければ、すぐに1枚描けます。\n\nただし、ヒートマップを真に受けすぎないでください。示されるのは最も識別に役立つ部位、たとえば動物の頭で、物体の一部しか覆っていないことがよくあります。\n","imageSizes":{"/content/papers/assets/c3c6af7f1943634784331ca03a55efc3e68a7714d936d953a14f11b0828d9cf8.png":{"width":1372,"height":615},"/content/papers/assets/5feae5d21639fe423e9457b6eee11d7c4357e0fab4014dac2dd2482a810f0c45.png":{"width":672,"height":462},"/content/papers/assets/dce42d560109e416d7229359699d2bca63f7ec9a74374b2d62fce387c9bbed22.png":{"width":1381,"height":304},"/content/papers/assets/89c6a4410389b611bdcc7e40a414223d52106f89494e17ede86188b4552d73a0.png":{"width":669,"height":235}}}
