
棋牌政策新动态,6.20法案全方位解读,德州扑克行业必看
2026年3月14日你知道几个德州扑克手牌的专业英文术语?
2026年3月14日
资料图
选自willtipton
机器之心编译
参与:Jane W、蒋思源
近日,强化学习,也就是RL,其成功,就像AlphaGo那样, 获取了大众的高度关注,然而其基本思路十分简单。接下来,我们在一对一无限注德州扑克游戏里开展强化学习。为了能够尽可能清晰地展现,我们将从无到有开发一个解决方案,而并非需要预设的机器学习框架,像Tensorflow这种。让我们通过Python3 Jupyter notebook这方式开始吧!
问题设置
规则提醒:该游戏是一个 2 人无限注的德扑游戏,其中:
游戏开启,两位选手都持有S筹码,还有随机给予的2张底牌。
大盲注玩家,下了一个盲注量,小盲注玩家,下了零点五个盲注量。
小盲注的玩家,能够选择全押,也就是all-in,或者选择弃牌,也就是fold。
要是小盲注玩家把所有筹码都押上了,那么大盲注玩家能够选择跟注(call),或者选择弃牌。
下述的决策树即我们可视化为显示规则的图面。游戏始于E,此时SB能够全押或者弃牌。要是他弃牌,我们转移到状态A,游戏结局已出呈结束状态。要是他全押,我们转移到状态D,BB必须在跟注与弃牌之间做出抉择。要是某玩家作出弃牌之举,另一玩家就会获取盲注,要是两个玩家都全押,便发放5张公共牌,并且金额依据扑克正常规则予以分配。

