Operaciones de regularización, recorte de gradiente e inicialización de sesgo en modelos profundos

Recientemente, depuré el código y descubrí que no importa cómo depurarlo, pensé en usar algunos métodos de optimización y luego no sabía los detalles específicos de estos métodos de optimización, así que aprendí un poco y lo grabé aquí para referencia futura.

regularización

Métodos de regularización comúnmente utilizados

regularización L1

La regularización L1 es un método de regularización basado en la norma L1, y su fórmula matemática es:

L = L datos + λ ∑ i = 1 norte ∣ wi ∣ L = L_{datos} + \lambda \sum_{i=1}^n |w_i|L=Ldatos _ _ _+yoyo = 1nwyo

donde L datos L_{datos}Ldatos _ _ _es la pérdida de datos, wi w_iwyoes el parámetro del modelo, λ \lambdaλ es un parámetro de regularización. El papel de la regularización L1 es castigar el valor absoluto de los parámetros del modelo, de modo que algunos parámetros se conviertan en 0, para lograr el efecto de selección de características y reducir la complejidad del modelo.

regularización L2

La regularización L2 es un método de regularización basado en la norma L2, y su fórmula matemática es:

L = L datos + λ ∑ i = 1 nwi 2 L = L_{datos} + \lambda \sum_{i=1}^n w_i^2L=Ldatos _ _ _+yoyo = 1nwi2

donde L datos L_{datos}Ldatos _ _ _es la pérdida de datos, wi w_iwyoes el parámetro del modelo, λ \lambdaλ es un parámetro de regularización. El papel de la regularización L2 es castigar la suma de los cuadrados de los parámetros del modelo, suavizando la distribución del peso del modelo, reduciendo la complejidad del modelo y evitando el sobreajuste.

Regularización de la deserción

La regularización por abandono es un método de regularización por desactivación aleatoria, y su fórmula matemática es:

y = 1 1 − pags × x × mi = \frac{1}{1-p} \times x \times my=1pag1×X×metro

donde ppp es la probabilidad de retener el nodo,xxx es la entrada,mmm es una máscara binarizada, que indica qué nodos se conservan y qué nodos se desactivan aleatoriamente. La función de la regularización de Dropout es descartar aleatoriamente algunos nodos, reduciendo así la coadaptación en el modelo y evitando el sobreajuste.

aumento de datos

El aumento de datos es un método de regularización basado en el aumento de datos, y su fórmula matemática es:

xaug = f ( x ) x_{aug} = f(x)Xun ug=f ( x )

donde xxx son los datos originales,fff es la función de mejora de datos,xaug x_{aug}Xun ugpara los datos mejorados. El aumento de datos puede expandir el conjunto de datos recortando, rotando, volteando, escalando, etc. de forma aleatoria, para mejorar la capacidad de generalización del modelo y evitar el sobreajuste.

Regularización de norma máxima del kernel

https://github.com/kevinzakka/pytorch-goodies#max-norm-constraint

Mejora de las redes neuronales al evitar la coadaptación de los detectores de características

La regularización de norma máxima del núcleo es un método de regularización de uso común, que puede limitar la norma máxima del valor de peso de cada núcleo de convolución en la red neuronal, para controlar el grado de sobreajuste.

La regularización de norma máxima del núcleo solo es válida durante el entrenamiento, por lo que debe establecer los parámetros correspondientes al compilar el modelo. No necesita usar este método de regularización al realizar pruebas o predicciones.

Si la norma L2 del vector de peso de una unidad oculta LLL nunca se vuelve más grande que un cierto valor máximoccc , multiplica el vector de pesos porc / L c/Lc / L . Aplicarlo inmediatamente después de cada actualización del vector de peso o después de cadaXXActualización de gradiente X.

Esta restricción es otra forma de regularización. Mientras que L2 penaliza los pesos elevados mediante la función loss, “max norm” actúa directamente sobre los pesos. L2 ejerce una presión constante para mover los pesos cerca de cero, lo que podría arrojar información útil cuando la función de pérdida no brinda incentivos para que los pesos permanezcan lejos de cero. Por otro lado, la "norma máxima" nunca lleva los pesos a casi cero. Siempre que la norma sea menor que el valor de la restricción, la restricción no tiene efecto.

