"Notas de aprendizaje profundo" El complemento "pequeño" exquisito y universal en el diseño de la red CNN


Prefacio

  • El llamado "plug-in" significa que puede ser la guinda del pastel, fácil de implantar y aterrizar, es decir, un verdadero plug and play. Los "complementos" revisados ​​en este artículo pueden mejorar la traducción, rotación, escala y otras capacidades de degeneración de CNN o extracción de características de múltiples escalas, campos receptivos y otras capacidades, que se verán en muchas redes SOTA.
  • El llamado "complemento" significa que puede integrarse fácilmente en las redes principales sin cambiar la estructura principal de la red, lo que mejora la capacidad de la red para extraer funciones y puede conectarse y reproducir

1. STN (Transformador espacial)

Inserte la descripción de la imagen aquí

1.1 Análisis de núcleos

  • A menudo lo verá en tareas como OCR. Para la cadena CNN, esperamos que tenga cierta invariancia con la postura y posición del objeto. Es decir, puede adaptarse a ciertos cambios de postura y posición en el equipo de prueba. La invariancia o equivariancia pueden mejorar efectivamente la capacidad de generalización del modelo. Aunque CNN utiliza una operación de convolución de ventana deslizante, tiene invariancia de traducción hasta cierto punto. Sin embargo, muchos estudios han encontrado que la reducción de resolución destruirá la invariancia de traducción de la red. Por tanto, se puede considerar que la capacidad de invariancia de la red es muy débil, sin mencionar la invariancia de rotación, escala e iluminación. Generalmente, utilizamos la mejora de datos para lograr la "inmutabilidad" de la red.
  • Este artículo propone el módulo STN, que integra explícitamente la transformación espacial en la red, mejorando así la invariancia de la rotación, traslación y escala de la red. Puede entenderse como operación de "alineación". La estructura de STN se muestra en la figura anterior.Cada módulo STN consta de tres partes: red de localización (red local), generador de red y muestreador.
  1. Localisation net Los parámetros utilizados para aprender a obtener la transformación espacial son los seis parámetros de la fórmula anterior.
  2. Grid generator Se utiliza para el mapeo de coordenadas.
  3. Sampler La recogida de píxeles se realiza mediante interpolación bilineal.

1.2 código de núcleo

class SpatialTransformer(nn.Module):
    def __init__(self, spatial_dims):
        super(SpatialTransformer, self).__init__()
        self._h, self._w = spatial_dims 
        self.fc1 = nn.Linear(32*4*4, 1024) # 可根据自己的网络参数具体设置
        self.fc2 = nn.Linear(1024, 6)

    def forward(self, x): 
        batch_images = x #保存一份原始数据
        x = x.view(-1, 32*4*4)
        # 利用 FC 结构学习到 6 个参数
        x = self.fc1(x)
        x = self.fc2(x) 
        x = x.view(-1, 2,3) # 2x3
        # 利用 affine_grid 生成采样点
        affine_grid_points = F.affine_grid(x, torch.Size((x.size(0), self._in_ch, self._h, self._w)))
        # 将采样点作用到原始数据上
        rois = F.grid_sample(batch_images, affine_grid_points)
        return rois, affine_grid_points

Dos, ASPP

Inserte la descripción de la imagen aquí

2.1 Análisis de núcleos

  • Este complemento es un módulo de agrupación piramidal espacial con convolución de agujeros, que se propone principalmente para mejorar el campo receptivo de la red e introducir información de múltiples escalas. Sabemos que para las redes de segmentación semántica, solemos enfrentarnos a imágenes con mayor resolución, lo que requiere que nuestra red tenga suficientes campos receptivos para cubrir el objeto objetivo. Para la red CNN, el campo receptivo se obtiene básicamente apilando capas convolucionales y reduciendo la resolución. El módulo de este artículo puede controlar el campo receptivo sin cambiar el tamaño del mapa de características, lo que favorece la extracción de información de múltiples escalas. Entre ellos, la tasa controla el tamaño del campo receptivo, cuanto mayor es r, mayor es el campo receptivo.
  • ASPP incluye principalmente las siguientes partes:
  1. Una capa de agrupación promedio global obtiene características a nivel de imagen, realiza una convolución 1X1 e interpola bilinealmente al tamaño original;
  2. Una capa convolucional 1X1 y tres convoluciones huecas 3X3;
  3. Las 5 características de diferentes escalas se juntan en la dimensión del canal y luego se envían a la convolución 1X1 para la salida de fusión.

2.2 Código del núcleo

