【Actor-Critic】演员评论家模型

本博客代码部分参考了《动手学强化学习》

基于值函数的方法(DQN)和基于策略的方法(REINFORCE),其中基于值函数的方法只学习一个价值函数,而基于策略的方法只学习一个策略函数。那么,一个很自然的问题是,有没有什么方法既学习价值函数,又学习策略函数呢?答案就是 Actor-Critic。Actor-Critic 是囊括一系列算法的整体架构,目前很多高效的前沿算法都属于 Actor-Critic 算法。需要明确的是,Actor-Critic 算法本质上是基于策略的算法,因为这一系列算法的目标都是优化一个带参数的策略,只是会额外学习价值函数,从而帮助策略函数更好地学习。



Actor-Critic 算法

class ActorCritic:
    def __init__(self, state_dim, hidden_dim, action_dim, actor_lr, critic_lr,
                 gamma, device):
        # 策略网络
        self.actor = PolicyNet(state_dim, hidden_dim, action_dim).to(device)
        self.critic = ValueNet(state_dim, hidden_dim).to(device)  # 价值网络
        # 策略网络优化器
        self.actor_optimizer = torch.optim.Adam(self.actor.parameters(),
                                                lr=actor_lr)
        self.critic_optimizer = torch.optim.Adam(self.critic.parameters(),
                                                 lr=critic_lr)  # 价值网络优化器
        self.gamma = gamma
        self.device = device

    def take_action(self, state):
        state = torch.tensor([state], dtype=torch.float).to(self.device)
        probs = self.actor(state)
        action_dist = torch.distributions.Categorical(probs)
        action = action_dist.sample()
        return action.item()

    def update(self, transition_dict):
        states = torch.tensor(transition_dict['states'],
                              dtype=torch.float).to(self.device)
        actions = torch.tensor(transition_dict['actions']).view(-1, 1).to(
            self.device)
        rewards = torch.tensor(transition_dict['rewards'],
                               dtype=torch.float).view(-1, 1).to(self.device)
        next_states = torch.tensor(transition_dict['next_states'],
                                   dtype=torch.float).to(self.device)
        dones = torch.tensor(transition_dict['dones'],
                             dtype=torch.float).view(-1, 1).to(self.device)

        # 时序差分目标
        td_target = rewards + self.gamma * self.critic(next_states) * (1 -
                                                                       dones)
        td_delta = td_target - self.critic(states)  # 时序差分误差
        log_probs = torch.log(self.actor(states).gather(1, actions))
        actor_loss = torch.mean(-log_probs * td_delta.detach())
        # 均方误差损失函数
        critic_loss = torch.mean(
            F.mse_loss(self.critic(states), td_target.detach()))
        self.actor_optimizer.zero_grad()
        self.critic_optimizer.zero_grad()
        actor_loss.backward()  # 计算策略网络的梯度
        critic_loss.backward()  # 计算价值网络的梯度
        self.actor_optimizer.step()  # 更新策略网络的参数
        self.critic_optimizer.step()  # 更新价值网络的参数

Actor 模型

class PolicyNet(torch.nn.Module):
    def __init__(self, state_dim, hidden_dim, action_dim):
        super(PolicyNet, self).__init__()
        self.fc1 = torch.nn.Linear(state_dim, hidden_dim)
        self.fc2 = torch.nn.Linear(hidden_dim, action_dim)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        return F.softmax(self.fc2(x), dim=1)

Actor模型最后输出的是根据State返回的动作概率,从F.softmax(self.fc2(x), dim=1)可以看出

Critic 模型

class Valuenet(nn.Module):
	def __init__(self, state_dim, hidden_dim, action_dim):
		super(Valuenet, self).__init__()
		self.fc1 = torch.nn.Linear(state_dim, hidden_dim)
		self.fc2 = torch.nn.Linear(hidden_dim, 1)
	
	def forward(self, x):
		x = F.relu(self.fc1(x))
		return self.fc2(x)

Critic模型最后输出的是对当前状态预测的最大值,与之前的DQN有些许不同的是,Critic模型输出的维度为1维度,也就是说Critic只要关注当前得分预测,不用参与实际的动作选择。

状态动作预测

