TensorFlow强化学习入门(1)——双臂赌博机

时间:2022-04-28
本文章向大家介绍TensorFlow强化学习入门(1)——双臂赌博机,主要内容包括简介、双臂赌博机、策略梯度、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

简介

强化学习不仅仅赋予了我们教会人工agent如何行动的能力,还使得agent可以通过我们提供的交互式环境进行学习。通过结合深度神经网络习得的复杂表示和RL agent的目标驱动型学习,计算机取得了很多令人惊叹的成绩:在很多中雅达利游戏中击败人类,打败围棋世界冠军等等。

要理解这种agent的构建方式,我们要在监督学习的思维方式上作出一点转变。与监督学习不同,输入信号不能立刻得到响应,因此监督学习中结合激励和响应设计的算法不再适用,取而代之的是强化学习通过 观测(observation)收益(rewards)行动(actions) 的组合来自主学习正确的组合。由于我们不能在任意场景下告诉agent什么才是“真正”正确的行动,所以我们需要一些技巧。在本篇和后面的文章中我会分享强化学习agent创建和训练的整个流程。为了概念的清晰,我们将从简单的agent和任务出发,随后再进行完善使其可以工作在复杂的环境下。

双臂赌博机

n臂赌博机是最简单的强化学习问题。从本质上来说,这个问题中我们要从n个具有不同固定赔率的老虎机当中找出收益率最高的一台并通过一直使用这台老虎机来达到最大的收益率。为了简化这一问题,我们假设只有两个老虎机以供选择。事实上简化后的问题严格来讲只能算是强化学习的前导,下面让我们来看一下一个问题要成为强化学习问题应当具备的条件:

  • 不同的行动将带来不同的收益。举例来说,假设我们在迷宫中寻宝,现在位于一个岔路口,此时选择向左可能能够获得宝藏,而向右会掉入有蛇的陷阱当中。
  • 收益是延迟发放的。在上面的例子中,我们即使左拐了也不能马上得到收益,只有再经过一系列决策之后才能得到结果。
  • 能够得到奖励的行动取决于当前环境的状态。还以迷宫为例,在上面的假设中是左拐才能得到收益,但在别的岔路口可能需要右拐才能得到收益。

由于n臂赌博机问题中不需要考虑上述的第二点和第三点,所以这是一个很好的出发点。我们只需要掌握任何可能的行动可能带来的收益从而确保当前的行动时最优的即可。在强化学习的行话当中,我们称这一过程在学习一个策略(policy)。下面我们将使用策略梯度的方法来解决这个问题,在这个方法当中我们的简易神经网络通过将环境中得到的反馈与梯度下降算法结合从而调整网络权重,据此来习得行动的策略。强化学习中agent学习的另一种方法称为价值函数。在这些方法中,agent不再是学习某个给定状态下的最优决策,而是去学习预测当前状态和行动的优劣。上面提到的两种方法都可以得到表现良好的agent,不过策略梯度方法会更直接一点。

策略梯度

简单来说,策略梯度网络可以产生直接的输出。在我们的赌博机问题当中,我们不希望用条件判断的方式得到任意状态下的输出。因此我们的网络需要包含一系列权重,从而使它可以对当前所有的赌博机臂作出响应,从而告诉我们各个赌博机臂的优劣。如果我们将这些权重全部初始化为1,那么我们的agent会对所有的赌博机的收益持乐观态度。

为了更新网络,我们使用e-greedy策略来选取赌博机臂(在第7部分我们会讲解行动选择策略)。这意味着我们的网络在大多数情况下会选择价值期望最大的决策,但是偶尔(与e相关)也会随机决策。通过这种方式可以确保网络尝试所有的决策,从而学到更多。一旦我们的网络作出决策之后,它就可以受到一个收益值(-1或1)。得到这个值之后,我们就可以使用策略损失函数来更新我们的网络。

Loss = -log(n)*A

A代表收益,它是所有强化学习算法中的必不可少的概念。它直观地反映了每个决策和参考值相比的优劣。本节中我们先假设参考基线为0,于此进行对比可以直接得到我们每个行动的收益,后面的文章中我们会开发更复杂的参考基线与我们的收益进行比较。

n代表策略。在本例当中其值会随着选定行动的权重值的变化而变化。

