Desvanecimiento y explosión de gradientes

Aprendizaje profundo intermedio con PyTorch

Michal Oleszak

Machine Learning Engineer

Gradientes de desaparición

  • Los gradientes se hacen cada vez más pequeños durante la pasada hacia atrás.
  • Las capas anteriores reciben pequeñas actualizaciones de parámetros.
  • El modelo no aprende

Gráficos que muestran el tamaño del gradiente en función del índice de capa: para las capas anteriores, los gradientes son más pequeños

Aprendizaje profundo intermedio con PyTorch

Gradientes explosivos

  • Los gradientes se hacen cada vez más grandes.
  • Las actualizaciones de los parámetros son demasiado grandes.
  • La formación diverge

Gráficos que muestran el tamaño del gradiente en función del índice de capa: para las capas anteriores, los gradientes son mayores

Aprendizaje profundo intermedio con PyTorch

Solución a gradientes inestables

  1. Inicialización correcta de los pesos
  2. Buenas activaciones
  3. Normalización por lotes

 

 

Tres pasos

Aprendizaje profundo intermedio con PyTorch

Inicialización de pesos

layer = nn.Linear(8, 1)
print(layer.weight)
Parameter containing:
tensor([[-0.0195,  0.0992,  0.0391,  0.0212,
         -0.3386, -0.1892, -0.3170,  0.2148]])
Aprendizaje profundo intermedio con PyTorch

Inicialización de pesos

Una buena inicialización garantiza:

  • Varianza de las entradas de la capa = varianza de las salidas de la capa
  • Variación de los gradientes igual antes y después de una capa

 

La forma de lograrlo depende de la activación:

  • Para ReLU y similares, podemos utilizar la inicialización He/Kaiming.
Aprendizaje profundo intermedio con PyTorch

Inicialización de pesos

import torch.nn.init as init

init.kaiming_uniform_(layer.weight)
print(layer.weight)
Parameter containing:
tensor([[-0.3063, -0.2410,  0.0588,  0.2664,
          0.0502, -0.0136,  0.2274,  0.0901]])
Aprendizaje profundo intermedio con PyTorch

Inicialización de él / Kaiming

init.kaiming_uniform_(self.fc1.weight)
init.kaiming_uniform_(self.fc2.weight)
init.kaiming_uniform_(
  self.fc3.weight,
  nonlinearity="sigmoid",
)
Aprendizaje profundo intermedio con PyTorch

Inicialización de él / Kaiming

import torch.nn as nn
import torch.nn.init as init

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(9, 16)
        self.fc2 = nn.Linear(16, 8)
        self.fc3 = nn.Linear(8, 1)


init.kaiming_uniform_(self.fc1.weight) init.kaiming_uniform_(self.fc2.weight) init.kaiming_uniform_( self.fc3.weight, nonlinearity="sigmoid", )




    def forward(self, x):
        x = nn.functional.relu(self.fc1(x))
        x = nn.functional.relu(self.fc2(x))
        x = nn.functional.sigmoid(self.fc3(x))
        return x







Aprendizaje profundo intermedio con PyTorch

Funciones de activación

Un gráfico que muestra la función ReLU. Para valores inferiores a cero, la línea es horizontal en cero; para valores superiores a cero, la curva toma una pendiente positiva.

  • A menudo utilizado como activación predeterminada.
  • nn.functional.relu()
  • Cero para entradas negativas: neuronas moribundas.

Un gráfico que muestra la función ELU. Es similar a la función ReLU, pero con una transición curva y suave de los valores negativos a la región positiva.

  • nn.functional.elu()
  • Gradientes distintos de cero para valores negativos: ayuda a evitar la muerte de las neuronas.
  • Salida media cercana a cero: ayuda a evitar los gradientes de desaparición.
Aprendizaje profundo intermedio con PyTorch

Normalización por lotes

Después de una capa:

  1. Normaliza las salidas de la capa mediante:

    • Restar la media
    • Dividir por la desviación estándar
  2. Escala y cambia las salidas normalizadas utilizando los parámetros aprendidos.

El modelo aprende la distribución óptima de entradas para cada capa:

  • Disminución más rápida de la pérdida
  • Ayuda contra los gradientes inestables.
Aprendizaje profundo intermedio con PyTorch

Normalización por lotes

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(9, 16)
        self.bn1 = nn.BatchNorm1d(16)

        ...


def forward(self, x): x = self.fc1(x) x = self.bn1(x) x = nn.functional.elu(x) ...
Aprendizaje profundo intermedio con PyTorch

¡Vamos a practicar!

Aprendizaje profundo intermedio con PyTorch

Preparing Video For Download...