79强化学习基础算法及实践--策略梯度强化学习方法实现

策略梯度强化学习方法实现

策略梯度方法介绍

前面,我们学习了 Q-learning 算法,这是一种典型的基于价值迭代的强化学习算法。在状态 → 动作的映射过程中,基于价值迭代的算法可以让系统按照策略指引进行探索,并在探索的每一步都对状态价值进行更新。
那么,在基于价值的迭代中,我们有几个问题无法回避。例如,对于每个状态的价值更新时,需要估计所有行动的可能性。不同于走迷宫这种离散性的动作,机器人控制和自动驾驶等应用场景下,连续动作带来的海量状态信息使得计算过程几乎无法实现。
此时,Policy Gradient 这种基于策略迭代的强化学习算法应运而生,策略梯度不再计算奖励,而是直接计算某种状态下采取某一动作的概率,并直接通过概率来选择动作。
如果你看完上面的描述依然比较懵,这里就模仿 David Silver 在其 深度强化学习课程 中的一个例子来形象化说明。如下图所示的迷宫,现在有一个机器人要找到金币。其中,找到金币奖励 +1,遇到炸弹奖励 -1。特别地,机器人无法区分两个灰色区域,即其无法得知自己在左边的灰色区域还是在右边的灰色区域。

image.png

如果我们采用基于价值迭代的方法学习,那么在确定的状态下就会得到确定的奖励。因此,灰色(状态)方格的下一步动作(向左或向右)是确定的,即总是向左或向右。而这可能会导致如下图所示,落入左边白色格子和相邻灰色格子的错误循环中而无法拿到金币。
image.png

而当使用策略迭代方法时,学习到的策略输出向右和向左动作的概率都是 0.5,从而不会陷入错误的循环过程中。
image.png

这就是策略梯度方法的优点,既可以处理价值函数无法适用的连续动作场景。除此之外,由于概率化输出从而避免价值函数确定性在某些场景下不适用的问题。

策略梯度过程推导

image.png

基于策略迭代的学习最终目标依旧是系统获得最多的奖励,为了求解最优策略函数πθ(s,a) ,那么同样可以通过一个目标函数来衡量策略的好坏。这就好比监督学习中选择平方损失函数来衡量真实值和预测值之间的误差,再对参数进行更新的过程。
一般情况下,根据不同的问题类型,对应这三种目标函数:


image.png

有了价值目标函数,接下来就是通过最优化方法使得目标函数值最大化,并得到此时对应的参数θ。因此,基于策略迭代的强化学习实际上又回到了最优化问题。
在监督学习的内容中,我们是通过一种叫做梯度下降的算法去找到目标函数的最小值。如今,面对寻找目标函数最大值的问题,同样可以通过梯度来完成,而这里可以使用梯度上升算法。无论是梯度下降还是梯度上升,其实都是一种思路,只是面临最小或最大值的问题。


image.png

既然有限差分并不是一个较好的方法,那么我们就要使用计算梯度的方法来更新策略,这就要求策略函数是可微分的。这里使用了似然系数 Likelihood ratios 概念,即函数在某个变量θ 处的梯度等于该处函数值与该函数的自然对数函数在此处梯度的乘积:
image.png

策略梯度定理

策略梯度定理揭示了不同目标函数求解梯度的一致性,知道如何计算梯度,那么就能通过梯度上升求解参数了。

蒙特卡洛策略梯度算法

image.png

蒙特卡罗策略梯度算法的伪代码如下:


image.png

除了蒙特卡洛策略梯度算法,还有一种叫 Actor-Critic 的策略梯度算法。蒙特卡洛策略梯度算法的一个很大缺陷在于方差较高,如果能通过某种机制相对准确地估计状态价值,并用来指导策略更新,那就太好了。Actor-Critic 算法就是这样做的,该算法分为 Actor 和 Critic 两部分。其中,Actor 负责更新策略,而 Critic 负责更新价值。当 Critic 更新价值时,其实就是 Q-learning 算法或者 SARSA 算法。
所以说,Actor-Critic 策略梯度算法相当于同时兼具了价值迭代和策略迭代的优点。Actor-Critic 策略梯度算法的伪代码如下:


image.png

本次实验中,我们重点实现较为简单的蒙特卡罗策略梯度算法。

策略梯度算法实现

