estructura residual invertida

  La estructura residual invertida (Residual invertido) es un módulo de diseño comúnmente utilizado en redes neuronales convolucionales livianas, con el objetivo de mejorar la eficiencia y el rendimiento del modelo. Fue introducido por primera vez por MobileNetV2 y se ha utilizado ampliamente en redes posteriores, incluidas MobileNetV3, etc. La idea central de la estructura residual invertida es variante de la estructura residual tradicional (Bloque Residual) para adaptarse a las características de las redes livianas.
  En la estructura residual tradicional, el mapa de características de entrada se somete a una serie de operaciones de convolución y se agrega a la entrada original para obtener la salida. En la estructura residual invertida, primero realizamos una convolución de expansión ligera en el mapa de características de entrada, luego realizamos una convolución separable en profundidad y finalmente usamos una convolución puntual (convolución puntual) reduce el número de canales y finalmente lo agrega al mapa de características de entrada original para obtener la salida.
  Las principales innovaciones de la estructura residual invertida se encuentran en dos aspectos:
  convolución de expansión ligera (Expand Convolution): en la estructura residual invertida, primero se utiliza una operación de convolución con una pequeña cantidad de canales de salida para expandir la cantidad de canales de la característica de entrada. mapa. . El propósito de esta convolución dilatada es introducir más expresiones de características para una convolución posterior separable en profundidad para extraer información.
  Convolución separable en profundidad: después de la convolución dilatada, se utiliza convolución separable en profundidad para la extracción de características. La convolución separable en profundidad divide la operación de convolución en dos pasos: convolución en profundidad y convolución puntual. La convolución en profundidad reduce la cantidad de cálculo al realizar operaciones de convolución en cada canal por separado. La convolución puntual se utiliza para reducir el número de canales e introducir una transformación no lineal.
  La importancia de este diseño es que la estructura residual invertida reduce el costo computacional a un nivel bajo al realizar una convolución separable en profundidad después de la expansión del canal, logrando así una extracción eficiente de características en redes livianas. Además, al agregar convolución de puntos después de la convolución de dilatación del canal, también se puede introducir una transformación no lineal para mejorar la capacidad expresiva de la red.
  Aquí hay un ejemplo de código PyTorch más detallado:

import torch
import torch.nn as nn
from torchsummary import summary

# 3、倒残差结构
class ConvBNReLU(nn.Sequential):
    def __init__(self, in_channel, out_channel, kernel_size=3, stride=1, groups=1):
        padding = (kernel_size - 1) // 2
        super(ConvBNReLU, self).__init__(
            nn.Conv2d(in_channel, out_channel, kernel_size, stride, padding, groups=groups, bias=False),
            nn.BatchNorm2d(out_channel),
            nn.ReLU(inplace=True)
        )


class InvertedResidual(nn.Module):
    def __init__(self, in_channel, out_channel, stride, expand_ratio):
        super(InvertedResidual, self).__init__()
        hidden_channel = in_channel * expand_ratio#expand_ratio:扩展因子
        self.use_shortcut = stride == 1 and in_channel == out_channel
        layers = []
        if expand_ratio != 1:
            layers.append(ConvBNReLU(in_channel, hidden_channel, kernel_size=1))#hxwxk-->hxwx(tk)
        layers.extend([#layers.extend() 是 Python 中的列表方法,用于在一个列表的末尾一次性添加另一个可迭代对象中的所有元素到该列表中。
                ConvBNReLU(hidden_channel, hidden_channel, kernel_size=stride, groups=hidden_channel),#hxwx(tk)-->(h/s)x(w/s)x(tk)
                nn.Conv2d(hidden_channel, out_channel, kernel_size=1, bias=False),#(h/s)x(w/s)x(tk)-->(h/s)x(w/s)xk'
                nn.BatchNorm2d(out_channel)
            ])

        self.conv = nn.Sequential(*layers)

    def forward(self, x):
        if self.use_shortcut:
            x = x + self.conv(x)
            return x
        else:
            x = self.conv(x)
            return x


if __name__ == '__main__':
    model=InvertedResidual(3,64,1,6)
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    model.to(device)
    input_tensor=torch.randn(1,3,224,224).to(device)
    input_tensor1 = (3, 224, 224)
    output_tensor=model(input_tensor)
    print(output_tensor.shape)

    print("InvertedResidual:")
    summary(model, input_tensor1)

  El código anterior muestra en detalle cómo usar PyTorch para construir un modelo MobileNetV2 con una estructura residual invertida. Puede ajustarlo y ampliarlo según sus necesidades reales.

Supongo que te gusta

Origin blog.csdn.net/qq_50993557/article/details/132418439
Recomendado
Clasificación