免模型控制

本节介绍两种基础免模型算法,Q-learning和Sarsa,都是基于时序差分的方法。(来自datawhale)

5.1 Q-learning

在预测与控制的内容中我们提到控制的方法是需要输出最优策略的同时也会输出对应的状态价值函数。策略与状态价值函数之间存在一个联系的,即动作价值函数。

为了解决控制问题,我们只要预测动作价值函数就行了,在决策时选择使得Q值最大的动作即可,这样一来,策略和相应的动作价值函数同时达到最优,则状态价值函数也是最优的。这既是Q-learning算法的思路。跟新公式如下:

回忆一下时序差分方法中的状态价值函数跟新公式,

动作价值函数是拿使得未来动作价值最大的估计,而状态价值函数是用对应的平均值估计的,一般称为Q值的过估计。

5.11 Q表格

两个概念,Q表格和探索策略。

如前所述二乘二的机器人走路表格,我们扩展到三乘三,且不限制方向,上下左右都可,还是把位置看作状态,这样就有了九个状态和四个动作。因为都是离散的,所以我们用表格来表示。

因为s9位置是终点,所以其Q值均为0,且不参与Q值跟新。Q值的跟新与前述的状态跟新类似,但前述为蒙特卡洛方法,而本次是时序差分,具体而言,让机器人自行在网格走动,每走一步跟新一次对应Q,这个过程称为探索。

5.1.2 探索策略

直接根据Q函数(也就是每次选择使得Q最大的动作)来探索没有问题,但是由于本身Q值也是估计出来的,所以需要跟新Q值。

Q-learning算法采取\varepsilon -greedy的探索策略,指的是以1-\varepsilon的概率来按照Q执行,剩下的概率随机,其实就是防止陷入局部最优。通常实践中还会使得这个值随时间的增长而衰减,例如0.1-0.01.

确切的说,以1-\varepsilon执行Q的过程为利用(exploitation),而以\varepsilon随机的过程为探索。这个探索-利用的平衡类似于深度学习中的偏差-方差权衡。

5.2 Sarsa算法

Q-learning算法被认为是off-policy算法,而Sarsa是on-policy算法。两者在形式上只有Q值的跟新公式不同,5-4为Sarsa跟新公式,5-2为Q-learning跟新公式。

5.3 同策略与异策略

Sarsa 算法在训练的过程中当前策略来生成数据样本,并在其基础上进行更新。换句话说,策略评估和策略改进过程是基于相同的策略完成的,这就是同策略算法。相应地,像Q-learning 算法这样从其他策略中获取样本然后利用它们来更新目标策略,我们称作异策略算法。也就是说,异策略算法基本上是从经验池或者历史数据中进行学习的。这两类算法有着不同的优缺点,同策略相对来说更加稳定,但是效率较低,如同我们实战中展示的那样。而异策略通常来说更加高效,但是需要让获取样本的策略和更新的策略具备一定的分布匹配条件,以避免偏差。

5.4 实战:Q-learning算法

伪代码是从数学理论到代码的桥梁。以下从定义算法,定义训练,定义环境,设置参数,开始训练为步骤展开。以下定义训练涉及所以强化学习的通用模式。

5.4.1 定义训练

伪代码第二行到最后一行是一个强化学习的通用模式,首先迭代M回合,每回合首先重置环境到初始化,智能体根据状态选择动作,根据环境反馈下一个状态和对应奖励,同时智能体跟新策略,直到回合结束,这就是马尔可夫决策过程中智能体与环境互动过程。通用代码如下:

for i_ep in range(train_eps):#遍历每个回合
     #重置环境,获取初始状态
     state=env.reset()  #重置环境,即开始新的回合
     while True:#对于复杂的游戏可设置每回合最大步长,例如while ep_step<100,即最大步长100
           #智能体根据策略采样动作
            action=agent.sample_action(state)  #根据算法采样一个动作
            #与环境进行一次交互,得到下一个状态和奖励
            next_state,reward,terminated,_=env.step(action)#智能体将样本记录到经验池中
            agent.memory.push(state,action,reward,next_state,terminated)
            #智能体跟新策略 
            agent.updata(state,action,reward,next_state,termnated)
            #跟新状态
            state=next_state
            #如果终止则本回合结束
            if terminated:
               break

5.4.2 定义算法

强化学习有几个要素,智能体,环境,经验池(经回放),实践中逐一定义。首先定义智能体,即算法,python中即为类。

5.4.2.1  采样动作

首先在训练中我需要采样动作与环境交互,于是定义类方法sample_action.

class Agent:
    def __init__():
        pass
    def sample_action(self, state):
        ''' 采样动作,训练时用
        '''
        self.sample_count += 1
        # epsilon是会递减的,这里选择指数递减
        self.epsilon = self.epsilon_end + (self.epsilon_start - self.epsilon_end) * math.exp(- self.sample_count / self.epsilon_decay) 
        # e-greedy 策略
        if np.random.uniform(0, 1) > self.epsilon:
            action = np.argmax(self.Q_table[str(state)]) # 选择Q(s,a)最大对应的动作
        else:
            action = np.random.choice(self.n_actions) # 随机选择动作
        return action     

