{"notes":[{"id":"classic-cnns/inception-v4","category":"classic-cnns","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"Inception-v4","subtitle":"Beaucoup plus rapide, un peu plus précis","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":"fr","path":"/content/papers/fr/classic-cnns/inception-v4.bc2e80dd34b2.md","headings":[{"id":"définir-le-problème","text":"Définir le problème","depth":2},{"id":"résoudre-le-problème","text":"Résoudre le problème","depth":2},{"id":"se-délester-de-lhéritage-inception-v4","text":"Se délester de l'héritage : Inception-v4","depth":3},{"id":"lentrée-en-matière","text":"L'entrée en matière","depth":3},{"id":"brancher-le-résidu-dans-inception","text":"Brancher le résidu dans Inception","depth":3},{"id":"réduire-le-résidu-pour-stabiliser-lentraînement","text":"Réduire le résidu pour stabiliser l'entraînement","depth":3},{"id":"réglages-dentraînement","text":"Réglages d'entraînement","depth":3},{"id":"discussion","text":"Discussion","depth":2},{"id":"le-résidu-accélère-nettement-lentraînement","text":"Le résidu accélère nettement l'entraînement","depth":3},{"id":"résultats-des-modèles-uniques","text":"Résultats des modèles uniques","depth":3},{"id":"ensembles","text":"Ensembles","depth":3},{"id":"les-connexions-résiduelles-sont-elles-indispensables","text":"Les connexions résiduelles sont-elles « indispensables » ?","depth":3},{"id":"conclusion","text":"Conclusion","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":"Un réseau convolutif de 100 couches","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":"fr","path":"/content/papers/fr/classic-cnns/resnet.2cc70ebed590.md","headings":[{"id":"définition-du-problème","text":"Définition du problème","depth":2},{"id":"résolution-du-problème","text":"Résolution du problème","depth":2},{"id":"quest-ce-quun-résidu-","text":"Qu'est-ce qu'un résidu ?","depth":3},{"id":"apprentissage-résiduel","text":"Apprentissage résiduel","depth":3},{"id":"blocs-résiduels","text":"Blocs résiduels","depth":3},{"id":"architecture-du-réseau","text":"Architecture du réseau","depth":3},{"id":"configuration-des-paramètres","text":"Configuration des paramètres","depth":3},{"id":"discussion","text":"Discussion","depth":2},{"id":"resnet-18-contre-resnet-34","text":"ResNet-18 contre ResNet-34","depth":3},{"id":"blocs-goulots-pour-les-réseaux-plus-profonds","text":"Blocs goulots pour les réseaux plus profonds","depth":3},{"id":"résultats-sur-imagenet","text":"Résultats sur ImageNet","depth":3},{"id":"conclusion","text":"Conclusion","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"classic-cnns/vgg","relation":"background","topic":"Entraîner des réseaux convolutifs plus profonds"},{"id":"classic-cnns/densenet","relation":"next","topic":"Entraîner des réseaux convolutifs plus profonds"}]},{"id":"classic-cnns/inception-v3","category":"classic-cnns","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"Inception-v3","subtitle":"Les grands noyaux tirent leur révérence","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":"fr","path":"/content/papers/fr/classic-cnns/inception-v3.cef04f61bedf.md","headings":[{"id":"définir-le-problème","text":"Définir le problème","depth":2},{"id":"résoudre-le-problème","text":"Résoudre le problème","depth":2},{"id":"remplacer-un-55-par-deux-couches-33","text":"Remplacer un 5×5 par deux couches 3×3","depth":3},{"id":"décomposer-encore-en-1n-et-n1","text":"Décomposer encore en 1×n et n×1","depth":3},{"id":"le-véritable-rôle-des-classifieurs-auxiliaires","text":"Le véritable rôle des classifieurs auxiliaires","depth":3},{"id":"réduire-les-cartes-de-caractéristiques-sans-étrangler-linformation","text":"Réduire les cartes de caractéristiques sans étrangler l'information","depth":3},{"id":"assembler-les-pièces","text":"Assembler les pièces","depth":3},{"id":"rendre-le-modèle-moins-sûr-de-lui","text":"Rendre le modèle moins sûr de lui","depth":3},{"id":"réglages-dentraînement","text":"Réglages d'entraînement","depth":3},{"id":"discussion","text":"Discussion","depth":2},{"id":"ajouter-les-modifications-une-à-une","text":"Ajouter les modifications une à une","depth":3},{"id":"avec-une-résolution-plus-faible-combien-perd-on","text":"Avec une résolution plus faible, combien perd-on ?","depth":3},{"id":"comparaison-avec-dautres-modèles","text":"Comparaison avec d'autres modèles","depth":3},{"id":"conclusion","text":"Conclusion","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":"Le raccourci doit rester propre","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":"fr","path":"/content/papers/fr/classic-cnns/resnet-v2.1e2cdeb3e2c3.md","headings":[{"id":"définir-le-problème","text":"Définir le problème","depth":2},{"id":"résoudre-le-problème","text":"Résoudre le problème","depth":2},{"id":"deux-applications-identité","text":"Deux applications identité","depth":3},{"id":"que-se-passe-t-il-si-lon-charge-le-raccourci","text":"Que se passe-t-il si l'on charge le raccourci ?","depth":3},{"id":"où-placer-la-relu-qui-suit-laddition","text":"Où placer la ReLU qui suit l'addition ?","depth":3},{"id":"changer-de-point-de-vue-la-préactivation","text":"Changer de point de vue : la préactivation","depth":3},{"id":"discussion","text":"Discussion","depth":2},{"id":"plus-cest-profond-plus-lécart-se-creuse","text":"Plus c'est profond, plus l'écart se creuse","depth":3},{"id":"comparaison-avec-dautres-méthodes","text":"Comparaison avec d'autres méthodes","depth":3},{"id":"conclusion","text":"Conclusion","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":"La classification de l'ILSVRC 2015 est remportée par ResNet, de Microsoft Research. Son architecture est très classique : des couches de convolution empilées les unes sur les autres, avec pour seule nouveauté les connexions résiduelles ; en modèle unique, ses résultats sont proches de ceux d'Inception-v3, que Google vient de publier.\n\nChaque lignée a sa méthode : Inception réduit le calcul grâce à des modules multibranches et à des nombres de canaux calculés au plus juste ; ResNet, grâce aux connexions résiduelles, rend entraînables des réseaux très profonds.\n\nEt si l'on réunissait les deux ?\n\nEn février 2016, Christian Szegedy, Sergey Ioffe, Vincent Vanhoucke et Alex Alemi, de Google, publient cet article, présenté ensuite à l'AAAI 2017. Le titre annonce les trois sujets : le nouvel Inception-v4, Inception-ResNet, qui ajoute des connexions résiduelles, et l'effet réel de ces connexions sur l'entraînement.\n\n\n> [!TIP]\n> \n> Pour les deux travaux qui précèdent cet article, vous pouvez commencer par nos notes :\n> \n> - **[[15.12] ResNet : Un réseau convolutif de 100 couches](/blog/papers/classic-cnns/resnet)**\n> - **[[15.12] Inception-v3 : Les grands noyaux tirent leur révérence](/blog/papers/classic-cnns/inception-v3)**\n\n\n## Définir le problème\n\nCet article s'attaque à deux problèmes à la fois.\n\nLe premier concerne les connexions résiduelles. Les auteurs de ResNet affirment que les connexions résiduelles sont **intrinsèquement nécessaires** pour entraîner des réseaux convolutifs très profonds. Les réseaux Inception sont déjà très profonds, et remplacer la « concaténation des canaux » à la fin d'un module Inception par un « ajout de l'entrée » semble naturel. Reste la question : qu'y gagne-t-on ? Le gain porte-t-il sur la précision finale, ou ailleurs ?\n\nLe second concerne Inception lui-même. Les auteurs l'admettent franchement : Inception-v3 traîne un lourd héritage. Les premiers modèles étaient entraînés de manière distribuée avec DistBelief, et chaque réplique devait être découpée en plusieurs sous-réseaux pour tenir en mémoire ; pour équilibrer le calcul entre ces sous-réseaux, le nombre de filtres de chaque couche avait été soigneusement ajusté. Avec le passage à TensorFlow, cette contrainte a disparu. Par ailleurs, ils modifiaient jusque-là l'architecture avec beaucoup de prudence, un seul composant à la fois, sans toucher au reste, si bien que le réseau devenait de plus en plus complexe.\n\nPuisque cet héritage peut désormais être abandonné, Inception peut-il devenir plus simple, plus profond et plus large ?\n\n## Résoudre le problème\n\n### Se délester de l'héritage : Inception-v4\n\n[![Architecture d'ensemble d'Inception-v4, de bas en haut : Input 299x299x3, Stem (sortie 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 de l'article, extraite de la [**page 5 du PDF v2**](https://arxiv.org/pdf/1602.07261v2#page=5). Architecture d'ensemble d'Inception-v4, avec à droite la taille de sortie de chaque étage.*\n\nCette figure ressemble beaucoup au tableau d'architecture d'Inception-v3 : trois résolutions ($35\\times35$, $17\\times17$, $8\\times8$), plusieurs modules Inception empilés à chaque étage, et des modules de réduction pour passer d'une résolution à la suivante. La différence : Inception-v4 **n'utilise qu'un seul type de module par résolution**, et en plus grand nombre : 4 Inception-A, 7 Inception-B, 3 Inception-C.\n\nLes trois modules reprennent les méthodes de factorisation d'Inception-v3 :\n\n- **Inception-A** ($35\\times35$) : quatre branches ; la plus longue remplace le $5\\times5$ par deux couches $3\\times3$ ; chaque branche produit 96 canaux, soit 384 au total.\n- **Inception-B** ($17\\times17$) : des convolutions asymétriques $1\\times7$ et $7\\times1$, pour 1024 canaux au total.\n- **Inception-C** ($8\\times8$) : des sorties $1\\times3$ et $3\\times1$ en parallèle, pour 1536 canaux au total.\n\nLes convolutions marquées « V » sur les figures utilisent un valid padding, sans remplissage, et leur sortie rapetisse ; toutes les autres utilisent un same padding, et leur sortie garde la taille de l'entrée.\n\n### L'entrée en matière\n\nPar rapport à Inception-v3, le changement le plus visible se situe au début du réseau, que les auteurs appellent le stem :\n\n[![Le stem d'Inception-v4, de bas en haut : Input 299x299x3 ; 3x3 Conv (32 stride 2 V) donne 149x149x32 ; 3x3 Conv (32 V) donne 147x147x32 ; 3x3 Conv (64) donne 147x147x64 ; puis deux branches, 3x3 MaxPool (stride 2 V) et 3x3 Conv (96 stride 2 V), réunies par Filter concat en 73x73x160 ; puis de nouveau deux branches : 1x1 Conv (64) suivie de 3x3 Conv (96 V), et 1x1 Conv (64), 7x1 Conv (64), 1x7 Conv (64), 3x3 Conv (96 V), réunies par Filter concat en 71x71x192 ; enfin deux branches, 3x3 Conv (192 V) et MaxPool (stride=2 V), réunies par Filter concat en 35x35x384](/content/papers/assets/a8aa67238a41bcf306ee4cf1d7d45c7564e9b522e9f9ea4272cbda8e3c2787e8.png)](/content/papers/assets/a8aa67238a41bcf306ee4cf1d7d45c7564e9b522e9f9ea4272cbda8e3c2787e8.png)\n\n*Figure 3 de l'article, extraite de la [**page 3 du PDF v2**](https://arxiv.org/pdf/1602.07261v2#page=3). Le stem commun à Inception-v4 et Inception-ResNet-v2.*\n\nLes trois premières couches sont les mêmes que dans Inception-v3 et mènent de $299\\times299$ à $147\\times147\\times64$. Viennent ensuite trois « séparations puis concaténations » successives : à chaque fois, soit une branche se charge de la réduction, soit deux branches traitent chacune les données avant d'être réunies. Suivons la figure :\n\n```python\nimport torch\nimport torch.nn as nn\n\ndef conv(cin, cout, k, stride=1, valid=False):\n    # Les convolutions marquées V n'ont pas de remplissage ; les autres en ont un, pour que la sortie garde la taille de l'entrée\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(\"après trois convolutions :\", tuple(x.shape[1:]))\n\n# Premier passage en parallèle : max pooling | convolution de pas 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(\"pooling\", tuple(a.shape[1:]), \"+ convolution\", tuple(b.shape[1:]), \"→\", tuple(x.shape[1:]))\n\n# Deuxième passage en parallèle : deux branches de convolution\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(\"branche 1\", tuple(a.shape[1:]), \"+ branche 2\", tuple(b.shape[1:]), \"→\", tuple(x.shape[1:]))\n\n# Troisième passage en parallèle : convolution de pas 2 | max pooling\na = conv(192, 192, 3, stride=2, valid=True)(x)    # pour se raccorder au 35×35 du pooling, le pas doit valoir 2\nb = nn.MaxPool2d(3, 2)(x)\nx = torch.cat([a, b], dim=1)\nprint(\"convolution\", tuple(a.shape[1:]), \"+ pooling\", tuple(b.shape[1:]), \"→\", tuple(x.shape[1:]))\n```\n\n```text\naprès trois convolutions : (64, 147, 147)\npooling (64, 73, 73) + convolution (96, 73, 73) → (160, 73, 73)\nbranche 1 (96, 71, 71) + branche 2 (96, 71, 71) → (192, 71, 71)\nconvolution (192, 35, 35) + pooling (192, 35, 35) → (384, 35, 35)\n```\n\nLes formes de sortie correspondent aux $73\\times73\\times160$, $71\\times71\\times192$ et $35\\times35\\times384$ indiqués sur la figure. Le pooling ne change pas le nombre de canaux : la première concaténation donne donc $64+96=160$, et la dernière $192+192=384$.\n\nLa première et la troisième concaténation reprennent la méthode de réduction des cartes de caractéristiques d'Inception-v3 : une convolution de pas 2 et un pooling de pas 2 en parallèle, pour éviter le goulot d'étranglement d'information que crée un pooling préalable. Cette fois, même le début du réseau procède ainsi.\n\n### Brancher le résidu dans Inception\n\nPour la version résiduelle d'Inception, les auteurs utilisent des modules moins coûteux. Prenons le module $35\\times35$ d'Inception-ResNet-v2 :\n\n[![Module Inception-ResNet-A : la Relu activation du bas se sépare en quatre voies. La plus à gauche va directement au signe plus du haut ; les trois autres branches sont 1x1 Conv (32), 1x1 Conv (32) suivie de 3x3 Conv (32), et 1x1 Conv (32) suivie de 3x3 Conv (48) puis de 3x3 Conv (64). Les sorties des trois branches entrent ensemble dans 1x1 Conv (384 Linear), puis sont additionnées à la voie directe de gauche, avant une dernière Relu activation](/content/papers/assets/cc8335c4ba4672514d3dd5e9953719d52b4f8fdd0af994c76722874543fcb864.png)](/content/papers/assets/cc8335c4ba4672514d3dd5e9953719d52b4f8fdd0af994c76722874543fcb864.png)\n\n*Figure 16 de l'article, extraite de la [**page 8 du PDF v2**](https://arxiv.org/pdf/1602.07261v2#page=8). Le module $35\\times35$ d'Inception-ResNet-v2 (Inception-ResNet-A).*\n\nPar rapport au module Inception pur, deux choses changent :\n\n1. Les branches sont plus étroites. Les trois branches ne produisent au total que $32+32+64=128$ canaux, bien moins que les 384 de l'entrée.\n2. Après la concaténation des branches s'ajoute une convolution $1\\times1$ **sans fonction d'activation**, qui ramène le nombre de canaux à 384 pour permettre l'addition avec l'entrée. Les auteurs l'appellent filter-expansion layer : elle compense la réduction de dimension opérée par le module 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, sans fonction d'activation\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(\"branches concaténées :\", tuple(branches.shape[1:]), \"→ après l'expansion 1×1 :\", tuple(residual.shape[1:]))\n        return torch.relu(x + self.scale * residual)\n\nx = torch.randn(2, 384, 35, 35)\nprint(\"sortie :\", tuple(InceptionResNetA()(x).shape[1:]))\n```\n\n```text\nbranches concaténées : (128, 35, 35) → après l'expansion 1×1 : (384, 35, 35)\nsortie : (384, 35, 35)\n```\n\nLe `scale` du code est le héros de la section suivante ; gardons-le pour plus tard.\n\nLes auteurs ont essayé plusieurs versions résiduelles, mais l'article n'en détaille que deux :\n\n| Réseau | Coût comparable à | Stem | Corps |\n| --- | --- | --- | --- |\n| Inception-ResNet-v1 | environ Inception-v3 | Son propre stem (Figure 14) | 5 × A, Reduction-A, 10 × B, Reduction-B, 5 × C |\n| Inception-ResNet-v2 | environ Inception-v4 | Identique à Inception-v4 (Figure 3) | Comme ci-dessus, avec des modules plus larges |\n\n*Tableau : synthèse de la section 3.2 et de la Figure 15 de l'article. Les deux réseaux ont la même structure d'ensemble ; leurs modules diffèrent par le nombre de canaux.*\n\nBien qu'Inception-ResNet-v2 et Inception-v4 aient un coût de calcul brut comparable, les auteurs notent qu'en pratique, chaque pas d'entraînement d'Inception-v4 est bien plus lent, probablement parce qu'il compte davantage de couches.\n\nAutre détail : dans Inception-ResNet, la batch normalization n'est appliquée qu'aux couches ordinaires, **pas après les additions**. Selon les auteurs, une batch normalization généralisée serait sans doute meilleure, mais sur les couches aux activations volumineuses, elle consomme une part disproportionnée de la mémoire du GPU ; pour faire tenir chaque réplique du modèle sur un seul GPU, ils ont retiré ces BN, ce qui leur a permis d'empiler beaucoup plus de modules.\n\n### Réduire le résidu pour stabiliser l'entraînement\n\nLes auteurs se heurtent ensuite à une difficulté : au-delà de 1000 filtres, les versions résiduelles deviennent instables, et le réseau « meurt » au début de l'entraînement. Concrètement, après quelques dizaines de milliers d'itérations, la dernière couche avant le pooling moyen ne produit plus que des 0. Ni la baisse du taux d'apprentissage ni l'ajout d'une batch normalization sur cette couche n'y changent rien.\n\nLa solution efficace est très simple : avant l'addition, multiplier le résidu par une petite constante.\n\n[![Schéma de la mise à l'échelle du résidu : la Relu activation du bas se sépare en deux voies ; l'une va directement au signe plus du haut, l'autre passe par le bloc Inception puis par le bloc Activation Scaling avant de rejoindre le signe plus ; après l'addition vient une Relu activation](/content/papers/assets/80acad99318e473fe9dab6f2b4d92977d9619ab66149982bd22ff1e8067a7917.png)](/content/papers/assets/80acad99318e473fe9dab6f2b4d92977d9619ab66149982bd22ff1e8067a7917.png)\n\n*Figure 20 de l'article, extraite de la [**page 9 du PDF v2**](https://arxiv.org/pdf/1602.07261v2#page=9). Mise à l'échelle du résidu dans un module Inception-ResNet ; la constante vaut généralement autour de 0,1.*\n\nLes auteurs choisissent en général une valeur entre 0,1 et 0,3. Face à l'instabilité des réseaux très profonds, l'article de ResNet utilisait un entraînement en deux phases : un « échauffement » avec un taux d'apprentissage très bas, puis un taux plus élevé. Les auteurs constatent qu'avec beaucoup de filtres, même un taux d'apprentissage de 0,00001 ne suffit pas à empêcher l'instabilité, et que le taux élevé qui suit peut ruiner l'effet de l'échauffement. En comparaison, la mise à l'échelle du résidu est bien plus fiable. Même quand l'entraînement fonctionnait sans elle, l'ajouter ne nuit pas à la précision finale et rend l'entraînement plus stable.\n\nL'article n'analyse pas la cause de cette « mort ». Une chose est cependant facile à voir : dans Inception-ResNet, les branches contiennent une batch normalization, et leur sortie a donc une amplitude à peu près fixe ; après l'addition sur le tronc, il n'y a pas de batch normalization, et chaque module ajoute sa contribution. Un modèle simplifié montre comment évolue le signal du tronc :\n\n```python\nimport torch\n\ntorch.manual_seed(0)\nx0 = torch.randn(4096, 256)                     # signal du tronc : 4096 positions, 256 canaux\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 dans la branche : la sortie de chaque canal revient à un écart-type de 1\n        x = x + scale * r                       # pas de BN après l'addition sur le tronc\n        if block in (10, 20, 40):\n            stds.append(f\"{x.std().item():5.2f}\")\n    print(f\"facteur {scale} : écart-type du tronc après les blocs 10, 20 et 40\", \" \".join(stds))\n```\n\n```text\nfacteur 1.0 : écart-type du tronc après les blocs 10, 20 et 40  3.31  4.57  6.42\nfacteur 0.3 : écart-type du tronc après les blocs 10, 20 et 40  1.37  1.67  2.15\nfacteur 0.1 : écart-type du tronc après les blocs 10, 20 et 40  1.05  1.10  1.18\n```\n\nSans mise à l'échelle, chaque module ajoute un signal à peu près aussi grand que le tronc ; après 40 modules, l'écart-type vaut environ $\\sqrt{41}\\approx6.4$. Avec un facteur 0,1, chaque module n'apporte qu'une petite correction, et le signal du tronc provient surtout de la voie directe. Ce n'est qu'une illustration simplifiée à l'initialisation, incapable d'expliquer la « mort » en cours d'entraînement ; la seule chose que l'article établit, c'est le résultat expérimental : avec la mise à l'échelle, les réseaux résiduels larges s'entraînent de façon stable.\n\n### Réglages d'entraînement\n\nIls sont presque identiques à ceux d'Inception-v3 : entraînement distribué avec TensorFlow, cette fois sur 20 répliques, chacune sur un GPU NVIDIA Kepler. Le meilleur modèle utilise RMSProp (decay 0,9, $\\epsilon=1.0$), avec un taux d'apprentissage de 0,045 multiplié par 0,94 toutes les deux époques ; l'évaluation utilise une moyenne mobile des paramètres.\n\n## Discussion\n\n### Le résidu accélère nettement l'entraînement\n\n[![Graphique en courbes : en abscisse, les époques (de 20 à 200) ; en ordonnée, l'erreur top-1 (de 15 % à 29 %). La ligne verte en pointillés correspond à inception-v3, la ligne rouge continue à inception-resnet-v1. La ligne rouge descend bien plus vite et approche 22 % vers 80 époques ; la ligne verte ne la rattrape que vers 160 époques ; à la fin, les deux lignes se stabilisent un peu au-dessus de 21 %](/content/papers/assets/2c7a11bd8741d531c7a4888f1c2efee55cf3b7f27c1fb808e2f1da765a585065.png)](/content/papers/assets/2c7a11bd8741d531c7a4888f1c2efee55cf3b7f27c1fb808e2f1da765a585065.png)\n\n*Figure 21 de l'article, extraite de la [**page 9 du PDF v2**](https://arxiv.org/pdf/1602.07261v2#page=9). Erreur top-1 (recadrage unique) pendant l'entraînement d'Inception-v3 et d'Inception-ResNet-v1, dont les coûts de calcul sont proches.*\n\nLa ligne rouge correspond à Inception-ResNet-v1, avec résidus, la verte à Inception-v3. La rouge descend bien plus vite, mais les deux finissent à peu près au même niveau : en top-1, la version résiduelle est légèrement moins bonne ; en top-5, légèrement meilleure. Pour la paire Inception-v4 et Inception-ResNet-v2, la version résiduelle s'entraîne elle aussi plus vite, et finit avec un résultat légèrement meilleur.\n\nEn comparant les quatre modèles, les auteurs concluent que les versions résiduelles convergent plus vite, mais que la précision finale dépend surtout de la taille du modèle.\n\n### Résultats des modèles uniques\n\n| Réseau | Erreur top-1 | Erreur 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*Tableau : extrait de la Table 2 de l'article. Modèle unique, recadrage unique, ensemble de validation sans les images de la liste noire.*\n\nPar paires de coût comparable : Inception-v3 et Inception-ResNet-v1 font presque jeu égal, et Inception-v4 et Inception-ResNet-v2 ne diffèrent que de 0,1 point de pourcentage. L'écart entre les deux paires est bien plus grand que l'écart, au sein d'une paire, entre version avec et sans résidus.\n\nLes résultats avec plusieurs recadrages suivent la même tendance :\n\n| Réseau | Recadrages | Erreur top-1 | Erreur 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*Tableau : extrait des Tables 3 et 4 de l'article, ensemble de validation complet de 50 000 images.*\n\n### Ensembles\n\n| Réseau | Modèles | Erreur top-1 | Erreur 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*Tableau : extrait de la Table 5 de l'article, ensemble de validation complet de 50 000 images. Évaluation dense pour ResNet, 144 recadrages pour la famille Inception.*\n\nUn Inception-v4 plus trois Inception-ResNet-v2 obtiennent une erreur top-5 de 3,1 % sur l'ensemble de validation. Soumis aussi au serveur de test, cet ensemble obtient 3,08 %. Les auteurs précisent qu'au cours de l'année écoulée, ils n'ont soumis que deux fois des résultats au serveur de test, une fois pour l'article de BN-Inception et une fois pour la compétition CLSLOC de l'ILSVRC 2015 ; le chiffre sur l'ensemble de test peut donc être considéré comme une estimation fidèle de la capacité de généralisation.\n\nLes auteurs remarquent aussi que les progrès des modèles uniques se retrouvent moins nettement dans les ensembles.\n\n### Les connexions résiduelles sont-elles « indispensables » ?\n\nRevenons à la première question du début. La réponse des auteurs est directe : du moins en reconnaissance d'images, leurs résultats ne confirment pas l'affirmation de l'article de ResNet selon laquelle les connexions résiduelles seraient « intrinsèquement nécessaires ». Inception-v4, sans connexion résiduelle, s'entraîne tout aussi bien, avec des résultats comparables à ceux d'Inception-ResNet-v2.\n\nIls nuancent toutefois leur propos : pour mesurer tous les bénéfices des connexions résiduelles, il faudrait peut-être des architectures plus profondes et davantage de points expérimentaux. Ce qui est établi, c'est que les connexions résiduelles accélèrent nettement l'entraînement, ce qui suffit à justifier leur usage.\n\n## Conclusion\n\nCet article livre trois réseaux : Inception-v4, un Inception pur, et Inception-ResNet-v1 et v2, dont les coûts de calcul s'alignent respectivement sur Inception-v3 et Inception-v4.\n\nIl faut d'abord préciser les conditions de la comparaison : les modules d'Inception-ResNet ont été « choisis de manière un peu arbitraire » (somewhat ad hoc, selon les termes des auteurs), avec pour seule exigence un coût de calcul proche de celui du modèle Inception pur correspondant ; les auteurs ont aussi essayé des versions plus grandes et plus larges, aux performances très proches sur ImageNet. Dans ces conditions, les connexions résiduelles apportent surtout de la vitesse d'entraînement ; ce qui creuse réellement l'écart, c'est l'agrandissement du modèle : Inception-v4 et Inception-ResNet-v2 font tous deux nettement mieux que les modèles de la catégorie de v3.\n\nPour qui veut utiliser ces modèles, la conclusion est très concrète : si le temps d'entraînement compte, ajoutez des connexions résiduelles ; si c'est la précision finale qui compte, la taille du modèle pèse plus que la présence de résidus. Avec un réseau très large, pensez à multiplier le résidu par 0,1 à 0,3 avant de l'additionner, faute de quoi il risque de « mourir » en plein entraînement.\n\nQuant à savoir si les résidus sont indispensables pour entraîner des réseaux profonds, ResNet et cet article ont chacun leur position. À la même époque, les auteurs de ResNet eux-mêmes étudiaient la bonne manière de brancher le résidu : c'est l'objet de la note suivante, [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}}}
