Aprendizaje profundo: sobreajuste y abandono

concepto basico

¿Qué es el sobreajuste?

El sobreajuste es uno de los problemas comunes en el aprendizaje automático y el aprendizaje profundo. Se refiere al fenómeno de que el modelo se desempeña bien en los datos de entrenamiento, pero se desempeña mal en los nuevos datos no vistos.
El sobreajuste ocurre cuando un modelo aprende demasiado los detalles y el ruido de los datos de entrenamiento, mientras ignora las regularidades y patrones generales en los datos. El sobreajuste se debe a que el modelo es demasiado complejo o tiene muy pocos datos de entrenamiento, lo que hace que el modelo memorice todos los detalles de los datos de entrenamiento y, por lo tanto, no pueda generalizar a nuevos datos.

Solución

1. Aumentar la cantidad de datos de entrenamiento: al agregar más datos de entrenamiento, el modelo puede aprender mejor las leyes generales de los datos, en lugar de depender demasiado de una pequeña cantidad de muestras de datos.
2. Simplifique el modelo: reduzca la complejidad del modelo, como reducir la cantidad de capas de la red, reducir la cantidad de nodos, reducir la cantidad de parámetros, etc., reduciendo así el riesgo de sobreajuste.
3. Usar técnicas de regularización: como regularización L1, regularización L2, etc., agregando elementos de regularización a la función de pérdida para castigar los pesos excesivos y evitar que el modelo sobreajuste los datos de entrenamiento.
4. Use Dropout: descarte aleatoriamente algunas neuronas durante el entrenamiento para reducir la complejidad del modelo y ayudar a prevenir el sobreajuste.
5. Validación cruzada: use la validación cruzada para evaluar el rendimiento del modelo y evalúe la capacidad de generalización del modelo a través de diferentes subconjuntos de conjuntos de entrenamiento y conjuntos de prueba.

Abandonar

El abandono es una técnica de regularización que se utiliza para reducir los problemas de sobreajuste y, a menudo, se utiliza en el entrenamiento de redes neuronales profundas. es un método para dejar caer neuronas al azar.
En una red neuronal normal, cada neurona realiza el cálculo del peso y la transmisión de la entrada, por lo que cada neurona puede contribuir demasiado, lo que hace que la red se sobreajuste a los datos de entrenamiento. Dropout descarta aleatoriamente algunas neuronas durante el proceso de entrenamiento, es decir, establece la salida de algunas neuronas en 0 con cierta probabilidad durante el proceso de propagación hacia adelante, lo que puede obligar a la red neuronal a aprender características más sólidas.

Comparación de agregar una capa de abandono y no agregar una capa de abandono

import torch
import matplotlib.pyplot as plt

# 用于复现
# torch.manual_seed(1)    # reproducible

# 20个数据点
N_SAMPLES = 20
# 隐藏层的个数为300
N_HIDDEN = 300

# training data
# 在-1到1之间等差取N_SAMPLES个点,然后再加维度,最终的数据变为N_SAMPLES行、1列的向量
x = torch.unsqueeze(torch.linspace(-1, 1, N_SAMPLES), 1)
# 在均值为0、标准差为1的正态分布中采样N_SAMPLES个点的值,然后乘0.3,加上x,最后得到x对应的y值
y = x + 0.3*torch.normal(torch.zeros(N_SAMPLES, 1), torch.ones(N_SAMPLES, 1))

# test data
test_x = torch.unsqueeze(torch.linspace(-1, 1, N_SAMPLES), 1)
test_y = test_x + 0.3*torch.normal(torch.zeros(N_SAMPLES, 1), torch.ones(N_SAMPLES, 1))

# show data
plt.scatter(x.data.numpy(), y.data.numpy(), c='magenta', s=50, alpha=0.5, label='train')
plt.scatter(test_x.data.numpy(), test_y.data.numpy(), c='cyan', s=50, alpha=0.5, label='test')
plt.legend(loc='upper left')
plt.ylim((-2.5, 2.5))
plt.show()

