[心得] 用强化学习设计21点AI机器人

楼主: b05703 (blue)   2018-08-30 16:34:08
嗨各位,最近花了一些时间学习机器学习相关主题,想说来用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,欢迎大家讨论
指教啦!
作者: cutekid (可爱小孩子)   2018-08-30 16:59:00
大推(Y)
作者: Blankfein (LloydBlankfein)   2018-08-30 17:15:00
如果state space (observation) 设计成已经出现过的牌+ 自己手上的牌+ 庄家手上已摊开的牌的话 不知道会不会变猛很多 等于是让RL agent可以记牌的概念
作者: bcew (bcew)   2018-08-30 17:18:00
推解说
楼主: b05703 (blue)   2018-08-30 17:28:00
回BL大:感觉可以试试看 目前我自己写的环境跟gym的环境都是用无限副牌在发的~要改一下
作者: seo074482 (tin730_11)   2018-08-30 22:07:00
推!
作者: andrew8062 (安祖鲁)   2018-08-31 11:29:00
推!很酷 希望有机会的话可以share出来
作者: st1009 (前端攻城师)   2018-08-31 13:07:00
欢迎到DataScience板发文唷/DataScience板是专门研究机械学习 NLP等等资料科学的板,说不定可以找到一些同好
楼主: b05703 (blue)   2018-08-31 14:25:00
已发 感谢~程式码上传到github囉https://github.com/blue0107/DQN-blackjack-pokerbot
作者: andrew8062 (安祖鲁)   2018-09-01 03:29:00
感谢!周末找时间来研究研究
作者: admin520 (admin)   2018-09-01 17:22:00
感谢分享和解说
作者: weilun911 (阿偷)   2018-09-01 21:14:00
感想分享
作者: blackmaninEE (黑人电机机)   2018-09-01 23:23:00
作者: ssd860505da (JAGER)   2018-09-02 00:38:00
作者: powerkshs (气质斯文读书人)   2018-09-02 16:33:00
大推
作者: kyrie77 (NTU KI)   2018-09-02 20:39:00
有趣推个
作者: kwht (KH)   2018-09-02 21:41:00
有趣!
作者: apoopa   2018-09-03 17:00:00
推一个

Links booklink

Contact Us: admin [ a t ] ucptt.com