Que sont les couches déconvolutionnelles?

188

J'ai récemment lu des réseaux entièrement convolutionnels pour la segmentation sémantique par Jonathan Long, Evan Shelhamer et Trevor Darrell. Je ne comprends pas ce que font les "couches déconvolutionnelles" / comment elles fonctionnent.

La partie pertinente est

3.3. L'échantillonnage est une convolution à pas en arrière

L'interpolation est un autre moyen de connecter des sorties grossières à des pixels denses. Par exemple, une simple interpolation bilinéaire calcule chaque sortie partir des quatre entrées les plus proches par une carte linéaire qui ne dépend que des positions relatives des cellules d’entrée et de sortie. En un sens, le suréchantillonnage avec le facteur f est une convolution avec une foulée d'entrée fractionnaire de 1 / f. Tant que f est intégral, un moyen naturel de suréchantillonner est donc la convolution vers l’arrière (parfois appelée déconvolution) avec une foulée de sortie de f . Une telle opération est triviale à mettre en oeuvre, car elle inverse simplement les passes de convolution aller et retour.yij
fff
Ainsi, le suréchantillonnage est effectué sur le réseau pour un apprentissage de bout en bout par rétrodiffusion à partir de la perte au niveau des pixels.
Il est à noter que le filtre de déconvolution dans une telle couche n'a pas besoin d'être fixé (par exemple, pour un suréchantillonnage bilinéaire), mais peut être appris. Une pile de couches de déconvolution et de fonctions d’activation peut même apprendre un échantillonnage croissant non linéaire.
Dans nos expériences, nous avons constaté que l'échantillonnage sur réseau est rapide et efficace pour l'apprentissage de la prédiction dense. Notre meilleure architecture de segmentation utilise ces couches pour apprendre à suréchantillonner pour une prédiction plus précise dans la section 4.2.

Je ne pense pas avoir vraiment compris comment les couches convolutives sont formées.

Ce que je pense avoir compris, c’est que les couches convolutives de taille apprennent des filtres de taille k × k . La sortie d’une couche convolutive de taille k , k , stride s N et n filtres est de dimension Input dimkk×kksNnInput dims2n . Cependant, je ne sais pas comment fonctionne l'apprentissage des couches convolutives. (Je comprends comment des MLP simples apprennent avec une descente de gradient, si cela peut aider).

Donc, si ma compréhension des couches convolutives est correcte, je ne sais pas comment cela peut être inversé.

Quelqu'un pourrait-il m'aider à comprendre les couches déconvolutionnelles?

Martin Thoma
la source
3
Cette conférence vidéo explique la déconvolution / rééchantillonnage: youtu.be/ByjaPdWXKJ4?t=16m59s
user199309 le
6
Espérant que cela pourrait être utile à tout le monde, j'ai créé un cahier de travail pour explorer comment utiliser la convolution et la convolution transposée dans TensorFlow (0.11). Peut-être que quelques exemples pratiques et des chiffres peuvent aider un peu plus à comprendre comment ils fonctionnent.
AkiRoss
1
Pour moi, cette page m'a donné une meilleure explication , il explique aussi la différence entre déconvolution et transposer convolution: towardsdatascience.com/...
T.Antoni
Le suréchantillonnage n'est-il pas plus une fusion en amont qu'une convolution à pas arrière, car il n'a pas de paramètre?
Ken Fehling
Remarque: Le nom « couche deconvolutional » est trompeur , car cette couche ne pas effectuer déconvolution .
user76284 le

Réponses:

210

La couche de déconvolution est un nom très malheureux et devrait plutôt s'appeler une couche convolutive transposée .

Visuellement, pour une convolution transposée avec stride one et sans remplissage, nous complétons simplement l'entrée d'origine (entrées bleues) avec des zéros (entrées blanches) (Figure 1).

Figure 1

En cas de foulée deux et de rembourrage, la convolution transposée ressemblerait à ceci (Figure 2):

Figure 2

Vous pouvez trouver plus de (grandes) visualisations d'arithmétiques de convolution ici .

