Cycle MLP of Vision MLP Архитектура, подобная MLP, для плотного прогнозирования

искусственный интеллект

Cycle MLP of Vision MLP Архитектура, подобная MLP, для плотного прогнозирования

Оригинальный документ:у-у-у. yuque.com/pulllingheads/papers…

image.png

Читать статью из аннотации

This paper presents a simple MLP-like architecture, CycleMLP, which is a versatile backbone for visual recognition and dense predictions, unlike modern MLP architectures, e.g., MLP-Mixer, ResMLP, and gMLP, whose architectures are correlated to image size and thus are infeasible in object detection and segmentation.

Похоже, что это снова пирамидальная архитектура MLP, и видно, что основная работа должна выполняться снова вокруг пространственного MLP. Потому что здесь снимается зависимость архитектуры от размера ввода. на самом деле вMLP-Mixer оригинальная бумагаВ , авторы на самом деле попробовали пирамидальную структуру, которая сходится быстрее, чем форма с фиксированным разрешением.

We tried using the token-mixing MLP to reduce the number of tokens by mapping from S input tokens to S'<S output tokens. While first experiments showed that on JFT-300M such models significantly reduced training time without losing much performance, we were unable to transfer these findings to ImageNet or ImageNet-21k.

CycleMLP has two advantages compared to modern approaches.

  • (1) It can cope with various image sizes.
  • (2) It achieves linear computational complexity to image size by using local windows.

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

In contrast, previous MLPs have quadratic computations because of their fully spatial connections.

Указывается на необходимость совершенствования пространственного МЛП. Его вычислительная сложность слишком высока.

We build a family of models that surpass existing MLPs and achieve a comparable accuracy (83.2%) on ImageNet-1K classification compared to the state-of-the-art Transformer such as Swin Transformer (83.3%) but using fewer parameters and FLOPs.

Видно, что производительность метода в данной работе очень высока. Не уверен, используются ли другие стратегии, помимо структуры.

We expand the MLP-like models' applicability, making them a versatile backbone for dense prediction tasks. CycleMLP aims to provide a competitive baseline on object detection, instance segmentation, and semantic segmentation for MLP models. In particular, CycleMLP achieves 45.1 mIoU on ADE20K val, comparable to Swin (45.2 mIOU). Code is available at this https URL.

основное содержание

весь кадр

image.pngКак видите, ядром является улучшение пространственного MLP. Три недостатка существующей структуры MLP:

  1. Большинство из них относятся к одномасштабной структуре, которую непросто перенести на другие задачи, требующие пирамиды признаков, такие как обнаружение, сегментация и т. д.
  2. Spatial MLP соединяет все точки во входном пространстве признаков, что также ограничивает зависимость модели от размера входных данных. Это не способствует многомасштабному обучению, многомасштабному тестированию или даже разным разрешениям обучения и тестирования.
  3. Spatial MLP имеет квадратичную вычислительную сложность, что делает неудобным обработку изображений с высоким разрешением.

Авторы решают эту проблему двумя способами:

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

Отличие от S2-MLP

Хотя пространственная MLP заменена MLP канала, конкретный метод и общая форма модели отличаются:

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

Фактически, для первого пункта стратегия использования свертки разделения по глубине фактически задана в S2-MLP, то есть смещение может быть реализовано конкретной формой ядра свертки разделения по глубине, а группировка и смещение входных данных и то, и другое Это может быть достигнуто непосредственно путем работы с ядром свертки. Пункт 1 здесь не имеет места. Можно лишь сказать, что реализация Cycle FC может быть более прямой, в отличие от S2-MLP, который требует некоторых операций обработки, не связанных с вычислениями. Кроме того, с точки зрения реализации, может ли Cycle FC также обеспечить дешевые операции с помощью свертки с разделением по глубине? Ответ положительный, и позже я приведу несколько простых попыток анализа кода.

Детали модели

image.png

  • модуль встраивания патчей: размер окна 7, шаг 4, окончательная функция понижения дискретизации в четыре раза.
  • Двукратное понижение частоты дискретизации достигается за счет пошаговой свертки в середине.
  • Окончательный результат — это особенности, уменьшенные в 32 раза.
  • Наконец, полностью подключенный слой используется для интеграции функций всех токенов.

Основная операция - Cycle FC

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

image.png

image.png

