优化算法 -- 动量法Momentum

目录

引入

基本思路

如何知道历史方向:

实现 


引入

对于普通的梯度下降算法,就是重复正向传播,计算梯度,更新权重的过程。

表示为:

import torch
import torch.nn as nn
class Model(nn.Module):
    def __init__(self,in_feature=10,out_feature=3):
        super(Model, self).__init__()
        self.linear1 = nn.Linear(in_feature,13)
        self.linear2 = nn.Linear(13,8)
        self.out = nn.Linear(8,out_feature)



    def forward(self,x):
        z1 = self.linear1(x)
        re = torch.relu(z1)
        z2 = self.linear2(re)
        sigma = torch.sigmoid(z2)
        output = self.out(sigma)
        # soft = torch.softmax(output,dim=1)
        return output



        return x_grad
if __name__ == '__main__':
    torch.random.manual_seed(22)
    x = torch.rand([500,20],dtype=torch.float32)
    y = torch.randint(low=0,high=3,size=(500,),dtype=torch.float32)
    net = Model(in_feature=x.shape[1],out_feature=len(y.unique()))
    zhat = net.forward(x)
    criterion = nn.CrossEntropyLoss()
    loss = criterion(zhat,y.long())
    loss.backward(retain_graph=True)
    print(net.linear1.weight.grad)
    print(loss)
    # renew w
    lr = 10# learning_rate
    w = net.linear1.weight.data
    dw = net.linear1.weight.grad
    w -= lr*dw

该过程会消耗较多时间,而时间消耗与步长紧密相关,为了加速迭代过程,优化步长,有了Momentum算法

基本思路

如果下降的方向一直是同一方向,那么使用较长的学习率,一旦方向发生改变,使用较小的学习率,重复这个过程,方向根据过去走过的方向来学习

如何知道历史方向:

上一步方向和更新出来的方向加权求和,得到一个新的方向为当前方向

这里加权求和时,上一步的方向会乘动量参数,真实移动的向量称为“动量” 

更新过程

实现 

import torch
import torch.nn as nn
import torch.optim as optim
from  torch.nn import functional as F
torch.random.manual_seed(22)
x = torch.rand([500,20],dtype=torch.float32)
y = torch.randint(low=0,high=3,size=(500,),dtype=torch.float32)

lr = 0.1  # learning_rate
gamma = 0.9

class Model(nn.Module):
    def __init__(self,in_feature=10,out_feature=3):
        super(Model, self).__init__()
        self.linear1 = nn.Linear(in_feature,13)
        self.linear2 = nn.Linear(13,8)
        self.out = nn.Linear(8,out_feature)



    def forward(self,x):
        z1 = self.linear1(x)
        re = torch.relu(z1)
        z2 = self.linear2(re)
        sigma = torch.sigmoid(z2)
        output = self.out(sigma)
        # soft = torch.softmax(output,dim=1)
        return output



        return x_grad
if __name__ == '__main__':

    net = Model(in_feature=x.shape[1],out_feature=len(y.unique())) # 实例化神经网络
    criterion = nn.CrossEntropyLoss()# 定义损失函数(交叉熵
    opt = optim.SGD(net.parameters(),lr=lr,momentum=gamma) # 定义优化算法  parameters 一次性导出神经网络架构下全部的权重和截距
    """
    梯度下降的流程
    1 计算本轮向前传播损失函数值
    2 反向传播 得到梯度
    3 更新权重和动量
    4 清除原来计算出来的,基于上一个点的坐标计算的梯度
    """
    zhat = net.forward(x)
    loss = criterion(zhat, y.long())
    loss.backward(retain_graph=True)
    opt.step() # 向前走一步(更新梯度
    opt.zero_grad()# 清空之前的梯度

梯度下降的流程
    1 计算本轮向前传播损失函数值
    2 反向传播 得到梯度
    3 更新权重和动量
    4 清除原来计算出来的,基于上一个点的坐标计算的梯度

完成上述代码,就可以进行一步的迭代(就是走一步),后面我们来实现走多步

传播过程理解:就是特征值经过前向传播,得到预测的结果,此结果经过选择好的损失函数与真实结果比较得到损失值loss,loss经过反向传播,借由链式法则得到损失函数对于权重w的偏导数@,@此时经过选择好的优化算法来更新权重(比如梯度下降,就会用当前的权重值减去步长与@的积)(对于动量法,会是上一步的权重值 + 优梯度下降更新出的方向和值,然后再得到真实下降的方向。然后“优梯度下降更新出的方向和值” 是上一不的真实方向乘动量参数减去步长乘偏导数。)

### Q-Learning与动量法结合 在强化学习领域,Q-learning是一种用于估计采取某个动作后的预期奖励的方法。通过引入动量法,可以改进参数更新过程中的稳定性以及收敛速度。 #### 动量法的作用机制 动量方法旨在加速梯度下降算法,在具有高曲率、小但一致的梯度方向上尤其有用。该技术利用过去几次迭代中累积的速度来调整当前的学习步长[^3]。具体来说,动量项帮助减少振荡并加快沿着最小化路径前进的步伐。 对于标准的Q-learning更新规则: \[ Q(s_t,a_t) \leftarrow Q(s_t,a_t)+\alpha[r_{t+1}+\gamma max_a Q(s_{t+1},a)-Q(s_t,a_t)] \] 可以通过加入动量因子\( v \),将其转换为带有动量的版本: ```python v = β * v + α * (r + γ * np.max(Q[next_state]) - Q[state, action]) Q[state, action] += v ``` 这里 \(β\) 是动量系数,通常设置为接近1的一个较小值;\(α\) 表示学习速率;\(γ\) 则代表折扣因子。这种修改使得每次权重更新不仅取决于即时误差信号,还依赖于之前积累的变化趋势。 #### 实现细节 为了实现带动量的Q-learning,除了初始化Q表外还需要额外维护一个相同维度的速度矩阵`V`用来存储历史变化信息。每当执行一次状态转移时,先计算新的增量再应用到对应的Q值位置上去。 ```python import numpy as np def q_learning_with_momentum(env, num_episodes=500, alpha=0.1, gamma=0.99, beta=0.9): n_states = env.observation_space.n n_actions = env.action_space.n # 初始化Q表格和动量向量 Q = np.zeros((n_states, n_actions)) V = np.zeros_like(Q) for episode in range(num_episodes): state = env.reset() while True: action = choose_action(state, Q) next_state, reward, done, _ = env.step(action) delta = reward + gamma * np.max(Q[next_state]) - Q[state][action] V[state][action] = beta * V[state][action] + alpha * delta Q[state][action] += V[state][action] if done: break state = next_state ``` 此代码片段展示了如何将动量应用于传统的Q-learning框架内,从而可能获得更好的性能表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tomorrow'sThinker

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值