David Dao
la source
16
Juste pour m'assurer que j'ai bien compris: "Déconvolution" est à peu près la même chose que convolution, mais vous ajoutez un peu de rembourrage? (Autour de l'image / quand s> 1 également autour de chaque pixel)?
Martin Thoma
17
Oui, une couche de déconvolution effectue également une convolution! C’est la raison pour laquelle la convolution transposée s’adapte tellement mieux que le nom et le terme de déconvolution est en réalité trompeur.
David Dao
11
Pourquoi dites-vous "pas de remplissage" dans la figure 1, si en réalité l'entrée est remplie à zéro?
Stas S
8
A propos: C'est ce qu'on appelle la convolution transposée maintenant dans TensorFlow: tensorflow.org/versions/r0.10/api_docs/python/…
Martin Thoma
9
Merci pour cette réponse très intuitive, mais je ne comprends pas pourquoi le second cas est le cas «stride two», il se comporte exactement comme le premier lorsque le noyau est déplacé.
Demonedge
49

Je pense qu’une façon d’obtenir une intuition très élémentaire derrière la convolution est de faire glisser des filtres K, que vous pouvez considérer comme des pochoirs K, sur l’image d’entrée et de produire des activations K, chacune représentant un degré d’adéquation à un gabarit particulier. . L’opération inverse consiste à prendre K activations et à les développer en une pré-image de l’opération de convolution. L’explication intuitive de l’opération inverse est donc, grosso modo, une reconstruction d’image en fonction des pochoirs (filtres) et des activations (degré de correspondance pour chaque pochoir) et donc au niveau intuitif de base nous voulons faire sauter chaque activation par le masque du pochoir et les additionner.

Une autre façon d’approcher la compréhension de deconv serait d’examiner l’implémentation de la couche de déconvolution dans Caffe, voir les bits de code pertinents suivants:

DeconvolutionLayer<Dtype>::Forward_gpu
ConvolutionLayer<Dtype>::Backward_gpu
CuDNNConvolutionLayer<Dtype>::Backward_gpu
BaseConvolutionLayer<Dtype>::backward_cpu_gemm

Vous pouvez voir qu'il est implémenté dans Caffe exactement comme backprop pour une couche convolutionnelle normale (pour moi, c'était plus évident après avoir comparé l'implémentation de backprop dans la couche convDNU contre ConvolutionLayer :: Backward_gpu implémenté à l'aide de GEMM). Donc, si vous étudiez comment la rétropropagation est effectuée pour une convolution régulière, vous comprendrez ce qui se passe au niveau du calcul mécanique. Le fonctionnement de ce calcul correspond à l'intuition décrite dans le premier paragraphe de ce résumé.

Cependant, je ne sais pas comment fonctionne l'apprentissage des couches convolutives. (Je comprends comment des MLP simples apprennent avec une descente de gradient, si cela peut aider).

Pour répondre à votre autre question dans votre première question, il y a deux différences principales entre la rétropropagation MLP (couche entièrement connectée) et les réseaux convolutionnels:

1) l’influence des poids est localisée, il faut donc commencer par déterminer comment procéder, par exemple pour un filtre 3x3 convolué avec une petite zone 3x3 d’une image en entrée, mappé sur un seul point de l’image résultante.

2) les poids des filtres de convolution sont partagés pour l'invariance spatiale. En pratique, cela signifie que lors du passage en aval, le même filtre 3x3 avec les mêmes poids est déplacé dans l'image entière avec les mêmes poids pour le calcul en avant afin d'obtenir l'image de sortie (pour ce filtre particulier). Cela signifie pour backprop, c'est que les gradients de backprop pour chaque point de l'image source sont additionnés sur toute la plage de traçage de ce filtre lors du passage en avant. Notez qu'il existe également différents gradients de perte par rapport à x, w et biais puisque dLoss / dx doit être rétropropagé, et dLoss / dw est la méthode de mise à jour des pondérations. w et biais sont des entrées indépendantes dans le DAG de calcul (il n'y a pas d'entrées antérieures), il n'est donc pas nécessaire de faire une rétro-propagation sur celles-ci.

