12、基于演员 - 评论家方法的强化学习

演员-评论家方法详解

基于演员 - 评论家方法的强化学习

1. 引言

在学习玩围棋时,让更强大的玩家复盘你的棋局是提升棋艺的绝佳方法。复盘反馈能指出关键胜负点,让你聚焦重要部分。强化学习中的演员 - 评论家学习就借鉴了这一原理,它结合了策略学习和价值学习,策略函数如同演员,负责选择行动;价值函数则像评论家,追踪游戏中智能体的优劣态势,为训练过程提供指导。

2. 优势:判断决策重要性

2.1 什么是优势

在强化学习中,信用分配问题是指区分智能体在游戏中做出的好决策和坏决策。优势这一概念可以帮助解决这个问题,它是衡量特定决策对最终结果贡献程度的公式。

优势的计算基于状态价值函数 (V(s)) 和行动价值函数 (Q(s,a))。(V(s)) 表示智能体处于状态 (s) 时的预期回报,反映了棋盘局势对某一方的有利程度;(Q(s,a)) 表示在状态 (s) 采取行动 (a) 后的预期回报。优势的定义通常为:
[A = Q(s, a) - V(s)]
但由于难以直接计算 (Q(s,a)),可以用游戏结束时获得的奖励 (R) 作为对 (Q(s,a)) 的无偏估计,因此优势可以估算为:
[A = R - V(s)]

以下是几个优势计算的例子:
| 游戏阶段 | (V(s)) | 奖励 (R) | 优势 (A) |
| ---- | ---- | ---- | ---- |
| 游戏开始 | 0 | 1(获胜) | (1 - 0 = 1) |
| 游戏接近结束,局势有利 | 0.95 | 1(获胜) | (1 - 0.95 = 0.05) |
| 游戏接近结束,局势有利但最终失败 | 0.95 | -1(失败) | (-1 - 0.95 = -1.95) |

2.2 自我对弈中计算优势

为了在自我对弈中计算优势,需要更新 ExperienceCollector 类。原经验缓冲区跟踪状态、行动和奖励三个并行数组,现在添加第四个并行数组来跟踪优势。

以下是更新后的代码:

class ExperienceCollector:
    def __init__(self):
        self.states = []
        self.actions = []
        self.rewards = []
        self.advantages = []
        self._current_episode_states = []
        self._current_episode_actions = []
        self._current_episode_estimated_values = []

    def record_decision(self, state, action, estimated_value=0):
        self._current_episode_states.append(state)
        self._current_episode_actions.append(action)
        self._current_episode_estimated_values.append(estimated_value)

    def complete_episode(self, reward):
        num_states = len(self._current_episode_states)
        self.states += self._current_episode_states
        self.actions += self._current_episode_actions
        self.rewards += [reward for _ in range(num_states)]
        for i in range(num_states):
            advantage = reward - self._current_episode_estimated_values[i]
            self.advantages.append(advantage)
        self._current_episode_states = []
        self._current_episode_actions = []
        self._current_episode_estimated_values = []

同时,还需要更新 ExperienceBuffer 类和 combine_experience 辅助函数来处理优势:

class ExperienceBuffer:
    def __init__(self, states, actions, rewards, advantages):
        self.states = states
        self.actions = actions
        self.rewards = rewards
        self.advantages = advantages

    def serialize(self, h5file):
        h5file.create_group('experience')
        h5file['experience'].create_dataset('states', data=self.states)
        h5file['experience'].create_dataset('actions', data=self.actions)
        h5file['experience'].create_dataset('rewards', data=self.rewards)
        h5file['experience'].create_dataset('advantages', data=self.advantages)

def combine_experience(collectors):
    combined_states = np.concatenate([np.array(c.states) for c in collectors])
    combined_actions = np.concatenate([np.array(c.actions) for c in collectors])
    combined_rewards = np.concatenate([np.array(c.rewards) for c in collectors])
    combined_advantages = np.concatenate([np.array(c.advantages) for c in collectors])
    return ExperienceBuffer(
        combined_states,
        combined_actions,
        combined_rewards,
        combined_advantages)

3. 设计用于演员 - 评论家学习的神经网络

对于演员 - 评论家学习,需要设计一个具有一个输入和两个输出的神经网络。输入是棋盘状态的表示,一个输出是行动的概率分布(演员),另一个输出是当前位置的预期回报(评论家)。

使用 Keras 函数式 API 构建网络的代码如下:

from keras.models import Model
from keras.layers import Conv2D, Dense, Flatten, Input

board_input = Input(shape=encoder.shape(), name='board_input')
conv1 = Conv2D(64, (3, 3), padding='same', activation='relu')(board_input)
conv2 = Conv2D(64, (3, 3), padding='same', activation='relu')(conv1)
conv3 = Conv2D(64, (3, 3), padding='same', activation='relu')(conv2)
flat = Flatten()(conv3)
processed_board = Dense(512)(flat)