Как видно из формы, представленной на рисунке, Cycle FC на самом деле является канальным MLP с определенным смещением позиции (ступенчатым стилем) на канале. Таким образом, требования к форме для ввода не слишком строгие. Конечно, по крайней мере позиция смещения не может превышать размер ядра, определенный на HW. Как видно из кода, здесь задается диапазон, и циклическое смещение в пределах ограниченного диапазона достигается путем взятия индекса канала по модулю Реализация здесь очень интересная, с использованием деформируемой свертки для применения смещения к параметрам ядра. сдвиг. В частности, MLP исходного канала рассчитывается как:Yi,j=c=0Ci1Fj,cXi,cY_{i,j} = \sum_{c=0}^{C_i - 1} \mathcal{F}^{\top}_{j,c} \cdot X_{i,c},один из нихFеRCi×Co\mathcal{F} \in \mathbb{R}^{C_i \times C_o}Представляет обучаемые веса для канала MLP. один из нихi&ji\&jИндексы, представляющие пробелы и каналы соответственно. Для цикла FC, предложенного в этой статье, метод расчета расширен до:Yi,j=c=0Ci1Fj,cXi+c%SP,cY_{i, j} = \sum_{c=0}^{C_i-1} \mathcal{F}^{\top}_{j,c} \cdot X_{i+c\%S_{\mathcal{P}},c}, который вводит параметр диапазона смещенияSPS_{\mathcal{P}}, то есть размер псевдоядра, который представляет собой площадь проекции всех задействованных расчетных позиций на пространство HW после смещения канала, и еще один параметрiiУказывает начальную позицию смещения. Значением в коде является относительная координата центра внутри прямоугольной области псевдоядра (начиная с левого верхнего угла области, индекс равен 0, а прямоугольная область сортируется и индексируется в порядке строк), этоstart_idx=(self.kernel_size[0]*self.kernel_size[1])//2.

Разбор кода

Здесь часть основного кода анализируется в виде комментариев.

from torchvision.ops.deform_conv import deform_conv2d as deform_conv2d_tv

