《TF2.x》强化学习手册-P47-P59-TD时序差分-Monte_carlo蒙特卡洛预测与控制算法

实现时序差分学习

时序差分(Temporal Difference ,TD)算法。TD算法是一种预测值或目标值校正的方法,用于强化学习中的值函数(如Q函数)的估计。它通过将当前估计的值将来更新的值进行比较来工作。

V ( S t ) ← V ( S t ) + α ( R t + 1 + γ V ( S t + 1 ) − V ( S t ) ) V(S_t)\leftarrow V(S_t)+\alpha\left(R_{t+1}+\gamma V(S_{t+1})-V(S_t)\right) V(St)V(St)+α(Rt+1+γV(St+1)V(St))

其中 S t 是当前状态, R t + 1 是下一个状态的即时奖励, S t + 1 是下一个状态。 \text{其中}S_t\text{是当前状态,}R_{t+1}\text{是下一个状态的即时奖励,}S_{t+1}\text{是下一个状态。} 其中St是当前状态,Rt+1是下一个状态的即时奖励,St+1是下一个状态。

允许渐进式地从不完整的经验片段中学习(TD算法不需要等待一个完整的任务周期结束才进行学习,它可以逐步地从每次交互中学习。这意味着,它不需要等到下一个时间步的奖励才能更新其值函数的估计,而是可以使用当前的观察和奖励来更新。)这意味着要解决在线学习的问题。

  • 在线学习是指算法在与环境互动的过程中即时学习。

适用于无模型强化学习,因为它不依赖于马尔科夫决策过程的转移模型和奖励模型。

  • 无模型强化学习(Model-Free Reinforcement Learning)是一种强化学习方法,它不需要知道环境的内部模型,即不需要知道未来的状态转移概率和奖励分布。这与模型驱动的强化学习(Model-Based Reinforcement Learning)形成对比,后者需要一个环境的模型来做出决策。
  • 无模型强化学习算法,如Q学习(Q-Learning)、深度Q网络(Deep Q-Network,DQN)、策略梯度(Policy Gradient)和演员-评论家(Actor-Critic)方法,可以直接从传感器接收输入并采取行动,而不需要了解这些行动如何影响环境的具体机制。

前期准备

import numpy as np
import matplotlib.pyplot as plt

实现步骤

第一部分是GridworldV2的实现。