El primer método de implementación:

def max_norm(model, max_val=3, eps=1e-8):
    for name, param in model.named_parameters():
        if 'bias' not in name:
            norm = param.norm(2, dim=0, keepdim=True)
            desired = torch.clamp(norm, 0, max_val)
            param = param * (desired / (eps + norm))

El segundo método de implementación:

class Conv2dWithConstraint(nn.Conv2d):
    def __init__(self, *args, doWeightNorm = True, max_norm=1, **kwargs):
        self.max_norm = max_norm
        self.doWeightNorm = doWeightNorm
        super(Conv2dWithConstraint, self).__init__(*args, **kwargs)

    def forward(self, x):
        if self.doWeightNorm: 
            self.weight.data = torch.renorm(
                self.weight.data, p=2, dim=0, maxnorm=self.max_norm
            )
        return super(Conv2dWithConstraint, self).forward(x)

class Conv1dWithConstraint(nn.Conv1d):
    def __init__(self, *args, doWeightNorm = True, max_norm=1, **kwargs):
        self.max_norm = max_norm
        self.doWeightNorm = doWeightNorm
        super(Conv1dWithConstraint, self).__init__(*args, **kwargs)

    def forward(self, x):
        if self.doWeightNorm: 
            self.weight.data = torch.renorm(
                self.weight.data, p=2, dim=0, maxnorm=self.max_norm
            )
        return super(Conv1dWithConstraint, self).forward(x)


class LinearWithConstraint(nn.Linear):
    def __init__(self, *args, doWeightNorm = True, max_norm=1, **kwargs):
        self.max_norm = max_norm
        self.doWeightNorm = doWeightNorm
        super(LinearWithConstraint, self).__init__(*args, **kwargs)

    def forward(self, x):
        if self.doWeightNorm: 
            self.weight.data = torch.renorm(
                self.weight.data, p=2, dim=0, maxnorm=self.max_norm
            )
        return super(LinearWithConstraint, self).forward(x)

¿Cuál es el principio de agregar la regularización de L1 y L2 a la pérdida para lograr el efecto de evitar el sobreajuste?

Agregar un término de regularización a la función de pérdida es una forma común de evitar el sobreajuste. El principio básico es 对模型参数进行约束reducir la complejidad del modelo en , para evitar que el modelo sobreajuste los datos de entrenamiento.

En concreto, el término de regularización suele tener dos formas: regularización L1 y regularización L2. La regularización L1 consiste en utilizar el valor absoluto del parámetro del modelo como término de regularización, y la regularización L2 consiste en utilizar el cuadrado del parámetro del modelo como término de regularización. 在损失函数中加入正则化项后,优化器在训练模型时不仅需要最小化损失函数的输出值,还需要最小化正则化项的输出值,从而使得模型参数尽量接近于0.

El efecto de agregar un término de regularización es evitar que el valor de los parámetros del modelo sea demasiado grande, evitando así que el modelo sobreajuste los datos de entrenamiento . Esto se debe a que cuando los parámetros del modelo son demasiado grandes, el modelo se sobreajustará a los datos de entrenamiento y no podrá generalizar a los datos de prueba. A través de las restricciones del término de regularización, el valor de los parámetros del modelo se controlará dentro de un rango más pequeño, haciendo que el modelo sea más generalizable.

Cabe señalar que la fuerza de la restricción del término de regularización está controlada por el parámetro de regularización, es decir, cuanto mayor es el parámetro de regularización, más cercano a 0 es el valor del parámetro del modelo . Sin embargo, un parámetro de regularización demasiado grande también puede dar lugar a un ajuste insuficiente del modelo, por lo que es necesario seleccionar un parámetro de regularización apropiado según la situación específica.

¿Cuál es la diferencia entre la regularización L1 y la regularización L2?