(my notation here assumes that convolution is y = x*w+b where '*' is the convolution operation)
Andrei Pokrovsky
la source
7
Je pense que c'est la meilleure réponse à cette question.
kli_nlpr
8
Je conviens que c'est la meilleure réponse. La réponse principale a de jolies animations, mais jusqu'à ce que je lise cette réponse, elles ressemblaient à des convolutions régulières avec un remplissage arbitraire pour moi. Oh, comment les gens sont influencés par les bonbons pour les yeux.
Reii Nakano
1
D'accord, la réponse acceptée n'a rien expliqué. Ceci est vraiment mieux.
BjornW
Merci pour votre bonne explication. Je ne sais pas comment faire le backprop correctement. Pourriez-vous me donner un indice à ce sujet s'il vous plaît?
Bastian
33

Calculs pas à pas expliquant comment la convolution transposée effectue un suréchantillonnage 2x avec un filtre 3x3 et une foulée de 2:

entrez la description de l'image ici

Le fragment de code TensorFlow le plus simple permettant de valider le calcul:

import tensorflow as tf
import numpy as np

def test_conv2d_transpose():
    # input batch shape = (1, 2, 2, 1) -> (batch_size, height, width, channels) - 2x2x1 image in batch of 1
    x = tf.constant(np.array([[
        [[1], [2]], 
        [[3], [4]]
    ]]), tf.float32)

    # shape = (3, 3, 1, 1) -> (height, width, input_channels, output_channels) - 3x3x1 filter
    f = tf.constant(np.array([
        [[[1]], [[1]], [[1]]], 
        [[[1]], [[1]], [[1]]], 
        [[[1]], [[1]], [[1]]]
    ]), tf.float32)

    conv = tf.nn.conv2d_transpose(x, f, output_shape=(1, 4, 4, 1), strides=[1, 2, 2, 1], padding='SAME')

    with tf.Session() as session:
        result = session.run(conv)

    assert (np.array([[
        [[1.0], [1.0],  [3.0], [2.0]],
        [[1.0], [1.0],  [3.0], [2.0]],
        [[4.0], [4.0], [10.0], [6.0]],
        [[3.0], [3.0],  [7.0], [4.0]]]]) == result).all()
Andriys
la source
Je pense que votre calcul est faux ici. La sortie intermédiaire doit être 3+ 2 * 2 = 7, puis pour un noyau 3x3, la sortie finale doit être 7-3 + 1 = 5x5
Alex
Désolé, @Alex, mais je ne comprends pas pourquoi la sortie intermédiaire est 7. Pouvez-vous élaborer?
andriys
2
@andriys Dans l'image que vous avez montrée, pourquoi le résultat final est-il tronqué?
James Bond
28

Les notes qui accompagnent la classe CS231n de Stanford CS : Réseaux de neurones convolutionnels pour la reconnaissance visuelle, par Andrej Karpathy , expliquent très bien les réseaux de neurones convolutionnels.

La lecture de cet article devrait vous donner une idée approximative de:

  • Réseaux déconvolutionnels Matthew D. Zeiler, Dilip Krishnan, Graham W. Taylor et Rob Fergus Département d'informatique, Institut Courant, Université de New York

Ces diapositives sont idéales pour les réseaux déconvolutionnels.

Azrael
la source
29
Est-il possible de résumer le contenu de l'un de ces liens dans un court paragraphe? Les liens peuvent être utiles pour des recherches ultérieures, mais idéalement, une réponse à un échange de pile devrait contenir suffisamment de texte pour traiter la question de base sans avoir à quitter le site.
Neil Slater
Je suis désolé mais le contenu de ces pages est trop volumineux pour être résumé dans un court paragraphe.
Azrael
12
Par exemple, "un réseau neuronal déconvolutionnel est similaire à un réseau CNN, mais il est conçu pour que les entités de toute couche masquée puissent être utilisées pour reconstruire la couche précédente (et par répétition sur plusieurs couches, éventuellement l’entrée peut être reconstituée à partir de la sortie), ce qui lui permet d’être formée sans surveillance afin d’apprendre les caractéristiques génériques de haut niveau dans un domaine problématique - généralement le traitement d’image "(remarque: je ne suis même pas sûr que cela soit correct propre réponse).
Neil Slater
6
Bien que les liens soient bons, un bref résumé du modèle dans vos propres mots aurait été préférable.
SmallChess
11

