作者 | Tony Yiu
编译 | Skura
编辑 | 唐里
原文标题:Teaching A Neural Net To Play Blackjack
不久前,我们开发了代码来模拟 21 点游戏。通过这些模拟,我们发现了赌场之所以具有优势的关键驱动因素。主要是以下 2 点:
获胜或平局的概率与玩家手牌值总数(21 未显示,因为概率为 100%)
最后,我们观察到一个简单的策略:只有在没有机会爆破的情况下才拿牌,这大大提高了我们获胜的几率,因为它将爆破的风险完全转移到了赌场。
如果你不熟悉 21 点游戏,我之前的文章描述了玩这个游戏的规则(https://towardsdatascience.com/lets-play-blackjack-with-python-913ec66c732f)。
但深度学习能做得更好吗?
本文的目标是讨论我们是否可以用深度学习来找到一个比上面更好的策略。我们将:
1、使用我们上次编码的 BLUJACK 模拟器生成数据(通过一些修改,使其更适合于训练算法)。
2、编码训练神经网络玩 21 点。
如果你不熟悉神经网络,我在这篇文章中写过它们的简介(https://towardsdatascience.com/understanding-neural-networks-19020b758230)。
生成我们的训练数据
1、输掉比赛的可能性。考虑到这种情况,我们可能希望模型告诉我们输的概率是多少。再说一次,只有当我们可以增加或减少赌注时,这才有用,而在 21 点游戏中我们不能这样做。
2、相反,我们希望我们的神经网络能够识别正确的动作,拿牌或不动。所以我们的目标变量应该是「正确的动作是拿牌还是不动」。
如果玩家拿牌并获胜,那么拿牌(y=1)是正确的决定。
如果玩家打输了,那么不动(y=0)是正确的决定。
如果玩家不动并获胜,那么不动(Y=0)是正确的决定。
如果玩家不动并输了,那么拿牌(y=1)是正确的决定。
庄家的正面卡(另一张隐藏起来)。
玩家手上牌的总值。
玩家是否有王牌。
玩家的动作(拿牌或不动)。
训练神经网络
from keras.models import Sequential
from keras.layers import Dense, LSTM, Flatten, Dropout
现在我们设置输入变量来训练神经网络。变量 feature_list 是一个列表,其中列有我在上面列出的特征(x 个变量)的列名。dataframe model_df 是存储我运行的 21 点模拟的所有数据的地方。
# Set up variables for neural net
feature_list = [i for i in model_df.columns if i not in
['dealer_card','Y','lose','correct_action']
]
train_X = np.array(model_df[feature_list])
train_Y = np.array(model_df['correct_action']).reshape(-1,1)
# Set up a neural net with 5 layers
model = Sequential()
model.add(Dense(16))
model.add(Dense(128))
model.add(Dense(32))
model.add(Dense(8))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='sgd')
model.fit(train_X, train_Y, epochs=20, batch_size=256, verbose=1)
检查我们模型的性能
玩游戏的时间到了!
def model_decision(model, player_sum, has_ace, dealer_card_num):
input_array = np.array([player_sum, 0, has_ace,
dealer_card_num]).reshape(1,-1)
predict_correct = model.predict(input_array)
if predict_correct >= 0.52:
return 1
else:
return 0
我们的模型很好!
结 论
我的目标变量的结构是否能让我预测它,然后我就能解决我的问题?在你开始收集数据和构建你的模型之前,确保你的预测是正确的至关重要。
新的数据和我训练过的数据有什么不同?如果它变化很大,那么统计模型甚至可能不是你的问题的正确答案。至少,你必须认识到这一点,并建立保障措施,例如用正规化和严格的验证和测试集对模型进行基准测试。
无法理解模型是如何到达它的决策的,所以你没有办法去理解和检验你的模型在严格的测试之外做出的决策,而这些测试是在模型训练过程中进行的。
1、尝试通过更优化的神经网络结构来改进模型,或者添加用于拆分 A 的代码(我没有把它构建到我原来的模拟器中),或者选择比我使用的基本特征更好的特征。
2、给模型计算卡片的能力,看看它对一副牌和六副牌的性能有什么影响(这是拉斯维加斯的标准)。