Архитектуры ResNet-18 и ResNet-50

Смотреть материал на YouTube | RuTube

После знакомства с идеей построения остаточных сетей (residual networks) пришло время разобрать конкретные архитектуры на примере сетей ResNet.

Фреймворк PyTorch в ветке:

torchvision.models

содержит несколько таких сетей под названиями:

resnet18, resnet34, resnet50, resnet101, resnet152

Если в программе создать какую-либо из этих моделей и отобразить ее структуру на экране:

from torchvision import models
 
model = models.resnet18()
print(model)

то увидим общие начальные и конечные слои, а между ними блоки слоев Layer1, Layer2, Layer3, Layer4:

В зависимости от вида этих промежуточных слоев (Layer1, …, Layer4) формируется та или иная архитектура сети ResNet. Например, в модели resnet18 каждый промежуточный слой состоит из двух последовательно соединенных BasicBlock. В модели resnet34: 3, 4, 6 и 3 блока соответственно. Более глубокие модели ResNet используют Bottleneck блоки. Модель resnet50 в слоях Layer1-4 содержит 3, 4, 6 и 3 таких блоков, а модель resnet101 – 3, 4, 23 и 3 блока. Как видите, сети ResNet строятся по достаточно простому принципу.

Архитектура ResNet-18

Давайте вначале детально рассмотрим архитектуру сети ResNet-18. Здесь каждый слой Layer1-4 составлен из двух последовательно соединенных BasicBlock. На вход первого блока подается тензор с 64 каналами и определенными размерами карт признаков H x W:

(64, H, W)

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

Следующий BasicBlock слоя Layer1 имеет абсолютно такую же структуру. На его выходе имеем тензор размерности (64, H, W).

Слой Layer2 также состоит из двух BasicBlock, но формирует на выходе 128 каналов с уменьшенными вдвое размерами карт признаков:

(128, H/2, W/2)

Здесь первый сверточный слой содержит 128 фильтров с ядрами 3x3 каждый и смещает их с шагом stride=2. Как раз этот шаг (вкупе с padding=1) уменьшают выходные размеры карт признаков вдвое. Второй сверточный слой BasicBlock L2_1 просто обрабатывает входной тензор без изменения его размерностей.

Как вы понимаете, из-за изменения размеров входного тензора, выполнить напрямую суммирование входа с выходом нельзя. Вначале нужно привести входной тензор к тем же размерам (128, H/2, W/2). Для этого в обходную связь добавляются два слоя. Первый сверточный слой приводит входной тензор к нужным размерам, а второй – нормализация по батчам. В результате получаем следующую структуру блока L2_1:

На вход следующего блока L2_2 поступает тензор размером (128, H/2, W/2), который пропускается через два сверточных слоя без изменения размеров.

Следующие два слоя Layer3 и Layer4 организованы по аналогии со слоем Layer2, увеличивая каналы в два раз и уменьшая размеры карт признаков также в два раза. В результате выходной тензор со слоя Layer4 подается на вход слоя AdaptiveAvgPool2d, который усредняет значения по картам признаков, формируя на выходе тензор размерностью (512, 1, 1):

Этот тензор вытягивается в один вектор и подается на вход полносвязного слоя с 512*factor входами и 1000 выходами. Величина factor=1 для сети ResNet-18.

Архитектура ResNet-50

Вот общий принцип построения моделей архитектур ResNet-18 и подобной ей ResNet-34. Давайте теперь посмотрим на структуру сети ResNet-50, которая использует Bottleneck блоки, вместо BasicBlock. Напомню, что распределение блоков по слоям в архитектуре ResNet-50 следующее:

3, 4, 6, 3

На вход первого Bottleneck блока подается тензор размерностью (64, H, W), а на выходе формируется тензор (64*4, H, W). Умножение на 4 – это фактор масштабирования каналов, который для Bottleneck равен factor=4. Соответственно для приведения размера входного тензора к выходному в обходной связи присутствует дополнительный сверточный слой, за которым следует нормализация по батчам:

На вход следующего Bottleneck блока подается тензор (64*4, H, W), который проходит по аналогичным слоям, только обходной путь здесь не содержит никаких слоев, т.к. размеры входного и выходного тензоров согласованы:

Третий Bottleneck блок слоя Layer1 отрабатывает абсолютно так же, как и блок L1_2.

Следующий слой Layer2 состоит из четырех последовательно соединенных Bottleneck блоков. На вход первого полается тензор (64*4, H, W). С помощью первого сверточного слоя он преобразуется в тензор со 128 каналами. Далее, отрабатывает сверточный слой с ядром 3x3 и шагом смещения stride=2. В результате вдвое уменьшаются размеры карт признаков. Последний третий сверточный слой расширяет число каналов до 128*4. Чтобы входной тензор был согласован по размерам с выходным, обходной путь содержит соответствующий сверточный слой с нормализацией по батчам.

Следующие три Bottleneck блока абсолютно одинаковы по своей структуре и имеют следующий вид:

Здесь все достаточно очевидно и главное их отличие от первого – отсутствие преобразования входного тензора в обходной связи.

А дальше, для слоев Layer3 и Layer4 в целом, все повторяется, только с разным числом Bottleneck блоков. В результате на выходе последнего Bottleneck блока формируется тензор размерностью:

(512*4, H/8, W/8)

Последние два слоя отрабатывают так же, как и в архитектуре ResNet-18.

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

Видео по теме