强化学习入门

Datawhale组队学习打卡data1

强化学习的基础

强化学习概述

强化学习(reinforcement learning,RL)讨论的问题是智能体(agent)怎么在复杂、不确定的环境(environment)中最大化它能获得的奖励。如图1.1所示。

图1.1 强化学习示意图
图1.1 强化学习示意图​​​

强化学习由两部分组成:智能体和环境。在强化学习过程中,智能体与环境一直在交互。智能体在环境中获取某个状态后,它会利用该状态输出一个动作 (action),这个动作也称为决策(decision)。然后这个动作会在环境中被执行,环境会根据智能体采取的动作,输出下一个状态以及当前这个动作带来的奖励。智能体的目的就是尽可能多地从环境中获取奖励。

Q&A环节:

Q:强化学习的基本结构?

A: 本质上是智能体与环境的交互。具体地,当智能体在环境中得到当前时刻的状态后,其会基于此状态输出一个动作,这个动作会在环境中被执行并输出下一个状态和当前的这个动作得到的奖励。智能体在环境里存在的目标是最大化期望累积奖励。

强化学习与有监督学习的区别

以cv为例,监督学习通常有如下假设:

  • 输入的数据(标注的数据)都应是没有关联的(独立同分布)。因为如果输入的数据有关联,学习器(learner)是不好学习的。
  • 需要告诉学习器正确的标签是什么,这样它可以通过正确的标签来修正自己的预测(有x, y)

强化学习的数据是不满足上述两条假设的。

  • 输入的数据是一条时间序列,即上一帧和下一帧有很强的关联性(RNN?)
  • 结果并不会立刻得到反馈,即不会立刻得知正确的标签(延迟奖励),像打游戏买装备一样,只有等最后钱攒够了买了这件装备,你才知道这个装备的效果。在强化学习中探索和利用是两个核心问题,探索指尝试一些新的动作, 这些新的动作有可能会使我们得到更多的奖励,也有可能使我们“一无所有”;利用指采取已知的可以获得最多奖励的动作,重复执行这个动作,因为我们知道这样做可以获得一定的奖励。
强化学习和监督学习的区别
强化学习监督学习
输入样本时间序列独立同分布样本
反馈方式延迟奖励直接反馈
获取反馈的方式探索和利用直接获取
上限环境标注的数据

Q&A环节:

Q: 强化学习相对于监督学习为什么训练过程会更加困难?

A: 1)强化学习处理的大多是序列数据,其很难像监督学习的样本一样满足独立同分布条件。 2)强化学习有奖励的延迟,即智能体的动作作用在环境中时,环境对于智能体状态的奖励存在延迟,使得反馈不实时。3)监督学习有正确的标签,模型可以通过标签修正自己的预测来更新模型,而强化学习相当于一个“试错”的过程,其完全根据环境的“反馈”更新对自己最有利的动作。

Q: 强化学习、监督学习和无监督学习三者有什么区别呢?

A: 首先强化学习和无监督学习是不需要有标签样本的,而监督学习需要许多有标签样本来进行模型的构建和训练。其次对于强化学习与无监督学习,无监督学习直接基于给定的数据进行建模,寻找数据或特征中隐藏的结构,一般对应聚类问题;强化学习需要通过延迟奖励学习策略来得到模型与目标的距离,这个距离可以通过奖励函数进行定量判断,这里我们可以将奖励函数视为正确目标的一个稀疏、延迟形式。另外,强化学习处理的多是序列数据,样本之间通常具有强相关性,但其很难像监督学习的样本一样满足独立同分布条件

强化学习的历史

标准强化学习 --------> 深度强化学习

  • 标准强化学习:设计特征 ----> 训练价值函数,如图 1.2 所示。标准强化学习先设计很多特征,这些特征可以描述现在整个状态。 得到这些特征后,我们就可以通过训练一个分类网络或者分别训练一个价值估计函数来采取动作。

    图1.2 标准强化学习
  • 深度强化学习:深度学习 + 标准强化学习,自从我们有了深度学习,有了神经网络,就可以把智能体玩游戏的过程改进成一个端到端训练(end-to-end training)的过程,如图 1.3所示。我们不需要设计特征,直接输入状态就可以输出动作。我们可以用一个神经网络来拟合价值函数或策略网络,省去特征工程(feature engineering)的过程。

    图1.3 深度强化学习

 序列决策

