Как реализован Spatial Dropout в 2D?


14

Это относится к статье « Эффективная локализация объектов с использованием сверточных сетей» , и, насколько я понимаю, выпадение реализовано в 2D.

После прочтения кода из Keras о том, как реализован пространственный выпадение 2D, в основном реализована случайная двоичная маска формы [batch_size, 1, 1, num_channels]. Однако, что именно этот пространственный 2D-выпадет делает с входным блоком свертки формы [batch_size, height, width, num_channels]?

Мое текущее предположение состоит в том, что для каждого пикселя, если какой-либо из слоев / каналов пикселя имеет отрицательное значение, все каналы этого одного пикселя будут по умолчанию установлены на ноль. Это верно?

Однако, если мое предположение верно, то как обычная поэлементная выпадающая функция дает использование бинарной маски формы [batch_size, height, width, num_channels], которые точно находятся в измерении исходного входного блока (это соответствует оригинальная реализация выпадения тензорного потока, которая устанавливает форму двоичной маски как форму ввода)? Потому что это будет означать, что если какой-либо пиксель в блоке конвекции будет отрицательным, тогда весь блок конвоя будет по умолчанию равен 0. Это запутанная часть, которую я не совсем понимаю.

Ответы:


14

Этот ответ немного запоздал, но мне нужно было самому заняться этим вопросом и подумать, что это может помочь.

Глядя на статью, кажется, что в Пространственном выпадении мы случайным образом устанавливаем целые карты объектов (также известные как каналы) на 0, а не на отдельные «пиксели».

Имеет смысл то, что они говорят, что обычное выпадение не будет работать так хорошо на изображениях, потому что смежные пиксели сильно коррелированы. Так что, если вы прячете пиксели случайным образом, я все равно могу иметь представление о том, что это было, просто посмотрев на соседние пиксели. Отбрасывание целых карт объектов может быть лучше согласовано с первоначальной целью исключения.

Вот функция, которая реализует ее в Tensorflow на основе tf.nn.dropout. Единственное реальное отличие от tf.nn.dropout заключается в том, что форма нашей маски выпадения имеет вид BatchSize * 1 * 1 * NumFeatureMaps, а не 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

Надеюсь, это поможет!


3

Мое текущее предположение состоит в том, что для каждого пикселя, если какой-либо из слоев / каналов пикселя имеет отрицательное значение, все каналы этого одного пикселя будут по умолчанию установлены на ноль. Это верно?

Я не совсем уверен, что вы имеете в виду здесь, но выпадение происходит независимо от каких-либо значений, кроме тех, которые выбраны случайным образом для маски выпадения. То есть выпадение не зависит от значений пикселей , весов фильтра или значений карты объектов. Если вы используете маску размера, [batch_size, 1, 1, num_channels]вы получите двоичную маску этого размера во время отсева. Нули в этой двоичной маске встречаются с вероятностью rate(по крайней мере, в реализации Keras, первый аргумент для Dropoutслоя). Затем эта маска умножается на ваши карты объектов, поэтому любой размер маски имеет размер 1 - этот размер маски передается в соответствии с вашей формой карты объектов.
Представьте себе более простую ситуацию - допустим, у вас есть карты размеров объектов [height, num_channels](давайте пока проигнорируем размер пакета), и у вас есть значения карт объектов:

print(feature_maps)

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

print(feature_maps.shape)

(4, 3)

Затем представьте двоичную маску отсева размера [1, num_channels], например:

print(dropout_mask)

[[0 1 0]]

print(dropout_mask.shape)

(1, 3)

Теперь обратите внимание, что происходит, когда вы умножаете feature_mapsи dropout_mask:

print(feature_maps * dropout_mask)

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

Значения в dropout_maskбыли переданы в соответствии с высотой каждой карты объектов, а затем было выполнено поэлементное умножение. В результате целые карты объектов обнулились - и это именно то, что делает пространственное выпадение.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.