class ASPP(nn.Module):
    def __init__(self, in_channel=512, depth=256):
        super(ASPP,self).__init__()
        self.mean = nn.AdaptiveAvgPool2d((1, 1))
        self.conv = nn.Conv2d(in_channel, depth, 1, 1)
        self.atrous_block1 = nn.Conv2d(in_channel, depth, 1, 1)
        # 不同空洞率的卷积
        self.atrous_block6 = nn.Conv2d(in_channel, depth, 3, 1, padding=6, dilation=6)
        self.atrous_block12 = nn.Conv2d(in_channel, depth, 3, 1, padding=12, dilation=12)
        self.atrous_block18 = nn.Conv2d(in_channel, depth, 3, 1, padding=18, dilation=18)
        self.conv_1x1_output = nn.Conv2d(depth * 5, depth, 1, 1)

    def forward(self, x):
        size = x.shape[2:]
     	# 池化分支
        image_features = self.mean(x)
        image_features = self.conv(image_features)
        image_features = F.upsample(image_features, size=size, mode='bilinear')
     	# 不同空洞率的卷积
        atrous_block1 = self.atrous_block1(x)
        atrous_block6 = self.atrous_block6(x)
        atrous_block12 = self.atrous_block12(x)
        atrous_block18 = self.atrous_block18(x)
        # 汇合所有尺度的特征
     	x = torch.cat([image_features, atrous_block1, atrous_block6,atrous_block12, atrous_block18], dim=1)
        # 利用1X1卷积融合特征输出
        x = self.conv_1x1_output(x)
        return net

三 、 No local

Inserte la descripción de la imagen aquí

3.1 Análisis de núcleos

Non-Local es un mecanismo de atención y un módulo de fácil implantación e integración. Local es principalmente para el campo receptivo. Tomando como ejemplo la operación de convolución y la operación de agrupación en CNN, el tamaño de su campo receptivo es el tamaño del núcleo de convolución y, a menudo, usamos capas convolucionales 3X3 para apilar. Solo considera el área local, que son todas las operaciones locales. La diferencia es que el campo receptivo de la operación no local puede ser muy grande, puede ser un área global en lugar de un área local. Capturar dependencias de largo alcance, es decir, cómo establecer la conexión entre dos píxeles con cierta distancia en la imagen, es una especie de mecanismo de atención. El llamado mecanismo de atención lo genera la red saliency map, y la atención corresponde al área de prominencia, que es el área que necesita que la red se concentre.

Pasos de implementación específicos:

  • Primero, realice una convolución 1X1 en los mapas de características de entrada para comprimir el número de canales y obtenga θ, ϕ, g \ theta, \ phi, gθ ,ϕ ,g características.
  • A través de la operación de remodelación, se transforman las dimensiones de las tres características, y luego se realiza la operación de multiplicación de matrices para obtener una matriz de covarianza similar. Este paso consiste en calcular la autocorrelación en la característica, es decir, obtener cada píxel en cada cuadro y todos los píxeles en todos los demás fotogramas Relación.
  • Luego, realice la operación Softmax en la función de autocorrelación para obtener los pesos de 0 ~ 1, aquí está el coeficiente de atención personal que necesitamos.
  • Finalmente, el coeficiente de atención se multiplica correspondientemente de nuevo a la matriz de características g, y el residuo del mapa de características de entrada original X se agrega a la salida.

3.2 código de núcleo

class NonLocal(nn.Module):
    def __init__(self, channel):
        super(NonLocalBlock, self).__init__()
        self.inter_channel = channel // 2
        self.conv_phi = nn.Conv2d(channel, self.inter_channel, 1, 1,0, False)
        self.conv_theta = nn.Conv2d(channel, self.inter_channel, 1, 1,0, False)
        self.conv_g = nn.Conv2d(channel, self.inter_channel, 1, 1, 0, False)
        self.softmax = nn.Softmax(dim=1)
        self.conv_mask = nn.Conv2d(self.inter_channel, channel, 1, 1, 0, False)

    def forward(self, x):
        # [N, C, H , W]
        b, c, h, w = x.size()
        # 获取phi特征,维度为[N, C/2, H * W],注意是要保留batch和通道维度的,是在HW上进行的
        x_phi = self.conv_phi(x).view(b, c, -1)
        # 获取theta特征,维度为[N, H * W, C/2]
        x_theta = self.conv_theta(x).view(b, c, -1).permute(0, 2, 1).contiguous()
        # 获取g特征,维度为[N, H * W, C/2]
        x_g = self.conv_g(x).view(b, c, -1).permute(0, 2, 1).contiguous()
        # 对phi和theta进行矩阵乘,[N, H * W, H * W]
        mul_theta_phi = torch.matmul(x_theta, x_phi)
        # softmax拉到0~1之间
        mul_theta_phi = self.softmax(mul_theta_phi)
        # 与g特征进行矩阵乘运算,[N, H * W, C/2]
        mul_theta_phi_g = torch.matmul(mul_theta_phi, x_g)
        # [N, C/2, H, W]
        mul_theta_phi_g = mul_theta_phi_g.permute(0, 2, 1).contiguous().view(b, self.inter_channel, h, w)
        # 1X1卷积扩充通道数
        mask = self.conv_mask(mul_theta_phi_g)
        out = mask + x # 残差连接
        return out

