1.输入的数据,标定的数据,它都是没有关联的,尽可能没有关联。因为如果有关联的话,这个网络是不好学习的。 2.我们告诉这个 learner 正确的标签是什么,这样它可以通过正确的标签来修正自己的这个预测。
1.在游戏过程中,大家可以发现这个 agent 得到的观测不是个 i.i.d 的分布,上一帧下一帧其实有非常强的连续性。 2.另外一点,在玩游戏的过程中,你并没有立刻获得这个反馈。比如你现在把这个木板往右移,那么只会使得这个球往上或者往左上去一点,你并不会得到立刻的反馈。所以强化学习这么困难的原因是没有得到很好的反馈,然后你依然希望这个 agent 在这个环境里面学习。
1.首先强化学习输入的序列的数据并不是像 supervised learning 里面这些样本都是独立的。
2.另外一点是 learner 并没有被告诉你每一步正确的行为应该是什么。Learner 不得不自己去发现哪些行为可以使得它最后得到这个奖励,只能通过不停地尝试来发现最有利的 action。
3.这里还有一点是 agent 获得自己能力的过程中,其实是通过不断地试错(trial-and-error exploration)。Exploration 和 exploitation 是强化学习里面非常核心的一个问题。Exploration 是说你会去尝试一些新的行为,这些新的行为有可能会使你得到更高的奖励,也有可能使你一无所有。Exploitation 说的是你就是就采取你已知的可以获得最大奖励的行为,你就重复执行这个 action 就可以了,因为你已经知道可以获得一定的奖励。因此,我们需要在 exploration 和 exploitation 之间取得一个权衡,这也是在监督学习里面没有的情况。
4.在强化学习过程中,没有非常强的 supervisor,只有一个奖励信号(reward signal),就是环境会在很久以后告诉你之前你采取的行为到底是不是有效的。Agent 在这个强化学习里面学习的话就非常困难,因为你没有得到即时反馈。当你采取一个行为过后,如果是监督学习,你就立刻可以获得一个指引,就说你现在做出了一个错误的决定,那么正确的决定应该是谁。而在强化学习里面,环境可能会告诉你这个行为是错误的,但是它并没有告诉你正确的行为是什么。而且更困难的是,它可能是在一两分钟过后告诉你错误,它再告诉你之前的行为到底行不行。所以这也是强化学习和监督学习不同的地方。 上图的过程是 rollout 的一个过程。Rollout 的意思是从当前帧去生成很多局的游戏。然后这个很多局就通过是你当前的这个网络去跟这个环境交互,你就会得到一堆这个观测。你可以把每一个观测看成一个轨迹(trajectory),轨迹的话就是当前帧以及它采取的策略,每一步的这个策略都有。最后结束过后,你会知道你到底有没有把这个球击到对方区域,对方没有接住,你是赢了还是输了。我们可以通过观测序列以及 Eventual Reward 来训练这个 agent ,使它尽可能地采取最后可以获得这个 Eventual Reward 的过程。
化学习研究的问题是 agent 跟环境交互,上图左边画的是一个 agent,agent 一直在跟环境进行交互。这个 agent 把它输出的动作给环境,环境取得这个动作过后,会进行到下一步,然后会把下一步的观测跟它上一步是否得到奖励返还给 agent。通过这样的交互过程会产生很多观测,agent 就是为了从这些观测之中学到能极大化奖励的策略。 这里给大家举一些奖励的例子。不同的环境,奖励也是不同的。
比如说一个下象棋的选手,它的目的其实就为了赢棋。奖励是说在最后棋局结束的时候,他知道会得到一个正奖励或者负奖励。 羚羊站立也是一个强化学习过程,它得到的奖励就是它是否可以最后跟它妈妈一块离开或者它被吃掉。 在股票管理里面,奖励定义由你的股票获取的收益跟损失决定。 在玩雅达利游戏的时候,奖励就是你有没有在增加游戏的分数,奖励本身的稀疏程度决定了这个游戏的难度。
在 agent 的内部也有一个函数来更新这个状态。当 agent 的状态跟环境的状态等价的时候,我们就说这个环境是 full observability,就是全部可以观测。换句话说,当 agent 能够观察到环境的所有状态时,我们称这个环境是完全可观测的(fully observed)。 但是有一种情况是 agent 得到的观测并不能包含所有环境运作的状态,因为在这个强化学习的设定里面,环境的状态才是真正的所有状态。比如 agent 在玩这个 black jack 这个游戏,它能看到的其实是牌面上的牌。或者在玩雅达利游戏的时候,观测到的只是当前电视上面这一帧的信息,你并没有得到游戏内部里面所有的运作状态。也就是说当 agent 只能看到部分的观测,我们就称这个环境是部分可观测的(partially observed)。在这种情况下面,强化学习通常被建模成一个 POMDP 的问题。
部分可观测马尔可夫决策过程(Partially Observable Markov Decision Processes, POMDP)是一个马尔可夫决策过程的泛化。POMDP 依然具有马尔可夫性质,但是假设智能体无法感知环境的状态 ss,只能知道部分观测值 oo。比如在自动驾驶中,智能体只能感知传感器采集的有限的环境信息。
同的环境允许不同种类的动作。在给定的环境中,有效动作的集合经常被称为动作空间(action space)。像 Atari 和 Go 这样的环境有离散动作空间(discrete action spaces),在这个动作空间里,agent 的动作数量是有限的。在其他环境,比如在物理世界中控制一个 agent,在这个环境中就有连续动作空间(continuous action spaces) 。在连续空间中,动作是实值的向量。
对于一个强化学习 agent,它有如下组成成分:
首先 agent 有一个 policy function,agent 会用这个函数来选取下一步的动作。
然后它也可能生成一个价值函数(value function)。我们用价值函数来对当前状态进行估价,它就是说你进入现在这个状态,可以对你后面的收益带来多大的影响。当这个价值函数大的时候,说明你进入这个状态越有利。
另外一个组成成分是模型(model)。模型表示了 agent 对这个环境的状态进行了理解,它决定了这个世界是如何进行的。
Policy 决定了这个 agent 的行为,它其实是一个函数,把输入的状态变成行为。这里有两种 policy:
一种是 stochastic policy(随机性策略),它就是 \piπ 函数 \pi(a | s)=P\left[A_{t}=a | S_{t}=s\right]π(a∣s)=P[A t =a∣S t =s] 。当你输入一个状态 ss 的时候,输出是一个概率。这个概率就是你所有行为的一个概率,然后你可以进一步对这个概率分布进行采样,得到真实的你采取的行为。比如说这个概率可能是有 70% 的概率往左,30% 的概率往右,那么你通过采样就可以得到一个 action。
一种是 deterministic policy(确定性策略),就是说你这里有可能只是采取它的极大化,采取最有可能的动作。你现在这个概率就是事先决定好的。
从 Atari 游戏来看的话,policy function 的输入就是游戏的一帧,它的输出决定你是往左走或者是往右走。
通常情况下,强化学习一般使用随机性策略。随机性策略有很多优点:
在学习时可以通过引入一定随机性来更好地探索环境;
随机性策略的动作具有多样性,这一点在多个智能体博弈时也非常重要。采用确定性策略的智能体总是对同样的环境做出相同的动作,会导致它的策略很容易被对手预测。
模型决定了下一个状态会是什么样的,就是说下一步的状态取决于你当前的状态以及你当前采取的行为。它由两个部分组成,
一个是 probability,它这个转移状态之间是怎么转移的。
另外是这个奖励函数,当你在当前状态采取了某一个行为,可以得到多大的奖励。
根据强化学习 agent 的不同,我们可以把 agent 进行归类。
基于价值函数的 agent。这一类 agent 显式地学习的是价值函数,隐式地学习了它的策略。因为这个策略是从我们学到的价值函数里面推算出来的。 基于策略的 agent,它直接去学习 policy,就是说你直接给它一个 state,它就会输出这个动作的概率。在这个 policy-based agent 里面并没有去学习它的价值函数。 把 value-based 和 policy-based 结合起来就有了 Actor-Critic agent。这一类 agent 就把它的策略函数和价值函数都学习了,然后通过两者的交互得到一个最佳的行为。
在强化学习里面,Exploration 和 Exploitation 是两个很核心的问题。
Exploration 是说我们怎么去探索这个环境,通过尝试不同的行为来得到一个最佳的策略,得到最大奖励的策略。
Exploitation 是说我们不去尝试新的东西,就采取已知的可以得到很大奖励的行为。 以选择餐馆为例,
Exploitation 是说我们直接去你最喜欢的餐馆,因为你去过这个餐馆很多次了,所以你知道这里面的菜都非常可口。 Exploration 是说你把手机拿出来,你直接搜索一个新的餐馆,然后去尝试它到底好不好吃。这里的结果就是有可能这个新的餐馆非常不满意,你就这个钱就浪费了。
class BespokeAgent: def __init__(self, env): pass def decide(self, observation): # 决策 position, velocity = observation lb = min(-0.09 * (position + 0.25) ** 2 + 0.03, 0.3 * (position + 0.9) ** 4 - 0.008) ub = -0.07 * (position + 0.38) ** 2 + 0.07 if lb < velocity < ub: action = 2 else: action = 0 return action # 返回动作 def learn(self, *args): # 学习 pass agent = BespokeAgent(env) def play_montecarlo(env, agent, render=False, train=False): episode_reward = 0. # 记录回合总奖励,初始化为0 observation = env.reset() # 重置游戏环境,开始新回合 while True: # 不断循环,直到回合结束 if render: # 判断是否显示 env.render() # 显示图形界面,图形界面可以用 env.close() 语句关闭 action = agent.decide(observation) next_observation, reward, done, _ = env.step(action) # 执行动作 episode_reward += reward # 收集回合奖励 if train: # 判断是否训练智能体 agent.learn(observation, action, reward, done) # 学习 if done: # 回合结束,跳出循环 break observation = next_observation return episode_reward # 返回回合总奖励 env.seed(0) # 设置随机数种子,只是为了让结果可以精确复现,一般情况下可删去 episode_reward = play_montecarlo(env, agent, render=True) print('回合奖励 = {}'.format(episode_reward)) env.close() # 此语句可关闭图形界面