{"notes":[{"id":"classic-cnns/wide-resnet","category":"classic-cnns","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"Wide ResNet","subtitle":"加寬不加深","author":"Z. Yuan","paperDate":"2016-05-23","publishedOn":"2024-02-14","world":"external/wide-resnet","paperTitle":"Wide Residual Networks","paperUrl":"https://arxiv.org/abs/1605.07146","bibliography":{"title":"Wide Residual Networks","authors":["Sergey Zagoruyko","Nikos Komodakis"],"url":"https://arxiv.org/abs/1605.07146","pdfUrl":"https://arxiv.org/pdf/1605.07146v4","codeUrl":null,"preprint":{"id":"1605.07146","submittedOn":"2016-05-23","url":"https://arxiv.org/abs/1605.07146"},"publication":{"venue":"BMVC","year":2016,"kind":"conference","url":"https://doi.org/10.5244/C.30.87"},"citation":"@misc{classiccnnswideresnet2016,\n  title = {{Wide Residual Networks}},\n  author = {Sergey Zagoruyko and Nikos Komodakis},\n  year = {2016},\n  eprint = {1605.07146},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/1605.07146}\n}\n","citationPath":"/content/papers/citations/classic-cnns/wide-resnet.2e42de74f658.bib"},"thumbnail":{"src":"/content/papers/assets/eb123078c88654918b04d17b5ebccd1009fc7fbc33305ebd9ba853f2ad2cc024.png","width":1400,"height":500},"locale":"zh-hant","path":"/content/papers/zh-hant/classic-cnns/wide-resnet.9aefa55a43c2.md","headings":[{"id":"定義問題","text":"定義問題","depth":2},{"id":"越做越細的-resnet","text":"越做越細的 ResNet","depth":3},{"id":"捷徑太好走","text":"捷徑太好走","depth":3},{"id":"細長的網路也跑不快","text":"細長的網路也跑不快","depth":3},{"id":"解決問題","text":"解決問題","depth":2},{"id":"能動的地方","text":"能動的地方","depth":3},{"id":"wrn-n-k","text":"WRN-n-k","depth":3},{"id":"區塊裡要放什麼","text":"區塊裡要放什麼","depth":3},{"id":"把-dropout-放進區塊","text":"把 dropout 放進區塊","depth":3},{"id":"討論","text":"討論","depth":2},{"id":"寬度和深度怎麼分","text":"寬度和深度怎麼分","depth":3},{"id":"和千層-resnet-比","text":"和千層 ResNet 比","depth":3},{"id":"寬的跑得比較快","text":"寬的跑得比較快","depth":3},{"id":"dropout-的效果","text":"Dropout 的效果","depth":3},{"id":"imagenet-要加寬中間那層","text":"ImageNet 要加寬中間那層","depth":3},{"id":"結論","text":"結論","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"classic-cnns/resnet-v2","relation":"referenced","topic":""},{"id":"classic-cnns/stochastic-depth","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":"2024-01-11","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":{"venue":"ECCV","year":2016,"kind":"conference","url":"https://doi.org/10.1007/978-3-319-46493-0_38"},"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":"zh-hant","path":"/content/papers/zh-hant/classic-cnns/resnet-v2.a7e4330b6bba.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":""}]},{"id":"classic-cnns/stochastic-depth","category":"classic-cnns","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"Stochastic Depth","subtitle":"今天這層請假","author":"Z. Yuan","paperDate":"2016-03-30","publishedOn":"2024-01-24","world":"external/stochastic-depth","paperTitle":"Deep Networks with Stochastic Depth","paperUrl":"https://arxiv.org/abs/1603.09382","bibliography":{"title":"Deep Networks with Stochastic Depth","authors":["Gao Huang","Yu Sun","Zhuang Liu","Daniel Sedra","Kilian Weinberger"],"url":"https://arxiv.org/abs/1603.09382","pdfUrl":"https://arxiv.org/pdf/1603.09382v3","codeUrl":null,"preprint":{"id":"1603.09382","submittedOn":"2016-03-30","url":"https://arxiv.org/abs/1603.09382"},"publication":{"venue":"ECCV","year":2016,"kind":"conference","url":"https://doi.org/10.1007/978-3-319-46493-0_39"},"citation":"@misc{classiccnnsstochasticdepth2016,\n  title = {{Deep Networks with Stochastic Depth}},\n  author = {Gao Huang and Yu Sun and Zhuang Liu and Daniel Sedra and Kilian Weinberger},\n  year = {2016},\n  eprint = {1603.09382},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/1603.09382}\n}\n","citationPath":"/content/papers/citations/classic-cnns/stochastic-depth.3716109ef477.bib"},"thumbnail":{"src":"/content/papers/assets/620e6ddf909f1f405e38b6055bd732ae4c4b7c208f147e00b870a56642020c02.png","width":963,"height":339},"locale":"zh-hant","path":"/content/papers/zh-hant/classic-cnns/stochastic-depth.f220fadf4066.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":"imagenet-上沒有贏","text":"ImageNet 上沒有贏","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/resnet-v2","relation":"referenced","topic":""},{"id":"classic-cnns/densenet","relation":"referenced","topic":""}]}],"text":"2016 年上半年，ResNet 的層數一路往上衝。\n\nResNet 的作者把殘差單元改成 pre-activation，在 CIFAR-10 上訓練了 1001 層的網路；同一時期的 Stochastic Depth 也把網路疊到 1202 層。\n\n\n> [!TIP]\n> \n> 這兩篇都有筆記，可以先看看：\n> \n> - **[[16.03] ResNet v2：捷徑要乾淨](/blog/papers/classic-cnns/resnet-v2)**\n> - **[[16.03] Stochastic Depth：今天這層請假](/blog/papers/classic-cnns/stochastic-depth)**\n\n\n層數越多，成績確實越好，只是越來越貴。pre-activation ResNet 從 110 層加到 1001 層，CIFAR-10 的錯誤率從 6.37% 降到 4.92%。層數多了九倍，錯誤率少了不到一個半百分點，訓練時間也跟著拉長。\n\n法國國立路橋學校（École des Ponts ParisTech）的 Sergey Zagoruyko 與 Nikos Komodakis 換了一個方向想，ResNet 一定要這麼細嗎？\n\n他們把網路變寬、變淺。\n\n## 定義問題\n\n### 越做越細的 ResNet\n\nResNet 的作者在設計時偏好細長的網路，用省下來的參數換更多層。後來的 bottleneck 區塊先用 $1\\times1$ 卷積降維，做完 $3\\times3$ 卷積再升回來，讓每個區塊又更細了一點。\n\n拿 CIFAR 用的 ResNet 來看，三個階段的通道數只有 16、32、64。在它之前的 VGG 和 Inception，通道數都比這寬得多。\n\n### 捷徑太好走\n\n作者指出，恆等捷徑讓 ResNet 能訓練到上千層，同時也是它的弱點。\n\n梯度可以沿著捷徑一路往回走，沒有任何機制強迫它經過殘差分支的權重。訓練下來，可能只有少數幾個區塊學到有用的東西，或是很多區塊各自只貢獻一點點。作者把這個現象叫做 diminishing feature reuse。\n\n作者拿 Stochastic Depth 當佐證。訓練時隨機關掉整個殘差區塊，網路反而變好，在作者看來，這說明很多區塊本來就沒做多少事。\n\n### 細長的網路也跑不快\n\nGPU 擅長一次處理大張量，細長的網路卻是一長串小卷積，必須一層等一層地算。作者在摘要裡提到，每多一點點準確率，層數就要差不多加倍，訓練也就越來越慢。\n\n於是作者想弄清楚，同樣的參數拿去加深好，還是拿去加寬好？ResNet 到底該多寬？\n\n## 解決問題\n\n### 能動的地方\n\n作者以 ResNet v2 的 pre-activation 區塊為起點，也就是每個卷積之前先做 BN 和 ReLU。要讓一個殘差區塊表達能力更強，大致有三種做法：\n\n1. 在區塊裡多放幾層卷積。\n2. 把卷積變寬，多一些通道。\n3. 把卷積核變大。\n\n第三種先排除了，VGG 和 Inception 系列的研究都已經說明 $3\\times3$ 這種小卷積核很有效。剩下的兩種，作者各給一個係數。**加深係數 $l$** 是一個區塊裡有幾層卷積，**加寬係數 $k$** 是通道數要乘上幾倍。原本的區塊就是 $l=2$、$k=1$。\n\n[![四種殘差區塊的示意圖，每張圖左邊是灰色的捷徑，右邊是殘差分支，兩者在下方相加。(a) basic：兩個 conv3x3；(b) bottleneck：conv1x1、conv3x3、conv1x1，中間的 conv3x3 比較窄；(c) basic-wide：兩個較寬的 conv3x3；(d) wide-dropout：兩個較寬的 conv3x3 之間夾一層 dropout](/content/papers/assets/eb123078c88654918b04d17b5ebccd1009fc7fbc33305ebd9ba853f2ad2cc024.png)](/content/papers/assets/eb123078c88654918b04d17b5ebccd1009fc7fbc33305ebd9ba853f2ad2cc024.png)\n\n*原論文 Figure 1，取自 [**v4 PDF 第 2 頁**](https://arxiv.org/pdf/1605.07146v4#page=2)。論文用到的四種殘差區塊，每個卷積之前都有 BN 和 ReLU，圖上省略。*\n\n圖上方塊的寬度代表通道數。(a) 是原本的 basic 區塊，(c) 結構一樣，只是兩層卷積都變寬了。(b) 的 bottleneck 是 ResNet 用來把網路做細的工具，和這篇要研究的加寬方向相反，所以作者不考慮它，後面都從 basic 區塊出發。(d) 是在兩層卷積之間加 dropout，後面再談。\n\n### WRN-n-k\n\n網路的骨架沿用 ResNet v2 在 CIFAR 上的設計，只多了加寬係數 $k$：\n\n| 組別 | 輸出大小 | 內容 |\n| --- | --- | --- |\n| conv1 | $32\\times32$ | $3\\times3$ 卷積，16 個通道 |\n| conv2 | $32\\times32$ | $N$ 個區塊，每個是兩層 $3\\times3$ 卷積，$16k$ 個通道 |\n| conv3 | $16\\times16$ | $N$ 個區塊，$32k$ 個通道 |\n| conv4 | $8\\times8$ | $N$ 個區塊，$64k$ 個通道 |\n| avg-pool | $1\\times1$ | $8\\times8$ 平均池化，接分類層 |\n\n*表：整理自原論文 Table 1。conv3 和 conv4 的第一層負責把特徵圖縮小一半；$k=1$ 就是原本的 pre-activation ResNet。*\n\n作者用 **WRN-$n$-$k$** 表示一個網路，$n$ 是卷積層的總數，$k$ 是加寬係數。官方程式要求 $n=6N+4$，所以 WRN-28-10 就是每組 $N=4$ 個區塊、通道數乘上 10 倍的網路。\n\n$k$ 對參數量的影響是平方級的。一層輸入、輸出都是 $C$ 個通道的 $3\\times3$ 卷積，有 $9C^2$ 個權重，通道數加倍，權重就變成四倍。我們照上表搭幾個網路，數一下參數：\n\n```python\nimport torch.nn as nn\n\nclass Block(nn.Module):\n    \"\"\"BN-ReLU-conv3×3-BN-ReLU-conv3×3，形狀改變時捷徑用 1×1 卷積\"\"\"\n    def __init__(self, cin, cout, stride):\n        super().__init__()\n        self.body = nn.Sequential(\n            nn.BatchNorm2d(cin), nn.ReLU(), nn.Conv2d(cin, cout, 3, stride, 1, bias=False),\n            nn.BatchNorm2d(cout), nn.ReLU(), nn.Conv2d(cout, cout, 3, 1, 1, bias=False))\n        self.shortcut = (nn.Identity() if cin == cout and stride == 1\n                         else nn.Conv2d(cin, cout, 1, stride, bias=False))\n\n    def forward(self, x):\n        return self.shortcut(x) + self.body(x)\n\ndef wrn(n, k, num_classes=10):\n    N = (n - 4) // 6                       # 每組的區塊數\n    widths = [16 * k, 32 * k, 64 * k]\n    layers, cin = [nn.Conv2d(3, 16, 3, 1, 1, bias=False)], 16\n    for width, stride in zip(widths, (1, 2, 2)):\n        for i in range(N):\n            layers.append(Block(cin, width, stride if i == 0 else 1))\n            cin = width\n    layers += [nn.BatchNorm2d(cin), nn.ReLU(), nn.AdaptiveAvgPool2d(1), nn.Flatten(), nn.Linear(cin, num_classes)]\n    return nn.Sequential(*layers)\n\nfor n, k in [(40, 1), (40, 2), (40, 4), (16, 8), (22, 8), (28, 10)]:\n    params = sum(p.numel() for p in wrn(n, k).parameters())\n    print(f\"WRN-{n}-{k}：每組 {(n - 4) // 6} 個區塊，通道 {16*k}/{32*k}/{64*k}，參數 {params / 1e6:.1f}M\")\n```\n\n```text\nWRN-40-1：每組 6 個區塊，通道 16/32/64，參數 0.6M\nWRN-40-2：每組 6 個區塊，通道 32/64/128，參數 2.2M\nWRN-40-4：每組 6 個區塊，通道 64/128/256，參數 8.9M\nWRN-16-8：每組 2 個區塊，通道 128/256/512，參數 11.0M\nWRN-22-8：每組 3 個區塊，通道 128/256/512，參數 17.2M\nWRN-28-10：每組 4 個區塊，通道 160/320/640，參數 36.5M\n```\n\n這幾個數字和論文表格上的參數量一致。同樣 40 層，$k$ 從 1 變 2 再變 4，參數從 0.6M 變成 2.2M、8.9M，每次大約四倍。反過來看，WRN-16-8 只有 16 層，參數已經比 40 層的 WRN-40-4 多。\n\n### 區塊裡要放什麼\n\n要不要像 NiN 那樣混一些 $1\\times1$ 卷積進去？作者用 $B(M)$ 表示區塊的結構，$M$ 是區塊裡各層卷積核的大小。例如 $B(3,3)$ 是原本的 basic 區塊，$B(3,1,3)$ 是在兩層 $3\\times3$ 中間多插一層 $1\\times1$。\n\n這組實驗都用 $k=2$，調整層數讓參數量相近，在 CIFAR-10 上各跑 5 次取中位數：\n\n| 區塊 | 深度 | 參數 | 一個 epoch（秒） | CIFAR-10 錯誤率 |\n| --- | ---: | ---: | ---: | ---: |\n| $B(1,3,1)$ | 40 | 1.4M | 85.8 | 6.06% |\n| $B(3,1)$ | 40 | 1.2M | 67.5 | 5.78% |\n| $B(1,3)$ | 40 | 1.3M | 72.2 | 6.42% |\n| $B(3,1,1)$ | 40 | 1.3M | 82.2 | 5.86% |\n| **$B(3,3)$** | 28 | 1.5M | 67.5 | **5.73%** |\n| $B(3,1,3)$ | 22 | 1.1M | 59.9 | 5.78% |\n\n*表：摘自原論文 Table 2。*\n\n$B(3,3)$ 最好，但差距很小；$B(3,1)$、$B(3,1,3)$ 參數比較少，成績幾乎一樣。作者據此判斷，參數量相近的區塊表現也差不多，之後就統一用 $3\\times3$ 卷積。\n\n一個區塊放幾層呢？作者固定 WRN-40-2 的總層數和參數量（2.2M），只改變每個區塊的層數 $l$：\n\n| $l$ | 1 | 2 | 3 | 4 |\n| --- | ---: | ---: | ---: | ---: |\n| CIFAR-10 錯誤率 | 6.69% | **5.43%** | 5.65% | 5.93% |\n\n*表：摘自原論文 Table 3。*\n\n總層數固定，$l$ 越大，區塊就越少，殘差連接也跟著變少。作者推測 $l=3$、$l=4$ 變差，是因為殘差連接少了，網路比較難最佳化；只放一層的 $l=1$ 又明顯更差。兩層剛好，也就是原本的 $B(3,3)$。\n\n試了一圈，區塊內部的設計都回到原點，剩下能動的只有寬度 $k$。\n\n### 把 dropout 放進區塊\n\n變寬之後參數暴增，需要正規化。BN 本身有正規化效果，但通常要搭配大量資料增強，作者不想依賴這一點。\n\n他們在區塊的兩層卷積之間、ReLU 之後加一層 dropout，就是 Figure 1(d) 的樣子。寫成程式，就是在前面 `Block` 的第二個 ReLU 後面多一層 `nn.Dropout`：\n\n```python\n        self.body = nn.Sequential(\n            nn.BatchNorm2d(cin), nn.ReLU(), nn.Conv2d(cin, cout, 3, stride, 1, bias=False),\n            nn.BatchNorm2d(cout), nn.ReLU(), nn.Dropout(0.3),   # 兩層卷積之間\n            nn.Conv2d(cout, cout, 3, 1, 1, bias=False))\n```\n\nResNet v2 也試過在殘差區塊裡用 dropout，不過是放在捷徑上，結果變差了。這裡的 dropout 只碰殘差分支，捷徑保持乾淨。機率用交叉驗證決定，CIFAR 用 0.3，SVHN 用 0.4。\n\n## 討論\n\n除了 ImageNet，所有實驗都以 pre-activation ResNet 為基準。CIFAR-10、CIFAR-100 是 $32\\times32$ 的彩色小圖，各有 5 萬張訓練、1 萬張測試，類別分別是 10 和 100 類；資料增強只有水平翻轉和隨機裁切。SVHN 是街景門牌數字，大約 60 萬張，完全不做增強。\n\n### 寬度和深度怎麼分\n\n| 深度 | $k$ | 參數 | CIFAR-10 | CIFAR-100 |\n| ---: | ---: | ---: | ---: | ---: |\n| 40 | 1 | 0.6M | 6.85% | 30.89% |\n| 40 | 2 | 2.2M | 5.33% | 26.04% |\n| 40 | 4 | 8.9M | 4.97% | 22.89% |\n| 40 | 8 | 35.7M | 4.66% | – |\n| 28 | 10 | 36.5M | **4.17%** | 20.50% |\n| 28 | 12 | 52.5M | 4.33% | **20.43%** |\n| 22 | 8 | 17.2M | 4.38% | 21.22% |\n| 22 | 10 | 26.8M | 4.44% | 20.75% |\n| 16 | 8 | 11.0M | 4.81% | 22.07% |\n| 16 | 10 | 17.1M | 4.56% | 21.59% |\n\n*表：摘自原論文 Table 4，CIFAR 測試錯誤率，影像以 ZCA whitening 前處理。*\n\n先固定深度看。40 層、22 層、16 層的網路，$k$ 越大，錯誤率大致越低。唯一的小例外是 22 層從 $k=8$ 加到 $k=10$，CIFAR-10 從 4.38% 略升到 4.44%，CIFAR-100 則還在下降。\n\n再固定寬度看。$k=8$ 時，深度從 16 層加到 22 層會變好，再加到 40 層反而變差，WRN-40-8 輸給了 WRN-22-8。WRN-40-8 有 35.7M 參數，作者認為深度和寬度一起加，參數多到某個程度，就需要更強的正規化。\n\n### 和千層 ResNet 比\n\n接下來和當時最強的細長網路正面比較。這組實驗改用一般的平均值／標準差正規化，和 ResNet 系列論文的前處理一致，也都沒有用 dropout：\n\n| 網路 | 深度-$k$ | 參數 | CIFAR-10 | CIFAR-100 |\n| --- | --- | ---: | ---: | ---: |\n| 原始 ResNet | 110 | 1.7M | 6.43% | 25.16% |\n| 原始 ResNet | 1202 | 10.2M | 7.93% | 27.82% |\n| Stochastic Depth | 1202 | 10.2M | 4.91% | – |\n| pre-act ResNet | 164 | 1.7M | 5.46% | 24.33% |\n| pre-act ResNet | 1001 | 10.2M | 4.92%（4.64%） | 22.71% |\n| WRN | 40-4 | 8.9M | 4.53% | 21.18% |\n| WRN | 16-8 | 11.0M | 4.27% | 20.43% |\n| WRN | 28-10 | 36.5M | **4.00%** | **19.25%** |\n\n*表：摘自原論文 Table 5。括號裡是 ResNet v2 用批次大小 64 訓練的結果，其他數字都是批次大小 128。*\n\nWRN-40-4 和 ResNet-1001 的參數量差不多（8.9M 和 10.2M），層數只有它的二十五分之一，兩個資料集上都贏。作者據此認為，在這個參數規模下，深度並沒有比寬度多帶來什麼正規化效果。\n\nWRN-28-10 的參數是 ResNet-1001 的 3.6 倍。當時普遍認為深度有正規化效果、寬度容易過擬合，照這個說法，它應該要過擬合。實際上，在相同批次大小下，它在 CIFAR-10 上贏了 0.92 個百分點，CIFAR-100 上贏了 3.46 個百分點。\n\n### 寬的跑得比較快\n\n[![長條圖，縱軸是時間（ms）。左邊藍色兩根是細長的網路：164 層 85 ms、一千層 512 ms；右邊紅色三根是寬的網路：WRN-40-4 68 ms、WRN-16-10 164 ms、WRN-28-10 312 ms。每根長條旁邊標著 CIFAR-10 測試錯誤率](/content/papers/assets/a243b50be60b82d957c92fa85eab5061afe10a86de40a8855c992996066803b0.png)](/content/papers/assets/a243b50be60b82d957c92fa85eab5061afe10a86de40a8855c992996066803b0.png)\n\n*原論文 Figure 4，取自 [**v4 PDF 第 12 頁**](https://arxiv.org/pdf/1605.07146v4#page=12)。批次大小 32 時，一次前向加反向傳播的時間（Titan X、cuDNN v5）。橫軸標的是深度，或深度-$k$。*\n\n藍色是細長的網路，紅色是寬的網路。千層的細長 ResNet 跑一個批次要 512 ms（一千層排隊算，快不起來），準確率和它差不多的 WRN-40-4 只要 68 ms，快了七倍多。最準的 WRN-28-10 參數多了好幾倍，還是比千層網路快 1.6 倍。\n\n差距來自前面提到的 GPU 特性。寬的卷積層一次處理一大塊張量，GPU 的平行計算用得滿；細長的網路是一千層小卷積排成一列，每一層都得等上一層算完。\n\n### Dropout 的效果\n\n| 深度 | $k$ | dropout | CIFAR-10 | CIFAR-100 | SVHN |\n| ---: | ---: | :---: | ---: | ---: | ---: |\n| 16 | 4 | | 5.02% | 24.03% | 1.85% |\n| 16 | 4 | ✓ | 5.24% | 23.91% | 1.64% |\n| 28 | 10 | | 4.00% | 19.25% | – |\n| 28 | 10 | ✓ | **3.89%** | **18.85%** | – |\n| 52 | 1 | | 6.43% | 29.89% | 2.08% |\n| 52 | 1 | ✓ | 6.28% | 29.78% | 1.70% |\n\n*表：摘自原論文 Table 6，平均值／標準差前處理，CIFAR 的數字是 5 次的中位數。*\n\nCIFAR 上的進步不大，WRN-28-10 加了 dropout，CIFAR-10 少 0.11 個百分點，CIFAR-100 少 0.4 個百分點；參數比較少的 WRN-16-4，在 CIFAR-10 上甚至略差。\n\nSVHN 上效果就明顯了，寬的和細的網路都進步 0.2 到 0.4 個百分點。SVHN 完全沒有資料增強，作者認為 BN 在這裡過擬合了，不加 dropout 時訓練損失會降到非常低。\n\n作者也注意到，第一次降學習率之後，損失和驗證錯誤率會突然一起上升，在高點震盪，直到下一次降學習率。他們查出原因是 weight decay，可是把 weight decay 調低，準確率又會明顯下降。dropout 在多數情況下能部分消除這個現象。\n\n作者也整理了各資料集的單一模型最佳結果，WRN-40-10 加 dropout 在 CIFAR-10、CIFAR-100 做到 3.8% 和 18.3%，WRN-16-8 加 dropout 在 SVHN 做到 1.54%。\n\n### ImageNet 要加寬中間那層\n\n到了 ImageNet，作者先把 ResNet-18、ResNet-34 這種 basic 區塊的網路加寬 1.5 到 3 倍。加寬一樣有效，參數量相近的網路，就算深度差了一倍，準確率也差不多。可是這些網路的參數動輒數千萬到上億，成績還是比不上參數少得多的 bottleneck 網路，例如加寬兩倍的 WRN-34 有 86.0M 參數，top-1 錯誤率 23.39%，ResNet-101 只用 44.5M 參數就做到 22.44%。\n\n作者推測，可能是 bottleneck 本來就比較適合 ImageNet，或是這個任務需要更深的網路。於是他們改從 ResNet-50 出發，只把 bottleneck 中間的 $3\\times3$ 卷積加寬兩倍，得到 WRN-50-2-bottleneck：\n\n| 網路 | Top-1 錯誤率 | Top-5 錯誤率 | 參數 | 一個批次的時間（ms） |\n| --- | ---: | ---: | ---: | ---: |\n| ResNet-50 | 24.01% | 7.02% | 25.6M | 49 |\n| ResNet-101 | 22.44% | 6.21% | 44.5M | 82 |\n| ResNet-152 | 22.16% | 6.16% | 60.2M | 115 |\n| **WRN-50-2-bottleneck** | **21.9%** | **6.03%** | 68.9M | 93 |\n| pre-ResNet-200 | 21.66% | 5.79% | 64.7M | 154 |\n\n*表：摘自原論文 Table 8，ILSVRC-2012 驗證集單一裁切，時間以批次大小 16 計算。*\n\nWRN-50-2 只有 50 層，贏過 ResNet-152，速度也比較快；和 200 層的 pre-activation ResNet 相比，錯誤率略高一點，每個批次只要 93 ms，對方要 154 ms。作者也坦白說，更大的 bottleneck 網路要 8 張 GPU 的機器才訓練得動，他們沒有再試。\n\n這個網路就是 torchvision 裡的 `wide_resnet50_2`。我們把它和 ResNet-50 的最後一個區塊拿出來比：\n\n```python\nfrom torchvision.models import resnet50, wide_resnet50_2\n\nfor name, build in [(\"ResNet-50\", resnet50), (\"Wide ResNet-50-2\", wide_resnet50_2)]:\n    model = build(weights=None)\n    last = model.layer4[-1]\n    widths = (last.conv1.in_channels, last.conv2.in_channels, last.conv3.out_channels)\n    params = sum(p.numel() for p in model.parameters())\n    print(f\"{name}：最後一個區塊 {widths[0]}-{widths[1]}-{widths[2]}，參數 {params / 1e6:.1f}M\")\n```\n\n```text\nResNet-50：最後一個區塊 2048-512-2048，參數 25.6M\nWide ResNet-50-2：最後一個區塊 2048-1024-2048，參數 68.9M\n```\n\n區塊的輸入、輸出還是 2048 個通道，只有中間那層從 512 變成 1024。參數量也和論文表格上的一樣。\n\n作者另外用 34 層、加寬兩倍的 WRN-34-2 參加 COCO 2016 物件偵測比賽，在單一模型裡拿到 35.2 mAP，贏過以 ResNet-152 和 Inception-v4 為骨幹的模型。\n\n## 結論\n\n回到開頭的問題，ResNet 一定要這麼細嗎？這篇論文的答案是不用。在 CIFAR 上，同樣的參數拿去加寬比拿去加深划算，16 層的 WRN 就贏過千層的 ResNet，訓練還快好幾倍。千層 ResNet 裡，看來有不少層在摸魚。\n\n這個結論主要來自 CIFAR。到了 ImageNet，作者只試到 50 層，原因很實在，更大的網路要 8 張 GPU 的機器才訓練得動。\n\n後來 WRN 成了 CIFAR 上最常見的骨幹之一，例如半監督學習的 [FixMatch](https://arxiv.org/abs/2001.07685) 就用 WRN-28-2。下次在論文裡看到這個名字，就知道它是 28 層、加寬兩倍的網路。\n","imageSizes":{"/content/papers/assets/eb123078c88654918b04d17b5ebccd1009fc7fbc33305ebd9ba853f2ad2cc024.png":{"width":1400,"height":500},"/content/papers/assets/a243b50be60b82d957c92fa85eab5061afe10a86de40a8855c992996066803b0.png":{"width":459,"height":542}}}
