Лучше бросить учебу! Реализация DropBlock в PyTorch

Интерактивную версию этой статьи можно найти здесь.

DropBlock доступен на очках в моей библиотеке компьютерного зрения!

Вступление

Сегодня мы собираемся внедрить DropBlock в PyTorch! DropBlock, представленный Ghiasi и др., Представляет собой методику регуляризации, специально предназначенную для изображений, которая эмпирически работает лучше, чем Dropout. Почему Dropout недостаточно?

Проблема с выпадением изображений

Dropout - это метод регуляризации, при котором случайным образом отбрасываются (обнуляются) части ввода перед передачей на следующий уровень. Если вы не знакомы с этим, я рекомендую эти конспекты лекций из Стэндфорда (перейдите в раздел для исключения). Если мы хотим использовать его в PyTorch, мы можем напрямую импортировать его из библиотеки. Посмотрим на пример!

Как видите, случайные пиксели ввода были отброшены!

Этот метод хорошо работает с одномерными данными, но с двухмерными данными мы можем добиться большего.

Основная проблема заключается в том, что мы удаляем независимые пиксели, и это неэффективно для удаления семантической информации, поскольку близлежащие активации содержат тесно связанную информацию. Я думаю, это довольно интуитивно понятно, даже если мы обнуляем один элемент, соседи все равно могут передавать важную информацию.

Давайте посмотрим, что происходит с картой функций. В следующем коде мы сначала получаем изображение бэби-йоды, а затем создаем предварительно обученную сеть18, используя очки. Затем мы вводим изображение и получаем карту функций из второго слоя. Наконец, мы показываем активацию первого канала с Dropout и без него.

Слева у нас есть активации карты функций, справа - активации той же карты функций после исключения. Они выглядят очень похоже, обратите внимание, как в каждом регионе, даже если некоторые юниты равны нулю, активация соседей все еще срабатывает. Это означает, что информация будет передана на следующий уровень, что не идеально.

DropBlock

DropBlock решает эту проблему, удаляя непрерывные регионы с карты функций, основная идея показана на следующем рисунке.

Dropblock работает следующим образом

Реализация

Мы можем начать с определения слоя DropBlock с правильными параметрами.

block_size - это размер каждой области, которую мы собираемся удалить из ввода, p - это keep_prob, как в Dropout.

Все идет нормально. Теперь сложная часть, нам нужно вычислить гамму, которая управляет отбрасываемыми функциями. Если мы хотим сохранить каждую активацию с p проблемой, мы можем выбрать из распределения Бернулли со средним 1 - p, как в Dropout. Проблема в том, что мы устанавливаем на нули block_size ** 2 единиц.

Гамма рассчитывается с использованием

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

# Output
0.14222222222222222 

Следующим шагом является выборка маски $ M $ того же размера, что и входные данные из распределения Бернулли с центральной гаммой, в PyTorch так же просто, как

Затем нам нужно обнулить области размером block_size. Мы можем использовать максимальный пул с kernel_size равным block_size и шагом в один пиксель для создания. Помните, что маска является двоичной маской (только 0 и 1), поэтому, когда maxpool видит 1 в своем радиусе kernel_size, он выдает единицу, используя шаг 1, мы гарантируем, что на выходе создается область размером block_size x block_size, если хотя бы одна единица на входе была установлена ​​на 1. Поскольку мы хотим обнулить их, нам нужно инвертировать их. В PyTorch

Затем мы нормализуем это

x = mask_block * x * (mask_block.numel() / mask_block.sum())

Давайте протестируем это с бэби-йодой, для простоты мы покажем выпавшую единицу на первом канале.

Выглядит хорошо, давайте посмотрим на карту характеристик предварительно обученной модели (как раньше).

Мы успешно обнуляем сплошные регионы, а не только отдельные единицы.

Кстати, DropBlock равно Dropout, когда block_size = 1, и Dropout2d (он же SpatialDropout), когда block_size - это полная карта функций.

Выводы

Теперь мы знаем, как реализовать DropBlock в PyTorch, классную технику регуляризации. В статье приведены разные эмпирические результаты. Они используют ванильный resnet50 и итеративно добавляют различную регуляризацию, это показано в следующей таблице.

Как видите, архивы ResNet-50 + DropBlock + 1% по сравнению с SpatialDropout (классический Dropout2d в PyTorch).

В статье больше исследований с разными гиперпараметрами DropBlock, если интересно, посмотрите :)

Спасибо за чтение!

Франческо