Pytorch中的数据集划分&正则化方法


Posted in Python onMay 27, 2021

1.训练集&验证集&测试集

训练集:训练数据

验证集:验证不同算法(比如利用网格搜索对超参数进行调整等),检验哪种更有效

测试集:正确评估分类器的性能

正常流程:验证集会记录每个时间戳的参数,在加载test数据前会加载那个最好的参数,再来评估。比方说训练完6000个epoch后,发现在第3520个epoch的validation表现最好,测试时会加载第3520个epoch的参数。

import  torch
import  torch.nn as nn
import  torch.nn.functional as F
import  torch.optim as optim
from    torchvision import datasets, transforms
#超参数
batch_size=200
learning_rate=0.01
epochs=10
#获取训练数据
train_db = datasets.MNIST('../data', train=True, download=True,   #train=True则得到的是训练集
                   transform=transforms.Compose([                 #transform进行数据预处理
                       transforms.ToTensor(),                     #转成Tensor类型的数据
                       transforms.Normalize((0.1307,), (0.3081,)) #进行数据标准化(减去均值除以方差)
                   ]))
#DataLoader把训练数据分成多个小组,此函数每次抛出一组数据。直至把所有的数据都抛出。就是做一个数据的初始化
train_loader = torch.utils.data.DataLoader(train_db, batch_size=batch_size, shuffle=True)
#获取测试数据
test_db = datasets.MNIST('../data', train=False,
                   transform=transforms.Compose([
                        transforms.ToTensor(),
                        transforms.Normalize((0.1307,), (0.3081,))
                   ]))
test_loader = torch.utils.data.DataLoader(test_db, batch_size=batch_size, shuffle=True)
#将训练集拆分成训练集和验证集
print('train:', len(train_db), 'test:', len(test_db))                              #train: 60000 test: 10000
train_db, val_db = torch.utils.data.random_split(train_db, [50000, 10000])
print('db1:', len(train_db), 'db2:', len(val_db))                                  #db1: 50000 db2: 10000
train_loader = torch.utils.data.DataLoader(train_db, batch_size=batch_size, shuffle=True)
val_loader = torch.utils.data.DataLoader(val_db, batch_size=batch_size, shuffle=True)
class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.model = nn.Sequential(         #定义网络的每一层,
            nn.Linear(784, 200),
            nn.ReLU(inplace=True),
            nn.Linear(200, 200),
            nn.ReLU(inplace=True),
            nn.Linear(200, 10),
            nn.ReLU(inplace=True),
        )
    def forward(self, x):
        x = self.model(x)
        return x
net = MLP()
#定义sgd优化器,指明优化参数、学习率,net.parameters()得到这个类所定义的网络的参数[[w1,b1,w2,b2,...]
optimizer = optim.SGD(net.parameters(), lr=learning_rate)
criteon = nn.CrossEntropyLoss()
for epoch in range(epochs):
    for batch_idx, (data, target) in enumerate(train_loader):
        data = data.view(-1, 28*28)          #将二维的图片数据摊平[样本数,784]
        logits = net(data)                   #前向传播
        loss = criteon(logits, target)       #nn.CrossEntropyLoss()自带Softmax
        optimizer.zero_grad()                #梯度信息清空
        loss.backward()                      #反向传播获取梯度
        optimizer.step()                     #优化器更新
        if batch_idx % 100 == 0:             #每100个batch输出一次信息
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                       100. * batch_idx / len(train_loader), loss.item()))
    #验证集用来检测训练是否过拟合
    val_loss = 0
    correct = 0
    for data, target in val_loader:
        data = data.view(-1, 28 * 28)
        logits = net(data)
        val_loss += criteon(logits, target).item()
        pred = logits.data.max(dim=1)[1]
        correct += pred.eq(target.data).sum()
    val_loss /= len(val_loader.dataset)
    print('\nVAL set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        val_loss, correct, len(val_loader.dataset),
        100. * correct / len(val_loader.dataset)))
#测试集用来评估
test_loss = 0
correct = 0                                         #correct记录正确分类的样本数
for data, target in test_loader:
    data = data.view(-1, 28 * 28)
    logits = net(data)
    test_loss += criteon(logits, target).item()     #其实就是criteon(logits, target)的值,标量
    pred = logits.data.max(dim=1)[1]                #也可以写成pred=logits.argmax(dim=1)
    correct += pred.eq(target.data).sum()
test_loss /= len(test_loader.dataset)
print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
    test_loss, correct, len(test_loader.dataset),
    100. * correct / len(test_loader.dataset)))

2.正则化

正则化可以解决过拟合问题。

2.1L2范数(更常用)

在定义优化器的时候设定weigth_decay,即L2范数前面的λ参数。

optimizer = torch.optim.SGD(net.parameters(), lr=learning_rate, weight_decay=0.01)

2.2L1范数

Pytorch没有直接可以调用的方法,实现如下:

Pytorch中的数据集划分&正则化方法

3.动量(Momentum)

Adam优化器内置了momentum,SGD需要手动设置。

optimizer = torch.optim.SGD(model.parameters(), args=lr, momentum=args.momentum, weight_decay=args.weight_decay)

4.学习率衰减

torch.optim.lr_scheduler 中提供了基于多种epoch数目调整学习率的方法。

