Come viene implementato il dropout spaziale in 2D?


14

Questo è con riferimento al documento Localizzazione efficiente degli oggetti utilizzando reti convoluzionali e da quello che ho capito il dropout è implementato in 2D.

Dopo aver letto il codice di Keras su come viene implementato il Dropout 2D spaziale, in pratica viene implementata una maschera binaria casuale di forma [batch_size, 1, 1, num_channels]. Tuttavia, cosa fa esattamente questo Dropout 2D spaziale al blocco di convoluzione di input di forma [batch_size, height, width, num_channels]?

La mia ipotesi attuale è che per ogni pixel, se uno qualsiasi dei livelli / canali del pixel ha un valore negativo, l'intero canale di quel pixel verrà automaticamente impostato su zero. È corretto?

Tuttavia, se la mia ipotesi è corretta, allora in che modo l'utilizzo di una maschera binaria di forma [batch_size, altezza, larghezza, num_channels] che sono esattamente nella dimensione del blocco di input originale dà il solito dropout dal punto di vista degli elementi (questo è secondo il l'implementazione dropout originale di tensorflow che imposta la forma della maschera binaria come forma dell'input)? Perché significherebbe quindi se qualsiasi pixel nel blocco conv è negativo, quindi l'intero blocco conv verrà impostato automaticamente su 0. Questa è la parte confusa che non capisco bene.

Risposte:


14

Questa risposta è un po 'in ritardo, ma ho dovuto occuparmene da solo e ho pensato che potesse essere d'aiuto.

Guardando il documento, sembra che in Dropout spaziale abbiamo impostato casualmente intere mappe di funzioni (anche note come canali) su 0, anziché singoli "pixel".

Ha senso quello che stanno dicendo, che il dropout regolare non funzionerebbe così bene sulle immagini perché i pixel adiacenti sono altamente correlati. Quindi, se nascondi i pixel in modo casuale, posso ancora avere una buona idea di cosa fossero semplicemente guardando i pixel adiacenti. Eliminare intere mappe delle caratteristiche potrebbe essere meglio allineato con l'intenzione originale di eliminazione.

Ecco una funzione che la implementa in Tensorflow, basata su tf.nn.dropout. L'unico vero cambiamento rispetto a tf.nn.dropout è che la forma della nostra maschera di dropout è BatchSize * 1 * 1 * NumFeatureMaps, al contrario di 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

Spero possa aiutare!


3

La mia ipotesi attuale è che per ogni pixel, se uno qualsiasi dei livelli / canali del pixel ha un valore negativo, l'intero canale di quel pixel verrà automaticamente impostato su zero. È corretto?

Non sono sicuro di cosa significhi qui, ma il dropout si verifica indipendentemente da valori diversi da quelli disegnati casualmente per la maschera di dropout. Questo dropout non è influenzato dai valori dei pixel , dai pesi del filtro o dai valori della mappa delle caratteristiche. Se usi una maschera di dimensioni [batch_size, 1, 1, num_channels]otterrai una maschera binaria di queste dimensioni durante l'abbandono. Gli zeri in quella maschera binaria si verificano con probabilità rate(almeno nell'implementazione di Keras, primo argomento da Dropoutsovrapporre). Questa maschera viene quindi moltiplicata per le mappe delle caratteristiche, in modo che la dimensione della maschera sia di dimensione 1: tale dimensione della maschera viene trasmessa in modo che corrisponda alla forma della mappa delle caratteristiche.
Immagina una situazione più semplice - supponiamo che tu abbia delle mappe delle dimensioni [height, num_channels](per ora ignoriamo le dimensioni del batch) e che i valori delle mappe delle caratteristiche sono:

print(feature_maps)

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

print(feature_maps.shape)

(4, 3)

Quindi immagina una maschera binaria di eliminazione delle dimensioni [1, num_channels], come questa:

print(dropout_mask)

[[0 1 0]]

print(dropout_mask.shape)

(1, 3)

Ora nota cosa succede quando si moltiplica feature_mapse dropout_mask:

print(feature_maps * dropout_mask)

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

I valori in dropout_masksono stati trasmessi per corrispondere all'altezza di ciascuna mappa delle caratteristiche e quindi è stata eseguita la moltiplicazione elemento per elemento. Di conseguenza sono state azzerate intere mappe delle caratteristiche, ed è esattamente ciò che fa il dropout spaziale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.