【机器学习】强化学习(四)-时序差分学习

蒙特卡洛算法需要使用完整的片段进行计算,这在有些问题中是不现实的,尤其是对于没有终止状态的问题。时序差分算法对此进行了改进

5593ef44acfac8d37dabe9e9a713d401.png

7f4fe94283995533602016a8c17cbfd6.png

蒙特卡洛控制和时序差分学习有什么区别?

8f615d1a1ee7aa7986444e9464a94d11.png

四、时序差分算法(Temporal Difference Learning, TD 学习)

7edd4a11530e57e6dae72aa13befee1b.jpeg

58251638064ea782ac62d19423c1b663.png

4.1 时序差分(0)

1cbefc77fe6c1d2e9729a54b234376b2.png

5adec1391dfb5df56b152e2de764608f.png

cea763064e551d677df788f7573d8e79.png

4.2 Sarsa算法

d80eb1f2bd2ed77ede7d87c51fdfe8f3.png

076e50956c2f0df4bf3170ea54c7d170.png

e775b85dd2669c174e58ad26584df9f8.png

4.3 Q学习(Q-learning)

e0bb9c327c91b7a14f705f1f46e04656.png

adcfa8ffc425d9872cd8d9f3359fc34b.png

97541e4088b179157e3381776a9e7522.png

4.4 Sarsa和Q-learning有什么区别?

8ee0528240e51e90ad5f7c9deadc3ba0.png

4.5 示例代码

公共类:discrete.py  plotting.py

离散环境的类 discrete.py它继承自 gym 库的 Env 类,用于创建和管理强化学习的环境。它的主要功能是:

  • 定义了环境的基本属性,如状态的数量,动作的数量,状态转移的概率,初始状态的分布,动作的空间,状态的空间等。

  • 定义了环境的基本方法,如设置随机数种子,重置环境,执行一个动作,返回下一个状态,奖励,是否结束和附加信息等。

  • 使用了 numpy 库,gym 库和 categorical_sample 函数来进行数值计算,环境管理和概率采样等操作。

# 导入 numpy 库,用于进行数值计算
import numpy as np


# 导入 gym 库,用于创建和管理强化学习的环境
from gym import Env, spaces
# 导入 gym 库的 seeding 模块,用于设置随机数种子
from gym.utils import seeding
# 导入 gym 库的 toy_text 模块的 categorical_sample 函数,用于从一个概率分布中采样一个类别
from gym.envs.toy_text.utils import categorical_sample


# 定义一个离散环境的类,继承自 gym 库的 Env 类
class DiscreteEnv(Env):


    """
    Has the following members
    - nS: number of states # 状态的数量
    - nA: number of actions # 动作的数量
    - P: transitions (*) # 状态转移的概率
    - isd: initial state distribution (**) # 初始状态的分布


    (*) dictionary of lists, where
      P[s][a] == [(probability, nextstate, reward, done), ...] # P[s][a] 是一个列表,表示在状态 s 下采取动作 a 后,可能的下一个状态,奖励和是否结束的概率
    (**) list or array of length nS # isd 是一个长度为 nS 的列表或数组,表示每个状态作为初始状态的概率
    """


    # 定义初始化方法,接受四个参数:状态的数量,动作的数量,状态转移的概率,初始状态的分布
    def __init__(self, nS, nA, P, isd):
        self.P = P # 将状态转移的概率赋值给 self.P
        self.isd = isd # 将初始状态的分布赋值给 self.isd
        self.lastaction = None  # for rendering # 定义一个属性,用于记录上一次的动作,用于渲染
        self.nS = nS # 将状态的数量赋值给 self.nS
        self.nA = nA # 将动作的数量赋值给 self.nA


        # 定义一个属性,表示动作的空间,是一个离散的空间,取值范围是 [0, nA-1]
        self.action_space = spaces.Discrete(self.nA)
        # 定义一个属性,表示状态的空间,是一个离散的空间,取值范围是 [0, nS-1]
        self.observation_space = spaces.Discrete(self.nS)


        self.seed() # 调用 seed 方法,设置随机数种子
        # 从初始状态的分布中采样一个状态,赋值给 self.s
        self.s = categorical_sample(self.isd, self.np_random)


    # 定义一个方法,用于设置随机数种子,接受一个参数:种子
    def seed(self, seed=None):
        # 调用 seeding 模块的 np_random 函数,根据种子生成一个随机数生成器,赋值给 self.np_random,并返回种子
        self.np_random, seed = seeding.np_random(seed)
        return [seed]


    # 定义一个方法,用于重置环境,返回初始状态
    def reset(self):
        # 从初始状态的分布中采样一个状态,赋值给 self.s
        self.s = categorical_sample(self.isd, self.np_random)
        self.lastaction = None # 将上一次的动作设为 None
        return int(self.s) # 返回初始状态,转换为整数类型


    # 定义一个方法,用于执行一个动作,返回下一个状态,奖励,是否结束和附加信息
    def step(self, a):
        # 根据当前状态和动作,从状态转移的概率中获取可能的转移列表,赋值给 transitions
        transitions = self.P[self.s][a]
        # 从转移列表中,根据转移的概率,采样一个转移的索引,赋值给 i
        i = categorical_sample([t[0] for t in transitions], self.np_random)
        # 根据转移的索引,获取转移的概率,下一个状态,奖励和是否结束,赋值给 p, s, r, d
        p, s, r, d = transitions[i]
        self.s = s # 将下一个状态赋值给 self.s
        self.lastaction = a # 将当前动作赋值给 self.lastaction
        # 返回下一个状态,奖励,是否结束和附加信息,其中附加信息是一个字典,包含转移的概率,下一个状态转换为整数类型
        return (int(s), r, d, {"prob": p})