对于这款游戏呀,存在着著名的解决方案,其链接为(http://www.dandbpoker.com/preflop-charts) ,并且呢,还有其它的办法,像是虚拟对局方面,链接是(https://www.youtube.com/watch?v=MVMfDswjJE0) ,另外还有直接优化之处,其链接是(http://willtipton.com/coding/poker/2016/03/06/shove-fold-with-tensorflow.html)。这里,我们将使用强化学习估算解决方案。
这里有
种不重复的两张手牌组合数,所以,我们能够给所有牌排序,并且从0到1325进行编号。只要前后编号相同,具体的顺序就没什么重要性了。下述函数隐含地界定如此一个排序,且创立了从牌的编号到相关决策信息的映射,即是:牌的排序即牌的等级顺序和顺花色情况,也就是牌面个数和顺花色情况。

请注意,若存在输出元组里的首个元素(代码之中的r2),其始终会排序在前面,要是有的话。举例来说,手牌编号57恰巧就是62,我们存在:

就是说,当玩家进行全押这项操作的时候,他们平均能够获得的那个底池呢,会依据游戏规则从而得以确定,而那儿的底池也就是所谓“期望利益”。文件,名为pf_eqs.dat,其链接为http://willtipton.com/static/pf_eqs.dat,此文件包含一个numpy矩阵,名为pfeqs,其链接为http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.savetxt.html,其中,pfeqs指的是,当对手持有手牌j时,持有手牌i的期望利益。
当然,有时两人起始手牌存在一张相同,在此情形下,其期望不能同时计算,此时获取他们的期望利益也不妥。文件pf_confl.dat(http://willtipton.com/static/pf_confl.dat)含有另一个1326×1326矩阵,矩阵中每个元素为0或1。数字0表示两位玩家起始手牌不同,数字1表示起始手牌相同。

例如,手牌56的情况是62,手牌57的情况是62,手牌58的情况是62,所以我们有:

为什么结果不正好是 0.5 呢?
强化学习
接下来步入RL训练课程。RL难题存在三个关键构成部分:状态,动作,奖励。它们组合起来是这样的:
1。 我们处于某‘状态’(即我们观察到的世界的状态)。
2。 我们使用这个信息来采取某‘动作’。
3。 我们会得到某种‘奖励’。
4。 重复以上过程。
不断地反复去重复上述的过程,即进行观察状态的事宜,接着采取相应的行动,随后获得对应的奖励,再去观察全新的状态,然后采取另外的行动,进而获得另外的奖励等等。RL问题仅仅是要找出怎样去选择行动的方案以便能够获取尽可能多的奖励。事实表明这是一个极为普遍的框架。我们能够借由这样的方式去考量诸多问题,而解决这些问题也存在着诸多不一样的方法。通常来讲,解决办法涵盖随机游走(四处徘徊),于各异状态挑选各类行为,牢记哪些组合可获取何种奖励,接着试着运用这些信息在往后做更优的抉择。
RL是怎样被运用到德扑游戏方面的呢?在每一个决策的节点之上,玩家清楚自身所拥有的2张底牌,明确自身所处的位置,此即状态。而后玩家能够施行行动:要么选择弃牌,要么进行GII。(GII对于SB而言意味着全押(shove),对于BB而言意味着跟注)。随后便可获取奖励——这乃是玩家所赢取到的钱数,于最终的手牌当中我们会运用玩家的总筹码大小。举例来说,要是初始筹码大小为S = 10,SB全押而BB弃牌,那么玩家所获得的奖励分别是11以及9。
由我们来通过模拟手牌组合,从而找到游戏的策略,我们会同时处理两个玩家的随机手牌,促使他们做出关于如何玩的决策,接着会观察他们单次结束时最终获得多少钱,我们将要使用该信息来学习(估计)Q函数Q(S,A),Q的参数是状态Sand动作A,输出值是在该状态下采取该动作时所得到的最终奖励值,一旦我们有了Q(或者它的某种估计),那么策略选择就变得容易了:我们能够评估每个策略,查看哪一个更好。
所以,我们这儿的工作是对Q进行估计,我们会用Q^(发音为‘Q hat’)来指代这个估计,初始化的时候,我们会随机猜一些Q^,接着,我们会模拟一些手牌,两名玩家依据Q^做出决定,每一次手牌之后,我们会调整估计值Q^,用以反映玩家在特定状态下采取特定动作后得到的实际值,最终,我们应当得到一个不错的Q^估计,这便是确定玩家策略所需的全部内容。
这里存在着一点需要予以留意,那便是我们务必要保证在全部状态下施行所有动作,每一个状态跟动作所形成的组合都起码得尝试一回,只有如此才能够妥善地估算出最终每一个有可能出现的值。因此呢,我们会促使玩家在一小段时长为ε之内进行随机地采取行动,运用他们(当下所估计的)最优策略。第一点来说,我们本身应当积极主动地去探索所选内容的可能性,要频繁地进行随机选取。伴随时间的逐步推移,我们将会更多地去运用我们所获取到的知识。简单来讲就是,ε会随着时间的推进而逐渐缩小。达成这件事情存在着诸多方式,就好比:

Q被称作‘动作价值函数(action-value function)’,是由于它给出了采取任意特定动作(从任意状态)的值,它在多数RL方法里有重要作用,Q^怎样表示,如何评估,是不是在每次手牌之后更新?
特征:Q^ 的输入
首先,Q^的输入是状态和动作,把这个信息传递给Q函数,作为位置,比如SB为1,而BB为0,还有手牌编码,是0到1325,再者是动作,比如GII为1,弃牌为0。不过,我们将会看到,如果我们作更多的工作,会得到更好的结果。在这里,我们用7个数字的向量描述状态和动作:

函数 phi 返回的向量 φ,会成为 Q 函数的输入,此向量被称作特征向量,其各元素均为特征(φ 发音为‘fee’)。我们将会看到,我们所挑选的特征,在结果质量方面会引发极大差异。于挑选特征(即‘特征工程’)之时,我们运用了与问题相关领域的知识。它恰似科学那般具有艺术性。在此处,我们把判断哪些属于相关信息(在此情形下)的知识,用以下几种方式进行编码。一起来看看。
方便起见,第一个元素一直是 ,接下来的四个元素要考虑(它们代表玩家的手牌)。手牌编码已经转换为 rank1、rank2 和 isSuited。这三个变量在技术层面上给出的信息和手牌编码一样(特定组合暂忽略),不过该模型利用这种格式的信息会更高效。除了原始排序,(|rank1 – rank2|)^0.25 也包含在内。我们恰巧知道 connectedness 是德扑的重要属性,就像它的名字所暗示的那样。另外,要是所有的特征在量纲方面保持一致,那么该模型的学习成效将会更佳。在此处,所有的特征大体上处于0与1之间,这是我们运用把rank除以numRanks的方式而得到的。
最终,要是 not 是 GII(亦即是在要是动作属于弃牌的情形下),我们事实上会把这些数字设定成 0。我们清楚,当玩家采取弃牌这一动作时,特定的持有手牌对于结果不会产生任何作用(将小概率的卡牌移除效果予以忽略),故而我们于这种状况下把无关的信息给去除掉。
现此刻思索最终末尾的那两个元素,头一个径直对玩家所处的位置予以编码,然而第二个却一并取决于 “isSB” 以及 “isGII”,缘何会这般呢?过后我们将会展示出这个 “交叉项” 的不可或缺性。
关于 Q^ 的线性模型
我们会去学习一个用于估计的线性函数,这个函数是Q^函数,这有所意味呐,我们会切实去学习一个参数向量,此参数向量一般被称作θ,它的长度是7,而且这个长度跟那个特征向量长得一样,随后呢,我们会针对特定的φ来对Q^进行估计。
此情形下,下标里的i用来指代向量当中的特定元素,并且把参数列表书写成(φ;θ),这意味着Q^的值同φ与θ相关联,不过我们能够将其视作是φ的一个函数,而θ是处于固定状态的值。代码是十分简洁的:

尽管此函数被广泛运用,然而该算法并无突出之处,无法使其成为解决此问题的最优选择。这仅是其中一种方式:把一些学习参数与一些特征相融合来得到输出,并且完全由我们去定义一个θ向量,让它生成我们期望的输出。可是,正确选定θ会为我们精准估计在拥有特定手牌时采取特定行动的价值。
模拟扑克游戏
我们紧接着要‘玩’手牌了,这将在后续的几个部分里开展,然而此刻我们要先构建三个关键的概念,其与 RL 问题的三个关键构成部分有联系,即状态、动作以及奖励。首先是状态,每一回手牌,我们会借助随机发牌的形式起始每个玩家处的状态。

第二点,要采取动作,以当前模型给出的theta,结合已知的手牌和身份为SB,每个玩家据此选择动作。这个函数里头,我们去估计GII和弃牌也就是FOLD的值,这俩分别是qGII和qFOLD。然后呢,选此时的最优项,这个最优项是1减ε,不然就随机选择动作。返回已经采取的动作,并返回相应的价值估计和特征向量,后面我们要用这两项东西。

第三点说起,一旦我们清楚每个玩家当下所拥有的手牌以及其做出的动作,那我们便去模拟其余的手牌进而获取玩家的奖励。要是任何一个玩家扔掉手中的牌退出博弈,那我们能够马上返回准确的奖励数值。不然的话,我们参照玩家的状态以及奖励期望(权益),在正确的时间段内随机挑选一个获胜的玩家。

处于玩家全押的情形下,我们运用小技巧避开了模拟。不同于借助5张公共牌切实模拟游戏并评定玩家的手牌以查看谁获胜,我们当下依据预先算出的概率随机挑选出一个赢家。这在数学方面是等同的(琐碎的证明予以忽略),这仅仅是一种更便利且更具计算效率的方式。
重中之重的是,我们学习的进程未曾运用这些equity,也没有利用有关游戏规则的信息。就像我们很快就要目睹的这般,哪怕是全然模拟,学习的过程也并无差异,甚至于智能体还会和外部黑盒的扑克游戏系统开展交互,进而有可能遵循不一样的规则!那么,学习的过程到底怎样进行呢?
学习:更新 Q^
一次手牌结束后,我们要更新theta。对于每个玩家,我们知晓其状态与所采取的动作。我们拥有动作对应的估计价值以及从游戏里获取的实际奖励。从某种意义来讲,实际得到的奖励是“正确解”,要是动作的估计价值与之不一样,那么我们的模型就有误。我们需要更新theta,以便让Q^(φ;θ)更靠近正确答案。
假使让 φ‘ 成为一位玩家所处的特定那种状态,R 是她所获取到的实际奖励。让 L 等于(R,减去 Q^(φ;θ))的平方。L 被称作损失函数。L 越小,表明 R 越接近于 Q^(φ;θ),要是 L 等于0,,那么 Q^ 恰好等同于 R。也就是说,我们期望去微调整 θ,从而让 L 变得更小。(需要留意的是,存在诸多可能的损失函数,以至于随着 Q^ 愈发趋近于 R,L 越来越小。这里所提及的损失函数仅仅是,一个较为常见的选择)。
故而,‘更新 Q’所指的乃是通过变动θ,进而让 L 变得更小。存在不止一种能够达成这一目的的办法,其中一种简便的办法是随机梯度下降。简言之,它用以更新θ的规则就是:
对于‘超参数’α(也就是被叫作学习率的那个),我们要从中作出选择,它具备控制每次更新幅度的作用。要是α过小,就会致使学习很慢;可是如若α太大了,那么学习进程或许没办法实现收敛。把L代入到这个更新规制里,而去开展几行微积分运算,最终我们获得。

最后一行给出了更新参数所需遵守的准则,我们会依据这个准则去编写代码。要留意,此处的θ以及φ均为长度是7的向量。这里用于更新参数的准则分别在每个元素上适用。
整合
最后,该整合所有内容了。重复以下步骤:
1。 随机发给每个玩家手牌。
2。 令玩家各自选择一个动作。
3。 得到结果。
4。 使用观测到的(状态,动作,结果)元组更新模型。
底下的函数,名为mc,达成了这般蒙特卡罗算法,且返回了学习模型的参数,名为theta。

特别注意,上节推导出的参数更新规则在代码中得到了实现。
结果
解释模型
本例中,固定 S=10。

我们获取到了数字,然而,这些数字具备意义吗?事实上,存有几种途径能协助我们进行判断,且借助这些途径,我们还能获取到某些模型的解释。
首先,我们思索某些特定的情形。当SB选择弃牌,也就是FOLD时,它的估计数值是多少呢?很简单就能得出,因为在这种状况下,φ相对简易。实际上,除开第1个,其固定是1,以及第6个,它对应着isSB外,所有的元素均为0:phi等于。
1,0,0,0,0,1,0
所以,我们的线性模型的Q^,仅仅等同于加总theta的第1个元素,以及加总theta的第6个元素。
现下,咱们了解到,契合游戏的规则,SB进行弃牌的价值为9.5。故而,极为酷,模型同真实情形极为相近!这是一项很棒的逻辑判断,且借助例子阐述了怎样去估量我们模型潜在的误差值大小。
另一种情形存在:BB选择弃牌,仅有phi的第1个元素为非零状态,我们察觉到了一个估计数值。
尽管并不明晰正确的答案究竟会是怎样的,只是晓得它必定应当处于9(要是SB一直总是GII的话)以及10.5(要是SB一直总是弃牌的话)之间。实际上,这个数值相较于10.5而言,更靠近9,而这跟SB更倾向于GII而非是相一致的情况。
采用一种更具一般性的方式,去思索每一个θ输入,每一个元素θ_i,都会致使Q^出现增加,这是由于与之对应的特征φ_i会增长1,比如说,在存有恰当手牌之际,同时施行GII策略,θ的第5个元素会增长1,故而,具备适合手牌情况下的估计奖励值为0.22571655,这是一个微小的正向奖励,看起来是合乎情理的。
对应于玩家排名较高的手牌的,θ的第2个元素是6.16764962,这事对应着这样的特征,倘若处于isGII的情况,那就为rank2除以numRanks,不然就是0,这所指的便是当玩家拥有排名较高手牌时的GII策略。这里是rank2除以numRanks,所以每让特征增加1,则近似等于2和ace之间存在的差。以一个额外的6BB再加上1个ace替代2来获取胜利,看起来好像有着一定的合理性。(但是,为什么你会觉得有第二张更高的手牌显然是负的?)
对于与第6个特征相对应的θ的元素进行检查,若isSB为1,那么该元素为1,要是isSB不为1,那该元素就是0,若所有其他特征都相等,若符合上述所有条件,那么SB中的附加值明显为 -0.15230302,我们有可能把这诠释为位置方面的劣势,是因为存在不得不首先采取行动而有的微小惩戒的缘故。
然而,其他所有方面并非必然相同。要是SB实施GII策略,那么最后一个特征同样不为零。因而,-0.15230302是SB执行弃牌操作时的附加价值。在执行GII期间,我们对最后一个特征的贡献予以归纳,发觉奖励是-0.15230302 + 0.14547532 = -0.0068277。显而易见,当SB采用更为激进的策略时,位置上的劣势便减少了!
我们于此处见到,于本问题范畴之中,挑选有意义之特征能够助力我们有效地阐释结果。有意思的是,存在一条名为SAGE的老规则用以玩德扑游戏。此规则于锦标赛现场易于被记住。其原则是为你的手牌构建“能力指数”,该指数依据顺子、同花以及对子来进行规则构建,随后运用它来判定是否GII。它们的特征组合与我们的特征组合相比较会怎样呢?它们的结果又是如何呢?
首先,为何我们选用isSB以及isGII去判定最后一个特征,而非仅仅是isGII呢?思索如下。(BB,FOLD)的估计数值仅仅是θ的第1个元素,因而这个第1个元素得能够随意变动,从而获取正确的(BB,FOLD)数值。如此一来,第6个元素乃是在SB里的额外贡献,它得能够随意变动以得到正确的(SB,FOLD)。
一旦我们从弃牌转换成GII,元素2至5变成非零状态,并且依据玩家调整成特定数值,然而这些决策同样适用于SB和BB,该模型需要为SB全押给出一些有别于BB全押的决策。
假设,我们最终的特征是这样的:要是isGII成立,那么就取值为1,不然的话就取值为0。这并非由玩家决定,所以,SB和BB的估计值之间,唯一存在的差异将会是在isSB项上面。这个数字,必须要把执行弃牌时SB和BB之间的差异考虑进去,还要把执行GII时SB和BB之间的差异考虑进去。模型必须在这两个差异之间挑选出一个数字,最终有可能会引发一些比较差的折中情况。相反,我们所需要的是:要是isGII以及isSB都成立,那么就取值为1,否则就取值为0。有这样一种情况,该模型能够对SB GII与BB GII的增量值予以区分。
留意,此模型依旧没办法获取诸多细微的详情。举例来说,鉴于模型全然内置的函数形态,我们所见到的,在诸如A2以及K2这般的两个特定手牌组合情形下,对于SB和BB而言的GII的估计值的差别是全然一样的。不论θ的值怎样,我们的模型都绝无可能做出预测。
这样的模型具有很高的偏差值,也就是bias,它不灵活,且有一个强大的内置“观点”用以决定结果会呈现何种样子,这便是特征工程非常重要的原因所在,要是我们未曾尝试为算法提供经过精心设计的特征,那么它或许就不具备表征一个良好解决方案的能力。
可给模型增添更多样的特征,像别的交叉项之类的,从而获取偏差较小的模型,然而这兴许会引发不足,这会迅速丧失可解释性,还可能会碰到更多的技术难题,诸如过拟合,当然,在多数运用当中这并非首要问题,准确性较之可解释性更为关键,并且存在处理过拟合的办法。
可视化策略
要寻觅到完整无缺的策略,那我们将会对该模型展开评估,以此去弄明白在每位玩家的1326种手牌组合当中,究竟是GII更好呢,还是弃牌更好呢:

表面看去,针对于SB而言,大概55%的手牌抉择皆为全押,然而针对于BB来讲,大概49%的时段会选择跟注。

最后,我们能够生成些许SVG,用以在Jupyter环境里绘制GII范围。


难道我们究竟该如何去做出选择?在此处存在着诸多我们所期望的具备定性性质的特征呢:比如说,手牌大的状况很好,拥有对子的情形很好,同花的情形要优于非同花的情形,SB的打法相较于BB而言更为宽松等等。然而,边界线手牌的打法有时候会和处于真正的平衡策略里得出的打法有所不一样。
结语
通过让智能体自身去进行游戏,观察其中相关结果,依据这些做出更好决定,从而纯粹地开展学习过程,此过程并不依赖于任何结构或者游戏规则,文章为我们提供了一些合理策略来进行德扑游戏,这篇文章是介绍性的且应用了RL技术。另一方面,要学习一个好的模型,重要特征工程需要一些领域专业知识才行。
最后,来介绍一些背景情况。存在着许多合适的问题经阐述后能够成为 RL 问题,同时也有着许多不一样的方法用以解决这些问题。在此处的解决方案可能具备以下这些特征:是无模型的,是基于价值的,属于蒙特卡罗类型,是在策略方面的德信竞技,是无折现型的,并且会运用线性函数逼近器。