在一个强化学习环境里面,智能体的目的就是选取一系列的动作来最大化奖励,所以这些选取的动作必须有长期的影响。但在这个过程里面,智能体的奖励其实是被延迟了的,就是我们现在选取的某一步动作,可能要等到很久后才知道这一步到底产生了什么样的影响。如图 1.13 所示,在玩雅达利的 Pong 游戏时,我们可能只有到最后游戏结束时,才知道球到底有没有被击打过去。过程中我们采取的上升(up)或 下降(down)动作,并不会直接产生奖励。强化学习里面一个重要的课题就是近期奖励和远期奖励的权衡(trade-off),研究怎么让智能体取得更多的远期奖励。在与环境的交互过程中,智能体会获得很多观测。针对每一个观测,智能体会采取一个动作,也会得到一个奖励。所以历史观测、动作、奖励的序列

H_{t} = o_{1}, a_{1},r_{1},....... o_{t}, a_{t},r_{t},

智能体在采取当前动作的时候会依赖于它之前得到的历史,所以我们可以把整个游戏的状态看成关于这个历史的函数

S_{t} = f(H_{t})

图1.4 奖励演示

状态是对世界的完整描述,不会隐藏世界的信息。观测是对状态的部分描述,可能会遗漏一些信息。环境有自己的函数s{_{t}^{e}} = f^{e}(H{_{t}})来更新状态,在智能体的内部也有一个函数s{_{t}^{a}} = f^{a}(H{_{t}})来更新状态。当智能体的状态与环境的状态等价的时候,即当智能体能够观察到环境的所有状态时,我们称这个环境是完全可观测的(fully observed)。在这种情况下面,强化学习通常被建模成一个马尔可夫决策过程 (Markov decision process,MDP)的问题。在马尔可夫决策过程中,​o{_{t}} = s{_{t}^{a}} = s{_{t}^{e}}。 当智能体只能看到部分的观测,我们就称这个环境是部分可观测的(partially observed)。 在这种情况下,强化学习通常被建模成部分可观测马尔可夫决策过程(partially observable Markov decision process, POMDP)的问题。部分可观测马尔可夫决策过程是马尔可夫决策过程的一种泛化。 部分可观测马尔可夫决策过程依然具有马尔可夫性质,但是假设智能体无法感知环境的状态,只能知道 部分观测值。比如在自动驾驶中,智能体只能感知传感器采集的有限的环境信息。部分可观测马尔可夫决策过程可以用一个七元组描述: (S,A,T,R,Ω,O,γ)。其中 S 表示状态空间,为隐变量,动作空间T(s′∣s,a) 状态转移概率奖励函数Ω(o∣s,a) 为观测概率观测空间γ 折扣系数

动作空间

不同的环境允许不同种类的动作。在给定的环境中有效动作的集合经常被称为动作空间(action space)。智能体的动作数量是有限的,在物理世界中控制一个智能体,在这个环境中就有连续动作空间(continuous action space)。在连续动作空间中,动作是实值的向量。例如,走迷宫机器人如果只有东南西北这4种移动方式,则其动作空间为离散动作空间;如果机器人可以向 360 度中的任意角度进行移动,则其动作空间为连续动作空间。

智能体组成成分和类型

对于一个强化学习智能体,它可能有一个或多个如下的组成成分。

  • 策略(policy)。智能体会用策略来选取下一步的动作。

  • 价值函数(value function)。我们用价值函数来对当前状态进行评估。价值函数用于评估智能体进 入某个状态后,可以对后面的奖励带来多大的影响。价值函数值越大,说明智能体进入这个状态越有利。

  • 模型(model)。模型表示智能体对环境的状态进行理解,它决定了环境中世界的运行方式。 