policy_hidden_layer = Dense(512, activation='relu')(processed_board)
policy_output = Dense(encoder.num_points(), activation='softmax')(policy_hidden_layer)

value_hidden_layer = Dense(512, activation='relu')(processed_board)
value_output = Dense(1, activation='tanh')(value_hidden_layer)

model = Model(inputs=board_input, outputs=[policy_output, value_output])

这个网络有三个卷积层,每个卷积层有 64 个滤波器。策略输出使用 softmax 激活函数,确保行动概率分布之和为 1;价值输出使用 tanh 激活函数,将输出值限制在 -1 到 1 的范围内。

4. 使用演员 - 评论家智能体进行游戏

选择行动的过程与策略智能体类似,但需要进行两处修改:一是解包模型的两个输出;二是将估计值传递给经验收集器。

以下是更新后的 select_move 方法:

class ACAgent(Agent):
    def select_move(self, game_state):
        num_moves = self.encoder.board_width * self.encoder.board_height
        board_tensor = self.encoder.encode(game_state)
        X = np.array([board_tensor])
        actions, values = self.model.predict(X)
        move_probs = actions[0]
        estimated_value = values[0][0]
        eps = 1e-6
        move_probs = np.clip(move_probs, eps, 1 - eps)
        move_probs = move_probs / np.sum(move_probs)
        candidates = np.arange(num_moves)
        ranked_moves = np.random.choice(
            candidates, num_moves, replace=False, p=move_probs)
        for point_idx in ranked_moves:
            point = self.encoder.decode_point_index(point_idx)
            move = goboard.Move.play(point)
            move_is_valid = game_state.is_valid_move(move)
            fills_own_eye = is_point_an_eye(
                game_state.board, point, game_state.next_player)
            if move_is_valid and (not fills_own_eye):
                if self.collector is not None:
                    self.collector.record_decision(
                        state=board_tensor,
                        action=point_idx,
                        estimated_value=estimated_value
                    )
                return goboard.Move.play(point)
        return goboard.Move.pass_turn()

5. 基于经验数据训练演员 - 评论家智能体

训练演员 - 评论家网络类似于结合策略网络和行动价值网络的训练。需要为每个输出构建单独的训练目标,并选择不同的损失函数。

5.1 训练目标

  • 策略输出 :训练目标是一个与棋盘大小相同的向量,对应所选行动的位置填充该行动的优势值。
  • 价值输出 :训练目标是总奖励。

5.2 损失函数

  • 策略输出使用分类交叉熵损失函数。
  • 价值输出使用均方误差损失函数。

5.3 损失权重

Keras 允许为每个输出指定损失权重,以调整不同输出的相对重要性。在实验中,发现价值损失相对较大,因此将价值损失的权重设置为 0.5。

以下是训练方法的代码:

class ACAgent(Agent):
    def train(self, experience, lr=0.1, batch_size=128):
        opt = SGD(lr=lr)
        self.model.compile(
            optimizer=opt,
            loss=['categorical_crossentropy', 'mse'],
            loss_weights=[1.0, 0.5])
        n = experience.states.shape[0]
        num_moves = self.encoder.num_points()
        policy_target = np.zeros((n, num_moves))
        value_target = np.zeros((n,))
        for i in range(n):
            action = experience.actions[i]
            policy_target[i][action] = experience.advantages[i]
            reward = experience.rewards[i]
            value_target[i] = reward
        self.model.fit(
            experience.states,
            [policy_target, value_target],
            batch_size=batch_size,
            epochs=1)

5.4 端到端训练流程

以下是使用 9×9 棋盘的端到端训练流程:
1. 初始化智能体

python init_ac_agent.py --board-size 9 ac_v1.hdf5
  1. 生成自我对弈游戏
python self_play_ac.py \
--board-size 9 \
--learning-agent ac_v1.hdf5 \
--num-games 5000 \
--experience-out exp_0001.hdf5
  1. 训练智能体
python train_ac.py \
--learning-agent bots/ac_v1.hdf5 \
--agent-out bots/ac_v2.hdf5 \
--lr 0.01 --bs 1024 \
exp_0001.hdf5
  1. 评估智能体
python eval_ac_bot.py \
--agent1 bots/ac_v2.hdf5 \
--agent2 bots/ac_v1.hdf5 \
--num-games 100

如果新智能体在 100 场比赛中获胜 60 场以上,则认为它有显著提升,可以使用新智能体继续生成自我对弈游戏并重复训练过程;否则,继续生成更多训练数据并重新训练。

6. 总结

