Pytorch中的数据集划分正则化⽅法
1.训练集&验证集&测试集
训练集:训练数据
验证集:验证不同算法(⽐如利⽤⽹格搜索对超参数进⾏调整等),检验哪种更有效
测试集:正确评估分类器的性能
正常流程:验证集会记录每个时间戳的参数,在加载test数据前会加载那个最好的参数,再来评估。⽐⽅说训练完6000个epoch后,发现在第3520个epoch的validation表现最好,测试时会加载第3520个epoch的参数。
import torch
import as nn
import 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__()
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 = del(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
<_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, um, 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随机失活
遍历每⼀层,设置消除神经⽹络中的节点概率,得到精简后的⼀个样本。
p表⽰的⽰的是删除节点数的⽐例(Tip:tensorflow中keep_prob表⽰保留节点数的⽐例,不要混淆)
测试阶段⽆需使⽤dropout,所以在train之前执⾏ain()相当于启⽤dropout,测试之前执⾏net_dropped.eval()相当于不启⽤dropout。
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论