La regularización de L1 se logra imponiendo restricciones a la norma L1 sobre los parámetros de peso. Específicamente, la regularización L1 consiste en sumar el valor absoluto de cada elemento en el parámetro de peso y luego multiplicarlo por un coeficiente de regularización λ para obtener un término de regularización, que se suma a la función objetivo. 通过L1正则化可以使得部分权重参数变成0,从而实现特征选择的效果,即去除对模型影响较小的特征.

La regularización de L2 se logra imponiendo una restricción a la norma L2 sobre los parámetros de peso. Específicamente, la regularización L2 consiste en sumar el cuadrado de cada elemento en el parámetro de peso y luego multiplicarlo por un coeficiente de regularización λ para obtener un término de regularización, que se suma a la función objetivo. 通过L2正则化可以使得权重参数的值变得更加平滑,从而减少模型的复杂度,提高模型的泛化性能.

¿Qué efecto tiene el valor del coeficiente de regularización λ sobre el modelo?

  1. Cuando el coeficiente de regularización λ es pequeño, la capacidad de ajuste del modelo es más fuerte y los datos de entrenamiento se pueden ajustar mejor, pero puede ocurrir el problema de sobreajuste, lo que hace que el modelo tenga un rendimiento deficiente en los datos de prueba.
  2. Cuando el coeficiente de regularización λ es grande, la capacidad de ajuste del modelo es débil, lo que puede evitar el problema de ajuste excesivo, pero puede ocurrir el problema de ajuste insuficiente, lo que resulta en un rendimiento deficiente del modelo en los datos de entrenamiento.

Cómo determinar el mejor valor del coeficiente de regularización λ

Determinar el valor óptimo del coeficiente de regularización λ es un problema común en el aprendizaje profundo. Hay muchas maneras de resolver este problema. Aquí hay algunos métodos de uso común:

Búsqueda de cuadrícula

La búsqueda en cuadrícula es un método simple pero efectivo que se puede utilizar para encontrar el mejor coeficiente de regularización λ. Específicamente, primero se puede definir un conjunto de coeficientes de regularización candidatos λ, luego se realiza una búsqueda exhaustiva entre estos valores y finalmente se selecciona el coeficiente de regularización λ que hace que el modelo funcione mejor en el conjunto de validación.

Búsqueda aleatoria

La búsqueda aleatoria es un método más eficiente que se puede utilizar para encontrar el mejor coeficiente de regularización λ. Específicamente, primero puede definir una distribución del valor de un conjunto de coeficientes de regularización λ, luego muestrear aleatoriamente estas distribuciones y finalmente seleccionar el coeficiente de regularización λ que hace que el modelo funcione mejor en el conjunto de validación.

Validación cruzada

La validación cruzada es un método común que se puede utilizar para evaluar el rendimiento de generalización del modelo y elegir el mejor coeficiente de regularización λ. Específicamente, el conjunto de datos se puede dividir en conjunto de entrenamiento y conjunto de validación, luego entrenar el modelo en el conjunto de entrenamiento, usar el conjunto de validación para seleccionar el mejor coeficiente de regularización λ y finalmente usar el conjunto de prueba para evaluar el rendimiento de generalización del modelo. .

Regularización Adaptativa de Pesos

La tasa de aprendizaje adaptativo con regularización es una forma efectiva de optimizar los parámetros de peso y el coeficiente de regularización λ simultáneamente. Específicamente, se puede agregar un término de penalización a la función de pérdida para que los parámetros de peso se optimicen junto con el coeficiente de regularización λ. Este método puede ajustar automáticamente el valor del coeficiente de regularización λ para obtener un mejor rendimiento de generalización.

Cómo agregar la regularización L2 al modelo

El siguiente es un código de muestra que usa PyTorch para definir un marco de aprendizaje profundo simple y agrega la regularización L2:

import torch
import torch.nn as nn
import torch.optim as optim

# 定义模型
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(784, 64)
        self.fc2 = nn.Linear(64, 10)

    def forward(self, x):
        x = x.view(-1, 784)
        x = nn.functional.relu(self.fc1(x))
        x = self.fc2(x)
        return x

# 创建模型实例
model = Net()

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, weight_decay=0.01)