演员 - 评论家学习是一种同时学习策略函数和价值函数的强化学习技术,它结合了策略学习和价值学习的优点,通常比单纯的策略梯度学习更稳定。

优势是实际奖励与预期奖励的差值,它有助于识别游戏中的重要决策。Keras 顺序网络可以有多个输出,在演员 - 评论家学习中,可以使用单个网络同时建模策略函数和价值函数。

通过这种方法可以训练出能够学习基本策略的围棋智能体,但仅靠演员 - 评论家实现可能会达到性能上限。结合强化学习和树搜索技术可以训练出比人类玩家更强的智能体。

下面是一个 mermaid 流程图,展示了端到端的训练过程:

graph LR
    A[初始化智能体] --> B[生成自我对弈游戏]
    B --> C[训练智能体]
    C --> D[评估智能体]
    D -- 新智能体获胜 >= 60场 --> E[使用新智能体重复流程]
    D -- 新智能体获胜 < 60场 --> B

通过以上步骤和方法,可以逐步提升智能体的性能,使其在围棋游戏中表现得越来越好。

7. 训练过程中的注意事项

在使用演员 - 评论家方法训练智能体时,有一些关键的注意事项需要牢记,这些要点对于确保训练的有效性和稳定性至关重要。

7.1 学习率和批量大小的调整

学习率(lr)和批量大小(batch_size)是优化器的重要调优参数。学习率控制着模型在每次更新时参数调整的步长,批量大小则决定了每次训练时使用的样本数量。

  • 学习率 :如果学习率设置得过大,模型可能会在训练过程中跳过最优解,导致无法收敛;而学习率过小,训练速度会变得非常缓慢。通常需要通过实验来找到合适的学习率。例如,在之前的训练代码中,初始设置学习率为 0.1,但在实际应用中,可能需要根据训练情况进行调整。
  • 批量大小 :较大的批量大小可以使训练更加稳定,但可能会占用更多的内存;较小的批量大小可以增加模型的随机性,有助于跳出局部最优解,但可能会导致训练过程不稳定。在训练代码中,批量大小设置为 128,同样需要根据具体情况进行调整。

7.2 损失权重的调整

如前文所述,Keras 允许为每个输出指定损失权重,以调整不同输出的相对重要性。在实验中,发现价值损失相对较大,因此将价值损失的权重设置为 0.5。但这并不是固定的,具体的权重需要根据网络结构和训练数据进行调整。

可以通过观察 Keras 在每次调用 fit 时打印的损失值来判断是否需要调整权重。如果一个输出的损失值远大于另一个输出,就需要考虑调整权重。例如,如果策略输出的损失值远小于价值输出的损失值,可以适当增加策略输出的损失权重。

7.3 数据的多样性和质量

训练数据的多样性和质量对模型的性能有着重要影响。在生成自我对弈游戏数据时,要确保数据涵盖了各种不同的游戏情况,包括开局、中盘和收官等不同阶段。

同时,要注意数据的质量。如果数据中存在错误或异常情况,可能会导致模型学习到错误的信息,从而影响模型的性能。例如,在判断行动是否有效时,要确保逻辑的正确性,避免将无效的行动记录到训练数据中。

8. 实际应用案例分析

为了更好地理解演员 - 评论家方法的实际应用,下面通过一个具体的案例来分析其在围棋游戏中的表现。

8.1 初始阶段

在初始阶段,使用 init_ac_agent.py 脚本初始化一个 9×9 棋盘的智能体:

python init_ac_agent.py --board-size 9 ac_v1.hdf5

此时,智能体的策略和价值估计基本是随机的。然后使用 self_play_ac.py 脚本生成 5000 场自我对弈游戏:

python self_play_ac.py \
--board-size 9 \
--learning-agent ac_v1.hdf5 \
--num-games 5000 \
--experience-out exp_0001.hdf5

这个过程可能需要一些时间,如果没有快速的 GPU 支持,可以利用这段时间休息一下。

8.2 第一轮训练和评估

生成完游戏数据后,使用 train_ac.py 脚本对智能体进行训练:

python train_ac.py \
--learning-agent bots/ac_v1.hdf5 \
--agent-out bots/ac_v2.hdf5 \
--lr 0.01 --bs 1024 \
exp_0001.hdf5

训练完成后,使用 eval_ac_bot.py 脚本对新智能体进行评估:

python eval_ac_bot.py \
--agent1 bots/ac_v2.hdf5 \
--agent2 bots/ac_v1.hdf5 \
--num-games 100

假设评估结果显示新智能体在 100 场比赛中获胜 60 场,这表明智能体在第一轮训练中取得了显著的提升,可以开始使用新智能体 ac_v2.hdf5 继续生成自我对弈游戏并重复训练过程。

8.3 后续训练和调整

