python convolutional - Tensorflow Strides Argument




neural network (4)

J'essaie de comprendre l'argument des foulées dans tf.nn.avg_pool, tf.nn.max_pool, tf.nn.conv2d.

La documentation dit à plusieurs reprises

strides: Une liste d'ints de longueur> = 4. La foulée de la fenêtre glissante pour chaque dimension du tenseur d'entrée.

Mes questions sont:

  1. Que représentent chacun des 4+ entiers?
  2. Pourquoi doivent-ils avoir des foulées [0] = foulées [3] = 1 pour les convnets?
  3. Dans cet exemple, nous voyons tf.reshape(_X,shape=[-1, 28, 28, 1]) . Pourquoi -1?

Malheureusement, les exemples dans les docs pour remodeler en utilisant -1 ne se traduisent pas trop bien dans ce scénario.


Answers

Les entrées sont en 4 dimensions et sont de forme: [taille_bloc, image_rows, image_cols, number_of_colors]

Les foulées définissent en général un chevauchement entre les opérations d'application. Dans le cas de conv2d, il spécifie quelle est la distance entre les applications consécutives des filtres convolutifs. La valeur de 1 dans une dimension spécifique signifie que nous appliquons l'opérateur à chaque ligne / col, la valeur de 2 signifie toutes les secondes, et ainsi de suite.

Re 1) Les valeurs qui comptent pour les convolutions sont les 2ème et 3ème et représentent le chevauchement dans l'application des filtres convolutionnels le long des lignes et des colonnes. La valeur de [1, 2, 2, 1] indique que nous voulons appliquer les filtres sur chaque deuxième ligne et colonne.

Re 2) Je ne connais pas les limitations techniques (peut-être l'exigence CuDNN) mais généralement les gens utilisent des foulées le long des rangées ou des colonnes. Cela n'a pas forcément de sens de le faire par rapport à la taille du lot. Pas sûr de la dernière dimension.

Re 3) En définissant -1 pour l'un des moyens de dimension, "définir la valeur pour la première dimension de sorte que le nombre total d'éléments dans le tenseur soit inchangé". Dans notre cas, le -1 sera égal à batch_size.


Commençons par ce que fait la foulée dans un boîtier 1-dim.

Supposons que votre input = [1, 0, 2, 3, 0, 1, 1] et kernel = [2, 1, 3] le résultat de la convolution est [8, 11, 7, 9, 4] , ce qui est calculé en faisant glisser votre noyau sur l'entrée, en effectuant une multiplication par élément et en additionnant tout. Comme ceci :

  • 8 = 1 * 2 + 0 * 1 + 2 * 3
  • 11 = 0 * 2 + 2 * 1 + 3 * 3
  • 7 = 2 * 2 + 3 * 1 + 0 * 3
  • 9 = 3 * 2 + 0 * 1 + 1 * 3
  • 4 = 0 * 2 + 1 * 1 + 1 * 3

Ici, nous glissons d'un élément, mais rien ne vous arrête en utilisant un autre nombre. Ce nombre est votre foulée. Vous pouvez considérer cela comme un sous-échantillonnage du résultat de la circonvolution à 1 striure en prenant simplement chaque résultat.

Connaissant la taille d'entrée i , la taille k du noyau, la stride s et le padding p, vous pouvez facilement calculer la taille de sortie de la convolution comme suit:

Ici || opérateur signifie opération de plafond. Pour une couche de regroupement s = 1.

Boîtier N-dim.

Connaissant le calcul pour un cas de 1-dim, cas n-dim est facile une fois que vous voyez que chaque dim est indépendant. Donc, vous venez de glisser chaque dimension séparément. Voici un exemple pour 2-d . Notez que vous n'avez pas besoin d'avoir la même foulée à toutes les dimensions. Donc, pour une entrée N-dim / noyau, vous devez fournir N strides.

