Этот пост можно скачать в формате PDF здесь.

Это часть серии руководств по архитектуре CNN.

Основная цель - дать понимание, чтобы понять ResNets и углубиться в ResNet34 для набора данных ImageNet.

  • Для ResNets, примененного к CIFAR10, есть еще одно руководство здесь.
  • Также здесь есть подробное руководство по реализации PyTorch.

Индекс

  • Фон
  • Мотивация
  • Какие проблемы решает ResNets?
  • Архитектура
  • Резюме

Фон

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

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

Мотивация

Поскольку нейронные сети являются хорошими аппроксиматорами функций, они должны уметь легко решать функцию идентификации, где выход функции становится самим входом.

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

Интуиция заключается в том, что обучение f (x) = 0 должно быть простым для сети.

Какие проблемы решает ResNets?

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

С ResNets градиенты могут течь прямо через пропускные соединения в обратном направлении от более поздних слоев к начальным фильтрам.

Архитектура

Поскольку ResNets могут иметь переменные размеры, в зависимости от того, насколько велик каждый из слоев модели и сколько в нем слоев, мы будем следовать описанию авторов в статье [1] - ResNet 34 - чтобы объяснить структура после этих сетей.

Если вы взглянули на этот документ, вы, вероятно, видели некоторые рисунки и таблицы, подобные приведенным ниже, которым вы изо всех сил пытаетесь следовать. Давайте изобразим эти фигуры, подробно описывая каждый шаг.

Здесь мы видим, что ResNet (тот, что справа) состоит из одного этапа свертки и объединения (на оранжевом), за которым следуют 4 уровня аналогичного поведения.

Каждый из слоев выполнен по одному и тому же шаблону. Они выполняют свертку 3x3 с фиксированным размером карты признаков (F) [64, 128, 256, 512] соответственно, обходя ввод каждые 2 свертки. Кроме того, размеры ширины (W) и высоты (H) остаются неизменными на протяжении всего слоя.

Пунктирная линия присутствует именно потому, что произошло изменение размера входного объема (конечно, уменьшение из-за свертки). Обратите внимание, что это уменьшение между слоями достигается увеличением шага с 1 до 2 при первой свертке каждого слоя; вместо операции объединения, которую мы привыкли рассматривать как понижающие сэмплеры.

В таблице приведены сводные данные о размере вывода на каждом уровне и размере сверточных ядер в каждой точке структуры.

Но этого не видно. Мы хотим изображений! Изображение лучше тысячи слов!

Рисунок 3 - это то, как я предпочитаю видеть сверточные модели, и с его помощью я объясню каждый слой.

Я предпочитаю наблюдать, как на самом деле объемы, проходящие через модель, меняют свои размеры. Таким образом легче понять механизм конкретной модели, чтобы иметь возможность адаптировать ее к нашим конкретным потребностям - мы увидим, как простое изменение набора данных приводит к изменению архитектуры всей модели. Кроме того, я постараюсь следовать обозначениям, близким к официальной реализации PyTorch, чтобы облегчить последующую реализацию ее на PyTorch.

Например, ResNet в документе в основном объясняется для набора данных ImageNet. Но в первый раз, когда мне захотелось поэкспериментировать с ансамблями ResNets, пришлось сделать это на CIFAR10. Очевидно, поскольку входные изображения CIFAR10 имеют размер (32x32) вместо (224x224), структуру ResNets необходимо изменить. Если вы хотите иметь контроль над изменениями, применяемыми к вашей ResNet, вам необходимо разбираться в деталях. Этот другой учебник является упрощенным по сравнению с текущим, применяемым к CIFAR10.

Итак, пойдем слой за слоем!

Свертка 1

Первым шагом в ResNet перед входом в поведение общего уровня является блок, называемый здесь Conv1, состоящий из операции свертки + пакетной нормализации + максимального объединения.

Если вы не помните, как выполнялись операции свертки и объединения, взгляните на эти рисунки, которые я сделал, чтобы объяснить их, поскольку я повторно использовал их часть здесь.

