Pytorch——Dropout

2022-10-02 11:06:49

1.前言

过拟合让人头疼, 明明训练时误差已经降得足够低, 可是测试的时候误差突然飙升. 这很有可能就是出现了过拟合现象.下面将用可视化的形式来对比使用Dropout和不使用Dropout的情况。

2.制造人工数据

import torchimport matplotlib.pyplotas plt

torch.manual_seed(123)#制造训练数据
x= torch.unsqueeze(torch.linspace(-1,1,40),1)
y= x+0.3*torch.normal(torch.zeros(40,1), torch.ones(40,1))#均值为0, 方差为1#制造测试数据
test_x= torch.unsqueeze(torch.linspace(-1,1,40),1)
test_y= test_x+0.3*torch.normal(torch.zeros(40,1), torch.ones(40,1))#可视化数据
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()

在这里插入图片描述

3.搭建神经网络模型

我们在这里搭建两个神经网络, 一个没有 dropout, 一个有 dropout. 没有 dropout 的容易出现 过拟合, 那我们就命名为 net_overfitting, 另一个就是 net_dropped. torch.nn.Dropout(0.5) 这里的 0.5 指的是随机有 50% 的神经元会被关闭/丢弃.

net_overfitting= torch.nn.Sequential(
    torch.nn.Linear(1,200),
    torch.nn.ReLU(),
    torch.nn.Linear(200,200),
    torch.nn.ReLU(),
    torch.nn.Linear(200,1))

net_dropped= torch.nn.Sequential(
    torch.nn.Linear(1,200),
    torch.nn.Dropout(0.5),
    torch.nn.ReLU(),
    torch.nn.Linear(200,200),
    torch.nn.Dropout(0.5),
    torch.nn.ReLU(),
    torch.nn.Linear(200,1))

4.训练模型

训练的时候, 这两个神经网络分开训练. 训练的环境都一样.

optimizer_ofit= torch.optim.Adam(net_overfitting.parameters(), lr=0.01)
optimizer_drop= torch.optim.Adam(net_dropped.parameters(), lr=0.01)

loss_func= torch.nn.MSELoss()for tinrange(500):
    pred_ofit= net_overfitting(x)
    pred_drop= net_dropped(x)
    
    loss_ofit= loss_func(pred_ofit, y)
    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()

5.可视化drop与不drop的情况

optimizer_ofit= torch.optim.Adam(net_overfitting.parameters(), lr=0.01)
optimizer_drop= torch.optim.Adam(net_dropped.parameters(), lr=0.01)

loss_func= torch.nn.MSELoss()for tinrange(500):
    pred_ofit= net_overfitting(x)
    pred_drop= net_dropped(x)
    
    loss_ofit= loss_func(pred_ofit, y)
    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()if t%10==0:#每10步画一次图#将神经网络转换成测试形式,画好图之后改回训练形式
        net_overfitting.eval()# 因为 drop 网络在 train 的时候和 test 的时候参数不一样.
        net_dropped.eval()
        
        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.5, label="train")
        plt.scatter(test_x.data.numpy(), test_y.data.numpy(),c='cyan', s=50, alpha=0.5, label="test")
        
        plt.plot(test_x.data.numpy(), test_pred_ofit.data.numpy(),'r-',lw=5)
        plt.plot(test_x.data.numpy(), test_pred_drop.data.numpy(),'b--',lw=5)
        
        plt.text(0,-1.2,'overfitting loss = %.4f'% loss_func(test_pred_ofit,test_y),fontdict={'size':20,'color':'red'})
        plt.text(0,-1.5,'dropout loss = %.4f'% loss_func(test_pred_drop,test_y),fontdict={'size':20,'color':'blue'})
        plt.legend(loc='upper left')
        plt.ylim(-2.5,2.5)
        plt.pause(0.1)#net_overfitting.train()    #预测完后,把神经网络放回去再训练#net_dropped.train()
  • 作者:程旭员
  • 原文链接:https://blog.csdn.net/weixin_37763870/article/details/104870356
    更新时间:2022-10-02 11:06:49