首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【强化学习】策略梯度---REINFORCE算法

【强化学习】策略梯度---REINFORCE算法

作者头像
不去幼儿园
发布2024-12-18 19:17:59
发布2024-12-18 19:17:59
1K00
代码可运行
举报
文章被收录于专栏:强化学习专栏强化学习专栏
运行总次数:0
代码可运行

📢本篇文章是博主强化学习(RL)领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在👉强化学习专栏: 【强化学习】- 【单智能体强化学习】(6)---《策略梯度---REINFORCE算法》

1.REINFORCE 算法

REINFORCE 是一种策略梯度算法,用于强化学习中的策略优化问题。它的核心思想是直接优化策略,通过采样环境中的轨迹来估计梯度并更新策略。

2.基本概念

2.1 策略 (Policy)

策略

\pi(a|s;\theta)
\pi(a|s;\theta)

:表示在状态

s
s

下选择动作

a
a

的概率,其中

\theta
\theta

是策略的参数。

2.2 目标

最大化策略的期望累计奖励

J(\theta)
J(\theta)

,即:

J(\theta) = \mathbb{E}{\pi\theta} \left[ \sum_{t=0}^\infty \gamma^t r_t \right]
J(\theta) = \mathbb{E}{\pi\theta} \left[ \sum_{t=0}^\infty \gamma^t r_t \right]

通过调整参数

\theta
\theta

来提升

J(\theta)
J(\theta)

2.3 策略梯度

REINFORCE 是一种基于梯度的方法,通过梯度上升优化

J(\theta)
J(\theta)


3.算法的关键思想

3.1 梯度公式

利用强化学习的公式推导出梯度:

R
R

是从状态

s
s

出发后的累计奖励,作为对策略

\pi
\pi

好坏的衡量。

3.2 梯度估计

使用蒙特卡洛采样的方法,从环境中生成轨迹

,估计梯度:

其中

N
N

是采样轨迹的数量。


4.REINFORCE 算法流程

初始化策略参数

\theta
\theta

(通常是神经网络的权重)。

重复以下步骤,直到收敛:

采样轨迹:从环境中采样多条轨迹

,基于当前策略

\pi_\theta(a|s)
\pi_\theta(a|s)

计算奖励:计算每条轨迹的累积奖励

R_t = \sum_{k=t}^T \gamma^{k-t} r_k
R_t = \sum_{k=t}^T \gamma^{k-t} r_k

策略更新

,其中

\alpha
\alpha

是学习率。


5.公式推导

策略梯度推导

强化学习的目标是最大化期望奖励:

使用采样分布的导数性质,得到:

蒙特卡洛估计

直接使用轨迹 ( \tau ) 中的采样点替代期望,得到无偏估计:

梯度更新

根据上述梯度进行更新,即完成策略的优化。


6.算法的改进点

基线函数 (Baseline)

为了减少累积奖励 ( R ) 的方差,引入基线函数 ( b(s) ),即:

常用的基线是状态值函数

V(s) = \mathbb{E}{\pi\theta}[R|s]
V(s) = \mathbb{E}{\pi\theta}[R|s]

优势函数

将基线函数扩展为优势函数

A(s, a) = Q(s, a) - V(s)
A(s, a) = Q(s, a) - V(s)

,即:

\nabla_\theta J(\theta) = \mathbb{E}{\pi\theta} \left[ \nabla_\theta \log \pi(a|s;\theta) \cdot A(s, a) \right]
\nabla_\theta J(\theta) = \mathbb{E}{\pi\theta} \left[ \nabla_\theta \log \pi(a|s;\theta) \cdot A(s, a) \right]

减少方差

使用 Actor-Critic 算法,用一个 Critic 网络来估计

V(s)
V(s)

,从而进一步降低方差。


[Python]REINFORCE算法实现

项目代码我已经放入GitCode里面,可以通过下面链接跳转:🔥 【强化学习】--- REINFORCE算法 后续相关单智能体强化学习算法也会不断在【强化学习】项目里更新,如果该项目对你有所帮助,请帮我点一个星星✨✨✨✨✨,鼓励分享,十分感谢!!! 若是下面代码复现困难或者有问题,也欢迎评论区留言

