强化学习—PPO代码实现及个人详解5(python)

这篇是PPO算法代码分析的最后一篇,如果要去跑代码,就将我这几篇挨着复制到运行软件中即可,要注意好缩进!

五、定义环境

import gym
import os
import numpy as np


def all_seed(env, seed=2):
    ''' 万能的seed函数
    '''
    if seed == 0:
        return
    env.seed(seed)  # env config
    np.random.seed(seed)
    random.seed(seed)
    torch.manual_seed(seed)  # config for CPU
    torch.cuda.manual_seed(seed)  # config for GPU
    os.environ['PYTHONISTA'] = str(seed)  # config for python scripts
    # config for cudnn
    torch.backends.cudnn.deterministic = True
    torch.backends.cudnn.benchmark = False
    torch.backends.cudnn.enabled = False


def env_agent_config(cfg):
    env = gym.make(cfg.env_name)  # 创建环境
    all_seed(env, seed=cfg.seed)
    n_states = env.observation_space.shape[0]
    n_actions = env.action_space.n
    print(f"状态空间维度:{n_states},动作空间维度:{n_actions}")
    # 更新n_states和n_actions到cfg参数中
    setattr(cfg, 'n_states', n_states)
    setattr(cfg, 'n_actions', n_actions)
    agent = Agent(cfg)
    return env, agent

Gym是环境,os是操作系统相关内容,numpy是数值操作相关。

env.seed(seed):设置环境的随机种子为指定的 seed 值。

之后设置其他随机种子:设置环境的、numpy 库、Python 内置的随机数生成器random的、PyTorch 在CPU上的、PyTorch 在GPU上随机种子。os.environ['PYTHONHASHSEED'] = str(seed):设置 Python 脚本的哈希种子。确保在不同的运行环境中相同的输入数据生成相同的哈希值。

针对 cudnn 进行一些配置,torch.backends.cudnn.deterministic = True: 这一行代码告诉 cuDNN 库在执行卷积等操作时使用确定性算法,即每次运行时相同输入会产生相同输出。这有助于确保在相同条件下运行时的结果一致性,尤其是在使用随机数种子控制的情况下。torch.backends.cudnn.benchmark = False: 将此参数设置为 False 可以禁用 cuDNN 的自动寻找最适合当前配置的卷积算法功能。关闭 benchmark 模式可能会增加一些计算时间,但有助于确保结果的可重复性。torch.backends.cudnn.enabled = False: 这行代码可以显式地禁用 cuDNN 加速。在某些情况下,可能需要禁用 cuDNN 加速以避免一些特定问题,或者用于调试目的。

之后定义一个新的函数,先创建环境env,之后设置所有需要的随机种子。获取环境的状态空间维度和动作空间维度(获取方式不同,获取状态是连续空间,所以需要用shape[0],对于动作的离散空间,用n就行了)。接着使用 setattr 函数将 n_states 和 n_actions 更新到配置参数 cfg 中(setattr 的作用是将 n_states 和 n_actions 这两个变量的值分别设置到对象 cfg 中)。最后创建智能体对象 agent,并返回环境和智能体对象。

注意:

(1)"种子"通常指的是一个用来初始化随机数生成器的数值。随机数生成器根据种子生成一个伪随机数序列。如果使用相同的种子,那么生成的随机数序列将是确定性的,也就是说每次生成的随机数都是一样的。(简单来说,我们对很多东西进行初始化时,需要给一个初始值,但是每次随机的初始值都不一样的话,结果就很难复现出来,所以我们加入一个种子值,这里设定的是seed=1,所以每次选择的随机数序列也就确定了,随机就变成了伪随机。这种机制确保了实验的可重现性,使得在同样的条件下,每次运行得到的结果都是相同的,有助于调试和验证算法的正确性。)

六、设置参数

import matplotlib.pyplot as plt
import seaborn as sns


