2018 年 11 月
第 33 卷,第 11 期
人工智能应用-仔细看一看强化学习
在上个月的专栏中,我探讨了几个基本概念的强化学习 (RL)、 尝试这两个导航一个简单的环境和然后实现一个问题与解答表记得过去的操作和哪些操作会导致哪些奖励严格随机一种方法。在演示中,随机工作代理已到达目标状态约为 1 时使用 Q 表格记住上一个操作的时间以及大约一半的时间百分比。但是,此试验中只被简要的 RL 很有前景的和拓展字段。
请记住,在以前的专栏中 (msdn.com/magazine/mt830356),RL 问题空间组成环境、 代理、 操作、 状态和奖励。代理将检查环境的状态并进行操作。然后该操作的代理和/或环境状态更改。该代理接收奖励,并检查其环境的更新的状态。周期然后重新启动,直到代理成功或失败的预定义的目标是在运行的迭代数。当代理成功或失败时,模拟结束。问: 表使用代理会记住的操作生成正奖励和决定在后续模拟时引用它。
多臂老虎机问题
RL 中的经典问题之一是探索和利用之间的紧张。赌博机,通常称为"单臂老虎"是此问题的灵感。赌博机一家银行然后创建"多臂老虎机"。 每个这些槽机具有或不出大获全胜付款的概率。导致大获全胜每个打开的概率可能表示为 P,且不需要付费的概率是 1 – p。 如果计算机已.5 大获全胜概率 (JP),每个请求级别具有赢得或失去的机会。相反,0.1 JP 的计算机将产生落选结果 90%的时间。
现在,假定为五个赌博机的插槽和播放机 (或代理) 具有的目标是最大化获胜的内容,并最大程度减少损失。使用的任何计算机的大获全胜概率 (JP) 没有监控,代理必须首先执行一些风险。使用级别的第一个请求,该代理 wins 并接收付款。但是,后续尝试显示出大约一半的时间,.54 JP 支付此计算机。当赌博机,这是相当多。代理必须确定它应利用当前已知资源还是探索新的计算机。如果第一个槽机支付的概率较这宽松,是否值得尝试任何以了解是否吐钱的机会更好的银行机?
若要进一步探索此问题空间的最佳方法是使用 Jupyter notebook 中的某些 Python 代码。在首选平台上创建一个 Python 3 notebook。我介绍了前一篇文章中的 Jupyter 笔记本 (msdn.com/magazine/mt829269)。创建空单元格并输入以下代码并执行该单元格。
import numpy as np
import matplotlib.pyplot as plt
number_of_slot_machines = 5
np.random.seed(100)
JPs = np.random.uniform(0,1, number_of_slot_machines)
print(JPs)
plt.bar(np.arange(len(JPs)),JPs)
plt.show()
输出应阅读并显示的值,绘图,如中所示图 1。
[0.54340494 0.27836939 0.42451759 0.84477613 0.00471886]
图 1 的五个的赌博机的大获全胜概率
代码将创建一系列的范围从 0.004 0.844 到五个赌博机的 JP 值的数组。但是,代理已尝试,而相比,在第一个计算机不是最佳。很明显,具有 84.4%付款率的第四个槽计算机是最好支付在环境中的计算机。它也是值得注意最后一个槽计算机具有最差的支付出大获全胜几率。请记住,代理的预先不知道付款率,并且它必须在其自己发现它们。代理迈第一个计算机上,选择而不是浏览,利用该漏洞代理从不会找到最佳付费槽机。
若要表示的一种模拟开始时知道的代理,请将下面的代码添加到新的单元格:
known_JPs = np.zeros(number_of_slot_machines)
这将创建为零,这意味着,代理假设的每个插槽机 JP 为零的数组。虽然这可能不是最佳的初始值在所有情况下,它就足够了,我们所希望的。若要创建的槽机模拟,将以下代码添加到新的单元格,并执行它:
def play_machine(slot_machine):
x = np.random.uniform(0, 1)
if (x <= JPs[slot_machine]):
return(10)
else:
return(-1)
此代码片段模拟支付出 10 如果机奖励和-1 的负数回报,如果计算机不在槽计算机。吐钱的几率基于 JPs numpy 数组中定义的可能性。若要测试此代码,在新单元格中输入以下 Python 代码,并执行:
# Test Slot Machine 4
for machines in range(10):
print(play_machine(3))
print ("------")
# Test Slot Machine 5
for machines in range(10):
print(play_machine(4))
此代码凹坑最佳的针对性能最坏的计算机的计算机。由于这所有基于机会,则无法保证的输出结果。结果应反映,大部分计算机 4 的 10 个值与几乎所有为-1 值机 5。与按预期方式运行的模拟的槽机器代码,它现在是时间来检查在 RL 中的一种算法:Epsilon 贪婪。
Epsilon 贪婪算法
代理的人脸此处核心难题是机会的确定优先级的好奇心,探索奖励更好,希望其他赌博机或贪婪,希望利用已知的资源。一个最简单的算法来解决此问题被称为代理位置之间使用具有最佳的付款观察到目前为止,或尝试使用另一台计算机,它可能会希望几率槽机随机选择的 Epsilon 贪婪算法提供更好的付款。使用 Epsilon 较低的值,此算法贪婪算法,但偶尔会尝试另一个槽机。例如,如果 Epsilon 值是.1,该算法将选择利用 90%的时间并探索只有 10%的时间。通常情况下,默认值的 Epsilon 往往.05 和.1 之间选择。简单地说,代理将主要播放最佳槽机发现它知道的并有时尝试新的计算机。请记住,级别每个请求需要付出一定代价,代理不知道我们知道: 4 该槽的最佳回报。
这样强调 RL 这一概念。代理不知道有关环境最初,因此,需要首先浏览,然后利用更高版本。学习贯穿于整个过程。从根本上来说,这是延迟地满足需求,这一概念,它是代理的最大利益,因此它会使一些空间来探索不要完全贪婪。
测试 Epsilon 贪婪假设
若要测试此假设,将添加中的代码图 2到新的单元格并执行它。此代码创建 multi_armed_bandit 函数,这一系列针对集合的赌博机的运行进行模拟。该函数将存储的大获全胜付款观察到的几率。在每次迭代,代理将随机播放具有最佳付款它到目前为止,已观察到的槽计算机或任意尝试另一台计算机。Argmax 函数 numpy 数组中返回的最大值。在这里,这意味着大获全胜的最佳可能具有的槽计算机。函数的参数,以控制赌博机的数量、 要运行的迭代的数量和 epsilon 值。
图 2 强化学习代码
def multi_armed_bandit(arms, iterations, epsilon):
total_reward, optimal_action = [], []
estimated_payout_odds = np.zeros(arms)
count = np.zeros(arms)
for i in range(0, iterations):
epsilon_random = np.random.uniform(0, 1)
if epsilon_random > epsilon :
# exploit
action = np.argmax(estimated_payout_odds)
else :
# explore
action = np.random.choice(np.arange(arms))
reward = play_machine(action)
estimated_payout_odds[action] = estimated_payout_odds[action] +
(1/(count[action]+1)) *
(reward - estimated_payout_odds[action])
total_reward.append(reward)
optimal_action.append(action == np.argmax(estimated_payout_odds))
count[action] += 1
return(estimated_payout_odds, total_reward)
RL 代码,现在它后即可测试 Epsilon 贪婪算法。输入中的代码图 3到一个空单元格并执行它。结果显示从图表图 1为了便于参考后, 跟 RL 代码观察到的机率。
图 3 代码以比较实际的槽机器可能与代理的观测值
print ("Actual Odds")
plt.bar(np.arange(len(JPs)),JPs)
plt.show()
print (JPs)
print("----------------------------------")
iterations = 1000
print("\n----------------------------------")
print ("Learned Odds with epsilon of .1")
print("----------------------------------")
learned_payout_odds, reward = multi_armed_bandit(number_of_slot_machines, iterations, .1)
plt.bar(np.arange(len(learned_payout_odds)),learned_payout_odds)
plt.show()
print (learned_payout_odds)
print ("Reward: ", sum(reward))
如中所示图 4,该算法做得真不错,不仅确定使用的最有利情况下,在槽计算机的但还生成相当准确吐钱概率其他四个槽机。关系图而不是好线对齐。的例外是第五个槽机,具有代理的观察中产生负面评分吐钱的此类低几率。
图 4 结果与.1 的 Epsilon 值
现在,与所建立的基线,它是时间一些更多的体验。会发生什么情况如果 epsilon 已设置为零,这意味着该算法将永远不会探讨?在新的单元格中输入以下代码并执行它,以运行该实验:
print("\n----------------------------------")
print ("Learned Odds with epsilon of 0")
print("----------------------------------")
learned_payout_odds, reward =
multi_armed_bandit(number_of_slot_machines, iterations, 0)
plt.bar(np.arange(len(learned_payout_odds)),learned_payout_odds)
plt.show()
print (learned_payout_odds)
print ("Reward: ", sum(reward))
生成的图表显示了其中一个值大于零。一台计算机优先级高于他人,使其很清楚在代理找到一台计算机,并仍然要使用它。但是,运行代码若干次并可能会注意到,有时一个有趣的模式开发。将有一个或多个计算机并将负值,与具有较高的一台计算机比零值。在这些情况下,代理在给定计算机上的丢失,然后队在另一台计算机上。一旦代理发现的入选机,它将只讨论与该计算机,因为它将成为 argmax 函数将选择的计算机。如果 epsilon 设置为零,代理可能仍然浏览,但它不会有意为之。在这种情况下,观察到的槽机几率这是实际的几率。它也是值得一提的"贪婪"方法会生成比 epsilon 设置为.1 时的较低奖励分数。贪婪,至少绝对贪婪似乎会适得其反。
什么如果 epsilon 已设置为 1,使代理浏览每次,根本不利用?在新单元格中输入以下代码并执行它:
print("\n----------------------------------")
print ("Learned Odds with epsilon of 1")
print("----------------------------------")
learned_payout_odds, reward = multi_armed_bandit(number_of_slot_machines, iterations, 1)
plt.bar(np.arange(len(learned_payout_odds)),learned_payout_odds)
plt.show()
print (learned_payout_odds)
print ("Reward: ", sum(reward))
结果将显示代理未极好地观察几率类似的则返回 true 的情况下和的图表行向上紧密图 1。实际上,设置为 1 的 epsilon 结果看起来很相似的值时为.1 到。但是,记下的奖励值,并且没有形成鲜明的差异。奖励值时 epsilon 已设置为.1 几乎始终将高于设置为 1 时。代理设置为仅浏览,它将尝试随机位于每次迭代的机。虽然它可能会观察从学习,它不作用于的那些观测值。
总结
RL 保持一个在 artificial intelligence 中最令人兴奋的空间。在本文中,我探讨了 Epsilon 贪婪算法与经典的"Multi-Armed 老虎机"问题,特别深化到资源管理器或攻击难题面临的代理。我鼓励您若要进一步探索通过实验得到 epsilon 和更大的赌博机的不同值之间权衡。
Frank La Vigne是 Microsoft 帮助公司的 AI 技术解决方案专业人员获得更多通过充分利用其数据与分析和 AI。他还共同主持 DataDriven 播客。他定期在 FranksWorld.com 和您可以看到他在他的 YouTube 频道"Frank's World TV"(FranksWorld.TV)。
衷心感谢以下技术专家对本文的审阅:Andy Leonard