Función PyTorch torch.nn.ReLU

PyTorch torch.nn 参考手册Manual de referencia de PyTorch torch.nn


torch.nn.ReLUEs una de las funciones de activación más utilizadas en PyTorch; aplica la operación de Unidad Lineal Rectificada (Rectified Linear Unit) elemento a elemento sobre el tensor de entrada.

ReLU es una de las funciones de activación más exitosas en el aprendizaje profundo, porque su cálculo es simple, converge rápidamente y puede aliviar eficazmente el problema del desvanecimiento del gradiente.

Definición de la función

torch.nn.ReLU(inplace=False)

Descripción de parámetros:

  • inplace(bool): si se establece enTrue, se modificará directamente el tensor de entrada in-place, ahorrando memoria. Por defecto esFalse。

Principio matemático

nn.ReLULa fórmula de cálculo que se ejecuta es la siguiente:

f(x) = max(0, x)

Es decir, para cada elemento de la entrada, si el valor es mayor que 0, se mantiene igual; si el valor es menor o igual a 0, la salida es 0.

Esta simple transformación no lineal permite que la red aprenda patrones complejos, manteniendo al mismo tiempo el flujo del gradiente.


Ejemplos de uso

Ejemplo 1: Uso básico

Crea una capa de activación ReLU y activa la entrada:

Ejemplo

import torch
import torch.nn as nn

# Crear capa de activación ReLU
relu = nn.ReLU()

# Crear un tensor de entrada con valores negativos
input_tensor = torch.tensor([[-1.0, 2.0, -3.0], [4.0, -5.0, 6.0]])

# Propagación hacia adelante
output = relu(input_tensor)

print("Entrada:n", input_tensor)
print("Salida:n", output)

El resultado es:

输入:
 tensor([[-1.,  2., -3.],
        [ 4., -5.,  6.]])
输出:
 tensor([[0., 2., 0.],
        [4., 0., 6.]])

Se puede observar que todos los valores negativos se establecen en 0, mientras que los positivos permanecen sin cambios.

Ejemplo 2: Operación in-place

Usar el parámetro inplace puede ahorrar memoria:

Ejemplo

import torch
import torch.nn as nn

# Crear ReLU con operación in-place habilitada
relu_inplace = nn.ReLU(inplace=True)

# Crear tensor de entrada
input_tensor = torch.randn(2, 4)
original_id = id(input_tensor)

# Modificación in situ
output = relu_inplace(input_tensor)

# Verificar si se ha modificado el tensor original
print("Si se modificó el tensor original:", id(output) == original_id)
print(Entrada/Salida:n, input_tensor)

El resultado es:

是否修改了原张量: True
输入/输出:
 tensor([[0.0000, 0.0000, 1.2345, 0.0000],
        [0.5432, 0.0000, 0.0000, 2.3456]])

Nota: la operación in-place puede ahorrar memoria, pero en algunos casos puede afectar el cálculo del gradiente. Al inicio del entrenamiento o cuando sea necesario conservar los valores de activación intermedios, se recomienda usar el valor predeterminadoinplace=False。

Ejemplo 3: Uso en redes neuronales

En las redes neuronales convolucionales, ReLU suele ir después de la capa convolucional:

Ejemplo

import torch
import torch.nn as nn

# Definir una red neuronal convolucional sencilla
class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        # Capa convolucional: 3 canales de entrada, 32 canales de salida, núcleo de convolución 3x3
        self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
        # Activación ReLU
        self.relu1 = nn.ReLU()
        # Segunda capa convolucional
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
        self.relu2 = nn.ReLU()
        # Capa de pooling
        self.pool = nn.MaxPool2d(2, 2)

    def forward(self, x):
        x = self.conv1(x)
        x = self.relu1(x)
        x = self.pool(x)

        x = self.conv2(x)
        x = self.relu2(x)
        x = self.pool(x)

        return x

# Crear modelo
model = SimpleCNN()

# Imprimir estructura del modelo
print(Estructura del modelo:)
print(model)

# Probar propagación hacia adelante
# Simular una imagen en color de 3x32x32
input_image = torch.randn(1, 3, 32, 32)
output = model(input_image)

print("nForma de entrada:", input_image.shape)
print(Forma de salida:, output.shape)

El resultado es:

模型结构:
SimpleCNN(
  (conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (relu1): ReLU()
  (conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (relu2): ReLU()
  (pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)

输入形状: torch.Size([1, 3, 32, 32])
输出形状: torch.Size([1, 64, 8, 8])

Ejemplo 4: Uso de nn.functional.relu

PyTorch también proporciona una interfaz funcionaltorch.nn.functional.relu:

Ejemplo

import torch
import torch.nn.functional as F

# Uso de la interfaz funcional
input_tensor = torch.randn(1, 5, 5)

# Método 1: usar la interfaz funcional
output1 = F.relu(input_tensor)

# Método 2: usar la versión inplace de la función
F.relu_(input_tensor)

print("Salida:n", output1)

La diferencia entre ambos:

  • nn.ReLUEs una clase de módulo, que se puede usar en la definición del modelo y guarda parámetros.
  • F.reluEs una interfaz funcional, que se usa a menudo en el método forward o en situaciones donde no hay parámetros aprendibles.
  • F.relu_Es la función con guion bajo de la versión in-place.

Comparación con otras funciones de activación

Función de activación Fórmula Características Escenarios de aplicación
nn.ReLU max(0, x) Cálculo simple, activación dispersa Aprendizaje profundo general (opción predeterminada)
nn.LeakyReLU x > 0 ? x : 0.01x Pequeño gradiente en el eje negativo Previene las "neuronas muertas"
nn.GELU x * Φ(x) Aproximación suave, predeterminada en Transformer Transformer, BERT, etc.
nn.Sigmoid 1/(1+e^(-x)) Salida 0-1, gradiente saturado Capa de salida, clasificación binaria
nn.Tanh (e^x - e^(-x))/(e^x + e^(-x)) Salida -1 a 1, centrada en cero RNN、LSTM

Preguntas frecuentes

Q1: ¿Por qué ReLU produce el problema de las "neuronas muertas"?

Cuando la entrada es continuamente negativa, la salida de ReLU es siempre 0 y el gradiente también es 0, lo que impide que estas neuronas sigan aprendiendo.

Soluciones:

  • Usarnn.LeakyReLUonn.ELUen lugar de
  • Usar una tasa de aprendizaje inicial más pequeña
  • Usar Batch Normalization

Q2: ¿Es adecuado poner ReLU en la capa de salida?

Por lo general no es adecuado. En la capa de salida se usa más comúnmenteSigmoid(clasificación) o la función identidad (regresión), porque la salida de ReLU no está acotada.


Escenarios de uso

nn.ReLUEs la función de activación más utilizada en el aprendizaje profundo; los principales escenarios de aplicación incluyen:

  • Redes neuronales convolucionales: introducir no linealidad después de la capa convolucional o de la capa completamente conectada.
  • Perceptrón multicapa: como función de activación de la capa oculta.
  • Transformer: como función de activación en FFN (Feed-Forward Network) (aunque ahora se usa más GELU).
  • Redes generativas adversariales: como función de activación del generador.

Consejo: a menos que existan requisitos especiales, al diseñar redes neuronales, ReLU es la primera opción para la función de activación de las capas ocultas.


PyTorch torch.nn 参考手册Manual de referencia de PyTorch torch.nn

Otras extensiones