class Config:
    def __init__(self) -> None:
        self.env_name = "CartPole-v1"  # 环境名字
        self.new_step_api = True  # 是否用gym的新api
        self.algo_name = "PPO"  # 算法名字
        self.mode = "train"  # train or test
        self.seed = 2  # 随机种子
        self.device = "cuda"  # device to use
        self.train_eps = 200  # 训练的回合数
        self.test_eps = 20  # 测试的回合数
        self.max_steps = 200  # 每个回合的最大步数
        self.eval_eps = 5  # 评估的回合数
        self.eval_per_episode = 10  # 评估的频率

        self.gamma = 0.99  # 折扣因子
        self.k_epochs = 4  # 更新策略网络的次数
        self.actor_lr = 0.0003  # actor网络的学习率
        self.critic_lr = 0.0003  # critic网络的学习率
        self.eps_clip = 0.2  # epsilon-clip
        self.entropy_coefficient = 0.01  # entropy的系数
        self.update_freq = 100  # 更新频率
        self.actor_hidden_dim = 256  # actor网络的隐藏层维度
        self.critic_hidden_dim = 256  # critic网络的隐藏层维度


def smooth(data, weight=0.9):
    '''用于平滑曲线,类似于Tensorboard中的smooth曲线
    '''
    last = data[0]
    smoothed = []
    for point in data:
        smoothed_val = last * weight + (1 - weight) * point  # 计算平滑值
        smoothed.append(smoothed_val)
        last = smoothed_val
    return smoothed


def plot_rewards(rewards, cfg, tag='train'):
    ''' 画图
    '''
    sns.set()
    plt.figure()  # 创建一个图形实例,方便同时多画几个图
    plt.title(f"{tag}ing curve on {cfg.device} of {cfg.algo_name} for {cfg.env_name}")
    plt.xlabel('episodes')
    plt.plot(rewards, label='rewards')
    plt.plot(smooth(rewards), label='smoothed')
    plt.legend()
    plt.show()  # 显示绘制的图形

用config类创造实例,然后进行初始化,设置好参数。

定义smooth函数对数据进行平滑处理。首先将数据的第一个点作为初始值,然后创建一个空列表用于存放平滑后的数值,并遍历原始数据中的每个数据点,之后使用指数加权移动平均计算平滑值,将平滑值添加到平滑列表中,最后更新last为当前的平滑值,以便下一次循环使用,循环结束后就返回平滑后的数据。

plot_rewards 函数用于绘制奖励曲线图,其中包括了原始奖励曲线和经过平滑处理后的奖励曲线。函数内部使用了 seaborn 库设置样式,并调用了 plt 对象来创建图形、设置标题、标签,并绘制曲线。

注意:

(1)self.new_step_api = False # 是否用gym的新api,对于这句而言,self.new_step_api 可能是用来控制是否使用 Gym 最新版本中引入的新的环境交互方法(新的 API)。不使用可能是为了兼容之前的代码或特定的需求。

(2)import matplotlib.pyplot as plt和import seaborn as sns是给画图设置样式,并让其可视化的。

七、开始训练

# 获取参数
cfg = Config()
# 训练
env, agent = env_agent_config(cfg)
best_agent, res_dic = train(cfg, env, agent)

plot_rewards(res_dic['rewards'], cfg, tag="train")
# 测试
res_dic = test(cfg, env, best_agent)
plot_rewards(res_dic['rewards'], cfg, tag="test")  # 画出结果

创建一个 Config 类的实例,用于存储参数配置,

根据参数配置创建环境和智能体。

使用训练函数 train 对代理进行训练,并返回最佳智能体和训练结果奖励。调用 plot_rewards 函数绘制训练奖励曲线。

使用测试函数 test 对最佳智能体进行测试。再次调用 plot_rewards 函数绘制测试奖励曲线。

当然,代码最好再整体看一下,理解一下各部分之间的关系