Итак, сначала выполняется операция свертки. На рисунке 1 мы видим, что они используют размер ядра 7 и размер карты функций 64. Вы должны сделать вывод, что они добавили нули 3 раза по каждому измерению - и проверьте это в документации PyTorch. Принимая это во внимание, на Рисунке 4 можно увидеть, что размер вывода этой операции будет том (112x122). Поскольку каждый фильтр свертки (из 64) предоставляет один канал в выходном объеме, мы получаем выходной объем (112x112x64) - обратите внимание, что это не зависит от размерности пакета, чтобы упростить объяснение.

Следующим шагом является пакетная нормализация, которая является поэлементной операцией и поэтому не меняет размер нашего тома. Наконец, у нас есть операция (3x3) Max Pooling с шагом 2. Мы также можем сделать вывод, что они сначала заполняют входной том, чтобы конечный том имел желаемые размеры.

Слои ResNet

Итак, давайте объясним это повторяющееся имя, блок. Каждый уровень ResNet состоит из нескольких блоков. Это связано с тем, что, когда ResNets идут глубже, они обычно делают это, увеличивая количество операций в блоке, но общее количество слоев остается неизменным - 4. Операция здесь относится к свертке или пакетной нормализации. и активация ReLU для входа, кроме последней операции блока, у которого нет ReLU.

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

Сейчас мы сталкиваемся с Базовым. Входной объем - это последний выходной объем от Conv1. Давайте посмотрим на рисунок 6, чтобы понять, что происходит внутри этого блока.

Блок 1

1 свертка

Мы копируем упрощенную операцию для каждого слоя на бумаге.

Теперь мы можем дважды проверить таблицу из статьи, в которой мы используем ядро ​​[3x3, 64], а размер вывода составляет [56x56]. Мы можем видеть, как, как мы упоминали ранее, размер тома не изменяется в пределах блока. Это потому, что используется padding = 1 и шаг также 1. Давайте посмотрим, как это распространяется на весь блок, чтобы покрыть 2 [3x3, 64], которые появляются в таблице.

Та же процедура может быть расширена на весь уровень, как показано на рисунке 8. Теперь мы можем полностью прочитать всю ячейку таблицы (просто напомним, что мы находимся в 34 слои ResNet на уровне Conv2_x.

Мы можем видеть, что у нас есть [3x3, 64] x 3 раза внутри слоя.

Узоры

Следующим шагом будет переход от всего блока ко всему слою. На Рисунке 1 мы видим, как слои различаются по цвету. Однако, если мы посмотрим на первую операцию каждого слоя, мы увидим, что шаг, используемый на этом первом уровне, равен 2, а не 1, как для остальных из них.

Это означает, что понижающая выборка тома в сети достигается за счет увеличения шага вместо операции объединения, как это обычно делают CNN. Фактически, только одна операция максимального объединения выполняется на нашем уровне Conv1 и один средний уровень объединения в конце ResNet, прямо перед полностью подключенным плотным слоем на рисунке 1.

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

Это различие в пропускаемых соединениях так называется в статье как Ярлык идентификации и Ярлык проекции. Ярлык идентификации - это тот, который мы уже обсуждали, просто минуя входной объем оператору сложения. Ярлык проекции выполняет операцию свертки, чтобы гарантировать, что объемы при этой операции добавления имеют одинаковый размер. Из документа мы видим, что есть 2 варианта соответствия выходному размеру. Либо заполните входной объем, либо выполните свертки 1x1. Здесь показан второй вариант.

На рисунке 9 представлена ​​эта понижающая выборка, выполняемая путем увеличения шага до 2. Количество фильтров дублируется в попытке сохранить временную сложность для каждой операции (56 * 64 = 28 * 128). Также обратите внимание, что теперь операция добавления не может быть выполнена, так как том был изменен. В ярлыке нам нужно применить одну из наших стратегий понижающей выборки. Метод свертки 1x1 показан на рисунке 10.

Окончательное изображение выглядит так, как показано на рисунке 11, где теперь 2 выходных тома каждого потока имеют одинаковый размер и могут быть добавлены.

На рисунке 12 мы можем видеть общую картину всего второго слоя. Поведение точно такое же для следующих слоев 3 и 4, изменяются только размеры входящих объемов.

Резюме

ResNets, построенные авторами в соответствии с объясненными правилами, образуют следующие структуры, как показано на рисунке 2:

Библиография

[1] К. Хе, Х. Чжан, С. Рен и Дж. Сун, «Глубокое остаточное обучение для распознавания изображений», в CVPR, 2016.