Je viens de trouver un excellent article du site Web de theaon sur ce sujet [1]:

La nécessité de convolutions transposées découle généralement de la volonté d'utiliser une transformation allant dans la direction opposée à une convolution normale, [...] pour projeter des cartes de caractéristiques dans un espace de dimension supérieure. [...] C'est-à-dire mapper d'un espace à 4 dimensions à un espace à 16 dimensions, tout en conservant le modèle de connectivité de la convolution.

Les convolutions transposées - également appelées convolutions à pas fractionné - fonctionnent en échangeant les passes en avant et en arrière d'une convolution. Une façon de le dire est de noter que le noyau définit une convolution, mais que ce soit une convolution directe ou une convolution transposée est déterminé par la manière dont les passes en avant et en arrière sont calculées.

L'opération de convolution transposée peut être considérée comme le gradient d'une convolution par rapport à son entrée, qui est généralement la manière dont les convolutions transposées sont mises en œuvre dans la pratique.

Notons enfin qu'il est toujours possible de mettre en oeuvre une convolution transposée avec une convolution directe. L'inconvénient est que cela implique généralement l'ajout de nombreuses colonnes et rangées de zéros à l'entrée, ce qui se traduit par une implémentation beaucoup moins efficace.

Ainsi, en termes simples, une "convolution transposée" est une opération mathématique utilisant des matrices (tout comme une convolution), mais elle est plus efficace que l'opération de convolution normale dans le cas où vous souhaitez revenir des valeurs convolutives à la valeur d'origine (sens opposé). C'est pourquoi il est préférable dans les implémentations de convolution lors du calcul de la direction opposée (c'est-à-dire pour éviter de nombreuses multiplications inutiles par 0 causées par la matrice creuse qui résulte du remplissage de l'entrée).

Image ---> convolution ---> Result

Result ---> transposed convolution ---> "originalish Image"

Parfois, vous enregistrez des valeurs le long du chemin de convolution et réutilisez ces informations lorsque vous "retournez":

Result ---> transposed convolution ---> Image

C'est probablement la raison pour laquelle on appelle à tort une "déconvolution". Cependant, cela a quelque chose à voir avec la transposée matricielle de la convolution (C ^ T), d'où le nom plus approprié de "convolution transposée".

Cela prend donc tout son sens lorsque l’on prend en compte les coûts informatiques. Si vous n’utilisiez pas la convolution transposée, vous paieriez beaucoup plus cher pour les gpus d’Amazon.

Lisez et regardez attentivement les animations ici: http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html#no-zero-padding-unit-strides-transposed

Une autre lecture pertinente:

La transposition (ou plus généralement, la transposition hermitienne ou conjuguée) d'un filtre est simplement le filtre adapté [3]. Ceci est trouvé en inversant le noyau dans le temps et en prenant le conjugué de toutes les valeurs [2].

Je suis également novice dans ce domaine et je serais reconnaissant de tout commentaire ou de toute correction.

[1] http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html

[2] http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html#transposed-convolution-arithmetic

[3] https://en.wikipedia.org/wiki/Matched_filter

Andrei
la source
1
Nit picking, mais le lien devrait être: deeplearning.net/software/theano_versions/dev/tutorial/…
Herbert
1
Je pense que c'est la meilleure réponse !!!
kli_nlpr
10

Nous pourrions utiliser PCA pour l'analogie.

