{"notes":[{"id":"classic-cnns/stn","category":"classic-cnns","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"STN","subtitle":"Remuer ciel et terre","author":"Z. Yuan","paperDate":"2015-06-05","publishedOn":"2025-11-27","world":"external/stn","paperTitle":"Spatial Transformer Networks","paperUrl":"https://arxiv.org/abs/1506.02025","bibliography":{"title":"Spatial Transformer Networks","authors":["Max Jaderberg","Karen Simonyan","Andrew Zisserman","Koray Kavukcuoglu"],"url":"https://arxiv.org/abs/1506.02025","pdfUrl":"https://arxiv.org/pdf/1506.02025v3","codeUrl":null,"preprint":{"id":"1506.02025","submittedOn":"2015-06-05","url":"https://arxiv.org/abs/1506.02025"},"publication":null,"citation":"@misc{classiccnnsstn2015,\n  title = {{Spatial Transformer Networks}},\n  author = {Max Jaderberg and Karen Simonyan and Andrew Zisserman and Koray Kavukcuoglu},\n  year = {2015},\n  eprint = {1506.02025},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/1506.02025}\n}\n","citationPath":"/content/papers/citations/classic-cnns/stn.e823b15c17eb.bib"},"thumbnail":{"src":"/content/papers/assets/7b29191fd34e282fbd2d0fa901014f5770192cf1641d814b39b43a903817fb7f.png","width":480,"height":364},"locale":"fr","path":"/content/papers/fr/classic-cnns/stn.2d76c667a0eb.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":"trois-composants","text":"Trois composants","depth":3},{"id":"le-générateur-de-grille-partir-de-la-sortie","text":"Le générateur de grille : partir de la sortie","depth":3},{"id":"léchantillonneur-prendre-des-valeurs-entre-les-points-de-la-grille","text":"L'échantillonneur : prendre des valeurs entre les points de la grille","depth":3},{"id":"linsérer-dans-le-réseau","text":"L'insérer dans le réseau","depth":3},{"id":"discussion","text":"Discussion","depth":2},{"id":"mnist-déformé","text":"MNIST déformé","depth":3},{"id":"numéros-de-rue","text":"Numéros de rue","depth":3},{"id":"classification-fine-des-oiseaux","text":"Classification fine des oiseaux","depth":3},{"id":"conclusion","text":"Conclusion","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"text-recognition/rare","relation":"referenced","topic":""}]},{"id":"text-recognition/rare","category":"text-recognition","legacyPath":"text-recognition/1603-rare","legacySlug":"1603-rare","legacyPaths":[],"title":"RARE","subtitle":"Une rectification entièrement automatique","author":"Z. Yuan","paperDate":"2016","publishedOn":"2024-10-08","paperTitle":"Robust Scene Text Recognition With Automatic Rectification","paperUrl":"https://openaccess.thecvf.com/content_cvpr_2016/html/Shi_Robust_Scene_Text_CVPR_2016_paper.html","bibliography":{"title":"Robust Scene Text Recognition With Automatic Rectification","authors":["Baoguang Shi","Xinggang Wang","Pengyuan Lyu","Cong Yao","Xiang Bai"],"url":"https://openaccess.thecvf.com/content_cvpr_2016/html/Shi_Robust_Scene_Text_CVPR_2016_paper.html","pdfUrl":"https://openaccess.thecvf.com/content_cvpr_2016/papers/Shi_Robust_Scene_Text_CVPR_2016_paper.pdf","codeUrl":null,"preprint":null,"publication":{"venue":"CVPR","year":2016,"kind":"conference","url":"https://openaccess.thecvf.com/content_cvpr_2016/html/Shi_Robust_Scene_Text_CVPR_2016_paper.html"},"citation":"@inproceedings{textrecognitionrare2016,\n  title = {{Robust Scene Text Recognition With Automatic Rectification}},\n  author = {Baoguang Shi and Xinggang Wang and Pengyuan Lyu and Cong Yao and Xiang Bai},\n  year = {2016},\n  booktitle = {CVPR},\n  url = {https://openaccess.thecvf.com/content_cvpr_2016/html/Shi_Robust_Scene_Text_CVPR_2016_paper.html}\n}\n","citationPath":"/content/papers/citations/text-recognition/rare.e993d8c6fce6.bib"},"thumbnail":{"src":"/content/papers/assets/ede56fcdf7e421a6d8418d322e7a516326d84123169b83be8f9badb72fbb994e.jpg","width":1224,"height":496},"locale":"fr","path":"/content/papers/fr/text-recognition/rare.30463ba8153b.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":"réseau-de-transformation-spatiale","text":"Réseau de transformation spatiale","depth":3},{"id":"réseau-de-localisation","text":"Réseau de localisation","depth":3},{"id":"générateur-de-grille","text":"Générateur de grille","depth":3},{"id":"échantillonneur","text":"Échantillonneur","depth":3},{"id":"encodeur-décodeur","text":"Encodeur-décodeur","depth":3},{"id":"reconnaissance-assistée-par-dictionnaire","text":"Reconnaissance assistée par dictionnaire","depth":3},{"id":"entraînement-du-modèle","text":"Entraînement du modèle","depth":3},{"id":"mesures-dévaluation","text":"Mesures d'évaluation","depth":3},{"id":"discussion","text":"Discussion","depth":2},{"id":"comparaison-avec-les-autres-méthodes","text":"Comparaison avec les autres méthodes","depth":3},{"id":"conclusion","text":"Conclusion","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[{"id":"text-recognition/sar","relation":"comparison","topic":"Reconnaître du texte courbe ou irrégulier"},{"id":"text-recognition/dan","relation":"comparison","topic":"Reconnaître du texte courbe ou irrégulier"}]}],"text":"Montrez à un réseau convolutif un chiffre manuscrit de travers : il le reconnaît en général quand même.\n\nD'où vient cette tolérance ? En partie du max pooling : comme il prend le maximum sur une petite zone de $2\\times2$, une caractéristique qui se déplace d'une ou deux cases ne change pas la sortie. Une fois de nombreuses couches empilées, le réseau acquiert une certaine indulgence envers les changements de position.\n\nMais cette indulgence s'accumule petit à petit, et sa portée est fixe. En juin 2015, Max Jaderberg, Karen Simonyan, Andrew Zisserman et Koray Kavukcuoglu, de Google DeepMind, publient cet article, présenté ensuite à NIPS 2015. Ils veulent que le réseau décide lui-même comment déplacer, redimensionner et faire pivoter une image pour la reconnaître au mieux.\n\n## Définir le problème\n\nLes auteurs commencent par souligner les limites du max pooling. Sa portée est généralement très petite, par exemple $2\\times2$ pixels ; l'invariance à la position doit donc s'accumuler lentement au fil de nombreuses couches de convolution et de pooling, et les cartes de caractéristiques intermédiaires ne sont en réalité pas invariantes aux grandes transformations de l'entrée.\n\nLa racine du problème : le mécanisme de pooling est figé à l'avance. Où il s'applique et sur quelle étendue, cela ne dépend en rien de l'entrée.\n\nLes auteurs veulent un module différent :\n\n- **Une transformation décidée d'après l'entrée** : chaque image reçoit sa propre transformation, au lieu d'un traitement commun à toutes les images.\n- **Une action sur toute la carte de caractéristiques** : recadrer, redimensionner, faire pivoter, voire déformer de manière non rigide, sans être limité à une zone locale.\n- **Aucune annotation supplémentaire** : personne ne lui indique le bon angle de rotation ni la bonne boîte ; il apprend uniquement à partir de la perte de la tâche finale.\n- **Un entraînement direct par rétropropagation** : pas besoin de modifier la procédure d'optimisation, et le module s'insère dans les réseaux convolutifs existants.\n\nVoyons d'abord à quoi ressemble le résultat :\n\n[![Trois lignes d'exemples MNIST, chacune sur quatre colonnes. (a) Des chiffres manuscrits translatés, redimensionnés, tournés ou bruités ; (b) le cadre d'échantillonnage prédit par le module, tracé en quadrilatère de couleur sur l'image d'origine ; (c) le chiffre transformé d'après ce cadre, redressé et agrandi ; (d) la prédiction du réseau de classification placé ensuite, respectivement 7, 5 et 6](/content/papers/assets/7b29191fd34e282fbd2d0fa901014f5770192cf1641d814b39b43a903817fb7f.png)](/content/papers/assets/7b29191fd34e282fbd2d0fa901014f5770192cf1641d814b39b43a903817fb7f.png)\n\n*Figure 1 de l'article, extraite de la [**page 2 du PDF v3**](https://arxiv.org/pdf/1506.02025v3#page=2). (a) Entrées MNIST déformées ; (b) transformation prédite par le module ; (c) résultat après transformation ; (d) prédiction du réseau de classification placé ensuite. Le réseau entier n'est entraîné qu'avec les étiquettes de classe.*\n\nLa troisième ligne est particulièrement parlante : le 6 est minuscule, entouré de points parasites ; le module encadre lui-même le 6, le découpe, l'agrandit et le transmet au réseau de classification. À aucun moment on ne lui a dit où se trouvait le 6.\n\n## Résoudre le problème\n\n### Trois composants\n\n[![Architecture du module de transformation spatiale. La carte de caractéristiques d'entrée U suit deux voies : l'une entre dans le réseau de localisation, qui produit les paramètres de transformation θ, à partir desquels le générateur de grille calcule la grille d'échantillonnage T_θ(G) ; l'autre va directement à l'échantillonneur, qui prélève des valeurs dans U selon la grille et produit la carte de caractéristiques V](/content/papers/assets/96a7134077ab04428f529111ff95e65d6863c038ad037e4d679cb1d2de57c0bb.png)](/content/papers/assets/96a7134077ab04428f529111ff95e65d6863c038ad037e4d679cb1d2de57c0bb.png)\n\n*Figure 2 de l'article, extraite de la [**page 3 du PDF v3**](https://arxiv.org/pdf/1506.02025v3#page=3). Réunis, le réseau de localisation, le générateur de grille et l'échantillonneur forment un transformateur spatial.*\n\nLe module se compose de trois éléments, dans cet ordre :\n\n1. **Le réseau de localisation** (localisation net) : il lit la carte de caractéristiques $U$ et produit les paramètres de transformation $\\theta$. Il peut s'agir d'un réseau entièrement connecté ou d'un réseau convolutif, pourvu que la dernière couche soit une couche de régression qui produise $\\theta$.\n2. **Le générateur de grille** (grid generator) : à partir de $\\theta$, il calcule un ensemble de points d'échantillonnage $\\mathcal{T}_\\theta(G)$, c'est-à-dire « l'endroit de l'entrée où chaque pixel de la sortie doit aller chercher sa valeur ».\n3. **L'échantillonneur** (sampler) : il prélève les valeurs de $U$ aux points d'échantillonnage et produit la sortie $V$.\n\nPour une entrée à plusieurs canaux, chaque canal subit la même transformation, afin que la correspondance spatiale entre canaux reste cohérente.\n\nLe réseau de localisation n'a rien de particulier ; l'essentiel se joue dans les deux étapes suivantes. Parcourons-les avec un petit exemple.\n\n### Le générateur de grille : partir de la sortie\n\nSupposons d'abord une transformation affine en deux dimensions, qui ne demande que 6 paramètres :\n\n$$\n\\begin{pmatrix} x_i^s \\\\ y_i^s \\end{pmatrix}\n= \\mathcal{T}_\\theta(G_i)\n= \\begin{bmatrix} \\theta_{11} & \\theta_{12} & \\theta_{13} \\\\ \\theta_{21} & \\theta_{22} & \\theta_{23} \\end{bmatrix}\n\\begin{pmatrix} x_i^t \\\\ y_i^t \\\\ 1 \\end{pmatrix}\n$$\n\n$(x_i^t, y_i^t)$ sont les coordonnées du $i$-ième pixel de la grille de sortie, l'exposant $t$ désignant la cible (target) ; $(x_i^s, y_i^s)$ est la position de l'entrée où ce pixel va chercher sa valeur, l'exposant $s$ désignant la source.\n\nLe sens du calcul mérite attention : la formule part des coordonnées de **la sortie** pour calculer celles de **l'entrée**. Chaque pixel de sortie a ainsi forcément une source, sans aucun trou, comme pour le placage de textures en infographie.\n\nLes coordonnées sont toutes normalisées dans $[-1, 1]$ : pour la sortie comme pour l'entrée, le coin supérieur gauche est $(-1, -1)$ et le coin inférieur droit $(1, 1)$ ; le même $\\theta$ convient donc quelle que soit la taille de la carte de caractéristiques.\n\nSupposons une sortie de $3\\times3$ : pour agrandir deux fois et regarder le coin supérieur gauche de l'entrée, on peut poser $\\theta_{11}=\\theta_{22}=0.5$ et $\\theta_{13}=\\theta_{23}=-0.5$ :\n\n```python\nimport torch\nimport torch.nn.functional as F\n\n# La sortie est une grille régulière 3×3 ; coordonnées normalisées dans [-1, 1]\ntheta = torch.tensor([[[0.5, 0.0, -0.5],\n                       [0.0, 0.5, -0.5]]])          # agrandir 2 fois, regarder le coin supérieur gauche\ngrid = F.affine_grid(theta, size=(1, 1, 3, 3), align_corners=True)\nprint(\"x_s :\\n\", grid[0, ..., 0])\nprint(\"y_s :\\n\", grid[0, ..., 1])\n```\n\n```text\nx_s :\n tensor([[-1.0000, -0.5000,  0.0000],\n        [-1.0000, -0.5000,  0.0000],\n        [-1.0000, -0.5000,  0.0000]])\ny_s :\n tensor([[-1.0000, -1.0000, -1.0000],\n        [-0.5000, -0.5000, -0.5000],\n        [ 0.0000,  0.0000,  0.0000]])\n```\n\nSur la grille de sortie, $x^t$ vaut $-1, 0, 1$ ; multiplié par 0,5 puis diminué de 0,5, il donne $x^s = -1, -0.5, 0$ : les 3 pixels de sortie ne prennent leurs valeurs que dans la moitié gauche de l'entrée. Il en va de même dans la direction $y$. Les $3\\times3$ pixels de sortie correspondent au quart supérieur gauche de l'entrée.\n\n[![Deux schémas. (a) Sur l'entrée U, les points d'échantillonnage verts forment une grille régulière, en correspondance un à un avec la sortie V, qui est identique à l'entrée ; (b) les points d'échantillonnage, transformés par une transformation affine, forment un parallélogramme incliné et réduit qui ne couvre qu'une partie du chiffre, et la sortie V montre le chiffre redressé et agrandi](/content/papers/assets/89651828c63ac51ce8bd1efa4deffe57d50cca84735217ef8b2c9087b5b760c8.png)](/content/papers/assets/89651828c63ac51ce8bd1efa4deffe57d50cca84735217ef8b2c9087b5b760c8.png)\n\n*Figure 3 de l'article, extraite de la [**page 4 du PDF v3**](https://arxiv.org/pdf/1506.02025v3#page=4). (a) Transformation identité : la grille d'échantillonnage est la grille régulière ; (b) grille d'échantillonnage après une transformation affine.*\n\nCette figure montre la même chose. En (a), les points d'échantillonnage forment une grille régulière, et la sortie est identique à l'entrée ; en (b), la transformation affine les dispose en un parallélogramme incliné qui ne couvre qu'une partie de l'entrée, et la sortie est le résultat recadré, tourné et agrandi.\n\nLes 6 paramètres d'une transformation affine peuvent exprimer un recadrage, une translation, une rotation, un changement d'échelle et un cisaillement. Lorsque la valeur absolue du déterminant de la sous-matrice $2\\times2$ de gauche est inférieure à 1, la grille d'échantillonnage se réduit à un parallélogramme de plus petite aire, ce qui revient à recadrer une zone.\n\n$\\mathcal{T}_\\theta$ peut aussi prendre d'autres formes. Les auteurs en donnent quelques exemples : une forme d'attention qui n'autorise que le recadrage, la translation et le changement d'échelle isotrope (3 paramètres, $s, t_x, t_y$) ; une transformation projective plane à 8 paramètres ; et la spline de plaque mince (thin plate spline, TPS), capable de déformations non rigides. La seule condition est que $\\mathcal{T}_\\theta$ soit différentiable par rapport à ses paramètres, pour que le gradient puisse remonter des points d'échantillonnage jusqu'à $\\theta$.\n\n### L'échantillonneur : prendre des valeurs entre les points de la grille\n\nLes points d'échantillonnage tombent rarement pile sur des coordonnées entières ; l'échantillonneur a donc besoin d'un noyau d'interpolation. Les auteurs en donnent une forme générale, puis s'en tiennent surtout à l'interpolation bilinéaire :\n\n$$\nV_i^c = \\sum_{n}^{H}\\sum_{m}^{W} U_{nm}^c\\,\\max\\!\\big(0,\\ 1-|x_i^s-m|\\big)\\,\\max\\!\\big(0,\\ 1-|y_i^s-n|\\big)\n$$\n\nChaque valeur de sortie est une moyenne pondérée des quatre pixels les plus proches du point d'échantillonnage, avec des poids fixés par la distance.\n\nLe point clé : cette expression admet un (sous-)gradient à la fois par rapport à $U$ et par rapport aux coordonnées d'échantillonnage $x_i^s$, $y_i^s$. Le gradient qui atteint les coordonnées d'échantillonnage peut remonter jusqu'à $\\theta$, puis jusqu'au réseau de localisation.\n\nPrenons un $\\theta$ dont les points ne tombent pas pile sur la grille, et essayons-le sur une entrée $5\\times5$ dont les valeurs vont de 0 en haut à gauche à 24 en bas à droite :\n\n```python\nimport torch\nimport torch.nn.functional as F\n\nU = torch.arange(25, dtype=torch.float32).reshape(1, 1, 5, 5)   # entrée 5×5, valeurs de 0 à 24\ntheta = torch.tensor([[[0.4, 0.0, -0.3],\n                       [0.0, 0.4, -0.3]]], requires_grad=True)\ngrid = F.affine_grid(theta, size=(1, 1, 3, 3), align_corners=True)\nprint(\"coordonnées x d'échantillonnage (en pixels) :\", [round(v, 2) for v in ((grid[0, 0, :, 0] + 1) * 2).tolist()])\n\nV = F.grid_sample(U, grid, mode=\"bilinear\", align_corners=True)\nprint(V[0, 0])\n\nV.sum().backward()               # une perte quelconque, pour voir si le gradient remonte jusqu'à θ\nprint(theta.grad)\n```\n\n```text\ncoordonnées x d'échantillonnage (en pixels) : [0.6, 1.4, 2.2]\ntensor([[ 3.6000,  4.4000,  5.2000],\n        [ 7.6000,  8.4000,  9.2000],\n        [11.6000, 12.4000, 13.2000]], grad_fn=<SelectBackward0>)\ntensor([[[ 0.,  0., 18.],\n         [ 0.,  0., 90.]]])\n```\n\nLes valeurs de cette entrée valent « ligne × 5 + colonne ». Le premier point d'échantillonnage tombe en ligne 0,6, colonne 0,6, et l'interpolation bilinéaire donne $0.6\\times5+0.6=3.6$ ; ce point ne coïncide avec aucun point entier de la grille, et sa valeur est un mélange des quatre pixels voisins, pondéré par la distance.\n\nLe gradient remonte bien jusqu'à $\\theta$. Celui du paramètre de translation $\\theta_{13}$ vaut 18 : décaler la grille d'échantillonnage d'une unité normalisée vers la droite revient à la décaler de deux pixels, ce qui augmente chaque valeur échantillonnée de 2 ; sur 9 points d'échantillonnage, cela fait 18. $\\theta_{23}$ décale la grille vers le bas : chaque point gagne 10, soit 90 au total. Les gradients des quatre autres paramètres sont nuls : cette entrée croît uniformément de gauche à droite et de haut en bas ; quand la grille s'agrandit, se réduit ou s'incline autour de son centre, les valeurs échantillonnées baissent d'un côté et augmentent de l'autre, et les deux effets s'annulent exactement.\n\nVoilà pourquoi tout le module s'entraîne de bout en bout : le gradient de la perte par rapport à la sortie $V$ traverse l'échantillonneur jusqu'aux coordonnées d'échantillonnage, puis le générateur de grille jusqu'à $\\theta$, et entre enfin dans les poids du réseau de localisation. Personne n'a besoin de fournir la bonne transformation.\n\n\n> [!NOTE]\n> \n> L'interpolation bilinéaire n'est pas différentiable lorsque le point tombe pile sur la grille ; on doit alors se contenter d'un sous-gradient. Les auteurs notent aussi qu'en pratique, il n'est pas nécessaire de sommer réellement sur toutes les positions de l'entrée : seuls comptent les quatre pixels qui entourent chaque point d'échantillonnage, ce qui rend le calcul très rapide sur GPU.\n\n\n### L'insérer dans le réseau\n\nCe module peut être inséré à n'importe quel endroit d'un réseau convolutif, et en autant d'exemplaires qu'on le souhaite :\n\n- **En série, à différentes profondeurs** : un module profond voit des caractéristiques plus abstraites, et son réseau de localisation dispose de plus d'information pour décider de la transformation.\n- **En parallèle** : quand une carte de caractéristiques contient plusieurs objets ou parties à traiter séparément, on peut placer plusieurs modules côte à côte, chacun se concentrant sur une zone. Les auteurs mentionnent aussi une limite : dans un réseau purement feed-forward, le nombre de modules en parallèle borne le nombre d'objets que le réseau peut traiter séparément.\n\nLa taille de sortie $H'$, $W'$ peut aussi différer de celle de l'entrée, ce qui permet au module de sous-échantillonner au passage. Toutefois, avec un noyau d'interpolation à support aussi réduit que le noyau bilinéaire, le sous-échantillonnage peut provoquer du repliement de spectre.\n\n## Discussion\n\n### MNIST déformé\n\nLes auteurs construisent plusieurs versions déformées de MNIST : rotation (R) ; rotation, translation et changement d'échelle (RTS) ; transformation projective (P) ; déformation élastique (E). Ils comparent un réseau entièrement connecté ordinaire (FCN), un réseau convolutif (CNN) et leurs versions dotées d'un module de transformation spatiale à l'entrée (ST-FCN, ST-CNN), avec des transformations affines (Aff), projectives (Proj) ou des TPS à 16 points de contrôle. Tous les modèles ont à peu près le même nombre de paramètres ; leur partie classification compte trois couches de poids, et les CNN ont deux couches de max pooling.\n\n| Modèle | R | RTS | P | E |\n| --- | ---: | ---: | ---: | ---: |\n| FCN | 2,1 | 5,2 | 3,1 | 3,2 |\n| CNN | 1,2 | 0,8 | 1,5 | 1,4 |\n| ST-FCN, Aff | 1,2 | 0,8 | 1,5 | 2,7 |\n| ST-FCN, TPS | 1,1 | 0,8 | 1,4 | 2,4 |\n| ST-CNN, Aff | 0,7 | 0,5 | 0,8 | 1,2 |\n| ST-CNN, Proj | 0,8 | 0,6 | 0,8 | 1,3 |\n| ST-CNN, TPS | 0,7 | 0,5 | 0,8 | 1,1 |\n\n*Tableau : taux d'erreur (%) extraits de la Table 1 de l'article ; la version ST-FCN à transformation projective est omise.*\n\nPour chaque type de déformation, le réseau doté du module fait mieux que sa référence. La colonne RTS est la plus intéressante : ST-FCN, sans aucune convolution ni aucun pooling, obtient 0,8 % d'erreur, autant que le CNN et ses deux couches de pooling. Pour les auteurs, cela montre que le transformateur spatial est une autre manière d'obtenir l'invariance spatiale. ST-CNN fait encore mieux que ST-FCN, car le pooling apporte davantage d'invariance et la convolution traite mieux les structures locales.\n\nSur la version en $60\\times60$, où les chiffres sont translatés sur un fond parsemé de parasites, l'écart se creuse : FCN 13,2 %, CNN 3,5 %, ST-FCN 2,0 %, ST-CNN 1,7 %.\n\nDes trois transformations, la TPS est la plus puissante : elle remodèle les chiffres déformés élastiquement pour les ramener près de leur forme standard, sans surapprendre sur les données simples à rotation. Les auteurs observent aussi que tous les modèles redressent les chiffres dans une pose « standard » verticale, c'est-à-dire la pose moyenne des données d'entraînement.\n\n### Numéros de rue\n\nSVHN contient environ 200 000 photos réelles de numéros de maison, avec 1 à 5 chiffres par image, de tailles et de dispositions très variables ; la tâche est de reconnaître la séquence complète. Le modèle de référence des auteurs compte 11 couches cachées, suivies de 5 softmax indépendants, chacun prédisant le chiffre d'une position.\n\nSur cette base, ils testent deux extensions :\n\n- **ST-CNN Single** : un module ajouté juste après l'entrée, avec un réseau de localisation convolutif à quatre couches.\n- **ST-CNN Multi** : un module avant chacune des quatre premières couches de convolution, avec des réseaux de localisation entièrement connectés à deux couches de 32 unités ; à part le premier, tous les modules transforment des cartes de caractéristiques.\n\nTous les modules utilisent une transformation affine et un échantillonnage bilinéaire, et la couche de régression de chaque réseau de localisation est initialisée pour produire la transformation identité.\n\n| Modèle | 64px | 128px |\n| --- | ---: | ---: |\n| Maxout CNN | 4,0 | — |\n| CNN (référence des auteurs) | 4,0 | 5,6 |\n| DRAM* | 3,9 | 4,5 |\n| ST-CNN Single | 3,7 | 3,9 |\n| ST-CNN Multi | 3,6 | 3,9 |\n\n*Tableau : taux d'erreur par séquence (%) extraits de la Table 2 de l'article. 64px désigne des images de $64\\times64$ recadrées autour de la séquence de chiffres, 128px des images de $128\\times128$ recadrées plus largement, avec davantage d'arrière-plan. DRAM utilise une moyenne de modèles et une moyenne de Monte-Carlo ; tous les autres sont des modèles uniques, en une seule passe avant.*\n\nEn 64px, ST-CNN Multi établit le meilleur résultat de l'époque avec 3,6 %. En 128px, avec plus d'arrière-plan, le CNN de référence se dégrade à 5,6 %, alors que ST-CNN reste à 3,9 % : le module découpe et agrandit la zone des chiffres, si bien que la résolution et la capacité du réseau se concentrent sur les chiffres. Le coût est modeste : la passe avant et arrière de ST-CNN Multi n'est que 6 % plus lente que celle du CNN de référence.\n\n### Classification fine des oiseaux\n\nCUB-200-2011 compte 200 espèces d'oiseaux, avec environ 6 000 images d'entraînement et 5 800 images de test ; les oiseaux varient en taille et en orientation, et les images ne sont pas recadrées serré sur l'oiseau. Pour distinguer les espèces, il faut examiner les détails de texture et de forme.\n\nLa référence des auteurs est déjà solide : un réseau Inception préentraîné sur ImageNet, avec batch normalization, qui atteint 82,3 % après affinage sur CUB, au-dessus du meilleur résultat antérieur, 81,0 %. Ils placent ensuite 2 ou 4 modules en parallèle, avec une transformation de forme attentionnelle appliquée à l'image d'entrée ; chaque zone découpée par un module est décrite par son propre sous-réseau Inception, puis les descriptions sont concaténées pour la classification. Le réseau entier n'est entraîné qu'avec les étiquettes de classe.\n\n| Modèle | Précision |\n| --- | ---: |\n| CNN (référence), 224px | 82,3 % |\n| 2×ST-CNN, 224px | 83,1 % |\n| 2×ST-CNN, 448px | 83,9 % |\n| 4×ST-CNN, 448px | 84,1 % |\n\n*Tableau : extrait de la Table 3 de l'article.*\n\nLa version à 4 modules atteint 84,1 %, soit 1,8 point de pourcentage de plus que la référence. Les auteurs ont aussi découvert que l'ensemble d'entraînement d'ImageNet et l'ensemble de test de CUB ont 22 images en commun (sur 5 794) ; une fois ces images retirées, on obtient 84,0 %.\n\nPlus intéressante encore est la répartition des rôles apprise par les modules : dans la version à 2 modules, l'un devient un détecteur de tête d'oiseau, l'autre se concentre sur le corps. Les méthodes antérieures s'appuyaient sur des annotations de points clés et entraînaient à part un détecteur pour chaque partie ; ici, sans aucune annotation de parties, les modules ont trouvé eux-mêmes les parties dans les données.\n\nL'entrée peut passer en 448px sans augmenter le calcul, car la sortie transformée par les modules est sous-échantillonnée à 224px avant d'être transmise au reste du réseau.\n\n## Conclusion\n\nLe transformateur spatial confie aussi au réseau l'apprentissage de « la manière de regarder l'image » : le réseau de localisation prédit la transformation, le générateur de grille calcule les positions d'échantillonnage, et l'échantillonnage bilinéaire différentiable laisse le gradient remonter jusqu'au bout. Le module ne demande ni annotation supplémentaire, ni modification de la fonction de perte.\n\nLes expériences couvrent MNIST déformé, des photos réelles de numéros de maison et la classification fine d'oiseaux, avec chaque fois de meilleurs résultats que la référence dans les mêmes conditions ; sans la moindre indication, le module apprend en outre à redresser les chiffres, à découper les numéros de maison, et à regarder séparément la tête et le corps des oiseaux. Les auteurs en signalent aussi les limites : le nombre de modules en parallèle borne le nombre d'objets traités séparément, et le sous-échantillonnage peut provoquer du repliement de spectre.\n\nLe transformateur spatial s'insère directement dans un réseau existant, sans modifier la fonction de perte ni ajouter d'annotations. PyTorch intègre déjà `affine_grid` et `grid_sample` ; les exemples ci-dessus utilisent justement ces deux fonctions, et en brancher un soi-même n'a rien de difficile.\n\nSi vos données contiennent beaucoup d'inclinaisons ou de déformations de perspective, comme le texte des enseignes dans les photos de rue, essayez d'en placer un en tête de réseau ; c'est ainsi que [RARE](/blog/papers/text-recognition/rare) aborde la reconnaissance de texte.\n","imageSizes":{"/content/papers/assets/7b29191fd34e282fbd2d0fa901014f5770192cf1641d814b39b43a903817fb7f.png":{"width":480,"height":364},"/content/papers/assets/96a7134077ab04428f529111ff95e65d6863c038ad037e4d679cb1d2de57c0bb.png":{"width":832,"height":330},"/content/papers/assets/89651828c63ac51ce8bd1efa4deffe57d50cca84735217ef8b2c9087b5b760c8.png":{"width":820,"height":364}}}