def take_action(self, state):
    state = torch.tensor([state], dtype=torch.float).to(self.device)
    probs = self.actor(state)
    action_dist = torch.distributions.Categorical(probs)
    action = action_dist.sample()
    return action.item()

可以看到与环境交互的时候,只有Actor参与了预测,Critic则是在计算误差的时候,才有调用。

参数更新

Reinforce 模型的损失计算推导可以参考该篇博客
Acotr模型的损失计算推导可以参考该博客

REINFORCE 通过蒙特卡洛采样的方法(也就是从最后一步反向累加奖励)对策略梯度的估计是无偏的,但是方差非常大。通过引入基线函数(baseline function)来减小方差,也就是Actor-Critic 中的self.critic(states)

REINFORCE 算法基于蒙特卡洛采样,只能在序列结束后进行更新,这同时也要求任务具有有限的步数,而 Actor-Critic 算法则可以在每一步之后都进行更新,并且不对任务的步数做限制。

 # 时序差分目标
 td_target = rewards + self.gamma * self.critic(next_states) * (1 -
                                                                dones)
 td_delta = td_target - self.critic(states)  # 时序差分误差
 log_probs = torch.log(self.actor(states).gather(1, actions))
 actor_loss = torch.mean(-log_probs * td_delta.detach())
 # 均方误差损失函数
 critic_loss = torch.mean(
     F.mse_loss(self.critic(states), td_target.detach()))
 self.actor_optimizer.zero_grad()
 self.critic_optimizer.zero_grad()
 actor_loss.backward()  # 计算策略网络的梯度
 critic_loss.backward()  # 计算价值网络的梯度
 self.actor_optimizer.step()  # 更新策略网络的参数
 self.critic_optimizer.step()  # 更新价值网络的参数

Acto 算法通过计算
td_target = rewards + self.gamma * self.critic(next_states) * (1 - dones)作为 TD目标
td_delta = td_target - self.critic(states) 计算时序差分误差
actor_loss = torch.mean(-log_probs * td_delta.detach()) 计算Actor 误差,其中的- 是因为根据公式推导,我们需要让目标函数趋向于期望价值,所以需要梯度上升来寻找最大值,在公式推导中没有-,但是优化器是用梯度下降进行参数更新,所以使用-做方向的调整。

Critic算法通过计算
critic_loss = torch.mean(F.mse_loss(self.critic(states), td_target.detach())) 作为Critic的误差

一些概念

模型的比较

  • Q-learning、DQN 及 DQN 改进算法都是基于价值(value-based), 他们通过选择最大价值动作来与环境交互

  • Actor-Critic 结合了两者的特点,Reinforce 作为 Actor 部分, DQN 作为 Critic 部分,从而结合了两者的有点

  • Reinforce、Actor-Critic 通过 SARSA 样本数据进行训练,所以他们是 on-policy基于策略,也就是学习一个策略,从策略中进行动作概率分布抽样

  • REINFORCE 算法基于蒙特卡洛采样,只能在序列结束后进行更新, Actor-Critic 算法则可以在每一步之后都进行更新,并且不对任务的步数做限制。

  • TRPO 是在 Actor-Critic 的基础上加入了更新幅度限,也就是制信任区域(trust region),从而避免模型效果的震荡。

  • PPO 是 TRPO 的改良版, 基于 TRPO 的思想,但是 PPO算法实现更加简单,没有TRPO 的计算那么复杂和远算量那么大。

  • PPO 有两种形式,一是 PPO-惩罚,二是 PPO-截断,

  • PPO-截断总是比 PPO-惩罚表现得更好, 大量实验表明。

  • REINFORCE、Actor-Critic 以及两个改进算法——TRPO 和 PPO, 这类算法有一个共同的特点:它们都是在线策略算法,这意味着它们的样本效率(sample efficiency)比较低。

  • TRPO(trust region policy optimization,TRPO)。当策略网络是深度模型时,沿着策略梯度更新参数,很有可能由于步长太长,策略突然显著变差,进而影响训练效果。针对这个问题,考虑在更新时找到一块信任区域(trust region),在这个区域上更新策略时能够得到某种策略性能的安全性保证,这就是信任区域策略优化(trust region policy optimization,TRPO)算法的主要思想。TRPO 算法在 2015 年被提出,它在理论上能够保证策略学习的性能单调性,并在实际应用中取得了比策略梯度算法更好的效果。