# 训练模型
for epoch in range(10):
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        inputs, labels = data

        # 梯度清零
        optimizer.zero_grad()

        # 前向传播
        outputs = model(inputs)

        # 计算损失
        loss = criterion(outputs, labels)

        # 反向传播
        loss.backward()

        # 更新参数
        optimizer.step()

        running_loss += loss.item()

    print('Epoch %d, loss: %.3f' % (epoch + 1, running_loss / len(trainloader)))

Después de configurar el parámetro weight_decay en el optimizador, el optimizador agregará automáticamente el término de regularización a la actualización del gradiente, logrando así la regularización L2.

¿El parámetro weight_decay en la función de optimización en pytorch regulariza todos los parámetros en la red?

En PyTorch, el parámetro weight_decay en el optimizador se usa para controlar la fuerza de la regularización L2 (también conocida como disminución de peso). Cuando se establece el parámetro weight_decay, el optimizador realizará la regularización L2 en todos los parámetros cada vez que se actualicen , es decir, multiplicará el valor de actualización de cada parámetro por un factor menor que 1, y este factor es el valor del parámetro weight_decay . Por lo tanto, el parámetro weight_decay regulariza todos los parámetros de la red.

Cabe señalar que el parámetro weight_decay tiene diferentes significados para diferentes optimizadores. En optimizadores como SGD y Adam, el parámetro weight_decay controla la fuerza de la regularización L2 ; en optimizadores como RMSprop, el parámetro weight_decay controla el coeficiente de regularización L2 . Por lo tanto, cuando se utilizan diferentes optimizadores, es necesario ajustar el valor del parámetro weight_decay según la situación específica para obtener un mejor rendimiento de generalización. Además, algunos optimizadores también proporcionan otros métodos de regularización, como los optimizadores AdamW y LAMB, que pueden controlar aún más el efecto de la regularización cuando se usan estos optimizadores.

¿Cuál es la diferencia en el significado del parámetro weight_decay en optimizadores como SGD y Adam y en optimizadores como RMSprop?

En optimizadores como SGD y Adam, el parámetro weight_decay generalmente se usa para controlar la fuerza de la regularización L2. Específicamente, weight_decay参数会在每次参数更新时对参数值进行衰减,从而使得权重参数尽量分散,防止过拟合. En SGD y Adam, el parámetro weight_decay es equivalente a agregar un término de regularización L2 a la función de pérdida, es decir, multiplicar la suma de los cuadrados del peso por un coeficiente de disminución del peso, restringiendo así la norma del parámetro de peso.

En optimizadores como RMSprop, el significado del parámetro weight_decay es diferente y se utiliza para controlar el coeficiente de regularización L2. Específicamente, weight_decay参数会在计算梯度平方的移动平均值时,对其进行加权衰减,从而使得梯度的范数尽量分散,防止过拟合. En RMSprop, el parámetro weight_decay es equivalente a agregar un término de regularización L2 por encima del gradiente, es decir, multiplicar la suma de los cuadrados del peso por un coeficiente de disminución del peso, restringiendo así la norma del parámetro de peso.

¿Cuál es la diferencia entre el algoritmo de optimización de Adam y el algoritmo de optimización de AdamW?

El decaimiento de peso en el algoritmo de optimización de Adam se implementa en base a la regularización L2, es decir, el parámetro de peso se multiplica por un coeficiente de decaimiento de peso cada vez que se actualiza el parámetro. Sin embargo, este método hará que la actualización de los parámetros de peso esté sujeta a mayores restricciones 特别是在学习率较小时,可能会导致模型的收敛速度减慢.

Para resolver este problema, el algoritmo de optimización de AdamW propone un nuevo método de caída de peso. En AdamW, el decaimiento de peso se implementa en función de la suma ponderada de la regularización de L2 y el decaimiento de peso , es decir, en cada actualización de parámetro, el parámetro de peso se multiplica por una suma ponderada de un coeficiente de regularización de L2 y un coeficiente de decaimiento de peso. De esta manera funciona 缓解权重参数更新受到较大约束的问题,同时还可以防止过拟合.

