作者b05703 (blue)
看板DataScience
标题[心得] 用强化学习设计21点AI机器人
时间Fri Aug 31 14:25:12 2018
嗨各位,最近花了一些时间学习机器学习相关主题,想说来用python设计一个会玩21点的
机器人好了,以下会简单介绍我使用的游戏环境,深度神经网路,和相关成果。
一、游戏环境:openAI的gym,简单程式码如下
https://imgur.com/wCFHI5t
可以看到要在python搭建Blackjack环境其实非常简单,import完gym之後用gym.make就能
搭建各种游戏环境。
二、规则:
而我们这个游戏是我们要担任player的角色和庄家(dealer)对赌,我们起始会有两张
手牌,庄家则会有一张。点数方面2~10都以牌面作为点数,J,Q,K都算10点,ace可算1或1
1。
我们只有两种动作可以选择:拿牌(hit)或不拿(stand)。
目标是让手牌点数和最靠近21点,若超过21点(爆牌)则直接判定输了。
在我们决定不拿牌後,换庄家开始拿牌,庄家若手牌和低於17点,必须继续要牌。
最後比谁的牌点数和最靠近21谁就赢了。
後续我还有改写gym的环境让我们可以做双倍加注(double),让玩家可以采取
更多策略,更符合实际情况。
总之这张图的重点在env.step(action)那行,简单说就是
我们随机采取了一个action(0代表stand, 1代表hit)然後observation就是游戏当前状态
,会回传一组数字:(我方当前手牌和, 庄家手牌, 我方是否有ace),那reward就是强化
学习当中很重要的机制,可以让我们透过这种奖惩机制去训练模型,-1代表输了;0代表
我们还没爆牌或是平手;1代表我们赢了。done回传True或False表示当局结束与否。
在完全采取随机action的情况下玩10万场的胜率约27%。
三、训练方法:Deep Q Learning
我是用keras搭建神经网路的,因为比tensorflow简洁直观。附上我使用的超参。
https://imgur.com/Fbv8Nwp
我搭建了三层fully connected layer,activation function都用relu没问题,
但output layer的activation function就不能用relu了,因为在DQN中我们的input
是游戏的state也就是我们上面提到的observation,我们的output则是在碰到这样的
state,我们“采取各个动作预期的reward们”
打个比方:我们可能input [11, 6, 0],表示我们手牌和是11,庄家拿6,我们没ace。
这个神经网路的output应该要像这样 [-0.4 0.2],其中-0.4表示采取stand预期的
reward,0.2表示采取hit预期的reward,那我们当然希望reward越大越好所以就采取
hit这个动作。
因此这个output通常是有正有负的,不能用relu,那就用linear吧。
再简单提一下memory,是我们储存各个observation跟action的地方,在训练的时候
会从中随机抽样用TD的方法去不断更新我们的神经网路。
四、基本版训练成果:
https://imgur.com/9l0Akrl
靠左的数字是我们的手牌,上面的数字是庄家的手牌,H(hit拿牌)或S(stand不拿)
则是这个神经网路打算采取的策略,会有两段是因为上面那段是手上没有ace的情况
,下面是有ace的。
可以看到这个神经网路已经可以做出和人类非常相近的决策:在大牌选择stand,
小牌选择hit,并在手上有ace的时候更积极hit。而在这样策略下胜率提升到42%,
败率49%。
也就是说平均每下注一百元会输掉七元,虽然相较完全随机玩有显着的进步,但还有
进步空间,因此我决定加入其他战略(double)让玩家可以选择双倍下注,看能不能
让机器人有更聪明的表现。
五、加入double战略
由於openAI的原始程式码并没有double的功能因此我自己改写了一下他们的程式码,
简单来说现在玩家可以选择在第一手要不要double,要是double的话,玩家只能再拿
一张牌,然後庄家开始要牌。
神经网路方面我一样用DQN下去train,只是在output的时候变成输出三种动作的
期望reward。除此之外我参考了周莫烦的code和prioritised replay的paper实作了
优先回放,其中有用到sumtree的资料结构。也加入了doubleDQN的训练方法。
六、double版训练成果
在看这个神经网路的决策之前我们先看一下我们人类推算出的最佳21点战略表。
https://imgur.com/15vKVBF
然後这是我们的神经网路在面对各种情况所下的决策表。
https://imgur.com/eKQzWDW
可以看到明显它学习到在我们握有9, 10, 11且庄家是weak hand的时候可以进行
double,还有在手上有ace的时候该如何double等等。虽然不尽完美,但在我用这个
神经网路下去玩一百万场的结果平均每一百元大约输2.X元左右,如果真的要赢钱,
可能还要加上split的战略和算牌了。
七、结语
其实发文也同时是记录自己的学习笔记和找到同样对RL也有兴趣的朋友、前辈一起
讨论啦,感谢大家耐心看完。要是对我的程式码有兴趣欢迎到我的github按个星https://
github.com/blue0107/DQN-blackjack-pokerbot,欢迎大家讨论
指教啦!
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 27.246.75.8
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/DataScience/M.1535696714.A.DA8.html
1F:推 goroundround: 推实作!强一点来做一发lol08/31 14:35
※ 编辑: b05703 (27.246.75.8), 08/31/2018 14:47:56
2F:推 tritonight: 推08/31 15:43
3F:推 nistik84114: 推 08/31 18:11
4F:推 st1009: 推08/31 19:55
5F:→ b05703: 程式码上传到github罗08/31 21:17
6F:推 dddddd67: 赞08/31 21:17
※ 编辑: b05703 (27.246.75.8), 08/31/2018 21:23:05
8F:→ yoyololicon: 副档名怎麽消失惹 08/31 22:52
9F:→ b05703: 你说在github里面吗 我看一下 08/31 23:33
10F:推 ymymio: 不推 不行 09/01 01:14
11F:推 y956403: 有实作有推 09/01 05:40
12F:推 gn02335338: 推 09/01 11:16
13F:推 goobbye: 很有趣,推@@~ 09/01 13:24
14F:推 st1009: 可以请问一下大该是花了多久的时间嘛? 09/01 15:18
15F:→ b05703: 从我开始学什麽是DQN到完成大约一个多礼拜吧 我花比较多 09/01 15:40
16F:→ b05703: 时间在理解别人的code和读prioritized replay的论文 欢迎 09/01 15:40
17F:→ b05703: 聊聊哈哈 09/01 15:40
18F:推 h5904098: 有趣推 09/01 19:19
19F:推 a78998042a: 推 09/03 00:34
20F:推 thefattiger: RL推推 09/03 10:42
21F:推 billy8407: q 09/04 21:40
22F:推 vvind: 推 09/13 17:55
23F:推 Echeo: Push 10/07 20:05
24F:推 uukoQAQ: 推推 01/06 20:41