Pytorch SGD随机梯度下降法

pytorch SGD随机梯度下降

1. 随机梯度下降方法类 torch.optim.SGD

class SGD(torch.optim.Optimizer):
    r"""实现随机梯度下降"""
    def __init__(self, params, lr, momentum=0, dampening=0, weight_decay=0, nesterov=False):
        """
        parameters:
            params: iterable, 要优化的参数迭代器或定义参数组;
            lr: float, 学习率;
            momentum: float, optional, 动量因子,用于动量梯度的下降算法,默认为0;
            dampening: float, optional, 动量抑制因子,默认0;
            weight_decay: float, optional, 权值衰减系数,l2惩罚,默认0;
            nesterov: bool, optional, 
            
        Methods defined here:
            SGD
            torch.optim.optimizer.Optimizer
            builtins.object
        """
        pass
    
    def add_param_group(self, param_group):
        r"""将参数添加到 Optimizer 类的 param_groups。
            可用于在预训练网络时,可随着训练的进行调整 frozen layers。
        parameters:
            param_group: dict, 指定要优化哪些张量以及特定与组的优化选型。
        """
        pass
        
    def load_state_dict(self, state_dict):
        r"""
        parameter:
            state_dict: dict, 返回一个优化器状态对象
        """
        pass
    
    def zero_grad(self, set_to_none: bool = False):
        r"""设置所有梯度张量为0。
        parameters:
            set_to_none: 设置梯度为None。
        """
        pass
    
    def step(self, closure=None):
        r"""进行单次优化(参数更新)
        parameters:
            closure: 一个重新评价模型并返回loss的闭包,对于大多数参数来说是可选的。
        """
        pass

2. 随机梯度下降的每一次迭代过程

优化器调用 trainer.step() 方法的执行步骤:

  1. 对于可学习参数 p p p,计算参数 p p p 的偏导数 g t g_t gt,使用 weight_decay 更新偏导数 g t g_t gt: g t = g t + ( p ∗ w i g h t _ d e c a y ) g_t=g_t+(p*wight\_decay) gt=gt+(p∗wight_decay);
  2. 计算中间值: v t = v t − 1 ∗ m o m e n t u m + g t ∗ ( 1 − d a m p e n i n g ) v_t=v_{t-1}*momentum + g_t*(1-dampening) vt=vt−1∗momentum+gt∗(1−dampening)
  3. 更新参数 p p p: p = p − v t ∗ l r p=p-v_t*lr p=p−vt∗lr。

例:

w = torch.tensor(data=[10], dtype=torch.float32, requires_grad=True)
optimizer = torch.optim.SGD(params=[w], lr=0.1, momentum=0.9, dampening=0.5, weight_decay=0.01, nesterov=False)

for i in range(5):
    y = w**2 + 2*w
    optimizer.zero_grad()
    y.backward()
    optimizer.step()
    print("第{}轮:变量梯度梯度: {},变量值:{}".format(i+1, w.grad, w.data))

输出:

第1轮:变量梯度梯度: tensor([22.]),变量值:tensor([7.7900])
第2轮:变量梯度梯度: tensor([17.5800]),变量值:tensor([4.9181])
第3轮:变量梯度梯度: tensor([11.8362]),变量值:tensor([1.7391])
第4轮:变量梯度梯度: tensor([5.4783]),变量值:tensor([-1.3967])
第5轮:变量梯度梯度: tensor([-0.7935]),变量值:tensor([-4.1786])
经验分享 程序员 微信小程序 职场和发展