(以上代码分析均为个人理解,如果有误,欢迎指正讨论!)

  • 18
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: PPO (Proximal Policy Optimization) 是一种基于梯度的强化学习算法。它的主要思想是通过对策略的更新来提高策略的效率。主要包括以下步骤: 1. 首先选取一个初始策略,然后使用这个策略在环境中进行多次探索。 2. 收集探索中获得的数据,并使用这些数据来估计策略的价值。 3. 通过梯度下降法来更新策略,使得策略的价值更高。 4. 通过使用一个称为“clip”的技巧来限制策略的更新,以避免策略变得过于激进。 5. 重复上述步骤,直到策略达到最优。 PPO 通过在策略迭代过程中限制更新的幅度来防止策略的更新过于激进,从而提高了稳定性和效率。这也是为什么 PPO 算法在实际应用中表现很好的原因。 ### 回答2: 强化学习ppo算法,全称是Proximal Policy Optimization,是一种用于解决连续动作空间问题的强化学习算法ppo算法的核心思想是通过参数更新策略,优化策略的近似目标函数,以获得更好的策略。它采用了两个核心技术:策略评估和策略改进。 首先,ppo算法使用一个神经网络来表示策略,并基于当前策略采样生成训练数据。然后,利用产生的训练数据来更新策略模型的参数,提高策略的性能。 在策略评估方面,ppo算法采用了一种称为价值函数的辅助函数,用于估计当前策略的优劣。这个价值函数可以帮助判断哪些动作对于获得更好的回报是有帮助的。通过评估策略的优劣,可以确定哪些策略需要得到改进,以及改进的方向。 在策略改进方面,ppo算法使用一种叫做近端策略优化的方法,将策略的更新限制在一个可接受的范围内,防止策略的更新过于剧烈。这种方法可以保证策略更新的稳定性,并且避免一些不可预见的问题。 最后,通过多轮的策略评估和策略改进,ppo算法可以逐步优化策略,提高强化学习的性能。相比于传统的强化学习算法ppo算法具有较强的鲁棒性和稳定性。 总结来说,ppo算法是一种用于解决连续动作空间问题的强化学习算法,通过使用策略评估和策略改进的方法,优化策略模型的参数,以提高策略的性能。它具有鲁棒性和稳定性的优势,适用于许多实际问题的求解。 ### 回答3: 强化学习(Reinforcement Learning)是一种机器学习方法,其通过智能体(agent)与环境(environment)的交互学习,通过观察环境状态和采取不同的行动来优化策略,使得智能体获得更高的奖励。 其中,PPO(Proximal Policy Optimization)是一种基于策略梯度(Policy Gradient)的强化学习算法PPO算法通过定义一个目标函数,通过最大化该目标函数,优化策略。其基本思想是通过充分利用已有数据的经验,进行更新,并保证更新策略与之前的策略之间的差异不会太大,避免过大的策略改变导致训练不稳定。PPO算法的目标函数使用了一种被称为"近似比率(Importance Sampling Ratio)"的技巧,用于约束策略更新的幅度。 PPO算法具体步骤如下: 1. 初始化策略参数 2. 根据当前策略与环境交互采集样本数据 3. 计算采集到的样本数据的优势估计值,用于评估每个状态行动对的价值 4. 根据样本数据计算目标函数,并通过优化算法(如Adam)更新策略参数 5. 重复步骤2-4,直到达到预设的训练轮数或满足停止条件 PPO算法相较于其他强化学习算法的优势在于,其采用了一种近似比率的方法来约束策略更新范围,避免了过于剧烈的改变,增强了算法的稳定性。此外,PPO算法还可通过引入剪切或克隆操作来控制策略更新的幅度,进一步增加算法的稳定性。 总结起来,PPO算法是基于策略梯度的一种强化学习算法,通过近似比率来约束策略更新的幅度,以提高算法的稳定性。通过与环境的交互学习,PPO算法能够优化策略,并使智能体获得更好的奖励。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值