前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >机器学习 DQN 算法在火影手游的实践

机器学习 DQN 算法在火影手游的实践

原创
作者头像
serena
修改2022-08-23 17:25:37
4.2K1
修改2022-08-23 17:25:37
举报

序言:

AlphaGo的出现,让我对机器学习产生了很大的兴趣,学习了 AnderwNG 大神“史坦福大学公开课:机器学习课程”之后开始尝试自己处理相关问题,并在项目中进行实践(一款横板动作游戏),最初采用的是 QLearning 算法( DQN 算法的前身),在 Unity 中用 C# 实现了 QLearning 算法核心,神经网络和训练等模块,实际效果如下:

未经选练的AI
(经过一段时间训练后)

从视频中可以看出,训练后的 Agent 已经学习到一些找寻敌人和攻击的基本能力,但这个应用场景状态比较简单,只有一个小兵的位置。Agent 要进行的操作也比较简单,8方向移动和2方向普攻。所以结果看上去还比较满意。

有了最初的实践,让我看到机器学习在复杂游戏中存在应用的可能,于是通过对 DQN 算法的进一步学习,并且在兄弟团队(火影项目组)的支持下,我开始在火影手游中进行了一些实践。

强化学习

机器学习有几个常见的解决问题的领域,包括回归和分类/聚类,例如手写字体识别,语音识别,图像识别等,基本上都可以划分到一个回归或者分类问题上。但在游戏领域要面对的情况有些不同,在用机器学习解决回归或者分类问题时,无论在训练阶段还是预测阶段,样本都是离散的,他们之间不存在时间上的前后依赖关系。

训练时样本的顺序对实际训练结果没有太大影响,而预测阶段也完全不用考虑样本的前后关系,虽然神经网络中也有 RNN 算法引入样本的时间序列(例如在处理语音识别问题时),但游戏领域要面对的是一个连续的交互问题。

人工智能领域常用 Agent 来表示一个具备行为能力的物体,强化学习要解决的问题就是 Agent 与环境 Environment 之间交互任务。

而无论什么样的任务,都包含了一系列的动作 Action , 状态 State 和收益 Reward。

Reward 置的是 Agent 在状态 State 下执行某个 Action 后,对环境产生变化的一个评估。

强化学习的目的就是通过训练,让智能体 Agent 学习到一个策略 Policy ,该策略反映的是状态 State 下选择 Action 的一个对应关系,也就是什么状态执行什么动作。

能够在环境中获得最多的 Reward 的策略,称为最优策略,也就是强化学习的目标。

所以深度学习算法带给我们学习的方法,而强化学习带给学习的目标,也就是常见到的说法:

AI = DL + RL

DQN 算法

DQN 就是结合了深度学习和强化学习的一种算法,最初是 DeepMind 在 NIPS 2013年提出,它的核心利润包括马尔科夫决策链以及贝尔曼公式。网上介绍DQN算法的文章很多,最初版本的算法可以概括如下:

添加描述

DQN 算法中有几个很核心的概念:

  • 状态定义

DeepMind在最初的实践中,采用连续4帧游戏画面作为状态输入,采用 CNN 网络对输入的画面状态进行处理提取高维信息,最后再通过全连结网络层进行各个Action的Q值计算。

在我的实践中考虑到性能和学习效率的问题,并没有采用游戏画面直接作为输入,而是深入到游戏中,直接通过状态收集模块提取游戏主要特征预处理后作为算法的输入,当然考虑到公平的原因,提取的特征都是玩家可以直接从游戏中观察到的,例如:双方位置,血量,技能CD等。

  • 预期收益

NatureDQN中使用两个网络QNetwork和TargetNetwork,其中QNetwork用来计算当前状态每个Action的Reward,TargetNetwork用来计算下一个状态最大收益,QNetwork和TargetNetwork网络结构相同,并且定期的将QNetwork覆盖TargetNetwork。。

每次训练计算当前状态State执行的Action带来的预期收益时,首先通过TargetNetwork将下个状态产生的最大收益通过一定的收益衰减叠加到QNetwork当前状态执行的Action产生的收益上,用来计算预期收益,这是一种很直观的方法,但也会带来一些潜在问题,在接下来的时间中会具体讲到改良方法。

所以本质上DQN算法是通过TargetNetwork迭代QNetwork中每个Action的Q值的算法。

  • 探索与贪婪

