zoukankan      html  css  js  c++  java
  • 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。

  • 相关阅读:
    HDU 1800 Flying to the Mars 字典树,STL中的map ,哈希树
    字典树 HDU 1075 What Are You Talking About
    字典树 HDU 1251 统计难题
    最小生成树prim算法 POJ2031
    POJ 1287 Networking 最小生成树
    次小生成树 POJ 2728
    最短路N题Tram SPFA
    poj2236 并查集
    POJ 1611并查集
    Number Sequence
  • 原文地址:https://www.cnblogs.com/cxq1126/p/13289364.html
Copyright © 2011-2022 走看看