TD算法,贝尔曼方程

policy-base 与 value-base

  1. Policy-Based RL(基于概率)

通过感官分析所处的环境,直接输出下一步要采取的各种动作的概率,然后根据概率采取行动,所以每种动作都有可能被选中,只是可能性不同。如,Policy Gradients等。

  1. Value-Based RL(基于价值)

输出所有动作的价值,根据最高价值来选择动作。如,Q learning、Sarsa等。(对于不连续的动作,这两种方法都可行,但如果是连续的动作基于价值的方法是不能用的,我们只能用一个概率分布在连续动作中选择特定的动作)。

  1. Actor-Critic

结合这两种方法建立一种Actor-Critic的方法,基于概率会给出做出的动作,基于价值会对做出的动作的价值二者的综合。

on-policy 与 off-policy

  1. 无论是在线策略(on-policy)算法还是离线策略(off-policy)算法,都有一个共同点:智能体在训练过程中可以不断和环境交互,得到新的反馈数据。
  2. 二者的区别主要在于在线策略算法会直接使用这些反馈数据,而离线策略算法会先将数据存入经验回放池中,需要时再采样

On-Policy Learning:
在On-Policy学习中,代理学习并改进当前正在执行的策略。它会根据当前策略收集的数据进行学习,因此策略的改进可能会受到当前策略的限制。On-Policy方法通常用于需要连续决策和探索的情境。
Off-Policy Learning:
在Off-Policy学习中,代理学习一个策略,但同时也可以使用来自不同策略的经验数据。这使得代理可以更灵活地学习,并且可以更有效地重用以前的经验。Off-Policy方法通常更具有样本效率,因为它们可以更好地利用之前的经验。

on-line 与 off-line

  1. online RL(在线强化学习) 学习过程中,智能体需要和真实环境进行交互(边玩边学习)。并且在线强化学习可分为on-policy RL和off-policy RL。on-policy(在线策略学习)采用的是当前策略搜集的数据训练模型,每条数据仅使用一次,如,Actor-Critic、Sarsa等。off-policy(离线策略学习)训练采用的数据不需要是当前策略搜集的,如Q learning。

  2. offline RL(离线强化学习) 学习过程中,不与真实环境进行交互,只从过往经验(dataset)中直接学习,而dataset是采用别的策略收集的数据,并且采集数据的策略并不是近似最优策略。。

Online Learning:在线学习是指代理在与环境互动的同时学习。它不断地采集经验,并根据当前的经验进行学习和决策。Online学习适用于需要实时决策的情境,但它也可能导致学习过程中的探索成本。
Offline Learning:离线学习是指代理在与环境互动之前收集一些经验数据,然后在离线状态下进行学习。这样可以避免在线学习的探索成本,但需要足够多的先前数据来训练模型。Offline学习在某些情况下更稳定,但可能无法应对快速变化的环境。

model-base 与 model-free

Model-Based Learning: 在Model-Based学习中,代理(学习者)试图建立一个关于环境的模型,该模型可以预测状态转移和奖励。代理使用这个模型来规划和执行动作,以最大化预期奖励。Model-Based方法通常需要较多的计算资源来构建和维护环境模型。
Model-Free Learning: 在Model-Free学习中,代理不试图建立环境模型,而是直接学习策略或价值函数,以根据观察到的经验来进行动作选择。Model-Free方法通常更适用于复杂或不确定的环境,因为它们不需要对环境进行精确的建模。基于值函数的方法 DQN、基于策略的方法 REINFORCE 以及两者结合的方法 Actor-Critic。

Q-learning 与 Sarsa

Q learning 与 Sarsa 由于TD算法实际内容上存在的差异,导致了其对样本数据利用的不同。Q learning 能够使用Exprience replay 而 Sarsa 不能使用Exprience replay
参考