每次Agent在选择一个Action进行执行的时候,通过一定的策略,选取一个Action,该Action可以有两种:一个随机Action,或者网络计算出来产生最大Reward的Action。

如果选择的是随机Action,即尝试没有执行过的Action,体现了Agent的探索能力

如果选择的是产生最大Reward的Action,即Agent表现得贪婪,尽力获得最大的Reward。

而我们的选取策略就是在探索与贪婪中找到一个平衡,具体应用中可以在训练前期Agent做更多的探索,随着训练次数的增加,逐渐的更加贪婪。

  • 经验回放

通常我们从游戏收集到的State,Action和Reward并不是直接进行训练,而是存放在一个经验池中(ExperienceMemory)。而每次训练从经验池中随机选取小批次(MiniBatch)经验进行训练,这样做可以避免观察到的数据前后依赖关系,同时也能避免Agent受最近的操作影响过大,而“遗忘”以前发生的事情。

上面提到的是NatureDQN算法比较核心的几点,之后DQN算法也出现很多改进。

实践

添加描述

首先感谢火影客户端团队兽兽,slicol和孙威的帮助,搞定了很多客户端的问题,才让这次实践有了应用基础,后续的深入实践和研究还需要很多客户端同学的支持。

目前在火影手游中,竞技场的AI采用行为树的方法实现,该AI水平较强,但行为模式比较单一,很容易玩家发觉是一个AI。

实践中希望采用DQN算法训练AI,使AI水平能随着训练增加而提高,并且能够体现出丰富行为模式。

定义状态和预处理

如前文所述,我并没有直接使用图像画面作为状态输入(这方面有待商榷,也请各位指正),主要是基于两方面的考虑:

1. 性能问题

图像识别需要多层的CNN网络,将来在客户端直接使用时可能存在性能问题。

2. 学习效率问题

CNN网络进行图像识别是为了提取游戏图像的高纬信息,在DeepMind的实验中由于要应对各种游戏,所以采用图像作为状态的方式比较通用,而我们在具体实践中,可以考虑直接通过客户端收集游戏的主要特征作为状态输入。

有了最初横板动作游戏中的尝试,这次在实践中,我们将状态定义的较为复杂,主要包含39个特征,例如:双方血量,位置,高度,技能CD,当前各动作执行阶段等。

收集到原始数据之后,还要进行预处理:

1.根据敌人和主角的相对位置,以主角为中心,划分20x24的格子,然后将敌人和主角的状态填入对应的格子中,形成一个散列的状态数据,该状态中大部分数据为0(没有敌人和主角的格子)

2.处理不同数据的表示范围,例如血量范围为0~1.0,技能CD为0~10.0,主要考量是不同特征对Action影响程度。

设计收益

我们的游戏中,收益组成比较复杂,包括:

  • 对敌人伤害产生的收益
  • 被敌人伤害产生的收益(负值)
  • 躲避敌人攻击产生的收益
  • 技能无法释放产生的收益(负值)

设计技能无法释放生成负收益的目的,是希望在模型在一个State下产生一个不能执行的技能Action时,对当前State下的Action进行惩罚,从而让模型学会技能释放的时机。

预测和执行动作

结合游戏实际情况,设计了包括空闲,8方向移动,2方向普攻,2方向使用1技能,2方向使用2技能,2方向使用3技能,使用替身技,一共18个 Action 。

整体训练流程

游戏客户端与训练进程进程之间通过 UDP 进行通信,每个时间片,客户端收集当前游戏状态 State,执行的 Action ,产生的收益 Reward 发送给训练进程。

训练进程将当前的 State ,前一个状态 State ,执行的 Action 和 Reward ,进行预处理后加入经验池中,等待后续训练过程处理。

同时根据当前状态,根据“探索和贪婪”策略计算得到一个 Action ,发回给客户端进行执行。

DQN 算法改进

添加描述

训练过程中发现 Agent 会倾向于总是使用某个固定的 Action ,引入对 Action 的惩罚后效果也不明显,查阅相关资料后发现 Nature DQN ,在计算预期收益时,使用了下个状态可能产生的最大收益进行计算,存在过优化的情况,导致任何状态下计算出来都是某个 Action 的收益最大,于是引入 Double DQN 和 DuellingNetwork 两个改进算法,提升了训练效果。

Double DQN

