Comment le décrochage spatial en 2D est-il implémenté?

14

Ceci est en référence à l'article Localisation efficace des objets utilisant des réseaux convolutionnels , et d'après ce que je comprends, le décrochage est implémenté en 2D.

Après avoir lu le code de Keras sur la façon dont le décrochage 2D spatial est implémenté, un masque binaire aléatoire de forme [batch_size, 1, 1, num_channels] est implémenté. Cependant, que fait exactement ce décrochage 2D spatial au bloc de convolution d'entrée de forme [batch_size, height, width, num_channels]?

Ma supposition actuelle est que pour chaque pixel, si l'un des calques / canaux du pixel a une valeur négative, les canaux entiers de ce pixel seront par défaut à zéro. Est-ce correct?

Cependant, si ma supposition est correcte, comment l'utilisation d'un masque binaire de forme [batch_size, height, width, num_channels] qui sont exactement dans la dimension du bloc d'entrée d'origine donne-t-elle la suppression habituelle par élément (c'est selon le l'implémentation de décrochage d'origine de tensorflow qui définit la forme du masque binaire comme la forme de l'entrée)? Parce que cela signifierait alors si un pixel du bloc conv est négatif, alors le bloc conv entier sera réglé par défaut sur 0. C'est la partie déroutante que je ne comprends pas très bien.

infomin101
la source

Réponses:

14

Cette réponse est un peu tardive, mais je devais y répondre moi-même et j'ai pensé que cela pourrait aider.

En regardant le papier, il semble que dans Spatial Dropout, nous définissons au hasard des cartes d'entités entières (également appelées canaux) à 0, plutôt que des «pixels» individuels.

Il est logique ce qu'ils disent, que le décrochage régulier ne fonctionnerait pas si bien sur les images car les pixels adjacents sont fortement corrélés. Donc, si vous cachez des pixels au hasard, je peux toujours avoir une bonne idée de ce qu'ils étaient en regardant simplement les pixels adjacents. Le fait de supprimer des cartes d'entités entières pourrait être mieux aligné sur l'intention d'origine de l'abandon.

Voici une fonction qui l'implémente dans Tensorflow, basée sur tf.nn.dropout. Le seul vrai changement par rapport à tf.nn.dropout est que la forme de notre masque de suppression est BatchSize * 1 * 1 * NumFeatureMaps, par opposition à BatchSize * Width * Height * NumFeatureMaps

def spatial_dropout(x, keep_prob, seed=1234):
    # x is a convnet activation with shape BxWxHxF where F is the 
    # number of feature maps for that layer
    # keep_prob is the proportion of feature maps we want to keep

    # get the batch size and number of feature maps
    num_feature_maps = [tf.shape(x)[0], tf.shape(x)[3]]

    # get some uniform noise between keep_prob and 1 + keep_prob
    random_tensor = keep_prob
    random_tensor += tf.random_uniform(num_feature_maps,
                                       seed=seed,
                                       dtype=x.dtype)

    # if we take the floor of this, we get a binary matrix where
    # (1-keep_prob)% of the values are 0 and the rest are 1
    binary_tensor = tf.floor(random_tensor)

    # Reshape to multiply our feature maps by this tensor correctly
    binary_tensor = tf.reshape(binary_tensor, 
                               [-1, 1, 1, tf.shape(x)[3]])
    # Zero out feature maps where appropriate; scale up to compensate
    ret = tf.div(x, keep_prob) * binary_tensor
    return ret

J'espère que cela pourra aider!

nlml
la source
3

Ma supposition actuelle est que pour chaque pixel, si l'un des calques / canaux du pixel a une valeur négative, les canaux entiers de ce pixel seront par défaut à zéro. Est-ce correct?

Je ne sais pas exactement ce que vous voulez dire ici, mais le décrochage se produit indépendamment de toute valeur autre que celles tirées au hasard pour le masque de décrochage. C'est-à-dire que le décrochage n'est pas affecté par les valeurs des pixels , les poids des filtres ou les valeurs de la carte d'entités. Si vous utilisez un masque de taille, [batch_size, 1, 1, num_channels]vous obtiendrez un masque binaire de cette taille lors de l'abandon. Les zéros dans ce masque binaire se produisent avec probabilité rate(au moins dans l'implémentation Keras, premier argument de la Dropoutcouche). Ce masque est ensuite multiplié par vos cartes d'entités. Ainsi, quelle que soit la dimension du masque de taille 1, cette dimension de masque est diffusée pour correspondre à la forme de la carte d'entités.
Imaginez une situation plus simple - disons que vous avez des cartes d'entités de taille [height, num_channels](ignorons la taille de lot pour l'instant) et que vos valeurs de cartes d'entités sont:

print(feature_maps)

[[2 1 4]
 [1 3 2]
 [5 2 6]
 [2 2 1]]

print(feature_maps.shape)

(4, 3)

Imaginez ensuite un masque de suppression de taille binaire [1, num_channels], comme celui-ci:

print(dropout_mask)

[[0 1 0]]

print(dropout_mask.shape)

(1, 3)

Remarquez maintenant ce qui se passe lorsque vous multipliez feature_mapset dropout_mask:

print(feature_maps * dropout_mask)

[[0 1 0]
 [0 3 0]
 [0 2 0]
 [0 2 0]]

Les valeurs de dropout_maskont été diffusées pour correspondre à la hauteur de chaque carte d'entités, puis la multiplication élément par élément a été effectuée. En conséquence, des cartes d'entités entières ont été mises à zéro - et c'est exactement ce que fait le décrochage spatial.

mmagnuski
la source