Alors maintenant, il est facile de répondre à toutes vos questions:

  1. Que représentent chacun des 4+ entiers? . conv2d , pool vous indique que cette liste représente les foulées entre chaque dimension. Notez que la longueur de la liste des foulées est la même que celle du tenseur du noyau.
  2. Pourquoi doivent-ils avoir des foulées [0] = foulées 3 = 1 pour les convnets? . La première dimension est la taille du lot, la dernière est les canaux. Il ne sert à rien de sauter ni par lot ni par canal. Donc, vous les faites 1. Pour la largeur / hauteur, vous pouvez sauter quelque chose et c'est pourquoi ils pourraient ne pas être 1.
  3. tf.reshape (_X, shape = [- 1, 28, 28, 1]). Pourquoi -1? tf.reshape a fait pour vous:

    Si un composant de forme est la valeur spéciale -1, la taille de cette dimension est calculée de sorte que la taille totale reste constante. En particulier, une forme de [-1] s'aplatit en 1-D. Au plus un composant de la forme peut être -1.


Les opérations de regroupement et de convolution font glisser une "fenêtre" sur le tenseur d'entrée. En utilisant tf.nn.conv2d comme exemple: Si le tenseur d'entrée a 4 dimensions: [batch, height, width, channels] , alors la convolution opère sur une fenêtre 2D sur les dimensions height, width .

strides détermine à quel point la fenêtre se déplace dans chacune des dimensions. L'utilisation typique définit la première (le lot) et la dernière (la profondeur) à 1.

Prenons un exemple très concret: Exécution d'une convolution de 2 jours sur une image d'entrée en niveaux de gris 32x32. Je dis échelle de gris parce que l'image d'entrée a profondeur = 1, ce qui aide à rester simple. Laissez cette image ressembler à ceci:

00 01 02 03 04 ...
10 11 12 13 14 ...
20 21 22 23 24 ...
30 31 32 33 34 ...
...

Lançons une fenêtre de convolution 2x2 sur un seul exemple (taille de lot = 1). Nous allons donner à la convolution une profondeur de canal de sortie de 8.

L'entrée de la convolution a la shape=[1, 32, 32, 1] .

Si vous spécifiez strides=[1,1,1,1] avec padding=SAME , la sortie du filtre sera [1, 32, 32, 8].

Le filtre va d'abord créer une sortie pour:

F(00 01
  10 11)

Et puis pour:

F(01 02
  11 12)

etc. Ensuite, il passera à la deuxième rangée, en calculant:

F(10, 11
  20, 21)

puis

F(11, 12
  21, 22)

Si vous spécifiez une foulée de [1, 2, 2, 1], les fenêtres ne se chevaucheront pas. Il va calculer:

F(00, 01
  10, 11)

et alors

F(02, 03
  12, 13)

La foulée fonctionne de manière similaire pour les opérateurs de pooling.

Question 2: Pourquoi les foulées [1, x, y, 1] pour les convnets

Le premier 1 est le lot: vous ne voulez généralement pas ignorer des exemples dans votre lot, ou vous ne devriez pas les avoir inclus en premier lieu. :)

Le dernier 1 est la profondeur de la convolution: vous ne voulez généralement pas ignorer les entrées, pour la même raison.

L'opérateur conv2d est plus général, vous pouvez donc créer des convolutions qui font glisser la fenêtre le long d'autres dimensions, mais ce n'est pas une utilisation typique dans les convnets. L'utilisation typique est de les utiliser dans l'espace.

Pourquoi reshape à -1 -1 est un espace réservé qui dit "ajuster si nécessaire pour correspondre à la taille nécessaire pour le tenseur complet." C'est une façon de rendre le code indépendant de la taille du lot d'entrée, de sorte que vous pouvez changer votre pipeline et ne pas avoir à ajuster la taille du lot partout dans le code.


Ces architectures étant complètement différentes, il est donc difficile de dire "quelle est la différence", le seul point commun étant le fait qu'elles sont toutes deux des réseaux de neurones.

Les réseaux de convolution sont des réseaux dont les "champs de réception" se chevauchent et exécutent des tâches de convolution.

Les réseaux récurrents sont des réseaux avec des connexions récurrentes (allant dans la direction opposée du flux de signaux "normal") qui forment des cycles dans la topologie du réseau.





python neural-network convolution tensorflow conv-neural-network