在 NatureDQN 算法中,Q 值的更新和动作的选择都通过在 QNetwork 网络上的 max 操作进行,这可能会产生过高估计一个 Action 产生收益的问题,DoubleDQN 算法的核心是将 Action 的选择与收益衡量分离。通过在QNetwork 上选择动作,然后用 TargetNetwork 衡量所有 Action 产生的收益。

网上很多文章把 DoubleDQN 和 NetureDQN 中引入的 TargetNetwork 概念混淆,实际上 DoubleDQN 是在 TargetNetwork 引入的基础上做的改进。

Duelling Network

Duelling Network 的提出就是将 NatureDQN 中 Q 值的计算分为两部分:价值( Value )和优势( Advantage )。价值用来表示一个状态 State 的好坏程度,而优势表示一个状态下各个 Action 的相对好坏程度。

由于在状态比较复杂的游戏中,执行哪个 Action 对下一个状态影响不大,这时候只是计算某个 Action 带来的潜在收益,就没有评估状态的价值作用大。

图中上部为NetureDQN模型,下部为DuellingNetwork网络模型

最终采用的网络模型如下:

添加描述

其他

本次实践中除了上面提到的主要功能之外,还包含了经验池,Minibatch,可降学习率,收益与动作回溯等具体细节,这里就不做详细描述。

训练效果

直观的看游戏中Agent的表现

(左侧蓝色圈的鸣人是DQN算法训练过6个小时后的AI,右侧红色圈的鸣人是游戏中行为树的AI)

视频中AI有5%的概率随机Action(探索机制),所以偶尔看到一些怪异的操作,但从中还是可以看到机器学习训练出的AI有下面几个特点:

  • 某些情况下Agent使用出了连招对敌人造成了连续伤害视频中可以看到蓝色鸣人(普攻+螺旋丸+大招的组合),已经显示出部分训练效果;
  • Agent对敌人攻击不太躲避,但偶尔会释放替身技,说明我们对躲避攻击的Reward设计有一定的效果,但可能收益值不够大;
  • 容易空放技能,可能是放空技能没有惩罚导致。
客观的统计Agent的平均收益和损失函数

添加描述

平均收益

平均收益Average Reward稳步提高,但提高速度较慢,显示训练有成果,但训练效率不高,这主要是因为我们采用的是在线学习结合一定探索策略导致的(后面会提到可以如何改进)。

添加描述

损失函数

损失函数loss在大的时间跨度上出现波动,慢慢趋于稳定,但并没有出现期待中的逐渐下降,说明我们的模型还有很大的优化空间。

改进

网络模型的改进

针对Loss较高的情况,尝试不同的网络模型(层数,神经元数量,经验池大小,MiniBatch大小,学习率,探索策略等),找到较佳的网络模型。

同时结合PrioritisedReplay特性,通过优化Reward计算的方法,

引入Prioritised Replay机制

由于训练过程中,对于经验池中的记录采样采取随机采样的方式,导致取出的Agent能产生较大Reward的样本被采样进行训练的概率较低,我在后续改进中将会通过PriorisisedReplay的方法,优先采样Reward较大的样本进行训练

改进训练样本收集方法

在本次实践中,采用在线训练的方式,训练进程客户端进行通信,训练与使用过程结合在一起,而由于个格斗游戏,策略比较复杂,Agent要在直接的战斗中学到好的策略(例如合适的技能施放时机,连招策略),需要大量的时间让Agent能够探索到成功的情况。毕竟单纯依靠简单的探索策略,在格斗类游戏中,找到一个好的战斗策略的机会很低。

接下来会我还会采用离线训练的方式,通过收集外网玩家真实战斗中的操作记录来训练Agent,让Agent能更快的学习到更好的操作策略。这就好比让一个打得好的老师傅教我们的AI如何进行战斗,通过这种方式能够快速的讲AI的水平提高到一个层次,然后再结合“探索和贪婪”策略,继续在较高的层次上进一步提高AI的水平。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 序言:
    • 强化学习
      • DQN 算法
        • 实践
          • 定义状态和预处理
          • 设计收益
          • 预测和执行动作
          • 整体训练流程
          • DQN 算法改进
          • 其他
          • 训练效果
          • 改进
      相关产品与服务
      语音识别
      腾讯云语音识别(Automatic Speech Recognition,ASR)是将语音转化成文字的PaaS产品,为企业提供精准而极具性价比的识别服务。被微信、王者荣耀、腾讯视频等大量业务使用,适用于录音质检、会议实时转写、语音输入法等多个场景。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档