在Q-learning中还有一个重要元素Q表,Q表的作用是输入状态和动作,输出一个即可,用二维数组表示,Q_table[0][1]=0.1,可以表示Q(s0,a1)=0.1.示例中用默认字典表示:

self.Q_table=defaultdict(lambda:np.zeros(n_actions))
5.4.2.2 预测动作

每个智能体在训练中和测试中采取动作的方式是不同的,因为训练中需要增加额外的探索策略,而测试中只需要输出Q值对应最大的动作即可。

class Agent:
    def __init__():
        pass
    def predict_action(self,state):
        ''' 预测或选择动作,测试时用
        '''
        action = np.argmax(self.Q_table[str(state)])
        return action
5.4.2.3 更新方法

强化学习算法的采样动作和预测动作方式较为固定,而最核心的是更新网络的方法,Q-learning算法中的更新方法较为简单,且不需要经验回放。(

在强化学习中,经验回放(Experience Replay)是一种常用的技术,主要用于解决神经网络训练中的梯度消失和梯度爆炸问题。强化学习中的经验回放主要思想是将之前收集到的经验存储起来,然后在训练过程中随机抽取一部分经验进行学习。这样做的目的是让神经网络有机会重新使用这些经验,从而使得训练过程更加稳定。具体来说,经验回放的过程可以分为以下几个步骤:

1. 收集经验:在强化学习中,每个时间步都会生成一个经验(Experience),通常包括当前状态(State)、动作(Action)、奖励(Reward)以及下一个状态(Next State)。这些经验会被存储在一个经验回放缓冲区(Experience Replay Buffer)中。
2. 随机抽取经验:在每次训练迭代中,从经验回放缓冲区中随机抽取一部分经验,这些经验会被用作训练样本。
3. 更新神经网络:使用抽取到的经验对神经网络进行更新。在强化学习中,通常会使用一个价值函数(Value Function)来估计当前状态的好坏,然后根据这个价值函数和奖励来更新神经网络的权重。通过经验回放,神经网络可以更加稳定地学习,因为每次训练迭代都有机会重新使用之前收集到的经验。此外,经验回放还可以有效地利用数据,因为同一个状态和动作可能会在不同的时间步中出现,通过回放这些经验,神经网络可以更好地泛化到新的情况。

def update(self, state, action, reward, next_state, terminated):
    Q_predict = self.Q_table[str(state)][action] 
    if terminated: # 终止状态
        Q_target = reward  
    else:
        Q_target = reward + self.gamma * np.max(self.Q_table[str(next_state)]) 
    self.Q_table[str(state)][action] += self.lr * (Q_target - Q_predict)

5.4.3 定义环境

本节选择CliffWalking-v0的环境(悬崖寻路),类似于前述机器人最短路。

目标是从起点到终点,并且避开悬崖。

在此环境中,状态较简单,即网格位置或编号,动作是上右下左(0,1,2,3),奖励分几种,走白色给-1,到达终点奖励0,其他则回合结束。负奖励意思是每走一步都要付出代价,不能让他随心所欲走。悬崖寻路 我们选择的环境是openAIGym开发的标准化环境。只需一行代码。

env = gym.make('CliffWalking-v0')  

获取环境状态数和动作数。

n_states = env.observation_space.n # 状态数
n_actions = env.action_space.n # 动作数
print(f"状态数:{n_states}, 动作数:{n_actions}")

5.4.4 设置参数

智能体,环境,训练之后就是参数设置。折扣因子\gamma比较固定,0.9-0.999,学习率α实际小于0.1.

self.epsilon_start = 0.95 #  e-greedy策略中epsilon的初始值
self.epsilon_end = 0.01 #  e-greedy策略中epsilon的最终值
self.epsilon_decay = 200 #  e-greedy策略中epsilon的衰减率

5.4.5 开始训练

...
回合:200/300,奖励:-22.0,Epsilon:0.010
回合:220/300,奖励:-20.0,Epsilon:0.010
回合:240/300,奖励:-15.0,Epsilon:0.010
回合:260/300,奖励:-20.0,Epsilon:0.010
回合:280/300,奖励:-13.0,Epsilon:0.010
回合:300/300,奖励:-13.0,Epsilon:0.010

确保训练策略有效,拿去测试,训练中是采样带探索,预测是预测动作,

5.4.6 结果分析

测试的动作列表:[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2]

5.4.7 消融实验

为验证\epsilon是衰减好还是不变好,设计消融实验。将\varepsilon=0.1,

# 将初始值和最终值设置为一样,这样 epsilon 就不会衰减
self.epsilon_start = 0.1 #  e-greedy策略中epsilon的初始值
self.epsilon_end = 0.1 #  e-greedy策略中epsilon的最终值
self.epsilon_decay = 200 #  e-greedy策略中epsilon的衰减率

虽然也收敛,但不稳定。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值