第二部分是TD算法的实现。

  1. 实现GridworldV2,定义GridworldV2Env()类

    class GridworldV2Env(gym.Env):
        def __init__(self, step_cost=-0.2, max_ep_length=500, explore_start=False):
            self.index_to_coordinate_map = {
                "0": [0, 0],
                "1": [0, 1],
                "2": [0, 2],
                "3": [0, 3],
                "4": [1, 0],
                "5": [1, 1],
                "6": [1, 2],
                "7": [1, 3],
                "8": [2, 0],
                "9": [2, 1],
                "10": [2, 2],
                "11": [2, 3],
            }
            self.coordinate_to_index_map = {
                str(val): int(key) for key, val in self.index_to_coordinate_map.items()
            }
    
  2. 实现_init_()函数,定义Gridworld大小、目标位置、墙体位置和炸弹位置等必要的值

    self.map = np.zeros((3, 4))
    self.observation_space = gym.spaces.Discrete(12)
    self.distinct_states = [str(i) for i in range(12)]
    self.goal_coordinate = [0, 3]
    self.bomb_coordinate = [1, 3]
    self.wall_coordinate = [1, 1]
    self.goal_state = self.coordinate_to_index_map[str(self.goal_coordinate)]  # 3
    self.bomb_state = self.coordinate_to_index_map[str(self.bomb_coordinate)]  # 7
    self.map[self.goal_coordinate[0]][self.goal_coordinate[1]] = 1
    self.map[self.bomb_coordinate[0]][self.bomb_coordinate[1]] = -1
    self.map[self.wall_coordinate[0]][self.wall_coordinate[1]] = 2
    
    self.exploring_starts = explore_start
    self.state = 8
    self.done = False
    self.max_ep_length = max_ep_length
    self.steps = 0
    self.step_cost = step_cost
    self.action_space = gym.spaces.Discrete(4)
    self.action_map = {"UP": 0, "RIGHT": 1, "DOWN": 2, "LEFT": 3}
    self.possible_actions = list(self.action_map.values())
    

    这个环境定义了基本的网格世界,其中代理可以在网格中移动,以到达目标位置,同时避免炸弹和墙壁。每一步都会收到一个负的step_cost,当达到目标或炸弹位置时,episode结束。

  3. 定义reset()函数,它将在每一个回合的开始被调用,包括第一个回合

    def reset(self):
        self.done = False
        self.steps = 0
        self.map = np.zeros((3, 4))
        self.map[self.goal_coordinate[0]][self.goal_coordinate[1]] = 1
        self.map[self.bomb_coordinate[0]][self.bomb_coordinate[1]] = -1
        self.map[self.wall_coordinate[0]][self.wall_coordinate[1]] = 2
    
        if self.exploring_starts:
            self.state = np.random.choice([0, 1, 2, 4, 6, 8, 9, 10, 11])
        else:
            self.state = 8
        return self.state
    

    在强化学习中,reset方法通常在每个episode开始时被调用,以重置环境状态并获取初始观察。在这个环境中,初始状态可能取决于是否进行探索开始,如果进行探索,则从一组排除特定状态(如墙壁)的状态中随机选择初始状态;如果不进行探索,则始终从状态8开始。

  4. 实现一个get_next_state()函数,以便获取下一个状态

    def get_next_state(self, current_position, action):
    
        next_state = self.index_to_coordinate_map[str(current_position)].copy()
    
        if action == 0 and next_state[0] != 0 and next_state != [2, 1]:
            # Move up
            next_state[0] -= 1
        elif action == 1 and next_state[1] != 3 and next_state != [1, 0]:
            # Move right
            next_state[1] += 1
        elif action == 2 and next_state[0] != 2 and next_state != [0, 1]:
            # Move down
            next_state[0] += 1
        elif action == 3 and next_state[1] != 0 and next_state != [1, 2]:
            # Move left
            next_state[1] -= 1
        else:
            pass
        return self.coordinate_to_index_map[str(next_state)]
    

    这个方法确保了Agent不能穿过墙壁(或任何不可通过的状态),并且在尝试超出网格边界时也不会移动。如果代理尝试移动到这些位置,它将保持在当前位置。

  5. 实现GridworldV2环境中的主要的step()函数。它实现了强化学习环境中的关键部分,即在给定动作的情况下执行一步并返回新的状态、奖励和是否完成。

    def step(self, action):
        assert action in self.possible_actions, f"Invalid action:{action}"
    
        current_position = self.state
        next_state = self.get_next_state(current_position, action)
    
        self.steps += 1
    
        if next_state == self.goal_state:
            reward = 1
            self.done = True
    
        elif next_state == self.bomb_state:
            reward = -1
            self.done = True
        else:
            reward = self.step_cost
    
        if self.steps == self.max_ep_length:
            self.done = True
    
        self.state = next_state
        return next_state, reward, self.done
    

    step方法在强化学习算法中非常重要,因为它定义了代理如何与环境互动。每次调用step方法时,代理都会根据所选动作在环境中前进一步,并获得相应的奖励,同时检查是否达到目标或遇到炸弹,或者是否达到了episode的最大长度。

  6. 继续实现时序差分学习算法,首先使用一个二维numpy数组初始化网络的状态值,然后设置目标位置和炸弹状态的值。

    def temporal_difference_learning(env, max_episodes):
        grid_state_values = np.zeros((len(env.distinct_states), 1))
        grid_state_values[env.goal_state] = 1
        grid_state_values[env.bomb_state] = -1
    
  7. 定义折扣因子gamma、学习率alpha、将done初始化为false。

    v = grid_state_values
    gamma = 0.99  # Discount factor
    alpha = 0.01  # learning rate
    
  8. 定义外部主循环,使其运行max_episode次,并在每个回合开始时将环境状态重置为初始值。

    for episode in range(max_episodes):
        state = env.reset()
    
  9. 实现内循环,其中使用一行代码进行时序差分学习更新。

    while not done:
        action = env.action_space.sample()  # random policy
        next_state, reward, done = env.step(action)
    
        # State-value function updates using TD(0)
        v[state] += alpha * (reward + gamma * v[next_state] - v[state])
        state = next_state
    

    这里实现了TD(0)更新规则,它更新状态价值函数v。更新的公式是:

    V ( S t ) ← V ( S t ) + α ( R t + 1 + γ V ( S t + 1 ) − V ( S t ) ) V(S_t)\leftarrow V(S_t)+\alpha\left(R_{t+1}+\gamma V(S_{t+1})-V(S_t)\right) V(St)V(St)+α(Rt+1+γV(St+1)V(St))

    其中 S t 是当前状态, R t + 1 是下一个状态的即时奖励, S t + 1 是下一个状态。 \text{其中}S_t\text{是当前状态,}R_{t+1}\text{是下一个状态的即时奖励,}S_{t+1}\text{是下一个状态。} 其中St是当前状态,Rt+1是下一个状态的即时奖励,St+1是下一个状态。

  10. 学习收敛后,希望能够可视化GridworldV2环境中每个状态的状态值。为此可以使用 value_function_utils()函数中的visualize_grid_state_values()函数

    visualize_grid_state_values(grid_state_values.reshape((3, 4)))
    
  11. 主函数中运行temporal_difference_learning函数

    if __name__ == "__main__":
        max_episodes = 4000
        env = GridworldV2Env(step_cost=-0.1, max_ep_length=30)
        temporal_difference_learning(env, max_episodes)
    
  12. 运行max_episodes个回合的时序差分学习,然后产生的图可以展示GridworldV2环境的网格单元坐标和状态值,每个状态根据右边显示的刻度着色。
    在这里插入图片描述