class CycleFC(nn.Module):
    def __init__(
        self,
        in_channels: int,
        out_channels: int,
        kernel_size,  # re-defined kernel_size, represent the spatial area of staircase FC
        stride: int = 1,
        padding: int = 0,
        dilation: int = 1,
        groups: int = 1,
        bias: bool = True,
    ):
        """
        这里的kernel_size实际使用的时候时3x1或者1x3
        """
        super(CycleFC, self).__init__()

        if in_channels % groups != 0:
            raise ValueError('in_channels must be divisible by groups')
        if out_channels % groups != 0:
            raise ValueError('out_channels must be divisible by groups')
        if stride != 1:
            raise ValueError('stride must be 1')
        if padding != 0:
            raise ValueError('padding must be 0')

        self.in_channels = in_channels
        self.out_channels = out_channels
        self.kernel_size = kernel_size
        self.stride = _pair(stride)
        self.padding = _pair(padding)
        self.dilation = _pair(dilation)
        self.groups = groups

        # 被偏移调整的1x1卷积的权重,由于后面使用torchvision提供的可变形卷积的函数,所以权重需要自己构造
        self.weight = nn.Parameter(torch.empty(out_channels, in_channels // groups, 1, 1))
        # kernel size == 1

        if bias:
            self.bias = nn.Parameter(torch.empty(out_channels))
        else:
            self.register_parameter('bias', None)
        # 要注意,这里是在注册一个buffer,是一个常量,不可学习,但是可以保存到模型权重中。
        self.register_buffer('offset', self.gen_offset())

    def gen_offset(self):
        """
        生成卷积核偏移量的核心操作。
        要想理解这一函数的操作,需要首先理解后面使用的deform_conv2d_tv的具体用法。
        具体可见:https://pytorch.org/vision/0.10/ops.html#torchvision.ops.deform_conv2d
        这里对于offset参数的要求是:
        offset (Tensor[batch_size,
        			   2 * offset_groups * kernel_height * kernel_width,
                       out_height,
                       out_width])
                       – offsets to be applied for each position in the convolution kernel.
        也就是说,对于样本s的输出特征图的通道c中的位置(x,y),这个函数会从offset中取出,形状为
        kernel_height*kernel_width的卷积核所对应的偏移参数为
        offset[s, 0:2*offset_groups*kernel_height*kernel_width, x, y]
        也就是这一系列参数都是对应样本s的单个位置(x,y)的。
        针对不同的位置可以有不同的offset,也可以有相同的(下面的实现就是后者)。
        对于这2*offset_groups*kernel_height*kernel_width个数,涉及到对于输入特征通道的分组。
        将其分成offset_groups组,每份单独拥有一组对应于卷积核中心位置的相对偏移量,
        共2*kernel_height*kernel_width个数。
        对于每个核参数,使用两个量来描述偏移,即h方向和w方向相对中心位置的偏移,
        即下面代码中的减去kernel_height//2或者kernel_width//2。
        需要注意的是,当偏移位置位于padding后的tensor边界外,则是将网格使用0补齐。
        如果网格上有边界值,则使用边界值和用0补齐的网格顶点来计算双线性插值的结果。
        """
        offset = torch.empty(1, self.in_channels*2, 1, 1)
        start_idx = (self.kernel_size[0] * self.kernel_size[1]) // 2
        assert self.kernel_size[0] == 1 or self.kernel_size[1] == 1, self.kernel_size
        for i in range(self.in_channels):
            if self.kernel_size[0] == 1:
                offset[0, 2 * i + 0, 0, 0] = 0
                # 这里计算了一个相对偏移位置。
                # deform_conv2d使用的以对应输出位置为中心的偏移坐标索引方式
                offset[0, 2 * i + 1, 0, 0] = (
                	(i + start_idx) % self.kernel_size[1] - (self.kernel_size[1] // 2)
                )
            else:
                offset[0, 2 * i + 0, 0, 0] = (
                    (i + start_idx) % self.kernel_size[0] - (self.kernel_size[0] // 2)
                )
                offset[0, 2 * i + 1, 0, 0] = 0
        return offset

    def forward(self, input: Tensor) -> Tensor:
        """
        Args:
            input (Tensor[batch_size, in_channels, in_height, in_width]): input tensor
        """
        B, C, H, W = input.size()
        return deform_conv2d_tv(input,
                                self.offset.expand(B, -1, H, W),
                                self.weight,
                                self.bias,
                                stride=self.stride,
                                padding=self.padding,
                                dilation=self.dilation)

Поскольку здесь есть некоторая путаница с генерацией смещения, я также поднял вопрос перед автором (GitHub.com/S post Chen/…), вместе с небольшим примером о deform_conv2d. Здесь автор предоставляет диаграмму, которая лучше соответствует коду:

class CycleMLP(nn.Module):
    def __init__(self, dim, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.):
        super().__init__()
        self.mlp_c = nn.Linear(dim, dim, bias=qkv_bias)

        self.sfc_h = CycleFC(dim, dim, (1, 3), 1, 0)
        self.sfc_w = CycleFC(dim, dim, (3, 1), 1, 0)

        self.reweight = Mlp(dim, dim // 4, dim * 3)

        self.proj = nn.Linear(dim, dim)
        self.proj_drop = nn.Dropout(proj_drop)

    def forward(self, x):
        B, H, W, C = x.shape
        h = self.sfc_h(x.permute(0, 3, 1, 2)).permute(0, 2, 3, 1)
        w = self.sfc_w(x.permute(0, 3, 1, 2)).permute(0, 2, 3, 1)
        c = self.mlp_c(x)

        a = (h + w + c).permute(0, 3, 1, 2).flatten(2).mean(2)
        a = self.reweight(a).reshape(B, C, 3).permute(2, 0, 1).softmax(dim=0).unsqueeze(2).unsqueeze(2)

        x = h * a[0] + w * a[1] + c * a[2]

        x = self.proj(x)
        x = self.proj_drop(x)

        return x

Как видно из кода, при реальном использовании два набора параллельных операций 1х3 и 3х1 строятся по форме, аналогичной фрактальной свёртке в Inception V3. Существует также общий канал MLP для обработки одного местоположения. Таким образом, строится трехветвевая структура.

which is inspired by the factorization of convolution [47] and criss-cross attention [26].

Экспериментальный эффект

image.png

image.png

Сравнение с современными методами MLP

image.png

Здесь автор упоминает GFNet, который использует БПФ для изучения пространственных характеристик и требует меньше вычислений, а его производительность аналогична CycleMLP. Однако оно ограничено входным разрешением.Если вы хотите изменить входное разрешение, вам необходимо использовать интерполяцию параметров. Это может повредить производительности плотных задач прогнозирования. (Это действительно будет иметь большое значение?)

Кроме того, авторы также дополняют эксперименты по абляции влиянием разных разрешений тестов и разных ветвей.

image.png

image.png

Эти два эксперимента выявили некоторые интересные явления.

  • Сначала взглянув на эффект разрешения, можно увидеть, что оптимальный тестовый мел может не соответствовать исходному обучению. Стабильность CycleFC для протестированных размеров отражена в результатах.
    • Но здесь следует отметить, что эксперименты здесь начинаются скодКак видно в тесте, используемый тест сначала увеличен до заданного размера256224\frac{256}{224}Метод операции вырезания соответствующего размера из центра после умножения. Соответствующие явления других форм обработки данных все еще нуждаются в дополнительной экспериментальной проверке.
  • Эксперименты по абляции выполняются на трех ветвях многоветвевой структуры в таблице 4. Видно, что операционное разнообразие имеет положительный эффект для многоотраслевой структуры.

image.png

image.png

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

Ссылка на сайт