在本次作业中,需要阅读程序,理解其中使用的强化学习算法,并尝试修改程序提高学习性能。阐述强化学习的方法和过程;尝试修改特征提取方法,得到更好的学习性能;尝试修改强化学习参数,得到更好的学习性能;并报告修改的尝试和得到的结果。
Go to file
difficult 849e8166d5 上传文件至 '' 2022-04-26 03:05:19 +00:00
Assignment1 上传文件至 '' 2022-04-26 03:05:19 +00:00
Assignment2 上传文件至 '' 2022-04-26 03:05:19 +00:00
Assignment3 上传文件至 '' 2022-04-26 03:05:19 +00:00
Assignment4 上传文件至 '' 2022-04-26 03:05:19 +00:00
Assignment5/mini_go 上传文件至 '' 2022-04-26 03:05:19 +00:00
.gitattributes 上传文件至 '' 2022-04-26 03:05:19 +00:00
LICENSE Initial commit 2022-04-26 02:59:28 +00:00
README.md 上传文件至 '' 2022-04-26 03:05:19 +00:00

README.md

FreeWay 游戏

摘 要: 在本次作业中,需要阅读程序,理解其中使用的强化学习算法,并尝试修改程序提高学习性能。阐述强化学习的方法和过程;尝试修改特征提取方法,得到更好的学习性能;尝试修改强化学习参数,得到更好的学习性能;并报告修改的尝试和得到的结果。

关键词: 强化学习,特征提取方法,强化学习参数。

一、任务 1

强化学习的方法和过程:框架代码在 act 函数中调用 learnPolicy 函数来完成强化学习,并根据强化学习得到的策略返回一个最优动作以供 Agent 执行。强化学习的方法和过程主要体现在 learnPolicy 函数中,在

learnPolicy 函数中进行了 10 次迭代,每次迭代都调用一次 simulate 函数来模拟,每次模拟的最大深度为 20 层。模拟探索采用了 epsilon-greedy 策略,有 epsilon 的概率随机选取一个动作探索,有 1 - epsilon 的概率选取 Q 值最大的动作来探索,并通过一个公式来更新 Q。每轮迭代都会根据模拟探索得到的结果更新数据集。迭代结

束后learnPolicy 函数会调用 fitQ 函数,根据模拟探索得到的数据集使用 weka 的 REPTree 模型训练策略。这样就完成了一次强化学习的过程

**问题一:**策略模型用一个有 epsilon-greedy 的 Q-learning 方法表示。该方法的缺点一个在于 m_epsilon 值固

定,而 m_epsilon 随着探索的进行减小效果会更好。因为再开局时探索范围小,不确定性较大,应更偏向随机探索;而到后期探索范围较大了,不确定性小,应更偏向于选择 Q 值高的动作。另一个在于每次都选择 Q 最大的

动作,容易导致过估计。所以应该将 m_epsilon 改为一个变量,随着探索的进行,其值应在一定范围内不断减小。另外可以采用 Double Q-Learning 的方法,防止出现过估计。

**问题二:**Agent.java 代码中 SIMULATION_DEPTH 变量表示模拟采样的最大深度,该参数值为 20限制了模拟采样进行的最大深度为 20。m_gamma 变量表示折扣因子,每一轮模拟时得到的 factor 都要乘以这个

m_gamma它可以控制未来不同深度下采样回报的重要程度如果它的值小接近 0则更重视层数较小时的回报如果它的值大接近 1则层数对回报的影响小这里的 m_gamma 值为 0.99说明层数对回报的影响较小但层数高时的回报还是会被减弱。m_maxPoolSize 变量表示 m_dataset 的最大容量,这里它的值为

,说明最多只能存储 1000 个状态。

**问题三:**两个函数的不同之处在于 getAction 函数应用了 epsilon-greedy 策略,而 getActionNoExplore 函数则没有使用。而 epsilon-greedy 策略主要是解决选择最优动作还是随机选择动作的问题getAction 函数有一定概率

随机选择动作,而 getActionNoExplore 则总是选择 Q 值最大的动作。正因如此getAction 函数用在 simulate 函数中,用来进行模拟探索,因为探索时需要一定的随机性,从而可以避免贪心算法的缺陷,提高找到最优解的

概率;而 getActionNoExplore 函数用在 act 函数中,情境是已经完成探索了,需要根据当前特征进行决策,选取执行的动作,所以直接选取最优的动作就行了。

二、任务 2