上面的理论介绍可能看起来实在是有一些头疼,策略梯度理解起来的确比较抽象。如果你不太能看明白,可以与下面的算法实现实例来结合理解。
实现策略梯度算法,这里使用 Gym 中的 CartPole-v1 环境,黑色小推车通过轴承连接到一根活动杆,并在无摩擦力的轨道上移动,移动是通过向小推车施加为 +1 或 -1 的推力完成。如果小车停下,木杆肯定会倒下,实验通过控制小车左右移动来保证木杆竖立起来。如果木杆左右顷角大于 15 度或者小车左右移动超过 2.4 个单元,游戏立即结束。木杆在每个时间步长内保存竖立,即获得 +1 的奖励。
下面,我们通过 Gym 载入 CartPole-v1 环境,由于 Notebook 不支持可视化 CartPole-v1 环境,故无法执行渲染操作。

import gym
import warnings
warnings.filterwarnings('ignore')

env = gym.make('CartPole-v1')

我们尝试通过随机动作,查看每次 episodes 能坚持多少个时间步长:

for _ in range(10):
    t = 0
    env.reset()
    while True:
        action = env.action_space.sample()
        observation, reward, done, _ = env.step(action)
        t += 1
        if done:
            print("Episode finished after {} timesteps".format(t))
            break

你可以发现,在随机动作下,每个 Episode 一般不超过 50 个时间步长。这里的时间步长其实也就对应着该次 Episode 的累计奖励值。
接下来,我们根据上面提供的蒙特卡洛策略梯度算法伪代码来实现基于蒙特卡洛策略梯度的强化学习算法。

def mc_policy_gradient(env, theta, lr, episodes):
    """
    参数:
    env -- 环境
    theta -- 参数
    lr -- 学习率
    episodes -- 迭代次数

    返回: 
    episodes -- 参数
    """
    # Monte-Carlo 策略梯度算法
    for episode in range(episodes):  # 迭代 episode
        episode = []
        start_observation = env.reset()  # 初始化环境
        t = 0
        while True:
            policy = np.dot(theta, start_observation)  # 计算策略值
            # 这里的 action_space 为 2, 故使用 Sigmoid 激活函数处理策略值
            pi = 1 / (1 + np.exp(-policy))
            if pi >= 0.5:
                action = 1  # 向右施加力
            else:
                action = 0  # 向左施加力
            next_observation, reward, done, _ = env.step(action)  # 执行动作
            # 将环境返回结果添加到 episode 中
            episode.append([next_observation, action, pi, reward])
            start_observation = next_observation  # 将返回 observation 作为下一次迭代 observation
            t += 1
            if done:
                print("Episode finished after {} timesteps".format(t))
                break
        # 根据上一次 episode 更新参数 theta
        for timestep in episode:
            observation, action, pi, reward = timestep
            theta += lr * (1 - pi) * np.transpose(-observation) * reward

    return theta
import numpy as np
lr = 0.02
theta = np.random.rand(4)
episodes = 10

mc_policy_gradient(env, theta, lr, episodes)

可以发现,引入蒙特卡洛策略梯度算法,每个 Episode 一般都会达到数百个时间步长(默认条件下,max_episode_steps = 500)。当然,由于随机初始化参数,有时也无法得到很好的学习结果。但是,如果你把一次比较不错的结果的参数重新传入到函数中,那么几乎每次都能得到更好的结果,这也就是不断强化学习的过程。

使用策略梯度训练 CartPole

上一个实验中,我们了解并实现了策略梯度算法。同时,使用 OpenAI 提供的 Gym 强化学习环境测试了算法。不过,受限于 Notebook 实验环境,我们无法可视化强化学习的过程,只能打印出学习参数和每个 Episode 学习的时间步长。
本次挑战,我们将利用实验楼提供的桌面在线环境,完成 CartPole 小游戏可视化学习过程。
首先,需要在桌面环境中安装 Gym 强化学习环境。安装步骤如下:
安装依赖:

sudo apt-get update
sudo apt-get install cmake swig

安装 Gym:

sudo pip3 install gym

挑战:参考「基于策略的强化学习方法」实验内容,尝试通过 Monte-Carlo 策略梯度算法训练 CartPole-v1 游戏。
规定:将代码写入 mc_cartpole.py,并放入 /home/shiyanlou/Code 路径下方。你可以通过执行 python3 mc_cartpole.py 查看结果。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容