工作原理

状态是线性化的,用一个整数表示环境中的12个不同状态。

构建强化学习中的蒙特卡洛预测和控制算法

与时序差分学习算法类似,蒙特卡洛学习算法可用于学习状态函数和动作价值函数。

  • 二者都可以用来估计强化学习中的状态价值函数(V函数)和动作价值函数(Q函数)。状态价值函数预测从某个状态出发,遵循某种策略所能获得的期望回报;动作价值函数预测在某个状态下采取特定动作后所能获得的期望回报。
  • 时序差分学习算法和蒙特卡洛学习算法的主要区别在于,时序差分学习不需要完整的回合来更新价值函数,它可以通过单步转移来更新;而蒙特卡洛方法需要等待一个回合结束后,使用该回合的全部经验来更新价值函数。

由于蒙特卡洛学习方法是从真实经验的完整回合中学习,而没有近似预测,所以蒙特卡洛方法是无偏的。

  • 蒙特卡洛方法基于实际完成的回合数据(即从状态到最终回报的完整序列),因此它的估计不依赖于任何模型或预测,只依赖于实际发生的事件。这使得蒙特卡洛方法在理论上能够提供无偏的估计,即它的长期平均估计将准确反映真实的价值函数。

这个方法适用于需要良好收敛性的应用。

  • 随着经验的积累,蒙特卡洛方法估计的价值函数将越来越接近真实的价值函数。因此,当应用场景要求算法最终能够收敛到正确的解决方案时,蒙特卡洛方法是一个合适的选择。

前期准备

import numpy as np

实现步骤

首先实现monte_carlo_prediction算法,并在GridworldV2环境中学习到的每个状态的价值函数进行可视化。随后实现epsilon-greedy策略和monte_carlo_control算法,构造一个可以在强化学习环境中行动的智能体

  1. 导入必要的Python模块

    import numpy as np
    from envs.gridworldv2 import GridworldV2Env
    from value_function_utils import (
        visualize_grid_action_values,
        visualize_grid_state_values,
    )
    
  2. 定义monte_carlo_prediction() 函数并初始化必要的对象

    def monte_carlo_prediction(env, max_episodes):
        returns = {state: [] for state in env.distinct_states}
        grid_state_values = np.zeros(len(env.distinct_states))
        grid_state_values[env.goal_state] = 1
        grid_state_values[env.bomb_state] = -1
        gamma = 0.99  # Discount factor
    
  3. 实现外部循环。外部循环在所有强化学习智能体代码中都很常见

    for episode in range(max_episodes):
            g_t = 0
            state = env.reset()
            done = False
            trajectory = []
    
  4. 实现内部循环

    while not done:
        action = env.action_space.sample()  # random policy
        next_state, reward, done = env.step(action)
        trajectory.append((state, reward))
        state = next_state
    
  5. 计算网络中的状态值

    for idx, (state, reward) in enumerate(trajectory[::-1]):
            g_t = gamma * g_t + reward
            # first visit Monte-Carlo prediction
            if state not in np.array(trajectory[::-1])[:, 0][idx + 1 :]:
                returns[str(state)].append(g_t)
                grid_state_values[state] = np.mean(returns[str(state)])
    visualize_grid_state_values(grid_state_values.reshape((3, 4)))
    

    对于轨迹 τ \tau τ中的每个状态 s s s和奖励 r r r,从后向前执行以下步骤:a.更新累积回报 G t = γ G t + r G_t=\gamma G_t+r Gt=γGt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值