代码语言:javascript
代码运行次数:0
运行
复制
"""《REINFORCE算法项目》
    时间:2024.012
    作者:不去幼儿园
"""
import argparse  # 用于处理命令行参数
import gym  # 引入OpenAI Gym库,提供强化学习环境
import numpy as np  # 用于数值计算
from itertools import count  # 用于创建无限计数器

import torch  # 引入PyTorch库,用于深度学习
import torch.nn as nn  # 引入神经网络模块
import torch.nn.functional as F  # 引入常用的神经网络函数,如激活函数
import torch.optim as optim  # 引入优化器模块
from torch.distributions import Categorical  # 引入分类分布,用于策略采样
定义策略网络
代码语言:javascript
代码运行次数:0
运行
复制
# 定义策略网络
class Policy(nn.Module):
    def __init__(self):
        super(Policy, self).__init__()
        self.affine1 = nn.Linear(4, 128)  # 输入层:状态维度为4,隐层维度为128
        self.affine2 = nn.Linear(128, 2)  # 输出层:动作维度为2(左右移动)

        self.saved_log_probs = []  # 保存动作对应的log概率,用于后续梯度计算
        self.rewards = []  # 保存回合奖励

    def forward(self, x):
        x = F.relu(self.affine1(x))  # 隐层使用ReLU激活函数
        action_scores = self.affine2(x)  # 输出动作得分
        return F.softmax(action_scores, dim=1)  # 使用Softmax将动作得分转换为概率分布
更新策略
代码语言:javascript
代码运行次数:0
运行
复制
# 完成一个回合并更新策略
def finish_episode():
    R = 0  # 初始化累计折扣奖励
    policy_loss = []  # 用于保存策略损失
    rewards = []  # 保存折扣奖励

    # 计算折扣奖励
    for r in policy.rewards[::-1]:  # 倒序遍历每一步的奖励
        R = r + args.gamma * R  # 计算累计奖励
        rewards.insert(0, R)  # 将累计奖励插入到列表开头

    rewards = torch.tensor(rewards)  # 将奖励转换为张量
    rewards = (rewards - rewards.mean()) / (rewards.std() + eps)  # 标准化奖励

    # 计算策略损失
    for log_prob, reward in zip(policy.saved_log_probs, rewards):
        policy_loss.append(-log_prob * reward)  # 损失是负的log概率乘以奖励

    optimizer.zero_grad()  # 清零梯度
    policy_loss = torch.cat(policy_loss).sum()  # 合并所有损失并求和
    policy_loss.backward()  # 反向传播计算梯度
    optimizer.step()  # 使用优化器更新网络参数

    del policy.rewards[:]  # 清空回合奖励
    del policy.saved_log_probs[:]  # 清空log概率
主函数
代码语言:javascript
代码运行次数:0
运行
复制
# 主函数
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='PyTorch REINFORCE example')  # 创建命令行参数解析器
    parser.add_argument('--gamma', type=float, default=0.99, metavar='G',
                        help='discount factor (default: 0.99)')  # 折扣因子
    parser.add_argument('--seed', type=int, default=543, metavar='N',
                        help='random seed (default: 543)')  # 随机种子
    parser.add_argument('--render', action='store_true',
                        help='render the environment')  # 是否渲染环境
    parser.add_argument('--log-interval', type=int, default=10, metavar='N',
                        help='interval between training status logs (default: 10)')  # 日志间隔
    args = parser.parse_args()  # 解析命令行参数

    policy = Policy()  # 创建策略网络
    optimizer = optim.Adam(policy.parameters(), lr=1e-2)  # 定义优化器,使用Adam,学习率为0.01
    eps = np.finfo(np.float32).eps.item()  # 防止浮点数精度问题的小数值

    env = gym.make('CartPole-v1')  # 创建CartPole-v1环境
    torch.manual_seed(args.seed)  # 设置随机种子
    running_reward = 10  # 初始化运行奖励

    for i_episode in count(1):  # 无限循环,直到达到停止条件
        state, _ = env.reset()  # 重置环境,获取初始状态
        for t in range(10000):  # 限制最大时间步,防止无限循环
            action = select_action(state)  # 选择动作
            state, reward, done, _, _ = env.step(action)  # 执行动作,返回下一状态和奖励
            if args.render:  # 如果启用了渲染
                env.render()  # 渲染环境
            policy.rewards.append(reward)  # 保存奖励
            if done:  # 如果当前回合结束
                break  # 跳出循环

        running_reward = running_reward * 0.99 + t * 0.01  # 更新运行奖励
        finish_episode()  # 完成回合并更新策略

        if i_episode % args.log_interval == 0:  # 每隔一定回合打印日志
            print('Episode {}\tLast length: {:5d}\tAverage length: {:.2f}'.format(
                i_episode, t, running_reward))

        if running_reward > env.spec.reward_threshold:  # 如果运行奖励超过环境要求的阈值
            print("Solved! Running reward is now {} and "
                  "the last episode runs to {} time steps!".format(running_reward, t))
            break  # 训练结束
