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


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

    训练集:训练数据

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

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

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

      1 import  torch
      2 import  torch.nn as nn
      3 import  torch.nn.functional as F
      4 import  torch.optim as optim
      5 from    torchvision import datasets, transforms
      6 
      7 #超参数
      8 batch_size=200
      9 learning_rate=0.01
     10 epochs=10
     11 
     12 #获取训练数据
     13 train_db = datasets.MNIST('../data', train=True, download=True,   #train=True则得到的是训练集
     14                    transform=transforms.Compose([                 #transform进行数据预处理
     15                        transforms.ToTensor(),                     #转成Tensor类型的数据
     16                        transforms.Normalize((0.1307,), (0.3081,)) #进行数据标准化(减去均值除以方差)
     17                    ]))
     18 
     19 #DataLoader把训练数据分成多个小组,此函数每次抛出一组数据。直至把所有的数据都抛出。就是做一个数据的初始化
     20 train_loader = torch.utils.data.DataLoader(train_db, batch_size=batch_size, shuffle=True)
     21 
     22 
     23 #获取测试数据
     24 test_db = datasets.MNIST('../data', train=False, 
     25                    transform=transforms.Compose([
     26                         transforms.ToTensor(),
     27                         transforms.Normalize((0.1307,), (0.3081,))
     28                    ]))
     29 
     30 test_loader = torch.utils.data.DataLoader(test_db, batch_size=batch_size, shuffle=True)
     31 
     32 
     33 #将训练集拆分成训练集和验证集
     34 print('train:', len(train_db), 'test:', len(test_db))                              #train: 60000 test: 10000
     35 train_db, val_db = torch.utils.data.random_split(train_db, [50000, 10000])
     36 print('db1:', len(train_db), 'db2:', len(val_db))                                  #db1: 50000 db2: 10000
     37 
     38 train_loader = torch.utils.data.DataLoader(train_db, batch_size=batch_size, shuffle=True)
     39 val_loader = torch.utils.data.DataLoader(val_db, batch_size=batch_size, shuffle=True)
     40 
     41 
     42 
     43 
     44 class MLP(nn.Module):
     45 
     46     def __init__(self):
     47         super(MLP, self).__init__()
     48         
     49         self.model = nn.Sequential(         #定义网络的每一层,
     50             nn.Linear(784, 200),
     51             nn.ReLU(inplace=True),
     52             nn.Linear(200, 200),
     53             nn.ReLU(inplace=True),
     54             nn.Linear(200, 10),
     55             nn.ReLU(inplace=True),
     56         )
     57 
     58     def forward(self, x):
     59         x = self.model(x)
     60         return x    
     61 
     62 
     63 net = MLP()
     64 #定义sgd优化器,指明优化参数、学习率,net.parameters()得到这个类所定义的网络的参数[[w1,b1,w2,b2,...]
     65 optimizer = optim.SGD(net.parameters(), lr=learning_rate)
     66 criteon = nn.CrossEntropyLoss()
     67 
     68 
     69 for epoch in range(epochs):
     70 
     71     for batch_idx, (data, target) in enumerate(train_loader):
     72         data = data.view(-1, 28*28)          #将二维的图片数据摊平[样本数,784]
     73 
     74         logits = net(data)                   #前向传播
     75         loss = criteon(logits, target)       #nn.CrossEntropyLoss()自带Softmax
     76 
     77         optimizer.zero_grad()                #梯度信息清空   
     78         loss.backward()                      #反向传播获取梯度
     79         optimizer.step()                     #优化器更新
     80 
     81         if batch_idx % 100 == 0:             #每100个batch输出一次信息
     82             print('Train Epoch: {} [{}/{} ({:.0f}%)]	Loss: {:.6f}'.format(
     83                 epoch, batch_idx * len(data), len(train_loader.dataset),
     84                        100. * batch_idx / len(train_loader), loss.item()))
     85 
     86     #验证集用来检测训练是否过拟合
     87     val_loss = 0
     88     correct = 0                                         
     89     for data, target in val_loader:
     90         data = data.view(-1, 28 * 28)
     91         logits = net(data)
     92         val_loss += criteon(logits, target).item()     
     93         
     94         pred = logits.data.max(dim=1)[1]                
     95         correct += pred.eq(target.data).sum()
     96 
     97     val_loss /= len(val_loader.dataset)
     98     print('
    VAL set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)
    '.format(
     99         val_loss, correct, len(val_loader.dataset),
    100         100. * correct / len(val_loader.dataset)))
    101     
    102 
    103     
    104 #测试集用来评估    
    105 test_loss = 0
    106 correct = 0                                         #correct记录正确分类的样本数
    107 for data, target in test_loader:
    108     data = data.view(-1, 28 * 28)
    109     logits = net(data)
    110     test_loss += criteon(logits, target).item()     #其实就是criteon(logits, target)的值,标量
    111     
    112     pred = logits.data.max(dim=1)[1]                #也可以写成pred=logits.argmax(dim=1)
    113     correct += pred.eq(target.data).sum()
    114 
    115 test_loss /= len(test_loader.dataset)
    116 print('
    Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)
    '.format(
    117     test_loss, correct, len(test_loader.dataset),
    118     100. * correct / len(test_loader.dataset)))

    2.正则化

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

    2.1L2范数(更常用)

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

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

    2.2L1范数

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

    3.动量(Momentum)

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

    1 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:基于测量指标对学习率进行动态的下降

    1 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

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

  • 相关阅读:
    [Python] 网络
    [c++] 命令
    [DB] 关系型数据库
    [win] cmd 常用命令
    [linux] Git基本概念&操作
    [SQL] 常用命令
    redis(二十四):Redis分布式锁以及实现(python)
    redis(二十三):Redis 集群(proxy 型)二
    redis(二十二):Redis 集群(proxy 型)一
    redis(二十一):Redis 架构模式实现(哨兵)
  • 原文地址:https://www.cnblogs.com/cxq1126/p/13289364.html
Copyright © 2020-2023  润新知