Cuatro, SE

Inserte la descripción de la imagen aquí

4.1 Análisis básico

Este artículo es el trabajo campeón de la última competencia de ImageNet. Lo verá en muchas estructuras de red clásicas, por ejemplo Mobilenet v3. En realidad, es un mecanismo de atención del canal. Debido a la compresión de funciones y FC, las funciones de atención del canal capturado tienen información global. Este artículo propone un nuevo “Squeeze-and Excitation(SE)”módulo- unidad estructural , que puede ajustar de forma adaptativa el valor de respuesta característico de cada canal y modelar la dependencia interna entre canales.

Hay varios pasos:

  • Apretar: realiza la compresión de entidades a lo largo de la dimensión espacial, convirtiendo cada canal de entidades bidimensionales en un número, que tiene un campo receptivo global.
  • Excitación: cada canal de funciones genera un peso para representar la importancia del canal de funciones.
  • Reponderación: considere el peso de la salida de excitación como la importancia de cada canal de función y actúe en cada canal mediante la multiplicación.

4.2 código central

class SE_Block(nn.Module):
    def __init__(self, ch_in, reduction=16):
        super(SE_Block, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)  # 全局自适应池化
        self.fc = nn.Sequential(
            nn.Linear(ch_in, ch_in // reduction, bias=False),
            nn.ReLU(inplace=True),
            nn.Linear(ch_in // reduction, ch_in, bias=False),
            nn.Sigmoid()
        )

    def forward(self, x):
        b, c, _, _ = x.size()
        y = self.avg_pool(x).view(b, c) # squeeze操作
        y = self.fc(y).view(b, c, 1, 1) # FC获取通道注意力权重,是具有全局信息的
        return x * y.expand_as(x) # 注意力作用每一个通道上

Cinco, CBAM

5.1 Análisis de núcleos

  • SENet adquiere el peso de la atención en el canal del mapa de características y luego lo multiplica por el mapa de características original. Este artículo señala que este método de atención solo se enfoca en qué capas en el nivel del canal tendrán capacidades de retroalimentación más fuertes, pero no refleja la atención en la dimensión espacial.
  • Como lo más destacado de este artículo, CBAM presta atención tanto al canal como a las dimensiones espaciales. Al igual que el módulo SE, CBAM puede integrarse en la mayoría de las redes principales y puede mejorar el modelo sin aumentar significativamente la cantidad de cálculos y parámetros. La capacidad de extracción de características.

Atención del canal: como se muestra arriba

  1. Primero, la entrada es una H×W×Ccaracterística F., se describirá cada grupo y grupo máximo global promedio de dos canales espaciales para obtener dos 1 × 1 × C.
  2. Luego, envíelos a una red neuronal de dos capas, el número de neuronas en la primera capa es C / r, la función de activación es Relu y el número de neuronas en la segunda capa es C. Tenga en cuenta que esta red neuronal de dos capas es compartida.
  3. Luego, se suman las dos características obtenidas y se pasan por una función de activación sigmoidea para obtener el coeficiente de ponderación Mc.
  4. Finalmente, multiplique el coeficiente de peso y la característica original F para obtener la nueva característica después de escalar.

Código falso:

def forward(self, x):
    # 利用FC获取全局信息,和Non-local的矩阵相乘本质上式一样的
    avg_out = self.fc2(self.relu1(self.fc1(self.avg_pool(x))))
    max_out = self.fc2(self.relu1(self.fc1(self.max_pool(x))))
    out = avg_out + max_out
    return self.sigmoid(out)

Atención espacial:

  • De manera similar a la atención del canal, dada una característica F 'de H × W × C, primero realizamos la agrupación promedio y la agrupación máxima de una dimensión de canal para obtener dos descripciones de canal de H × W × 1, y combinar estas dos Las descripciones se empalman juntos según el canal. Luego, después de una capa convolucional de 7 × 7, la función de activación es Sigmoide, y se obtiene el coeficiente de peso Ms. Finalmente, multiplique el coeficiente de peso y la característica F 'para obtener la nueva característica después de escalar.

Código falso:

def forward(self, x):
    # 这里利用池化获取全局信息
    avg_out = torch.mean(x, dim=1, keepdim=True)
    max_out, _ = torch.max(x, dim=1, keepdim=True)
    x = torch.cat([avg_out, max_out], dim=1)
    x = self.conv1(x)
    return self.sigmoid(x)

待补全调整...

Link de referencia

  1. https://mp.weixin.qq.com/s/glQSmbuvRI6CV8EyfYLezw

Supongo que te gusta

Origin blog.csdn.net/libo1004/article/details/112793383
Recomendado
Clasificación