torch.optim的灵活使用(包括重写SGD,加上L1正则)

前端之家收集整理的这篇文章主要介绍了torch.optim的灵活使用(包括重写SGD,加上L1正则)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

torch.optim的灵活使用

1. 基本用法

要构建一个优化器Optimizer,必须给它一个包含参数的迭代器来优化,然后,我们可以指定特定的优化选项,
例如学习速率,重量衰减值等。

注:如果要把model放在GPU中,需要在构建一个Optimizer之前就执行model.cuda(),确保优化器里面的参数也是在GPU中。
例子:

optimizer = optim.SGD(model.parameters(),lr = 0.01,momentum=0.9)

2. 灵活的设置各层的学习率

将model中需要进行BP的层的参数送到torch.optim中,这些层不一定是连续的。
这个时候,Optimizer的参数不是一个可迭代的变量,而是一个可迭代的字典
(字典的key必须包含'params'(查看源码可以得知optimizer通过'params'访问parameters),
其他的key就是optimizer可以接受的,比如说'lr','weight_decay'),可以将这些字典构成一个list,
这样就是一个可迭代的字典了。

注:这个时候,可以在optimizer设置选项作为关键字参数传递,这时它们将被认为是默认值(当字典里面没有这个关键字参数key-value对时,就使用这个默认的参数)
This is useful when you only want to vary a single option,while keeping all others consistent between parameter groups.

例子:

optimizer = SGD([
                {'params': model.features12.parameters(),'lr': 1e-2},{'params': model.features22.parameters()},{'params': model.features32.parameters()},{'params': model.features42.parameters()},{'params': model.features52.parameters()},],weight_decay1=5e-4,lr=1e-1,momentum=0.9)

上面创建的optim.SGD类型的Optimizer,lr默认值为1e-2,momentum默认值为0.9。features12的参数学习率为1e-2。

重写torch.optim,加上L1正则

查看torch.optim.SGD等Optimizer的源码,发现没有L1正则的选项,而L1正则更容易得到稀疏解。
这个时候,可以更改/home/smiles/anaconda2/lib/python2.7/site-packages/torch/optim/sgd.py文件,模拟L2正则化的操作。
L1正则化求导如下:

dw = 1 * sign(w)

更改后的sgd.py如下:

import torch
from torch.optim.optimizer import Optimizer,required

class SGD(Optimizer):
    def __init__(self,params,lr=required,momentum=0,dampening=0,weight_decay1=0,weight_decay2=0,nesterov=False):
        defaults = dict(lr=lr,momentum=momentum,dampening=dampening,weight_decay1=weight_decay1,weight_decay2=weight_decay2,nesterov=nesterov)
        if nesterov and (momentum <= 0 or dampening != 0):
            raise ValueError("Nesterov momentum requires a momentum and zero dampening")
        super(SGD,self).__init__(params,defaults)

    def __setstate__(self,state):
        super(SGD,self).__setstate__(state)
        for group in self.param_groups:
            group.setdefault('nesterov',False)

    def step(self,closure=None):
        """Performs a single optimization step. Arguments: closure (callable,optional): A closure that reevaluates the model and returns the loss. """
        loss = None
        if closure is not None:
            loss = closure()

        for group in self.param_groups:
            weight_decay1 = group['weight_decay1']
            weight_decay2 = group['weight_decay2']
            momentum = group['momentum']
            dampening = group['dampening']
            nesterov = group['nesterov']

            for p in group['params']:
                if p.grad is None:
                    continue
                d_p = p.grad.data
                if weight_decay1 != 0:
                    d_p.add_(weight_decay1,torch.sign(p.data))
                if weight_decay2 != 0:
                    d_p.add_(weight_decay2,p.data)
                if momentum != 0:
                    param_state = self.state[p]
                    if 'momentum_buffer' not in param_state:
                        buf = param_state['momentum_buffer'] = torch.zeros_like(p.data)
                        buf.mul_(momentum).add_(d_p)
                    else:
                        buf = param_state['momentum_buffer']
                        buf.mul_(momentum).add_(1 - dampening,d_p)
                    if nesterov:
                        d_p = d_p.add(momentum,buf)
                    else:
                        d_p = buf

                p.data.add_(-group['lr'],d_p)

        return loss

一个使用的例子:

optimizer = SGD([
                {'params': model.features12.parameters()},momentum=0.9)
原文链接:https://www.f2er.com/regex/357565.html

猜你在找的正则表达式相关文章