Lors de l'utilisation de conv, le passage direct consiste à extraire les coefficients des composantes principales de l'image d'entrée et le passage arrière (qui met à jour l'entrée) consiste à utiliser (le gradient de) les coefficients pour reconstruire une nouvelle image d'entrée, de sorte que le La nouvelle image d'entrée a des coefficients PC qui correspondent mieux aux coefficients souhaités.

Lors de l'utilisation de deconv, les passes avant et arrière sont inversées. La passe avant tente de reconstruire une image à partir de coefficients PC et la passe arrière met à jour les coefficients PC donnés (le gradient de) de l'image.

Le deconv forward pass effectue exactement le calcul de gradient de conv donné dans ce message: http://andrew.gibiansky.com/blog/machine-learning/convolutional-neural-networks/

C'est pourquoi, dans l'implémentation caffe de deconv (voir la réponse d'Andrei Pokrovsky), les appels de transfert de deconv transmettent backward_cpu_gemm () et d'appels de transfert arrière forward_cpu_gemm ().

Shaohua Li
la source
6

En plus de la réponse de David Dao: Il est également possible de penser autrement. Au lieu de vous focaliser sur les pixels d'entrée (basse résolution) utilisés pour produire un seul pixel de sortie, vous pouvez également vous focaliser sur les pixels d'entrée individuels qui contribuent à quelle région des pixels de sortie.

Ceci est fait dans cette publication distillée , y compris une série de visualisations très intuitives et interactives. L'un des avantages de la réflexion dans cette direction est qu'il est facile d'expliquer les artefacts en damier.

Martin R.
la source
5

Convolutions du point de vue du DSP

Je suis un peu en retard, mais j'aimerais quand même partager mon point de vue et mes idées. Mes antécédents sont la physique théorique et le traitement du signal numérique. J'ai notamment étudié les ondelettes et les convolutions sont presque dans ma colonne vertébrale;)

La façon dont les membres de la communauté d’apprentissage en profondeur parlent de convolutions m’a également troublé. De mon point de vue, ce qui semble manquer est une séparation appropriée des préoccupations. Je vais expliquer les convolutions d'apprentissage approfondi à l'aide de certains outils DSP.

Avertissement

Mes explications seront un peu ondulées à la main et non pas mathématiques rigoureuses afin de faire passer les points principaux.


Définitions

xn={xn}n=={,x1,x0,x1,} .

ynxn

(yx)n=k=ynkxk

q=(q0,q1,q2)x=(x0,x1,x2,x3)T

qx=(q1q000q2q1q000q2q1q000q2q1)(x0x1x2x3)

kN

kxn=xnk

kk1