4.1torch.optim.lr_scheduler.ReduceLROnPlateau:基于测量指标对学习率进行动态的下降

torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10, verbose=False, threshold=0.0001, threshold_mode='rel', cooldown=0, min_lr=0, eps=1e-08)

训练过程中,optimizer会把learning rate 交给scheduler管理,当指标(比如loss)连续patience次数还没有改进时,需要降低学习率,factor为每次下降的比例。

scheduler.step(loss_val)每调用一次就会监听一次loss_val。

Pytorch中的数据集划分&正则化方法

4.2torch.optim.lr_scheduler.StepLR:基于epoch

torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1)

当epoch每过stop_size时,学习率都变为初始学习率的gamma倍。

Pytorch中的数据集划分&正则化方法

5.提前停止(防止overfitting)

基于经验值。

6.Dropout随机失活

遍历每一层,设置消除神经网络中的节点概率,得到精简后的一个样本。

torch.nn.Dropout(p=dropout_prob)

p表示的示的是删除节点数的比例(Tip:tensorflow中keep_prob表示保留节点数的比例,不要混淆)

Pytorch中的数据集划分&正则化方法

测试阶段无需使用dropout,所以在train之前执行net_dropped.train()相当于启用dropout,测试之前执行net_dropped.eval()相当于不启用dropout。

Pytorch中的数据集划分&正则化方法

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

Python 相关文章推荐
python使用正则表达式提取网页URL的方法
May 26 Python
基于python脚本实现软件的注册功能(机器码+注册码机制)
Oct 09 Python
Python数据分析之双色球统计两个红和蓝球哪组合比例高的方法
Feb 03 Python
利用python的socket发送http(s)请求方法示例
May 07 Python
Python实现在某个数组中查找一个值的算法示例
Jun 27 Python
python 读写文件,按行修改文件的方法
Jul 12 Python
python实现从pdf文件中提取文本,并自动翻译的方法
Nov 28 Python
python实现画五角星和螺旋线的示例
Jan 20 Python
python 的 openpyxl模块 读取 Excel文件的方法
Sep 09 Python
Python range、enumerate和zip函数用法详解
Sep 11 Python
社区版pycharm创建django项目的方法(pycharm的newproject左侧没有项目选项)
Sep 23 Python
Python爬虫自动化爬取b站实时弹幕实例方法
Jan 26 Python
Pytorch 如何实现常用正则化
PyTorch 实现L2正则化以及Dropout的操作
Python开发之QT解决无边框界面拖动卡屏问题(附带源码)
pytorch 实现在测试的时候启用dropout
使用Python脚本对GiteePages进行一键部署的使用说明
教你使用Python pypinyin库实现汉字转拼音
基于tensorflow权重文件的解读
May 26 #Python
You might like
同一空间绑定多个域名而实现访问不同页面的PHP代码
2006/12/06 PHP
解析yii数据库的增删查改
2013/06/20 PHP
PHP数组内存利用率低和弱类型详细解读
2017/08/10 PHP
javascript编程起步(第一课)
2007/01/10 Javascript
ext form 表单提交数据的方法小结
2008/08/08 Javascript
动态为事件添加js代码示例
2009/02/15 Javascript
Dom操作之兼容技巧分享
2011/09/20 Javascript
js读写(删除)Cookie实例详解
2013/04/17 Javascript
JavaScript对象学习经验整理
2013/10/12 Javascript
js获取checkbox复选框选中的选项实例
2014/08/24 Javascript
7个让JavaScript变得更好的注意事项
2015/01/28 Javascript
javascript动画之磁性吸附效果篇
2016/12/09 Javascript
js实现单张图片平移切换效果
2017/10/11 Javascript
详解Chart.js轻量级图表库的使用经验
2018/05/22 Javascript
Angular 多级路由实现登录页面跳转(小白教程)
2019/11/19 Javascript
jQuery实时统计输入框字数及限制
2020/06/24 jQuery
[05:03]2018DOTA2亚洲邀请赛主赛事首日回顾
2018/04/04 DOTA
Python对象转JSON字符串的方法
2016/04/27 Python
Python判断某个用户对某个文件的权限
2016/10/13 Python
Python 使用os.remove删除文件夹时报错的解决方法
2017/01/13 Python
Python实现的生成格雷码功能示例
2018/01/24 Python
python scatter散点图用循环分类法加图例
2019/03/19 Python
python tkinter组件使用详解
2019/09/16 Python
Pytorch mask_select 函数的用法详解
2020/02/18 Python
django ListView的使用 ListView中获取url中的参数值方式
2020/03/27 Python
Python爬虫工具requests-html使用解析
2020/04/29 Python
详解pycharm配置python解释器的问题
2020/10/15 Python
HTML高亮关键字的实现代码
2018/10/22 HTML / CSS
JD Sports意大利:英国篮球和运动时尚的领导者
2017/10/29 全球购物
机关道德讲堂实施方案
2014/03/15 职场文书
小学教师读书活动总结
2014/07/08 职场文书
2014年团支书工作总结
2014/11/14 职场文书
治理商业贿赂工作总结
2015/08/10 职场文书
教师教育心得体会
2016/01/19 职场文书
2021-4-5课程——SQL Server查询【3】
2021/04/05 SQL Server
html5+实现plus.io进行拍照和图片等获取
2022/06/01 HTML / CSS