pytorch Dropout过拟合的操作


Posted in Python onMay 27, 2021

如下所示:

pytorch Dropout过拟合的操作

import torch
from torch.autograd import Variable
import matplotlib.pyplot as plt
torch.manual_seed(1)
N_SAMPLES = 20
N_HIDDEN = 300
# training data
x = torch.unsqueeze(torch.linspace(-1, 1, N_SAMPLES), 1)
y = x + 0.3 * torch.normal(torch.zeros(N_SAMPLES, 1), torch.ones(N_SAMPLES, 1))
x, y = Variable(x), Variable(y)
# 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))
test_x = Variable(test_x, volatile=True)
test_y = Variable(test_y, volatile=True)
# 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()
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),
)
net_dropped = torch.nn.Sequential(
    torch.nn.Linear(1, N_HIDDEN),
    torch.nn.Dropout(0.5),
    torch.nn.ReLU(),
    torch.nn.Linear(N_HIDDEN, N_HIDDEN),
    torch.nn.Dropout(0.5),
    torch.nn.ReLU(),
    torch.nn.Linear(N_HIDDEN, 1),
)
print(net_overfitting)
print(net_dropped)
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()
plt.ion()
for t in range(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:
        net_overfitting.eval()
        net_dropped.eval()
        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[0], fontdict={'size': 20, 'color':  'red'})
        plt.text(0, -1.5, 'dropout loss=%.4f' % loss_func(test_pred_drop, test_y).data[0], 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()
plt.ioff()
plt.show()

补充:pytorch避免过拟合-dropout丢弃法的实现

对于一个单隐藏层的多层感知机,其中输入个数为4,隐藏单元个数为5,且隐藏单元pytorch Dropout过拟合的操作的计算表达式为:

pytorch Dropout过拟合的操作

pytorch Dropout过拟合的操作

开始实现drop丢弃法避免过拟合

定义dropout函数:

%matplotlib inline
import torch
import torch.nn as nn
import numpy as np
def dropout(X, drop_prob):
    X = X.float()
    assert 0 <= drop_prob <= 1
    keep_prob = 1 - drop_prob
    # 这种情况下把全部元素都丢弃
    if keep_prob == 0:
        return torch.zeros_like(X)
    mask = (torch.rand(X.shape) < keep_prob).float()
    return mask * X / keep_prob

定义模型参数:

num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256, 256
W1 = torch.tensor(np.random.normal(0, 0.01, size=(num_inputs, num_hiddens1)), dtype=torch.float, requires_grad=True)
b1 = torch.zeros(num_hiddens1, requires_grad=True)
W2 = torch.tensor(np.random.normal(0, 0.01, size=(num_hiddens1, num_hiddens2)), dtype=torch.float, requires_grad=True)
b2 = torch.zeros(num_hiddens2, requires_grad=True)
W3 = torch.tensor(np.random.normal(0, 0.01, size=(num_hiddens2, num_outputs)), dtype=torch.float, requires_grad=True)
b3 = torch.zeros(num_outputs, requires_grad=True)
params = [W1, b1, W2, b2, W3, b3]

定义模型将全连接层和激活函数ReLU串起来,并对每个激活函数的输出使用丢弃法。

分别设置各个层的丢弃概率。通常的建议是把靠近输入层的丢弃概率设得小一点。

在这个实验中,我们把第一个隐藏层的丢弃概率设为0.2,把第二个隐藏层的丢弃概率设为0.5。

我们可以通过参数is_training来判断运行模式为训练还是测试,并只在训练模式下使用丢弃法。

drop_prob1, drop_prob2 = 0.2, 0.5
def net(X, is_training=True):
    X = X.view(-1, num_inputs)
    H1 = (torch.matmul(X, W1) + b1).relu()
    if is_training:  # 只在训练模型时使用丢弃法
        H1 = dropout(H1, drop_prob1)  # 在第一层全连接后添加丢弃层
    H2 = (torch.matmul(H1, W2) + b2).relu()
    if is_training:
        H2 = dropout(H2, drop_prob2)  # 在第二层全连接后添加丢弃层
    return torch.matmul(H2, W3) + b3
def evaluate_accuracy(data_iter, net):
    acc_sum, n = 0.0, 0
    for X, y in data_iter:
        if isinstance(net, torch.nn.Module):
            net.eval() # 评估模式, 这会关闭dropout
            acc_sum += (net(X).argmax(dim=1) == y).float().sum().item()
            net.train() # 改回训练模式
        else: # 自定义的模型
            if('is_training' in net.__code__.co_varnames): # 如果有is_training这个参数
                # 将is_training设置成False
                acc_sum += (net(X, is_training=False).argmax(dim=1) == y).float().sum().item() 
            else:
                acc_sum += (net(X).argmax(dim=1) == y).float().sum().item() 
        n += y.shape[0]
    return acc_sum / n

训练和测试模型:

num_epochs, lr, batch_size = 5, 100.0, 256
loss = torch.nn.CrossEntropyLoss()
def load_data_fashion_mnist(batch_size, resize=None, root='~/Datasets/FashionMNIST'):
    """Download the fashion mnist dataset and then load into memory."""
    trans = []
    if resize:
        trans.append(torchvision.transforms.Resize(size=resize))
    trans.append(torchvision.transforms.ToTensor())
    
    transform = torchvision.transforms.Compose(trans)
    mnist_train = torchvision.datasets.FashionMNIST(root=root, train=True, download=True, transform=transform)
    mnist_test = torchvision.datasets.FashionMNIST(root=root, train=False, download=True, transform=transform)
    if sys.platform.startswith('win'):
        num_workers = 0  # 0表示不用额外的进程来加速读取数据
    else:
        num_workers = 4
    train_iter = torch.utils.data.DataLoader(mnist_train, batch_size=batch_size, shuffle=True, num_workers=num_workers)
    test_iter = torch.utils.data.DataLoader(mnist_test, batch_size=batch_size, shuffle=False, num_workers=num_workers)
    return train_iter, test_iter
def train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size,
              params=None, lr=None, optimizer=None):
    for epoch in range(num_epochs):
        train_l_sum, train_acc_sum, n = 0.0, 0.0, 0
        for X, y in train_iter:
            y_hat = net(X)
            l = loss(y_hat, y).sum()
            
            # 梯度清零
            if optimizer is not None:
                optimizer.zero_grad()
            elif params is not None and params[0].grad is not None:
                for param in params:
                    param.grad.data.zero_()
            
            l.backward()
            if optimizer is None:
                sgd(params, lr, batch_size)
            else:
                optimizer.step()  # “softmax回归的简洁实现”一节将用到
            
            
            train_l_sum += l.item()
            train_acc_sum += (y_hat.argmax(dim=1) == y).sum().item()
            n += y.shape[0]
        test_acc = evaluate_accuracy(test_iter, net)
        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'
              % (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc))
