PyTorch 优化

作者: Jancd | 来源:发表于2018-06-22 20:28 被阅读15次

    torch.optim is a package implementing various optimization algorithms. Most commonly used methods are already supported, and the interface is general enough, so that more sophisticated ones can be also easily integrated in the future..

    更多可以查看官网 :
    > PyTorch 官网


    载入数据

    编造一些伪数据用于实验.

    import torch
    import torch.utils.data as Data
    import torch.nn.functional as F
    from torch.autograd import Variable
    import matplotlib.pyplot as plt
    
    torch.manual_seed(1)    # reproducible
    
    LR = 0.01
    BATCH_SIZE = 32
    EPOCH = 12
    
    # fake dataset
    x = torch.unsqueeze(torch.linspace(-1, 1, 1000), dim=1)
    y = x.pow(2) + 0.1*torch.normal(torch.zeros(*x.size()))
    
    # plot dataset
    plt.scatter(x.numpy(), y.numpy())
    plt.show()
    
    torch_dataset = Data.TensorDataset(data_tensor=x, target_tensor=y)
    loader = Data.DataLoader(dataset=torch_dataset, batch_size=BATCH_SIZE, shuffle=True, num_workers=2,)
    

    优化神经网络

    为了对比每一种优化器, 我们给他们各自创建一个神经网络, 但这个神经网络都来自同一个 Net 形式.

    # 默认的 network 形式
    class Net(torch.nn.Module):
        def __init__(self):
            super(Net, self).__init__()
            self.hidden = torch.nn.Linear(1, 20)   # hidden layer
            self.predict = torch.nn.Linear(20, 1)   # output layer
    
        def forward(self, x):
            x = F.relu(self.hidden(x))      # activation function for hidden layer
            x = self.predict(x)             # linear output
            return x
    
    # 为每个优化器创建一个 net
    net_SGD         = Net()
    net_Momentum    = Net()
    net_RMSprop     = Net()
    net_Adam        = Net()
    nets = [net_SGD, net_Momentum, net_RMSprop, net_Adam]
    

    Optimizer

    接下来在创建不同的优化器, 用来训练不同的网络. 并创建一个 loss_func 用来计算误差.
    几种常见的优化器, SGD, Momentum, RMSprop, Adam.

    # different optimizers
    opt_SGD         = torch.optim.SGD(net_SGD.parameters(), lr=LR)
    opt_Momentum    = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8)
    opt_RMSprop     = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
    opt_Adam        = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))
    optimizers = [opt_SGD, opt_Momentum, opt_RMSprop, opt_Adam]
    
    loss_func = torch.nn.MSELoss()
    losses_his = [[], [], [], []]   # 记录 training 时不同神经网络的 loss
    

    结果

    训练和 loss 画图.

    for epoch in range(EPOCH):
        print('Epoch: ', epoch)
        for step, (batch_x, batch_y) in enumerate(loader):
            b_x = Variable(batch_x)  # 务必要用 Variable 包一下
            b_y = Variable(batch_y)
    
            # 对每个优化器, 优化属于他的神经网络
            for net, opt, l_his in zip(nets, optimizers, losses_his):
                output = net(b_x)              # get output for every net
                loss = loss_func(output, b_y)  # compute loss for every net
                opt.zero_grad()                # clear gradients for next train
                loss.backward()                # backpropagation, compute gradients
                opt.step()                     # apply gradients
                l_his.append(loss.data[0])     # loss recoder
    
    image

    SGD 是最普通的优化器, 也可以说没有加速效果, 而 MomentumSGD 的改良版, 它加入了动量原则.

    后面的 RMSprop 又是 Momentum 的升级版. 而 Adam 又是 RMSprop 的升级版.

    不过从这个结果中看到, Adam 的效果似乎比 RMSprop 要差一点. 所以说并不是越先进的优化器, 结果越佳.

    在试验中可以尝试不同的优化器, 找到那个最适合的数据/网络的优化器.

    相关文章

      网友评论

        本文标题:PyTorch 优化

        本文链接:https://www.haomeiwen.com/subject/kpphyftx.html