定义策略网络
代码语言:javascript
代码运行次数:0
运行
复制
# 定义策略网络
class Policy(nn.Module):
    def __init__(self):
        super(Policy, self).__init__()
        self.affine1 = nn.Linear(4, 128)  # 输入层:状态维度为4,隐层维度为128
        self.affine2 = nn.Linear(128, 2)  # 输出层:动作维度为2(左右移动)

        self.saved_log_probs = []  # 保存动作对应的log概率,用于后续梯度计算
        self.rewards = []  # 保存回合奖励

    def forward(self, x):
        x = F.relu(self.affine1(x))  # 隐层使用ReLU激活函数
        action_scores = self.affine2(x)  # 输出动作得分
        return F.softmax(action_scores, dim=1)  # 使用Softmax将动作得分转换为概率分布

[Notice] 注意事项

策略网络Policy 类定义了一个简单的全连接神经网络,用于预测动作的概率分布。

REINFORCE算法

使用策略梯度方法直接优化策略。

每一回合计算折扣奖励,并基于梯度上升更新策略。

环境交互

使用OpenAI Gym的CartPole-v1环境。

通过策略网络与环境交互并采集经验。

可以通过调整--gamma--seed--log-interval等参数来测试不同的训练效果。

代码语言:javascript
代码运行次数:0
运行
复制
​# 环境配置
Python                  3.11.5
torch                   2.1.0
torchvision             0.16.0
gym                     0.26.2

7.Policy Gradient算法和REINFORCE算法的对比

PG(Policy Gradient)算法是一个更大的算法框架,而 REINFORCE 是 PG 算法的一种具体实现。因此,比较两者的关键在于 PG 的普适性和 REINFORCE 的具体特性。

优缺点对比

特性

PG 算法

REINFORCE

普适性

是一个框架,包含多个算法实现。

是 PG 框架下的一种具体实现。

梯度估计方式

支持多种方法,如时间差分、优势函数、基线等。

仅使用蒙特卡洛方法,直接计算累积奖励。

方差

使用基线函数和优势函数,可以有效降低梯度估计的方差。

累积奖励估计方差较大,收敛速度较慢。

偏差

根据估计方法,可能引入小偏差。

梯度估计无偏,但训练噪声较大。

计算效率

Actor-Critic 等变种可以逐步更新,计算高效。

需要完整的轨迹,不能实时更新,效率较低。

适用场景

高效适用于连续动作空间或复杂策略优化问题。

适用于小型问题或作为基线方法用于研究和对比。

  • PG 是更灵活和高效的框架,适用于复杂任务,算法设计可扩展性强。
  • REINFORCE 是最基础的策略梯度算法,适合作为入门学习和小型问题的参考实现,但在实际应用中效果可能受限于方差较高的问题。

8.REINFORCE 的优点和缺点

优点

算法简单易实现,适用于多种环境。

不需要建模环境的动态或奖励函数。

缺点

收敛速度较慢,尤其是在高维动作空间中。

奖励的方差可能较大,影响梯度估计。

9.总结

REINFORCE 是强化学习中的经典策略梯度方法,通过直接优化策略来解决问题。尽管存在一些缺陷(如方差较高),但它为后续的改进算法(如 Actor-Critic、PPO)奠定了理论基础。

更多强化学习文章,请前往:【强化学习(RL)】专栏

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.REINFORCE 算法
  • 2.基本概念
  • 3.算法的关键思想
  • 4.REINFORCE 算法流程
  • 5.公式推导
  • 6.算法的改进点
  • [Python]REINFORCE算法实现
    • 定义策略网络
    • 更新策略
    • 主函数
    • 定义策略网络
  • [Notice] 注意事项
  • 7.Policy Gradient算法和REINFORCE算法的对比
    • 优缺点对比
  • 8.REINFORCE 的优点和缺点
  • 9.总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档