Q-learning的目标是求解“真正”的 Q ∗ ( s , a ) Q^{*}(s,a) Q(s,a) ,而Sarsa的目标则是求解 Q π ( s , a ) Q_\pi(s,a) Qπ(s,a)
在Q-learning中,我们一般会采用experience replay技术,即准备一个数据库并不断把Agent新产生的 ( s , a , r , s ′ ) (s,a,r,s^{\prime}) (s,a,r,s) 数据集存入数据库中。我们每次会从数据库中随机抽取一个batch的数据集用以训练,这意味着每次训练时我们用到的数据集可能是Agent在很久以前产生的。但是,无论我们用到的数据是Agent在训练中的哪一个阶段产生的,数据都是服从环境分布的,所以它们当然都可以被用以训练。

在Sarsa中,情况则与Q-learning很不一样。对于 ( s , a , r , s ′ , a ′ ) (s,a,r,s',a') (s,a,r,s,a) 的训练数据集,我们不但要求 ( r , s ′ ) (r,s^{\prime}) (r,s) 应该服从环境分布,也要求 a ′ a^{\prime} a 必须服从 π \pi π 关于 s ′ s^{\prime} s 的条件分布。在训练中,Q表的内容会不断被改变,所以Agent产生数据的策略 也会不断被改变。这意味在Agent过去产生的 ( s , a , r , s ′ , a ′ ) (s,a,r,s',a') (s,a,r,s,a) 中, ( s ′ , a ′ ) (s^{\prime},a^{\prime}) (s,a) 可能不服从现在策略 π \pi π 对应的条件分布,因此Agent在过去产生的数据就不能用以现在的训练。

由于上述的原因,我们不能在Sarsa中采用experience replay。在训练中,设当前Agent产生数据的策略为 π \pi π
。我们可以一次性用Agent产生大量服从环境及 π \pi π 分布的数据,并用这些数据来进行训练。而训练过后,Q表的内容发生了变化,这意味着Agent产生数据的策略变成了与 π \pi π 不同的 π ′ \pi^{\prime} π 。这时,刚才那些服从环境与 π \pi π 分布的 ( s , a , r , s ′ , a ′ ) (s,a,r,s',a') (s,a,r,s,a) 数据就变得不再有价值,我们只能将其丢弃。接下来,我们就要让Agent用当前产生数据的策略 继续产生大量的数据,并进行下一步的训练。
我们将Q-learning中那种experience replay的训练方式称作off-policy的,而将Sarsa中这种“边学边玩”的训练方式称作on-policy的。不难看出,二者的核心差别就在于off-policy方法中我们只是要求数据服从于环境分布,而on-policy方法中我们却要求数据要服从环境与当前策略的分布。如果只要求数据服从环境分布,由于过去产生的数据都是服从环境分布的,所以我们当前可以将其储存下来多次利用;如果要求数据服从环境与当前策略分布,由于训练中我们的策略可能会一直发生改变,用过去策略产生的数据很可能无法用于当前的训练,所以我们的数据就不能被多次利用。

区别

  1. off-line 在现实生活中的许多场景下,让尚未学习好的智能体和环境交互可能会导致危险发生,或是造成巨大损失。例如,在训练自动驾驶的规控智能体时,如果让智能体从零开始和真实环境进行交互,那么在训练的最初阶段,它操控的汽车无疑会横冲直撞,造成各种事故。再例如,在推荐系统中,用户的反馈往往比较滞后,统计智能体策略的回报需要很长时间。而如果策略存在问题,早期的用户体验不佳,就会导致用户流失等后果。因此,离线强化学习(offline reinforcement learning)的目标是,在智能体不和环境交互的情况下,仅从已经收集好的确定的数据集中,通过强化学习算法得到比较好的策略。
    在这里插入图片描述

  2. On-Policy和Off-Policy 是关于策略评估和改进的方式。二者的区别主要在于在线策略算法会直接使用这些反馈数据,而离线策略算法会先将数据存入经验回放池中,需要时再采样。

  3. Model-Based和Model-Free 是关于如何对环境建模和学习的方法。Model-Based建立模型,Model-Free直接学习策略或价值函数。


https://blog.csdn.net/niulinbiao/article/details/134081800
https://blog.csdn.net/qq_43585760/article/details/133557729
https://wjrsbu.smartapps.cn/pages/article/index?id=602217717
https://zhuanlan.zhihu.com/p/166412379
https://hrl.boyuai.com/chapter/2/actor-critic%E7%AE%97%E6%B3%95

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值