n 臂强盗问题是一个强化学习问题,其中给代理一个有 n 个强盗/臂的老虎机。老虎机的每个臂都有不同的获胜机会。拉动任何手臂都会奖励或惩罚智能体,即成功或失败。
代理的目标是一次拉一个强盗/武器,以使操作后收到的总奖励最大化。此外,问题描述指出特工不知道武器成功的可能性。它最终通过反复试验以及价值评估来学习。
本教程将教我们如何利用策略梯度方法,该方法使用 TensorFlow 构建一个基本神经网络,该网络由与每个可用臂获得老虎机奖金的可能性成比例的权重组成。在此策略中,智能体基于 e-greedy 方法选择机器臂。
这意味着智能体通常会选择期望值最高的动作,但它也会随机选择。
通过这种方式,间谍测试了几把枪中的每一把,以更多地了解它们。当智能体采取行动时,例如选择老虎机的一个臂,它会得到 1 或 -1 的奖励。
用 Python 实现强盗问题
下面是用Python编写的n-arm/multi-arm bandit问题的简单实现:
对于我们的代码实现,我们选择 n=6(老虎机的 6 个臂),它们的编号为 [2,0,0.2,-2,-1,0.8]。
我们将逐渐发现代理学习并有效地选择具有最高收益的强盗。
第 1 步:导入模块
该方法tf.disable_v2_behavior
(顾名思义)会禁用TensorFlow 1.x 和 2.x 之间更改的任何全局行为,并使它们按照 1.x 的预期运行。
1
2
3
|
import numpy as np import tensorflow.compat.v1 as tf tf.disable_v2_behavior() |
第 2 步:计算武器奖励
我们在槽臂数组中指定我们的强盗。数组的长度存储在 中len_slot_arms
。该方法发现reward() 根据正态分布创建一个均值为 0 的随机整数。
手臂/强盗数量越低,代理返回正奖励的可能性就越大 (1)。
1
2
3
4
5
6
7
8
9
10
|
slot_arms = [ 2 , 0 , 0.2 , - 2 , - 1 , 0.8 ] len_slot_arms = len (slot_arms) def findReward(arm): result = np.random.randn( 1 ) if result > arm: #returns a positive reward return 1 else : #returns a negative reward return - 1 |
第 3 步:设置神经代理
TensorFlow 库的方法tf.rese_default_graph
清除默认图堆栈并重置全局默认图。第 2 行和第 3 行将特定老虎机的权重设置为 1,然后进行实际的臂选择。
1
2
3
|
tf.reset_default_graph() weights = tf.Variable(tf.ones([len_slot_arms])) chosen_action = tf.argmax(weights, 0 ) |
训练由下面的代码处理。它最初向网络提供奖励和指定的动作(arm)。然后神经网络使用如下所示的算法计算损失。然后利用这种损失通过更新网络来提高网络性能。
1
2
3
4
5
6
7
8
|
reward_holder = tf.placeholder(shape = [ 1 ],dtype = tf.float32) action_holder = tf.placeholder(shape = [ 1 ],dtype = tf.int32) responsible_weight = tf. slice (weights,action_holder,[ 1 ]) loss = - (tf.log(responsible_weight) * reward_holder) optimizer = tf.train.GradientDescentOptimizer(learning_rate = 0.001 ) update = optimizer.minimize(loss) Loss = - log(weight for action) * A(Advantage from baseline(here it is 0 )). |
第 4 步:训练 Agent 并找到最佳的手臂/强盗
我们通过进行随机活动并获得激励来训练代理。上面的代码启动一个 TensorFlow 网络,然后选择一个随机动作,并从其中一个臂中选择一个奖励。这种激励有助于网络更新,并且也会显示在屏幕上。
total_episodes = 1000 total_reward = np.zeros(len_slot_arms) #output reward array e = 0.1 #chance of taking a random action. init = tf.initialize_all_variables() with tf.Session() as sess: sess.run(init) i = 0 while i < total_episodes: if np.random.rand( 1 ) < e: action = np.random.randint(len_slot_arms) else : action = sess.run(chosen_action) reward = findReward(slot_arms[action]) _,resp,ww = sess.run([update,responsible_weight,weights], feed_dict = {reward_holder:[reward],action_holder:[action]}) total_reward[action] + = reward if i % 50 = = 0 : print ( "Running reward for the n=6 arms of slot machine: " + str (total_reward)) i + = 1 print ( "The agent thinks bandit " + str (np.argmax(ww) + 1 ) + " has highest probability of giving poistive reward" ) if np.argmax(ww) = = np.argmax( - np.array(slot_arms)): print ( "which is right." ) else : print ( "which is wrong." ) |
结论
恭喜!您刚刚学习了如何使用 Python 编程语言解决多臂老虎机问题。我希望你喜欢它!😇
喜欢该教程吗?无论如何,我建议您查看下面提到的教程:
- FizzBuzz 问题 – 在 Python 中实现 FizzBuzz 算法
- 用 Python 解决梯子问题
- 使用递归解决 Python 中的 0-1 背包问题
- 解决 Python 中的平铺问题
感谢您抽出宝贵时间!希望你学到新东西!😄