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

作者:tsq292978891 时间:2023-06-06 07:58:32 

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-1,momentum默认值为0.9。features12的参数学习率为1e-2。

灵活更改各层的学习率

torch.optim.optimizer.Optimizer的初始化函数如下:

__init__(self, params, lr=<object object>, momentum=0, dampening=0, weight_decay=0, nesterov=False)

params (iterable): iterable of parameters to optimize or dicts defining parameter groups (params可以是可迭代的参数,或者一个定义参数组的字典,如上所示,字典的键值包括:params,lr,momentum,dampening,weight_decay,nesterov)

想要改变各层的学习率,可以访问optimizer的param_groups属性。type(optimizer.param_groups) -> list


optimizer.param_groups[0].keys()
Out[21]: ['dampening', 'nesterov', 'params', 'lr', 'weight_decay', 'momentum']

因此,想要更改某层参数的学习率,可以访问optimizer.param_groups,指定某个索引更改'lr'参数就可以。


def adjust_learning_rate(optimizer, decay_rate=0.9):
 for para in optimizer.param_groups:
   para['lr'] = para['lr']*decay_rate

重写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()},
       {'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)

来源:https://blog.csdn.net/tsq292978891/article/details/79724781

标签:torch.optim,SGD,L1
0
投稿

猜你喜欢

  • python实操练习案例(六)

    2021-01-06 08:09:23
  • python可视化分析的实现(matplotlib、seaborn、ggplot2)

    2021-10-20 13:59:21
  • Nodejs做文本数据处理实现详解

    2024-05-13 10:04:06
  • 一起来看看五条Python中的隐含特性

    2023-06-30 12:46:43
  • 闲聊html和body标签

    2009-02-21 10:50:00
  • python统计字母、空格、数字等字符个数的实例

    2022-10-04 12:02:29
  • GDB调试Mysql实战之源码编译安装

    2024-01-28 00:37:42
  • pycharm安装和首次使用教程

    2022-05-23 19:01:36
  • python处理DICOM并计算三维模型体积

    2022-07-16 09:24:29
  • python数据类型相关知识扩展

    2021-12-21 10:20:07
  • wxPython中wx.gird.Gird添加按钮的实现

    2021-07-05 15:13:19
  • 在js中调用asp页面的方法

    2007-08-21 20:30:00
  • python使用sorted函数对列表进行排序的方法

    2022-08-19 00:36:46
  • 关于Theano和Tensorflow多GPU使用问题

    2023-10-10 13:58:59
  • Go语言中strings和strconv包示例代码详解

    2024-04-23 09:41:58
  • 浅谈js中startsWith 函数不能在任何浏览器兼容的问题

    2024-04-23 09:11:38
  • 你知道哪几种MYSQL的连接查询

    2024-01-20 15:00:34
  • Python 网络编程说明第1/2页

    2023-05-07 13:25:13
  • 详解Python下Flask-ApScheduler快速指南

    2023-12-25 07:37:34
  • W3C优质网页小贴士(四)

    2008-04-17 13:34:00
  • asp之家 网络编程 m.aspxhome.com