Wie wird Spatial Dropout in 2D implementiert?


13

Dies geschieht unter Bezugnahme auf das Papier Effiziente Objektlokalisierung mithilfe von Faltungsnetzwerken. Soweit ich weiß, ist das Dropout in 2D implementiert.

Nachdem der Code von Keras zur Implementierung des räumlichen 2D-Dropouts gelesen wurde, wird im Grunde eine zufällige binäre Maske mit der Form [batch_size, 1, 1, num_channels] implementiert. Was genau bewirkt dieses räumliche 2D-Dropout jedoch für den Eingabe-Faltungsblock mit der Form [batch_size, height, width, num_channels]?

Ich gehe davon aus, dass für jedes Pixel, wenn eine der Ebenen / Kanäle des Pixels einen negativen Wert aufweist, die gesamten Kanäle dieses einen Pixels standardmäßig auf Null gesetzt werden. Ist das richtig?

Wenn meine Vermutung jedoch richtig ist, wie ergibt sich bei Verwendung einer Binärmaske mit der Form [batch_size, height, width, num_channels], die genau in der Dimension des ursprünglichen Eingabeblocks liegt, das übliche elementweise Dropout (dies entspricht dem Die ursprüngliche Dropout-Implementierung von Tensorflow, die die Form der Binärmaske als die Form der Eingabe festlegt. Da dies dann bedeuten würde, wenn ein Pixel im Conv-Block negativ ist, wird der gesamte Conv-Block standardmäßig auf 0 gesetzt. Dies ist der verwirrende Teil, den ich nicht ganz verstehe.

Antworten:


14

Diese Antwort ist etwas spät, aber ich musste mich selbst darum kümmern und dachte, es könnte helfen.

Auf dem Papier sieht es so aus, als hätten wir in Spatial Dropout ganze Feature-Maps (auch als Kanäle bezeichnet) nach dem Zufallsprinzip auf 0 gesetzt, anstatt einzelne "Pixel".

Es macht Sinn, was sie sagen, dass reguläre Aussetzer bei Bildern nicht so gut funktionieren würden, weil benachbarte Pixel stark korreliert sind. Wenn Sie also Pixel nach dem Zufallsprinzip ausblenden, kann ich immer noch eine gute Vorstellung davon haben, was sie waren, indem ich nur auf die benachbarten Pixel schaue. Das Löschen ganzer Feature-Maps ist möglicherweise besser auf die ursprüngliche Absicht des Dropouts ausgerichtet.

Hier ist eine Funktion, die es in Tensorflow implementiert, basierend auf tf.nn.dropout. Die einzige wirkliche Änderung gegenüber tf.nn.dropout ist, dass die Form unserer Dropout-Maske BatchSize * 1 * 1 * NumFeatureMaps lautet und nicht 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

Ich hoffe, das hilft!


3

Ich gehe davon aus, dass für jedes Pixel, wenn eine der Ebenen / Kanäle des Pixels einen negativen Wert aufweist, die gesamten Kanäle dieses einen Pixels standardmäßig auf Null gesetzt werden. Ist das richtig?

Ich bin mir nicht sicher, was Sie hier genau meinen, aber es kommt zu Aussetzern, unabhängig von anderen Werten als denen, die zufällig für die Aussetzermaske gezogen wurden. Das heißt, Dropout wird nicht von Pixelwerten , Filtergewichten oder Feature-Map-Werten beeinflusst. Wenn Sie eine Maske der Größe verwenden, erhalten [batch_size, 1, 1, num_channels]Sie beim Dropout eine Binärmaske dieser Größe. Nullen in dieser Binärmaske treten mit Wahrscheinlichkeit auf rate(zumindest in der Keras-Implementierung, erstes Argument für die DropoutEbene). Diese Maske wird dann mit Ihren Feature-Maps multipliziert. Unabhängig davon, welche Maskendimension die Größe 1 hat, wird diese Maskendimension entsprechend Ihrer Feature-Map-Form übertragen.
Stellen Sie sich eine einfachere Situation vor: Nehmen wir an, Sie haben Feature-Maps mit folgender Größe [height, num_channels](lassen Sie die Stapelgröße vorerst ignorieren) und Sie haben folgende Feature-Maps-Werte:

print(feature_maps)

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

print(feature_maps.shape)

(4, 3)

Stellen Sie sich dann eine binäre Dropout-Maske der folgenden Größe vor [1, num_channels]:

print(dropout_mask)

[[0 1 0]]

print(dropout_mask.shape)

(1, 3)

Beachten Sie nun, was passiert, wenn Sie multiplizieren feature_mapsund dropout_mask:

print(feature_maps * dropout_mask)

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

Die Werte in dropout_maskwurden gesendet, um mit der Höhe jeder Feature-Map übereinzustimmen, und dann wurde die Multiplikation Element für Element durchgeführt. Infolgedessen wurden ganze Feature-Maps auf Null gesetzt - und genau das macht räumliche Aussetzer.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.