策略

策略是智能体的动作模型,它决定了智能体的动作。它其实是一个函数,用于把输入的状态变成动作。策略可分为两种:随机性策略和确定性策略。随机性策略(stochastic policy)就是 π 函数,即\pi (a|s) = p(a{_{t}}=a|s{_{t}}=s)。输入一个状态 s,输出一个概率。 这个概率是智能体所有动作的概率,然后对这个概率分布进行采样,可得到智能体将采取的动作。比如可能是有 0.7 的概率往左,0.3 的概率往右,那么通过采样就可以得到智能体将采取的动作。确定性策略(deterministic policy)就是智能体直接采取最有可能的动作,即a^{​{*}} = \arg max(\pi (a|s))。通常情况下,强化学习一般使用随机性策略,随机性策略有很多优点。比如,在学习时可以通过引入一定的随机性来更好地探索环境; 随机性策略的动作具有多样性,这一点在多个智能体博弈时非常重要。采用确定性策略的智能体总是对同样的状态采取相同的动作,这会导致它的策略很容易被对手预测。

 价值函数

价值函数的值是对未来奖励的预测,我们用它来评估状态的好坏。 价值函数里面有一个折扣因子(discount factor),我们希望在尽可能短的时间里面得到尽可能多的奖励。比如现在给我们两个选择:10天后给我们100块钱或者现在给我们100块钱。我们肯定更希望现在就给我们 100 块钱,因为我们可以把这 100 块钱存在银行里面,这样就会有一些利息。因此,我们可以把折扣因子放到价值函数的定义里面,价值函数的定义为:

V{_{\pi}}(s) = \mathbb{E}{_{\pi}}[G{_{t}} | s{_{t}} = s] = \mathbb{E}{_{\pi}}\left [ \sum_{k=0}^{\propto}\gamma ^{​{k}}r{_{t+k+1}} | s{_{t}} = s\right ],对所有的s \in S

期望\mathbb{E}{_{\pi}}的下标是 π 函数, π函数的值可反映在我们使用策略π的时候,到底可以得到多少奖励。我们还有一种价值函数: Q函数。Q函数里面包含两个变量:状态和动作。其定义:

V{_{\pi}}(s, a) = \mathbb{E}{_{\pi}}[G{_{t}} |s{_{t}} =s, a{_{t}}=a] = \mathbb{E}{_{\pi}} [ \sum_{k=0}^{\propto}\gamma ^{​{k}}r{_{t+k+1}} | s{_{t}} = s, a{_{t}}=a ]

所以我们未来可以获得奖励的期望取决于当前的状态和当前的动作。Q 函数是强化学习算法里面要学习的一个函数。因为当我们得到 Q 函数后,进入某个状态要采取的最优动作可以通过 Q 函数得到。

模型

模型决定了下一步的状态。下一步的状态取决于当前的状态以及当前采取的动作。它由状态转移概率和奖励函数两个部分组成。状态转移概率:

p{_{s{s}'}^{a}} = p(s{_{t+1}} = {s}' | s{_{t}} = s, a{_{t}} = a)

奖励函数是指我们在当前状态采取了某个动作,可以得到多大的奖励,即

R(s,a) = \mathbb{E}\left [ r{_{t+1}} | s{_{t}}=s, a{_{t}}=a \right ]

当我们有了策略、价值函数和模型3个组成部分后,就形成了一个马尔可夫决策过程(Markov decision process)。如图 1.5 所示,这个决策过程可视化了状态之间的转移以及采取的动作。

图1.5 马尔可夫决策过程
智能体的类型

根据智能体学习的事物不同:

  • 基于价值的智能体(value-based agent)显式地学习价值函数,隐式地学习它的策略。策略是其从学到的价值函数里面推算出来的。
  • 基于策略的智能体(policy-based agent)直接学习策略,我们给它一个状态,它就会输出对应动作的概率。基于策略的智能体并没有学习价值函数。
  • 把基于价值的智能体和基于策略的智能体结合起来就有了演员-评论员智能体(actor-critic agent)。这一类智能体把策略和价值函数都学习了,然后通过两者的交互得到最佳的动作。 

根据智能体是否学习环境模型分类。 

  • 有模型(model-based)强化学习智能体通过学习状态的转移来采取动作。 
  • 免模型(model-free)强化学习智能体没有去直接估计状态的转移,也没有得到环境的具体转移变量,它通过学习价值函数和策略函数进行决策。免模型强化学习智能体的模型里面没有环境转移的模型。 
图1.6 强化学习智能体类型

Q&A环节

Q:强化学习中所谓的损失函数与深度学习中的损失函数有什么区别呢?

A: 深度学习中的损失函数的目的是使预测值和真实值之间的差距尽可能小,而强化学习中的损失函数的目的是使总奖励的期望尽可能大。

智能体实验浅尝

OpenAI 的 Gym库是一个环境仿真库,里面包含很多现有的环境。针对不同的场景,我们可以选择不同的环境。离散控制场景(输出的动作是可数的,比如Pong游戏中输出的向上或向下动作)一般使用雅达利环境评估;连续控制场景(输出的动作是不可数的,比如机器人走路时不仅有方向,还有角度,角度就是不可数的,是一个连续的量 )一般使用 MuJoCo 环境评估。Gym Retro是对 Gym 环境的进一步扩展,包含更多的游戏。由于 Gym 库 0.26.0 及其之后的版本对之前的代码不兼容,所以我们安装 0.26.0 之前的 Gym,比如 0.25.2

pip install gym==0.25.2
pip install pygame    ##显示图形界面

 简单的环境配置见:Mountain Car Continuous - Gym Documentation (gymlibrary.dev)

  1. CartPole_v0

如图 1.7 所示,CartPole-v0 环境有两个动作:将小车向左移动和将小车向右移动。我们还可以得到观测:小车当前的位置,小车当前往左、往右移的速度,杆的角度以及杆的最高点(顶端)的速度。 观测越详细,我们就可以更好地描述当前所有的状态。这里有奖励的定义,如果能多走一步,我们就会得到一个奖励(奖励值为1),所以我们需要存活尽可能多的时间来得到更多的奖励。当杆的角度大于某一个角度(没能保持平衡),或者小车的中心到达图形界面窗口的边缘,或者累积步数大于200,游戏就结束了,我们就输了。所以智能体的目的是控制杆,让它尽可能地保持平衡以及尽可能保持在环境的中央。

图1.7 CartPole_v0示意图

import gym  
env = gym.make('CartPole-v0')  
env.reset()  
for _ in range(1000):
    env.render()  
    action = env.action_space.sample() 
    observation, reward, done, info = env.step(action)   ##完成 S-->A-->R-->S'
    print(observation)
env.close()    

输出:

[ 0.01653398 0.19114579 0.02013859 -0.28050058]
[ 0.0203569 -0.00425755 0.01452858 0.01846535]
[ 0.02027175 -0.19958481 0.01489789 0.31569658] 
......

我们只要不断观测这样的过程,并让智能体在其中用相应的算法完成训练,就能得到一个高质量的强化学习模型。Gym 库已注册的环境可以通过以下代码查看:

from gym import envs
env_specs = envs.registry.all()
envs_ids = [env_spec.id for env_spec in env_specs]
print(envs_ids)

输出:

['CartPole-v0', 'CartPole-v1', 'MountainCar-v0', 'MountainCarContinuous-v0', 'Pendulum-v1', 'Acrobot-v1', 'LunarLander-v2', 'LunarLanderContinuous-v2', 'BipedalWalker-v3', 'BipedalWalkerHardcore-v3', 'CarRacing-v2', 'Blackjack-v1', 'FrozenLake-v1', 'FrozenLake8x8-v1', 'CliffWalking-v0', 'Taxi-v3', 'Reacher-v2', 'Reacher-v4', 'Pusher-v2', 'Pusher-v4', 'InvertedPendulum-v2', 'InvertedPendulum-v4', 'InvertedDoublePendulum-v2', 'InvertedDoublePendulum-v4', 'HalfCheetah-v2', 'HalfCheetah-v3', 'HalfCheetah-v4', 'Hopper-v2', 'Hopper-v3', 'Hopper-v4', 'Swimmer-v2', 'Swimmer-v3', 'Swimmer-v4', 'Walker2d-v2', 'Walker2d-v3', 'Walker2d-v4', 'Ant-v2', 'Ant-v3', 'Ant-v4', 'Humanoid-v2', 'Humanoid-v3', 'Humanoid-v4', 'HumanoidStandup-v2', 'HumanoidStandup-v4']

 Gym 库中的每个环境都定义了观测空间和动作空间。观测空间和动作空间可以是离散的(取值为有限个离散的值),也可以是连续的(取值为连续的值)。

        2. MountainCar-v0 例子 

首先查看观测空间和动作空间

###MountainCar-v0示例
import gym
env = gym.make('MountainCar-v0')                                ##环境创建
print('观测空间 = {}'.format(env.observation_space))            
print('动作空间 = {}'.format(env.action_space))
print('观测范围 = {} ~ {}'.format(env.observation_space.low,
        env.observation_space.high))
print('动作数 = {}'.format(env.action_space.n))

输出:

观测空间 = Box([-1.2  -0.07], [0.6  0.07], (2,), float32)
动作空间 = Discrete(3)
观测范围 = [-1.2  -0.07] ~ [0.6  0.07]
动作数 = 3    

其中离散空间用 gym.spaces.Discrete 类表示,连续空间用 gym.spaces.Box 类表示。对于离散空间,Discrete (n) 表示可能取值的数量为 n;对于连续空间,Box类实例成员中的 low 和 high 表示每个浮点数的取值范围。MountainCar-v0 中的观测是长度为 2 的 numpy 数组,数组中值的类型为 float。MountainCar-v0 中的动作是整数,取值范围为 {0,1,2}。 

gym库的操作总结:Gym库官方操作文档

import gym

 env=gym.make(env_name)   ##env_name:环境名,取出环境
 env.reset()              ##初始化环境
 env.step(action)         ##action:动作,执行一步环境
 env.render()             ##显示环境
 env.close()              ##关闭环境

具体代码如下:

###MountainCar-v0示例
import gym
import numpy as np

###实现对智能体的控制
class SimpleAgent:
    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

###实现是智能体与环境的交互
def play(env, agent, render=False, train=False):
    '''
    env: 环境
    agent: 智能体
    render: 确定是否需要图形化界面
    train: 是否需要训练智能体,训练时为true, 测试的时候为false
    '''
    
    episode_reward = 0. # 记录回合总奖励,初始值为0
    observation = env.reset() # 重置游戏环境,开始新回合
    while True: # 不断循环,直到回合结束
        if render: # 判断是否显示
            env.render() # 显示图形界面
        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 = gym.make('MountainCar-v0')
env.seed(3) # 设置随机种子,让结果可复现
agent = SimpleAgent(env)
print('观测空间 = {}'.format(env.observation_space))
print('动作空间 = {}'.format(env.action_space))
print('观测范围 = {} ~ {}'.format(env.observation_space.low,env.observation_space.high))
print('动作数 = {}'.format(env.action_space.n))

###实现智能体和环境交互一个回合
episode_reward = play(env, agent, render=True)  #单次调用表示一个回合
print('回合奖励 = {}'.format(episode_reward))
env.close() # 关闭图形界面

###性能评估 要求:连续100回合奖励大于-110
episode_rewards = [play(env, agent) for _ in range(100)]
print('平均回合奖励 = {}'.format(np.mean(episode_rewards)))



注:vscode安装的notebook在运行代码的时候不会显示图形化界面,但是脚本运行可以显示图形化界面,这个问题浅试了下没有搜到合适的方法,期待大佬解释下。 

参考文献: 第一章 强化学习基础 (datawhalechina.github.io)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值