Función de activación Yolov5

 

Este archivo de activación.py, este archivo contiene todas las funciones de activación utilizadas en Yolov 5. Las diferentes versiones pueden tener diferentes métodos de nomenclatura de funciones, pero el principio de implementación es el mismo.

Función chasquido

expresión

Imagen de función

código fuente

class SiLU(nn.Module):  # export-friendly version of nn.SiLU()
    @staticmethod
    def forward(x):
        return x * torch.sigmoid(x)  # Swish函数  f(x) = x * sigmoid(x)

class Hardswish(nn.Module):  # export-friendly version of nn.Hardswish()
    @staticmethod
    def forward(x):
        # return x * F.hardsigmoid(x)  # for torchscript and CoreML
        return x * F.hardtanh(x + 3, 0., 6.) / 6.  # for torchscript, CoreML and ONNX

 En el código fuente, podemos ver que además de la función swish original, también hay una función Hardswish . Esto se debe a que la función swish original usa la función sigmoide. La función sigmoide está compuesta por exponentes. El costo de cálculo en dispositivos móviles mucho más alto. La función de activación Sigmoid se puede equipar con la función lineal por partes HardSigmoid, que ha ahorrado rendimiento del equipo.

Esta función utiliza una función por partes para ajustar el sigmoide:

 Pero, de hecho, hay una clase Hardswish en torch.nn, pero el autor aún escribió esta expresión porque es posible que no la admita al exportar modelos de torchscript, CoreML y ONNX, por lo que todos los autores escribieron una directamente.

 
 

función mezcla

expresión

 Imagen de función

 Se puede ver que no trunca directamente en el semieje negativo como la función Relu, y es mejor que la función swish en el semieje negativo.

código fuente

class Mish(nn.Module):
    @staticmethod
    def forward(x):
        return x * F.softplus(x).tanh()


class MemoryEfficientMish(nn.Module):
    class F(torch.autograd.Function):
        @staticmethod
        def forward(ctx, x):
            ctx.save_for_backward(x) 

            return x.mul(torch.tanh(F.softplus(x)))  # x * tanh(ln(1 + exp(x)))

        @staticmethod
        def backward(ctx, grad_output):
            x = ctx.saved_tensors[0]
            sx = torch.sigmoid(x)
            fx = F.softplus(x).tanh()
            return grad_output * (fx + x * sx * (1 - fx * fx))

    def forward(self, x):
        return self.F.apply(x)

Después de leer el código fuente, descubrí que hay un MemoryEfficientMish adicional. No es difícil entender por el nombre que es "una función Mish para guardar memoria".

El punto clave es este código   ctx.save_for_backward(x)    A través de la función save_for_backward, el objeto se puede guardar para la función posterior posterior, y luego se conservará toda la información de la entrada y se evitará la operación en el lugar. , lo que hace que la entrada se pierda en la situación Modificada hacia atrás.

Función FReLU

Esta función es una función de activación simple pero efectiva para las tareas de reconocimiento de imágenes propuestas en ECCV2020, llamada función de activación de embudo (FReLU), que extiende ReLU y PReLU a funciones de activación 2D al agregar una sobrecarga condicional espacial insignificante.

Esta imagen en su artículo de esta función puede entender su principio. 

 
 

El extremo izquierdo de esta imagen es Relu: él es el valor máximo de x y 0. PRelu en el medio: x y pX encuentran el valor máximo. El FRelu en el extremo derecho es para encontrar el valor máximo con una superficie. Mayor sensibilidad espacial en las funciones de activación. Robustez mejorada.

Este enlace lo dice muy claro.

ECCV2020 | FReLU: Megvii propone una nueva función de activación para lograr el modelado de información espacial a nivel de píxel_Blog del campamento de entrenamiento de algoritmos de IA-Blog de CSDN

código fuente:

class FReLU(nn.Module):
    def __init__(self, c1, k=3):  # ch_in, kernel
        super().__init__()
        self.conv = nn.Conv2d(c1, c1, k, 1, 1, groups=c1, bias=False)
        self.bn = nn.BatchNorm2d(c1)

    def forward(self, x):
        return torch.max(x, self.bn(self.conv(x)))

(Para hacer una digresión, la función de activación tiene que ver con la metafísica cuando se ajustan los parámetros... tienes que probar cada uno para saber cuál es el más adecuado para el conjunto de datos... A veces está bien, a veces no. ..)

Supongo que te gusta

Origin blog.csdn.net/qq_35326529/article/details/128246386
Recomendado
Clasificación