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

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没有直接可以调用的方法,实现如下:

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。

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倍。

5.提前停止(防止overfitting)

基于经验值。

6.Dropout随机失活

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

torch.nn.Dropout(p=dropout_prob) 

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

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 在PyTorch中使用标签平滑正则化的问题

    什么是标签平滑?在PyTorch中如何去使用它? 在训练深度学习模型的过程中,过拟合和概率校准(probability calibration)是两个常见的问题.一方面,正则化技术可以解决过拟合问题,其中较为常见的方法有将权重调小,迭代提前停止以及丢弃一些权重等.另一方面,Platt标度法和isotonic regression法能够对模型进行校准.但是有没有一种方法可以同时解决过拟合和模型过度自信呢? 标签平滑也许可以.它是一种去改变目标变量的正则化技术,能使模型的预测结果不再仅为一个确定值.

  • PyTorch 实现L2正则化以及Dropout的操作

    了解知道Dropout原理 如果要提高神经网络的表达或分类能力,最直接的方法就是采用更深的网络和更多的神经元,复杂的网络也意味着更加容易过拟合. 于是就有了Dropout,大部分实验表明其具有一定的防止过拟合的能力. 用代码实现Dropout Dropout的numpy实现 PyTorch中实现dropout import torch.nn.functional as F import torch.nn.init as init import torch from torch.autograd

  • Pytorch 如何实现常用正则化

    Stochastic Depth 论文:Deep Networks with Stochastic Depth 本文的正则化针对于ResNet中的残差结构,类似于dropout的原理,训练时对模块进行随机的删除,从而提升模型的泛化能力. 对于上述的ResNet网络,模块越在后面被drop掉的概率越大. 作者直觉上认为前期提取的低阶特征会被用于后面的层. 第一个模块保留的概率为1,之后保留概率随着深度线性递减. 对一个模块的drop函数可以采用如下的方式实现: def drop_connect(i

  • pytorch 实现L2和L1正则化regularization的操作

    1.torch.optim优化器实现L2正则化 torch.optim集成了很多优化器,如SGD,Adadelta,Adam,Adagrad,RMSprop等,这些优化器自带的一个参数weight_decay,用于指定权值衰减率,相当于L2正则化中的λ参数,注意torch.optim集成的优化器只有L2正则化方法,你可以查看注释,参数weight_decay 的解析是: weight_decay (float, optional): weight decay (L2 penalty) (defa

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

    1.训练集&验证集&测试集 训练集:训练数据 验证集:验证不同算法(比如利用网格搜索对超参数进行调整等),检验哪种更有效 测试集:正确评估分类器的性能 正常流程:验证集会记录每个时间戳的参数,在加载test数据前会加载那个最好的参数,再来评估.比方说训练完6000个epoch后,发现在第3520个epoch的validation表现最好,测试时会加载第3520个epoch的参数. import torch import torch.nn as nn import torch.nn.func

  • PyTorch中常用的激活函数的方法示例

    神经网络只是由两个或多个线性网络层叠加,并不能学到新的东西,简单地堆叠网络层,不经过非线性激活函数激活,学到的仍然是线性关系. 但是加入激活函数可以学到非线性的关系,就具有更强的能力去进行特征提取. 构造数据 import torch import torch.nn.functional as F from torch.autograd import Variable import matplotlib.pyplot as plt x = torch.linspace(-5, 5, 200) #

  • pytorch实现mnist数据集的图像可视化及保存

    如何将pytorch中mnist数据集的图像可视化及保存 导出一些库 import torch import torchvision import torch.utils.data as Data import scipy.misc import os import matplotlib.pyplot as plt BATCH_SIZE = 50 DOWNLOAD_MNIST = True 数据集的准备 #训练集测试集的准备 train_data = torchvision.datasets.M

  • pytorch中如何使用DataLoader对数据集进行批处理的方法

    最近搞了搞minist手写数据集的神经网络搭建,一个数据集里面很多个数据,不能一次喂入,所以需要分成一小块一小块喂入搭建好的网络. pytorch中有很方便的dataloader函数来方便我们进行批处理,做了简单的例子,过程很简单,就像把大象装进冰箱里一共需要几步? 第一步:打开冰箱门. 我们要创建torch能够识别的数据集类型(pytorch中也有很多现成的数据集类型,以后再说). 首先我们建立两个向量X和Y,一个作为输入的数据,一个作为正确的结果: 随后我们需要把X和Y组成一个完整的数据集,

  • pytorch 自定义数据集加载方法

    pytorch 官网给出的例子中都是使用了已经定义好的特殊数据集接口来加载数据,而且其使用的数据都是官方给出的数据.如果我们有自己收集的数据集,如何用来训练网络呢?此时需要我们自己定义好数据处理接口.幸运的是pytroch给出了一个数据集接口类(torch.utils.data.Dataset),可以方便我们继承并实现自己的数据集接口. torch.utils.data torch的这个文件包含了一些关于数据集处理的类. class torch.utils.data.Dataset: 一个抽象类

  • PyTorch中torch.utils.data.DataLoader简单介绍与使用方法

    目录 一.torch.utils.data.DataLoader 简介 二.实例 参考链接 总结 一.torch.utils.data.DataLoader 简介 作用:torch.utils.data.DataLoader 主要是对数据进行 batch 的划分. 数据加载器,结合了数据集和取样器,并且可以提供多个线程处理数据集. 在训练模型时使用到此函数,用来 把训练数据分成多个小组 ,此函数 每次抛出一组数据 .直至把所有的数据都抛出.就是做一个数据的初始化. 好处: 使用DataLoade

  • Pytorch中求模型准确率的两种方法小结

    方法一:直接在epoch过程中求取准确率 简介:此段代码是LeNet5中截取的. def train_model(model,train_loader): optimizer = torch.optim.Adam(model.parameters()) loss_func = nn.CrossEntropyLoss() EPOCHS = 5 for epoch in range(EPOCHS): correct = 0 for batch_idx,(X_batch,y_batch) in enu

  • Pytorch中使用ImageFolder读取数据集时忽略特定文件

    目录 一.使用ImageFolder读取数据集时忽略特定文件 二.ImageFolder只读取部分类别文件夹 一.使用ImageFolder读取数据集时忽略特定文件 如果事先知道需要忽略哪些文件,当然直接从数据集里删除就行了.但如果需要在程序运行时动态确认,或者筛选规则比较复杂,人工不好做,就需要让ImageFolder在读取时使用自定义的筛选规则. ImageFolder有一个可选参数为is_valid_file,参数类型为可调用的函数,该函数传入一个str参数,返回一个bool值.当返回值为

  • C#中使用ADOMD.NET查询多维数据集的实现方法

    本文实例讲述了C#中使用ADOMD.NET查询多维数据集的实现方法,分享给大家供大家参考.具体实现方法分析如下: ADOMD.NET 是用于与 Microsoft SQL Server Analysis Services 进行通信的 Microsoft .NET Framework 数据访问接口. ADOMD.NET 可使用 XML for Analysis 协议与分析数据源通信,方法为使用 TCP/IP 或 HTTP 连接传输和接收符合 XML for Analysis 规范的 SOAP 请求

随机推荐