S2-MLP V1 и V2 Vision MLP: Архитектура MLP с пространственным сдвигом для Vision
Оригинальный документ:у-у-у. yuque.com/pulllingheads/papers…
Здесь будут представлены две статьи о S2-MLP. Основная идея этих двух статей одинакова, то есть пространственный MLP заменяется на основе операции пространственного смещения.
Понимание статей из тезисов
V1
Recently, visual Transformer (ViT) and its following works abandon the convolution and exploit the self-attention operation, attaining a comparable or even higher accuracy than CNNs. More recently, MLP-Mixer abandons both the convolution and the self-attention operation, proposing an architecture containing only MLP layers. To achieve cross-patch communications, it devises an additional token-mixing MLP besides the channel-mixing MLP. It achieves promising results when training on an extremely large-scale dataset. But it cannot achieve as outstanding performance as its CNN and ViT counterparts when training on medium-scale datasets such as ImageNet1K and ImageNet21K. The performance drop of MLP-Mixer motivates us to rethink the token-mixing MLP.
Это приводит к основному содержанию данной статьи, а именно к улучшению пространственного MLP.
We discover that the token-mixing MLP is a variant of the depthwise convolution with a global reception field and spatial-specific configuration. But the global reception field and the spatial-specific property make token-mixing MLP prone to over-fitting.
указал на проблему пространственного MLP, из-заЕго глобальное рецептивное поле и пространственные свойства делают модель склонной к переоснащению..
In this paper, we propose a novel pure MLP architecture, spatial-shift MLP (S2-MLP). Different from MLP-Mixer, our S2-MLP only contains channel-mixing MLP.
Здесь упоминается, что существует только канал MLP, что указывает на то, что был придуман новый метод расширения рецептивного поля канала MLP, а также сохранения точечных операций.
We utilize a spatial-shift operation for communications between patches. It has a local reception field and is spatial-agnostic. It is parameter-free and efficient for computation.
Это приводит к основному содержанию этой статьи, а именно к операции пространственного смещения, упомянутой в заголовке. Кажется, что эта операция не принимает никаких параметров и является просто методом обработки, используемым для настройки функции. Операция Spatial-Shift может ссылаться на несколько статей здесь:Woohoo Yuque.com/Pull people/Arch IT…
The proposed S2-MLP attains higher recognition accuracy than MLP-Mixer when training on ImageNet-1K dataset. Meanwhile, S2-MLP accomplishes as excellent performance as ViT on ImageNet-1K dataset with considerably simpler architecture and fewer FLOPs and parameters.
V2
Recently, MLP-based vision backbones emerge. MLP-based vision architectures with less inductive bias achieve competitive performance in image recognition compared with CNNs and vision Transformers. Among them, spatial-shift MLP (S2-MLP), adopting the straightforward spatial-shift operation, achieves better performance than the pioneering works including MLP-mixer and ResMLP. More recently, using smaller patches with a pyramid structure, Vision Permutator (ViP) and Global Filter Network (GFNet) achieve better performance than S2-MLP.
Это приводит к пирамидальной структуре, и кажется, что версия V2 будет использовать аналогичную структуру.
In this paper, we improve the S2-MLP vision backbone. We expand the feature map along the channel dimension and split the expanded feature map into several parts. We conduct different spatial-shift operations on split parts.
Стратегия пространственного смещения все еще продолжается, но я не знаю, как она меняется по сравнению с версией V1.
Meanwhile, we exploit the split-attention operation to fuse these split parts.
Здесь также используется расщепление внимания (ResNeSt), чтобы объединять группы. Можно ли здесь использовать параллельные ветки?
Moreover, like the counterparts, we adopt smaller-scale patches and use a pyramid structure for boosting the image recognition accuracy. We term the improved spatial-shift MLP vision backbone as S2-MLPv2. Using 55M parameters, our medium-scale model, S2-MLPv2-Medium achieves an 83.6% top-1 accuracy on the ImageNet-1K benchmark using 224×224 images without self-attention and external training data.
На мой взгляд, по сравнению с V1, V2 в основном заимствует некоторые идеи у CycleFC и вносит адаптивные корректировки. Общее изменение имеет два аспекта:
- Представьте идею многоветвевой обработки и примените Split-Attention для объединения разных ветвей.
- Вдохновленные существующей работой, используются более мелкие патчи и иерархическая пирамидальная структура.
основное содержание
Сравнение основной структуры
В V1 общий процесс продолжает идею MLP-Mixer и по-прежнему сохраняет прямую цилиндрическую структуру.
Структурная схема MLP-Mixer:
Как видно из рисунка, в отличие от структуры Pre-Norm в MLP-Mixer, S2MLP использует структуру Post-Norm.
Кроме того, изменения S2MLP в основном сосредоточены на положении пространственного MLP по сравнению с исходнымSpatial-MLP(Linear->GeLU->Linear)
ВSpatial-Shifted Channel-MLP(Linear->GeLU->Spatial-Shift->Lienar)
.
Базовый псевдокод для пространственного смещения выглядит следующим образом:
Как видите, вотВвод разделен на четыре разные группы, каждая из которых смещена по своей оси (оси H и W)., из-за реализации в граничной части будут повторяющиеся значения.Количество групп зависит от количества направлений, здесь по умолчанию используется 4, то есть смещение по четырем направлениям.Хотя с точки зрения одного модуля пространственного смещения связаны только соседние патчи, с точки зрения общей многослойной структуры может быть достигнут примерный процесс взаимодействия на большом расстоянии.
По сравнению с версией V1, в версии V2 была введена многоветвевая стратегия обработки, а в структуре использовалась форма Pre-Norm.
Идея построения многоветвевой структуры очень похожа на CycleFC. В разных ветвях используются разные стратегии обработки, и в то же время при интеграции нескольких ветвей для слияния используется метод Split-Attention.
Split-Attention: Vision Permutator (Hou et al., 2021) использует разделение внимания, предложенное в ResNeSt (Zhang et al., 2020) для улучшения нескольких карт функций из разных операций, Этот документ основан на использовании для объединения нескольких ветвей. Основной рабочий процесс:
- входитькарты характеристик (могут быть из разных веток)
- Суммируем результаты суммирования столбцов всех графов специальной диагностики:
- Преобразуйте сложенные полносвязные слои, чтобы получить журналы внимания канала для различных карт объектов:
- Используйте reshape, чтобы изменить форму вектора внимания:
- Используйте softmax по индексуВычислите, чтобы получить нормализованные веса внимания для разных выборок:
- для вводаВзвешенное суммирование карт признаков для получения результата, результат одной строки может быть выражен как:
Однако следует отметить, что третья ветвь здесь - постоянная ветвь, непосредственно взятая входной канал, который продолжает идею Ghostnet, и отличается от CycleFC, используют отдельный канал MLP.
GhostNetОсновная структура:
Основной псевдокод многоветвевой структуры выглядит следующим образом:
другие детали
Взаимосвязь пространственного сдвига и свертки по глубине
На самом деле смещения в четырех направлениях могут быть достигнуты с помощью специальной конструкции ядра свертки:
Таким образом, операция смещения пространства группировки может быть достигнута путем указания соответствующих ядер свертки выше для разных групп свертки по глубине.
На самом деле способов добиться смещения много.Помимо индекса слайса и упомянутого в статье метода глубинной свертки построения ядра, можно еще группировать поtorch.roll
и пользовательское смещениеdeform_conv2d
реализовать.
import torch
import torch.nn.functional as F
from torchvision.ops import deform_conv2d
xs = torch.meshgrid(torch.arange(5), torch.arange(5))
x = torch.stack(xs, dim=0)
x = x.unsqueeze(0).repeat(1, 4, 1, 1).float()
direct_shift = torch.clone(x)
direct_shift[:, 0:2, :, 1:] = torch.clone(direct_shift[:, 0:2, :, :4])
direct_shift[:, 2:4, :, :4] = torch.clone(direct_shift[:, 2:4, :, 1:])
direct_shift[:, 4:6, 1:, :] = torch.clone(direct_shift[:, 4:6, :4, :])
direct_shift[:, 6:8, :4, :] = torch.clone(direct_shift[:, 6:8, 1:, :])
print(direct_shift)
pad_x = F.pad(x, pad=[1, 1, 1, 1], mode="replicate") # 这里需要借助padding来保留边界的数据
roll_shift = torch.cat(
[
torch.roll(pad_x[:, c * 2 : (c + 1) * 2, ...], shifts=(shift_h, shift_w), dims=(2, 3))
for c, (shift_h, shift_w) in enumerate([(0, 1), (0, -1), (1, 0), (-1, 0)])
],
dim=1,
)
roll_shift = roll_shift[..., 1:6, 1:6]
print(roll_shift)
k1 = torch.FloatTensor([[0, 0, 0], [1, 0, 0], [0, 0, 0]]).reshape(1, 1, 3, 3)
k2 = torch.FloatTensor([[0, 0, 0], [0, 0, 1], [0, 0, 0]]).reshape(1, 1, 3, 3)
k3 = torch.FloatTensor([[0, 1, 0], [0, 0, 0], [0, 0, 0]]).reshape(1, 1, 3, 3)
k4 = torch.FloatTensor([[0, 0, 0], [0, 0, 0], [0, 1, 0]]).reshape(1, 1, 3, 3)
weight = torch.cat([k1, k1, k2, k2, k3, k3, k4, k4], dim=0) # 每个输出通道对应一个输入通道
conv_shift = F.conv2d(pad_x, weight=weight, groups=8)
print(conv_shift)
offset = torch.empty(1, 2 * 8 * 1 * 1, 1, 1)
for c, (rel_offset_h, rel_offset_w) in enumerate([(0, -1), (0, -1), (0, 1), (0, 1), (-1, 0), (-1, 0), (1, 0), (1, 0)]):
offset[0, c * 2 + 0, 0, 0] = rel_offset_h
offset[0, c * 2 + 1, 0, 0] = rel_offset_w
offset = offset.repeat(1, 1, 7, 7).float()
weight = torch.eye(8).reshape(8, 8, 1, 1).float()
deconv_shift = deform_conv2d(pad_x, offset=offset, weight=weight)
deconv_shift = deconv_shift[..., 1:6, 1:6]
print(deconv_shift)
"""
tensor([[[[0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.],
[4., 4., 4., 4., 4.]],
[[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.]],
[[0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.],
[4., 4., 4., 4., 4.]],
[[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.]],
[[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.]],
[[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.]],
[[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.],
[4., 4., 4., 4., 4.],
[4., 4., 4., 4., 4.]],
[[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.]]]])
tensor([[[[0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.],
[4., 4., 4., 4., 4.]],
[[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.]],
[[0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.],
[4., 4., 4., 4., 4.]],
[[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.]],
[[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.]],
[[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.]],
[[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.],
[4., 4., 4., 4., 4.],
[4., 4., 4., 4., 4.]],
[[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.]]]])
tensor([[[[0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.],
[4., 4., 4., 4., 4.]],
[[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.]],
[[0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.],
[4., 4., 4., 4., 4.]],
[[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.]],
[[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.]],
[[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.]],
[[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.],
[4., 4., 4., 4., 4.],
[4., 4., 4., 4., 4.]],
[[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.]]]])
tensor([[[[0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.],
[4., 4., 4., 4., 4.]],
[[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.],
[0., 0., 1., 2., 3.]],
[[0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.],
[4., 4., 4., 4., 4.]],
[[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.],
[1., 2., 3., 4., 4.]],
[[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.]],
[[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.]],
[[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.],
[4., 4., 4., 4., 4.],
[4., 4., 4., 4., 4.]],
[[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.],
[0., 1., 2., 3., 4.]]]])
"""
Влияние направления смещения
Эксперименты проводятся на подмножестве ImageNet.
Эксперименты по абляции выполняются для разных направлений смещения в V1.В этой модели каналы сгруппированы по количеству направлений. Как видно из результатов:
- Смещения действительно могут привести к повышению производительности.
- а и б: нет большой разницы между четырьмя направлениями и восемью направлениями.
- e и f: Горизонтальное смещение работает лучше.
- c и e/f: смещение двух осей лучше, чем смещение одной оси.
Размер ввода и влияние размера патча
Эксперименты проводятся на подмножестве ImageNet.
В V1, после исправления размера патча, производительность разных входных размеров ШхВ тоже разная. Чрезмерный размер патча также неэффективен, он приведет к потере более подробной информации, но может эффективно повысить скорость логического вывода.
Эффективность пирамидальной структуры
В V2 строятся две разные структуры: одна с меньшим патчем и с использованием пирамидальной структуры, а другая с большим патчем без использования пирамидальной структуры. Можно видеть, что в то же время, благодаря повышению производительности подробной информации, обеспечиваемой небольшим размером патча, и лучшей вычислительной эффективности, обеспечиваемой пирамидальной структурой, первая достигает лучшей производительности.
Эффект разделения внимания
V2 добавляет расщепление внимания непосредственно к функциям и сравнивает их в среднем. Видно, что первое лучше. Однако количество параметров здесь разное, на самом деле, более разумное сравнение должно как минимум добавить несколько слоев структур с параметрами для интеграции признаков трех ветвей.
Справедливость трехветвевой структуры
Описание эксперимента здесь немного расплывчато. Автор говорит: «В этом разделе мы оцениваем влияние удаления одной из них».
Результаты экспериментов
Экспериментальные результаты можно непосредственно просмотреть в таблице статьи V2:
Ссылка на сайт
- бумага:
- В1:АР Вест V.org/PDF/2106.07…
- Версия 2:АР Вест V.org/PDF/2108.01…
- Код ссылки:
- Код CycleFC можно использовать для справки:GitHub.com/S post Chen/…