# 快速搭建神经网络,不加dropout层
net_overfitting = torch.nn.Sequential(
    torch.nn.Linear(1, N_HIDDEN),
    torch.nn.ReLU(),
    torch.nn.Linear(N_HIDDEN, N_HIDDEN),
    torch.nn.ReLU(),
    torch.nn.Linear(N_HIDDEN, 1),
)

# 加了dropout层的
net_dropped = torch.nn.Sequential(
    torch.nn.Linear(1, N_HIDDEN),
    torch.nn.Dropout(0.5),  # drop 50% of the neuron
    torch.nn.ReLU(),
    torch.nn.Linear(N_HIDDEN, N_HIDDEN),
    torch.nn.Dropout(0.5),  # drop 50% of the neuron
    torch.nn.ReLU(),
    torch.nn.Linear(N_HIDDEN, 1),
)

print(net_overfitting)  # net architecture
print(net_dropped)

# 使用Adam优化神经网络的参数
optimizer_ofit = torch.optim.Adam(net_overfitting.parameters(), lr=0.01)
optimizer_drop = torch.optim.Adam(net_dropped.parameters(), lr=0.01)
# 误差函数使用MSELoss
loss_func = torch.nn.MSELoss()

# 开启交互式绘图
plt.ion()   # something about plotting

# 训练五百步
for t in range(500):
    # 将x输入到不加dropout层的神经网络中,得预测值
    pred_ofit = net_overfitting(x)
    # 将x输入到加了dropout层的神经网络中,得预测值
    pred_drop = net_dropped(x)
    # 计算loss
    loss_ofit = loss_func(pred_ofit, y)
    # 计算loss
    loss_drop = loss_func(pred_drop, y)

    # 梯度清零
    optimizer_ofit.zero_grad()
    optimizer_drop.zero_grad()
    # 误差反向传播
    loss_ofit.backward()
    loss_drop.backward()
    # 优化器逐步优化
    optimizer_ofit.step()
    optimizer_drop.step()

    # 每10步进行更新
    if t % 10 == 0:
        """
            net_overfitting.eval()和net_dropped.eval()是将两个神经网络模型切换到评估模式,
            用于在测试数据上进行稳定的前向传播,得到准确的预测结果。
        """
        # change to eval mode in order to fix drop out effect
        net_overfitting.eval()
        net_dropped.eval()  # parameters for dropout differ from train mode

        # plotting
        plt.cla()
        test_pred_ofit = net_overfitting(test_x)
        test_pred_drop = net_dropped(test_x)
        plt.scatter(x.data.numpy(), y.data.numpy(), c='magenta', s=50, alpha=0.3, label='train')
        plt.scatter(test_x.data.numpy(), test_y.data.numpy(), c='cyan', s=50, alpha=0.3, label='test')
        plt.plot(test_x.data.numpy(), test_pred_ofit.data.numpy(), 'r-', lw=3, label='overfitting')
        plt.plot(test_x.data.numpy(), test_pred_drop.data.numpy(), 'b--', lw=3, label='dropout(50%)')
        plt.text(0, -1.2, 'overfitting loss=%.4f' % loss_func(test_pred_ofit, test_y).data.numpy(), fontdict={
    
    'size': 20, 'color':  'red'})
        plt.text(0, -1.5, 'dropout loss=%.4f' % loss_func(test_pred_drop, test_y).data.numpy(), fontdict={
    
    'size': 20, 'color': 'blue'})
        plt.legend(loc='upper left')
        plt.ylim((-2.5, 2.5))
        plt.pause(0.1)

        # change back to train mode
        """
            在训练模式下,神经网络中的Dropout层将会生效,即在前向传播过程中会随机丢弃一部分神经元。
            这是为了在训练阶段增加模型的鲁棒性,避免过拟合。
        """
        net_overfitting.train()
        net_dropped.train()

# 关闭交互模式
plt.ioff()
plt.show()

resultado de ejecución

inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/Elon15/article/details/131884963
Recomendado
Clasificación