train_iter, test_iter = load_data_fashion_mnist(batch_size)
train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params, lr)

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中删除文件的程序代码
Mar 13 Python
Python编程中运用闭包时所需要注意的一些地方
May 02 Python
在Python的Flask框架中验证注册用户的Email的方法
Sep 02 Python
Python中动态检测编码chardet的使用教程
Jul 06 Python
TensorFlow模型保存和提取的方法
Mar 08 Python
Python3.6实现连接mysql或mariadb的方法分析
May 18 Python
python从list列表中选出一个数和其对应的坐标方法
Jul 20 Python
python3 正则表达式基础廖雪峰
Mar 25 Python
python查看矩阵的行列号以及维数方式
May 22 Python
Python xml、字典、json、类四种数据类型如何实现互相转换
May 27 Python
Python Selenium实现无可视化界面过程解析
Aug 25 Python
Python实现查询剪贴板自动匹配信息的思路详解
Jul 09 Python
浅谈pytorch中的dropout的概率p
May 27 #Python
让文件路径提取变得更简单的Python Path库
Pytorch中的数据集划分&正则化方法
Pytorch 如何实现常用正则化
PyTorch 实现L2正则化以及Dropout的操作
Python开发之QT解决无边框界面拖动卡屏问题(附带源码)
pytorch 实现在测试的时候启用dropout
You might like
一个php短网址的生成代码(仿微博短网址)
2014/05/07 PHP
PHP FTP操作类代码( 上传、拷贝、移动、删除文件/创建目录)
2014/05/10 PHP
php定义一个参数带有默认值的函数实例分析
2015/03/16 PHP
Laravel的Auth验证Token验证使用自定义Redis的例子
2019/09/30 PHP
php使用自带dom扩展进行元素匹配的原理解析
2020/05/29 PHP
PHP基于openssl实现非对称加密代码实例
2020/06/19 PHP
Textarea根据内容自适应高度
2013/10/28 Javascript
JavaScript的设计模式经典之建造者模式
2016/02/24 Javascript
js阻止浏览器默认行为触发的通用方法(推荐)
2016/05/15 Javascript
详解JavaScript中双等号引起的隐性类型转换
2016/05/30 Javascript
JavaScript知识点总结(六)之JavaScript判断变量数据类型
2016/05/31 Javascript
JS动态给对象添加事件的简单方法
2016/07/19 Javascript
关于javascript原型的修改与重写(覆盖)差别详解
2016/08/31 Javascript
jQuery实现图片轮播效果代码
2016/09/27 Javascript
微信小程序实现图片预加载组件
2017/01/18 Javascript
js实现文字选中分享功能
2017/01/25 Javascript
JavaScript运动框架 解决速度正负取整问题(一)
2017/05/17 Javascript
centos 上快速搭建ghost博客方法分享
2018/05/23 Javascript
SSM+layUI 根据登录信息显示不同的页面方法
2019/09/20 Javascript
axios如何取消重复无用的请求详解
2019/12/15 Javascript
如何基于javascript实现贪吃蛇游戏
2020/02/09 Javascript
一篇文章带你使用Typescript封装一个Vue组件(简单易懂)
2020/06/05 Javascript
[49:35]KG vs SECRET 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
Python自动重试HTTP连接装饰器
2015/04/28 Python
python中的lambda表达式用法详解
2016/06/22 Python
对python tkinter窗口弹出置顶的方法详解
2019/06/14 Python
python可视化爬虫界面之天气查询
2019/07/03 Python
Hoover胡佛官网:美国吸尘器和洗地机品牌
2019/01/09 全球购物
个人教师自我评价范文
2013/12/02 职场文书
医学专业毕业生个人求职信
2013/12/25 职场文书
建筑工地标语
2014/06/18 职场文书
人大代表选举标语
2014/10/07 职场文书
2014年小学教研工作总结
2014/12/06 职场文书
技术转让协议书
2016/03/19 职场文书
详解MySQL 联合查询优化机制
2021/05/10 MySQL
Li list-style-image 图片垂直居中实现方法
2023/05/21 HTML / CSS