Función PyTorch torch.nn.ReLU
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.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.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 predeterminado
inplace=False。
Ejemplo 3: Uso en redes neuronales
En las redes neuronales convolucionales, ReLU suele ir después de la capa convolucional:
Ejemplo
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.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:
- Usar
nn.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.
Otras extensiones