首先我直接使用框架代码运行了一次,可能是由于电脑硬件的限制,运行速度比较缓慢,大约半小时才进行到第八轮游戏,然后程序因为出现了爆堆的情况而被迫中止。通过对前八轮游戏进行观察,我发现框架现有的学习方法效果较差,没有一次到达顶端,基本只在最下面两层活动,尤其是右下角的部位,因此我尝试对特征提取方法进行改进。

原有的特征提取方法记录了地图中所有的位置信息,以及 GameTick、AvatarSpeed、AvatarHealthPoints 和AvatarType 四个参数。在此基础上我添加了 Avatar 的横纵坐标,因为地图是固定的,而目标均位于最上层,一种可行的方法是先以一种较容易地固定路径移动到最顶层,再左右移动到达目标,因此 Avatar 的横纵坐标是一个重要特征;添加了 Avatar 的前方是否有障碍物这一特征,防止其被卡在障碍物前;添加了精灵与目标的横向距离和纵向距离这两个特征,希望能让它更有针对性地向目标移动;加入了 Avatar 所在行和 Avatar 前方一行中

Avatar 左侧或右侧(根据高度而定,因为移动障碍物的运动方向不同)最近的移动障碍物的横向距离这两个特征,希望它能躲开移动的障碍物。

修改完运行以后发现这次 Avatar 能够向上越过最低的那层固定障碍物了。但又发现了新的问题Avatar 对于绕开固定障碍物的能力较差,所以我又加入了一个记录 Avatar 前方一行中 Avatar 两侧最近的固定障碍物的横向距离这一特征。

这次修改完以后再运行Avatar 能够向上越过中间的那层固定障碍物了又有所进步。但是积极的向上运动仅限于开局时血量较满时当血量较少时Avatar 依旧只会在最低两层活动。

最终的代码修改如下:

makeInstance 函数与 featureExtract 函数:

datasetHeader 函数:

三、任务 3

针对在任务二中通过修改特征提取方法无法解决的问题,我希望能够通过修改强化学习参数来解决。

阅读强化学习框架中原有的启发式函数代码,我发现这个函数基本没有什么作用,如果赢了就返回 1000输了就返回-1000如果没赢也没输就返回当前局面的游戏得分但是因为单次游戏中一次都没有达到目标所以都是 0而且每次游戏都是以失败告终所以这个启发式函数对于游戏的学习基本上没有什么作用。

接下来就是修改启发式函数,简单地添加了一些影响得分的因素,如 Avatar 离目标的距离、Avatar 的血量、Avatar 离本行最近的移动障碍物的距离、Avatar 离前方固定障碍物所在行的最近缺口的距离等等。尝试添加了其中几个因素以后,发现运行时间比之前更长了,卡顿明显(电脑配置有点吃不消),可能是由于修改了启发式函数导致运算量增大所致。因为运行时间实在是太长了,运行一轮游戏都需要十几分钟,而最初的一两轮学习效果并不显著,以现有设备无法观测后续学习效果是否有所改善。故修改启发式函数只好作罢。

接下来我试图对其他几个参数进行修改其它强化学习参数主要就是SIMULATION_DEPTH、m_maxPoolSize、m_gamma 和 m_epsilon。SIMULATION_DEPTH 是最大深度理论上深度越大距离成功就越近学习效果也会更好但考虑到设备性能和时间开销SIMULATION_DEPTH 不能

太大。m_maxPoolSize 是数据集的大小,理论上数据集越大学习效果也会更好,同样考虑到设备性能和时间、空

间开销m_maxPoolSize 也不能太大。m_epsilon 和 m_gamma 理论上太高或太低都不合适,应该都有一个中间值达到平衡,使学习效果最好。对这几个参数分别修改后进行测试,发现学习效果还是不明显,我认为原因主要有两点,一是计算量过大,电脑硬件性能不够好,导致花费的时间实在太长,难以观测到迭代后期的效果;二是启发式函数的缺陷,原有的启发式函数过于简单,没有起到它应有的作用,导致学习效果较差,也使修改其他参数对学习效果的影响难以体现,而修改后的启发式函数又大大增加了运算量,使得时间上的开销难以承受。

总结通过修改特征提取方法和强化学习参数强化学习效果有所提升Avatar 探索到的最大高度显著提高,但还是未能到达最高层的目标位置,也未能赢得游戏。我认为如果实验时间更加充裕并且有性能更好的设备,应该能做更多修改,达到更好的效果。