{"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-hans","path":"/content/papers/zh-hans/classic-cnns/wide-resnet.70d00b511f7e.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-hans","path":"/content/papers/zh-hans/classic-cnns/resnet-v2.3600c96a0854.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-hans","path":"/content/papers/zh-hans/classic-cnns/stochastic-depth.264f95f6a1fe.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 只碰残差分支，捷径保持干净。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}}}