用于绘制一些问题中的价值函数的图形的函数 plotting.py 。价值函数表示在不同的状态下,采取最优策略能够获得的期望回报。这些代码使用了matplotlib库,numpy库,pandas库和namedtuple来进行数据处理和图形绘制。代码中定义了三个函数,分别是:

  • plot_cost_to_go_mountain_car:这个函数用于绘制山地车问题的价值函数,山地车问题是一个连续状态空间的强化学习问题,目标是让一辆车在两座山之间来回移动,最终到达右边的山顶。这个函数接受一个环境对象,一个估计器对象和一个网格数作为参数,然后生成一个三维的曲面图,显示在不同的位置和速度下,采取最优动作的成本(负的价值)。

  • plot_value_function:这个函数用于绘制二十一点游戏的价值函数,二十一点游戏是一个离散状态空间的强化学习问题,目标是让玩家的牌的总和尽可能接近21,但不超过21,同时要比庄家的牌的总和大。这个函数接受一个价值函数字典和一个标题作为参数,然后分别绘制两个三维的曲面图,显示在不同的玩家总和和庄家显示牌下,有可用的Ace和没有可用的Ace的情况下的价值。

  • plot_episode_stats:这个函数用于绘制每个回合的统计信息,包括回合的长度,回合的奖励,回合的时间步数和回合的编号。这个函数接受一个命名元组,一个平滑窗口和一个是否显示图形的标志作为参数,然后分别绘制三个二维的折线图,显示回合的长度,回合的奖励和回合的时间步数随回合的编号的变化。这个函数返回三个图形对象。

# 导入matplotlib库,用于绘制图形
import matplotlib
# 导入numpy库,用于进行数值计算
import numpy as np
# 导入pandas库,用于进行数据分析
import pandas as pd
# 导入namedtuple,用于创建命名元组
from collections import namedtuple
# 导入pyplot模块,用于绘制二维图形
from matplotlib import pyplot as plt
# 导入Axes3D模块,用于绘制三维图形
from mpl_toolkits.mplot3d import Axes3D


# 创建一个命名元组,用于存储每个回合的长度和奖励
EpisodeStats = namedtuple("Stats",["episode_lengths", "episode_rewards"])


# 定义一个函数,用于绘制山地车问题的价值函数
def plot_cost_to_go_mountain_car(env, estimator, num_tiles=20):
    # 生成一个等差数列,表示状态空间中的位置范围
    x = np.linspace(env.observation_space.low[0], env.observation_space.high[0], num=num_tiles)
    # 生成一个等差数列,表示状态空间中的速度范围
    y = np.linspace(env.observation_space.low[1], env.observation_space.high[1], num=num_tiles)
    # 生成一个网格,表示状态空间中的所有可能组合
    X, Y = np.meshgrid(x, y)
    # 对每个状态,计算估计器预测的最大动作价值,并取负数,表示成本
    Z = np.apply_along_axis(lambda _: -np.max(estimator.predict(_)), 2, np.dstack([X, Y]))


    # 创建一个图形对象,设置大小为10*5
    fig = plt.figure(figsize=(10, 5))
    # 在图形对象上添加一个子图,设置为三维投影
    ax = fig.add_subplot(111, projection='3d')
    # 在子图上绘制一个曲面,表示价值函数
    surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1,
                           cmap=matplotlib.cm.coolwarm, vmin=-1.0, vmax=1.0)
    # 设置子图的x轴标签为位置
    ax.set_xlabel('Position')
    # 设置子图的y轴标签为速度
    ax.set_ylabel('Velocity')
    # 设置子图的z轴标签为价值
    ax.set_zlabel('Value')
    # 设置子图的标题为山地车问题的成本函数
    ax.set_title("Mountain \"Cost To Go\" Function")
    # 在图形对象上添加一个颜色条,表示价值的范围
    fig.colorbar(surf)
    # 显示图形
    plt.show()




# 定义一个函数,用于绘制价值函数的曲面图
def plot_value_function(V, title="Value Function"):
    """
    Plots the value function as a surface plot.
    """
    # 找到价值函数中的最
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值