kxn={xn/kn/kZ0otherwise

k=3

3{,x0,x1,x2,x3,x4,x5,x6,}={,x0,x3,x6,}
3{,x0,x1,x2,}={x0,0,0,x1,0,0,x2,0,0,}

k=2

2x=(x0x2)=(10000010)(x0x1x2x3)

et

2x=(x00x10)=(10000100)(x0x1)

k=kT


Approfondissement des convolutions par pièces

qx

  • kk(qx)
  • k(kq)x
  • kq(kx)

q(kx)=q(kTx)=(k(q)T)Tx

(q)q

q(kx)=(q1q000q2q1q000q2q1q000q2q1)(10000100)(x0x1)=(q1q200q0q1q200q0q1q200q0q1)T(10000010)T(x0x1)=((10000010)(q1q200q0q1q200q0q1q200q0q1))T(x0x1)=(k(q)T)Tx

Comme on peut le voir, l’opération est transposée, ainsi le nom.

Connexion au suréchantillonnage du voisin le plus proche

2(11)xq2(11)qxq=(q0q1q2)

(11)q=(q0q0+q1q1+q2q2),

c'est-à-dire que nous pouvons remplacer un échantillonneur périodique avec le facteur 2 et une convolution avec un noyau de taille 3 par une convolution transposée avec une taille de noyau 4. Cette convolution transposée a la même "capacité d'interpolation", mais serait en mesure d'apprendre de meilleures interpolations de correspondance.


Conclusions et remarques finales

J'espère pouvoir clarifier un peu certaines convolutions communes trouvées dans l'apprentissage en profondeur en les décomposant dans les opérations fondamentales.

Je n'ai pas couvert la mise en commun ici. Mais il ne s'agit que d'un échantillonneur descendant non linéaire et peut également être traité dans cette notation.

André Bergner
la source
Excellente réponse. Prendre une perspective mathématique / symbolique clarifie souvent les choses. Ai-je raison de penser que le terme "déconvolution" dans ce contexte se heurte à la terminologie existante ?
user76284
Cela ne se heurte pas vraiment, cela n'a aucun sens. La déconvolution n'est qu'une convolution avec un opérateur suréchantillonneur. Le terme déconvolution ressemble à une forme d'opération inverse. Parler d'un inverse ici n'a de sens que dans le contexte d'opérations matricielles. Il se multiplie avec la matrice inverse et non pas l'opération inverse de convolution (comme division vs multiplication).
André Bergner le
zθx=zzθz=x
θz=xz=(θ)+x
En bref, la "couche de déconvolution" du PO ne fait pas de déconvolution. C'est faire autre chose (ce que vous avez décrit dans votre réponse).
user76284 le
4

J'ai eu beaucoup de mal à comprendre ce qui s'est vraiment passé dans le journal jusqu'à ce que je tombe sur ce billet de blog: http://warmspringwinds.github.io/tensorflow/tf-slim/2016/11/22/upsampling-and-image-segmentation -avec-tensorflow-et-tf-slim /

Voici un résumé de la façon dont je comprends ce qui se passe dans un suréchantillonnage 2x:

Informations du papier

  • Qu'est-ce que l'échantillonnage?
  • Quels sont les paramètres de cette convolution?
  • Est-ce que les poids sont fixes ou peuvent être entraînés?
    • Le document indique "nous initialisons l’échantillonnage 2x vers le haut en interpolation bilinéaire, mais nous autorisons l’apprentissage des paramètres [...]".
    • Cependant, la page correspondante de github indique "Dans nos expériences originales, les couches d'interpolation étaient initialisées en noyaux bilinéaires puis apprises. Dans les expériences suivantes, et cette implémentation de référence, les noyaux bilinéaires sont fixés"
    • → poids fixes

Exemple simple

  1. imaginez l'image d'entrée suivante:

Image d'entrée

  1. Les convolutions à pas fractionné fonctionnent en insérant un facteur-1 = 2-1 = 1 zéros entre ces valeurs, puis en supposant que foulée = 1 ultérieurement. Ainsi, vous recevez l'image 6x6 padded suivante

image capitonnée

  1. Le filtre 4x4 bilinéaire ressemble à ceci. Ses valeurs sont choisies de telle sorte que les poids utilisés (= tous les poids ne soient pas multipliés par un zéro inséré) totalisent jusqu'à 1. Ses trois valeurs uniques sont 0.56, 0.19 et 0.06. De plus, le centre du filtre est par convention le pixel de la troisième ligne et de la troisième colonne.

filtre

  1. L'application du filtre 4x4 sur l'image capitonnée (en utilisant padding = 'same' et stride = 1) donne l'image suréchantillonnée 6x6 suivante:

Image de haut niveau

  1. Ce type de suréchantillonnage est effectué pour chaque canal individuellement (voir la ligne 59 de la page https://github.com/shelhamer/fcn.berkeleyvision.org/blob/master/surgery.py ). À la fin, le suréchantillonnage 2x est vraiment un redimensionnement très simple utilisant une interpolation bilinéaire et des conventions sur la façon de gérer les bordures. Je pense que le suréchantillonnage 16x ou 32x fonctionne de manière très similaire.
gebbissimo
la source
-1

Le document suivant aborde les couches déconvolutionnelles. Du point de vue de l’architecture et de la formation. Réseaux déconvolutionnels

Avhirup
la source
1
Cela n’ajoute aucune valeur à cette réponse
Martin Thoma