Excepto por el diferente manejo de la disminución del peso, AdamW y Adam son básicamente iguales en otros aspectos. Todos son algoritmos de optimización basados ​​en la tasa de aprendizaje adaptable, que pueden ajustar automáticamente la tasa de aprendizaje para adaptarse a diferentes modelos y conjuntos de datos. Además, ambos pueden manejar problemas como gradientes escasos y funciones objetivo no estacionarias.

En términos de aplicación, el algoritmo de optimización de Adam es más adecuado para la mayoría de las tareas de aprendizaje profundo, especialmente para modelos con muchos parámetros , el rendimiento de Adam suele ser mejor que los algoritmos de optimización básicos como SGD. El algoritmo de optimización de AdamW es más adecuado para tratar el problema de la disminución del peso, especialmente cuando la tasa de aprendizaje es pequeña . AdamW puede controlar mejor la actualización de los parámetros de peso, mejorando así el rendimiento de generalización del modelo. Por lo tanto, en tareas que requieran decaimiento de peso, el uso de AdamW puede lograr un mejor rendimiento.

Cómo agregar un término de regularización a cierta capa del modelo

Aquí hay un código de ejemplo que demuestra cómo implementar la regularización de una capa en PyTorch:

import torch
import torch.nn as nn
import torch.optim as optim

# 定义模型
class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.lin1 = nn.Linear(10, 10)
        self.lin2 = nn.Linear(10, 5)
    
    def forward(self, x):
        x = self.lin1(x)
        x = nn.functional.relu(x)
        x = self.lin2(x)
        return x

model = MyModel()

# 定义正则化项的权重
weight_decay = 0.01

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 训练模型
for epoch in range(10):
    running_loss = 0.0
    for i in range(100):
        # 获取数据和标签
        inputs = torch.randn(10)
        labels = torch.randint(0, 5, (1,)).long()
        
        # 清空梯度
        optimizer.zero_grad()
        
        # 前向传播和计算损失
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        
        # 计算正则化项
        reg_loss = 0.0
        for name, param in model.named_parameters():
            if 'weight' in name:
                reg_loss += torch.norm(param, p=2)**2
                
        # 总损失为交叉熵损失加上正则化项
        total_loss = loss + weight_decay * reg_loss
        
        # 反向传播和计算梯度
        total_loss.backward()
        
        # 更新参数
        optimizer.step()
        
        running_loss += loss.item()
    
    print("Epoch %d, loss: %.3f" % (epoch+1, running_loss/100))

En el código anterior, primero definimos un modelo simple llamado MyModel, que contiene dos capas completamente conectadas. A continuación, definimos el peso peso_decaimiento del término de regularización. Durante el proceso de entrenamiento, al calcular la pérdida total, sumamos el producto de la pérdida de entropía cruzada y el término de regularización a la pérdida total para lograr la regularización de una determinada capa.

Cabe señalar que para diferentes modelos y tareas, el tipo y el peso del término de regularización más adecuado pueden ser diferentes. Por lo general, podemos encontrar una estrategia de regularización adecuada probando diferentes métodos de regularización y valores de peso, para lograr un mejor rendimiento del modelo.

Agregue clip_grad_norm_ al modelo

El siguiente es un código de ejemplo que usa el marco PyTorch que demuestra cómo usar la función torch.nn.utils.clip_grad_norm_() para recortar gradientes durante el entrenamiento del modelo:

import torch
import torch.nn as nn
import torch.optim as optim

# 定义模型
class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.lin1 = nn.Linear(10, 10)
        self.lin2 = nn.Linear(10, 5)
    
    def forward(self, x):
        x = self.lin1(x)
        x = nn.functional.relu(x)
        x = self.lin2(x)
        return x

model = MyModel()

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 训练模型
for epoch in range(10):
    running_loss = 0.0
    for i in range(100):
        # 获取数据和标签
        inputs = torch.randn(10)
        labels = torch.randint(0, 5, (1,)).long()
        
        # 清空梯度
        optimizer.zero_grad()
        
        # 前向传播和计算损失
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        
        # 反向传播和计算梯度
        loss.backward()
        
        # 对梯度进行裁剪
        nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
        
        # 更新参数
        optimizer.step()
        
        running_loss += loss.item()
    
    print("Epoch %d, loss: %.3f" % (epoch+1, running_loss/100))