直观地来说,这个损失函数会增大带来正收益的行为的权重,减小带来负收益的行动的权重,长此以往agent的选择就具有了更强的偏向性。通过决策=>获得收益=>更新网络这样的循环过程,我们可以迅速得到一个可以帮我们解决老虎机问题的agent!尽管我这么说了,但是你更应该亲自尝试一下再做判断,下面给出实现的代码:

import tensorflow as tf
import numpy as np
# 定义一个四臂赌博机
# pullBandit函数会根据均值为0的正态分布来生成随机数,输入的bandit数越小,得到正收益的概率越大
# 我们的目标是agent可以一直选择带来正收益的赌博机
# 列出我们的赌博机bandit值,按照下面的设定,第四个机臂(index为3)带来正收益的可能性最大。
bandits = [0.2, 0, -0.2, -5]
num_bandits = len(bandits)
def pullBandit(bandit):
    # 获取随机数
    result = np.random.randn(1)
    if result > bandit:
        # 返回正收益
        return 1
    else:
        return -1

# 建立agent,包含了对每个赌博机的价值预估,使用策略梯度方法进行更新
tf.reset_default_graph()
# 建立网络的前馈部分,通过它可以实现决策
weights = tf.Variable(tf.ones([num_bandits]))
chosen_action = tf.argmax(weights, 0)
# 网络训练部分,通过计算损失值来更新网络
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)

# 训练agent
total_episodes = 1000
total_reward = np.zeros(num_bandits)
e = 0.1 # 随机决策概率
init = tf.initialize_all_variables()
# 启动TensorFlow计算图
with tf.Session() as sess:
    sess.run(init)
    i = 0
    while i < total_episodes:
        # 根据价值决策或随机决策
        if np.random.rand(1) < e:
            action = np.random.randint(num_bandits)
        else:
            action = sess.run(chosen_action)
        reward = pullBandit(bandits[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(str(num_bandits) + "个老虎机的实时收益为:" + str(total_reward))
        i += 1
print("agent认为" + str(np.argmax(ww)+1) + "号老虎机的收益最高")
if np.argmax(ww) == np.argmax(-np.array(bandits)):
    print("经验证正确!")
else:
    print("经验证错误!")
4个机臂的实时收益为:[1. 0. 0. 0.]
4个机臂的实时收益为:[-2. -1.  1. 31.]
4个机臂的实时收益为:[-2. -1.  2. 78.]
4个机臂的实时收益为:[ -1.   0.   2. 126.]
4个机臂的实时收益为:[ -1.   0.   3. 175.]
4个机臂的实时收益为:[  0.   0.   3. 222.]
4个机臂的实时收益为:[ -1.   0.   3. 269.]
4个机臂的实时收益为:[ -2.   0.   2. 315.]
4个机臂的实时收益为:[ -2.   0.   1. 364.]
4个机臂的实时收益为:[ -1.   3.   0. 409.]
4个机臂的实时收益为:[ -1.   3.   0. 453.]
4个机臂的实时收益为:[ -2.   1.   1. 499.]
4个机臂的实时收益为:[ -3.   0.   0. 544.]
4个机臂的实时收益为:[ -3.   1.   0. 591.]
4个机臂的实时收益为:[ -3.   0.  -1. 639.]
4个机臂的实时收益为:[ -2.  -1.   0. 684.]
4个机臂的实时收益为:[ -1.  -1.   0. 731.]
4个机臂的实时收益为:[ -1.  -1.   0. 779.]
4个机臂的实时收益为:[ -2.   2.   0. 823.]
4个机臂的实时收益为:[ -2.   1.   2. 870.]
agent认为4号机臂的收益最高
经验证正确!

译者计划翻译的系列文章:

  1. (0) Q-Learning的查找表实现和神经网络实现
  2. (1) 双臂赌博机
  3. Part 1.5 — Contextual Bandits
  4. Part 2 — Policy-Based Agents
  5. Part 3 — Model-Based RL
  6. Part 4 — Deep Q-Networks and Beyond
  7. Part 5 — Visualizing an Agent’s Thoughts and Actions
  8. Part 6 — Partial Observability and Deep Recurrent Q-Networks
  9. Part 7 — Action-Selection Strategies for Exploration
  10. Part 8 — Asynchronous Actor-Critic Agents (A3C)