在后续的训练过程中,可能会遇到新智能体的性能提升不明显的情况。例如,在某一轮评估中,新智能体 ac_v3.hdf5 在与 ac_v2.hdf5 的 100 场比赛中只获胜了 51 场。此时,不能确定 ac_v3.hdf5 是否真的比 ac_v2.hdf5 更强,需要继续生成更多的训练数据:

python self_play_ac.py \
--board-size 9 \
--learning-agent ac_v2.hdf5 \
--num-games 5000 \
--experience-out exp_0002a.hdf5

然后将新生成的数据和之前的数据一起用于训练:

python train_ac.py \
--learning-agent ac_v2.hdf5 \
--agent-out ac_v3.hdf5 \
--lr 0.01 --bs 1024 \
exp_0002.hdf5 exp_0002a.hdf5

经过多次尝试,最终可能会得到令人满意的结果,例如新智能体在 100 场比赛中获胜 62 场,此时可以确定智能体的性能得到了提升。

8.4 性能上限和改进方向

虽然通过演员 - 评论家方法可以训练出能够学习基本策略的围棋智能体,但仅靠这种方法可能会达到性能上限。这是因为该方法主要基于当前的状态和奖励进行学习,缺乏对未来可能情况的深入探索。

为了突破性能上限,可以结合强化学习和树搜索技术。树搜索可以在当前状态下对未来的多种可能行动进行搜索,找到更优的行动策略。通过将强化学习和树搜索技术深度集成,可以训练出比人类玩家更强的智能体。

9. 总结与展望

9.1 方法总结

演员 - 评论家方法是一种强大的强化学习技术,它通过同时学习策略函数和价值函数,能够更有效地进行决策和训练。优势的引入使得智能体能够更好地识别游戏中的重要决策,提高训练效率。

在实际应用中,通过设计合适的神经网络结构、调整训练参数和优化训练流程,可以逐步提升智能体的性能。Keras 提供的多输出网络功能为实现演员 - 评论家方法提供了便利,使得可以使用单个网络同时建模策略函数和价值函数。

9.2 未来展望

随着强化学习技术的不断发展,演员 - 评论家方法有望在更多领域得到应用。除了围棋游戏,它还可以应用于机器人控制、自动驾驶、金融投资等领域。

在未来的研究中,可以进一步探索如何更好地结合强化学习和其他技术,如树搜索、深度学习等,以提高智能体的性能和泛化能力。同时,也可以研究如何减少训练过程中的计算资源消耗,提高训练效率。

以下是一个表格,总结了演员 - 评论家方法的关键要点:
| 要点 | 描述 |
| ---- | ---- |
| 核心技术 | 同时学习策略函数和价值函数 |
| 优势作用 | 识别重要决策,提高训练效率 |
| 网络结构 | 一个输入,两个输出(策略输出和价值输出) |
| 训练要点 | 调整学习率、批量大小和损失权重,确保数据质量 |
| 性能提升 | 结合强化学习和树搜索技术 |

下面是一个 mermaid 流程图,展示了未来可能的研究方向:

graph LR
    A[演员 - 评论家方法] --> B[结合树搜索技术]
    A --> C[应用于更多领域]
    A --> D[减少计算资源消耗]
    B --> E[提高智能体性能]
    C --> F[拓展应用范围]
    D --> G[提高训练效率]

通过不断地研究和改进,演员 - 评论家方法有望在人工智能领域发挥更大的作用,为解决各种复杂问题提供有效的解决方案。

本资源集提供了针对小型无人机六自由度非线性动力学模型的MATLAB仿真环境,适用于多个版本(如2014a、2019b、2024b)。该模型完整描述了飞行器在三维空间中的六个独立运动状态:绕三个坐标轴的旋转(滚转、俯仰、偏航)与沿三个坐标轴的平移(前后、左右、升降)。建模过程严格依据牛顿-欧拉方程,综合考虑了重力、气动力、推进力及其产生的力矩对机体运动的影响,涉及矢量运算与常微分方程求解等数学方法。 代码采用模块化与参数化设计,使用者可便捷地调整飞行器的结构参数(包括几何尺寸、质量特性、惯性张量等)以匹配不同机型。程序结构清晰,关键步骤配有详细说明,便于理解模型构建逻辑与仿真流程。随附的示例数据集可直接加载运行,用户可通过修改参数观察飞行状态的动态响应,从而深化对无人机非线性动力学特性的认识。 本材料主要面向具备一定数学与编程基础的高校学生,尤其适合计算机、电子信息工程、自动化及相关专业人员在课程项目、专题研究或毕业设计中使用。通过该仿真环境,学习者能够将理论知识与数值实践相结合,掌握无人机系统建模、仿真与分析的基本技能,为后续从事飞行器控制、系统仿真等领域的研究或开发工作奠定基础。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值