En el código anterior, primero definimos un modelo simple llamado MyModel, que contiene dos capas completamente conectadas. A continuación, definimos la función de pérdida y el optimizador, y comenzamos a entrenar el modelo. Durante el proceso de retropropagación de cada minilote de datos, usamos la función nn.utils.clip_grad_norm_() para recortar el gradiente del modelo y evitar el problema de la explosión del gradiente. Después de esto, llamamos a la función step() del optimizador para actualizar los parámetros del modelo.

Cabe señalar que para diferentes modelos y tareas, el umbral de recorte de gradiente más adecuado puede ser diferente. Por lo general, podemos encontrar un rango de recorte adecuado ajustando el tamaño del umbral para lograr un mejor rendimiento del modelo.

¿Cuál es el papel de la regularización y el recorte de gradiente, cuál es la diferencia y en qué circunstancias se utilizan?

La regularización y el recorte de gradientes son técnicas de optimización de modelos comúnmente utilizadas, y su función es evitar el problema del sobreajuste del modelo o la explosión de gradientes. Si bien ambas tecnologías tienen un propósito similar, se implementan y utilizan en situaciones ligeramente diferentes.

El papel de la regularización es evitar el problema del sobreajuste del modelo añadiendo restricciones a los parámetros del modelo en la función de pérdida . Los métodos de regularización comunes incluyen la regularización L1, la regularización L2, etc. En el proceso de implementación, podemos agregar un elemento de regularización (como la norma del peso) a la función de pérdida para penalizar el tamaño de los parámetros del modelo, a fin de realizar las restricciones en el modelo. La regularización generalmente se aplica durante el entrenamiento del modelo para reducir el error de generalización del modelo.

La función del recorte de degradado es evitar el problema de la explosión de degradado limitando el degradado del modelo . Cuando el gradiente del modelo es demasiado grande, podemos limitarlo a un rango razonable recortando el gradiente, evitando así una actualización excesiva de los parámetros del modelo. El recorte de degradado generalmente se aplica en el proceso de retropropagación del optimizador para evitar el impacto de la explosión de degradado en el modelo.

la diferencia:

  1. La regularización es para restringir los parámetros del modelo, mientras que el recorte de degradado es para limitar el degradado.
  2. La regularización puede evitar el sobreajuste del modelo y el recorte de degradado puede evitar la explosión de degradado.
  3. La regularización generalmente se aplica durante el entrenamiento del modelo, mientras que el recorte de gradiente generalmente se aplica durante la retropropagación del optimizador.

Escenas a utilizar:

  1. La regularización generalmente se aplica cuando el modelo está sobreajustado.Cuando el modelo funciona bien en el conjunto de entrenamiento, pero no funciona bien en el conjunto de prueba, puede intentar usar técnicas de regularización.
  2. El recorte de degradado generalmente se aplica a la situación en la que el modelo tiene una explosión de degradado. Cuando el degradado del modelo es demasiado grande, la actualización de los parámetros del modelo es demasiado drástica y afecta el rendimiento del modelo, puede intentar usar el degradado técnica de recorte.

Inicialice el sesgo de la capa convolucional a 0

En la mayoría de los marcos de aprendizaje profundo, esto se puede lograr configurando el parámetro de inicialización de sesgo de la capa convolucional en 0. Aquí hay un código de ejemplo que usa Python y el marco PyTorch:

import torch.nn as nn

# 定义卷积层(具体参数可以根据实际情况进行修改)
conv_layer = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, stride=1, padding=1, bias=True)

# 将卷积层的偏置初始化为0
conv_layer.bias.data.fill_(0.0)

En el código anterior, primero usamos el marco PyTorch para definir una capa convolucional conv_layer y especificamos que la capa debe contener un sesgo a través del parámetro bias=True. A continuación, inicializamos el sesgo de la capa convolucional a 0 a través de conv_layer.bias.data.fill_(0.0).

Supongo que te gusta

Origin blog.csdn.net/qq_41990294/article/details/130240722
Recomendado
Clasificación