强化学习——Actor Critic Method

本文介绍了如何使用PaddlePaddle库实现Actor-Critic方法进行强化学习,通过Actor和Critic网络在CartPole-v0环境中进行训练,展示了迭代过程和实验结果。
部署运行你感兴趣的模型镜像

强化学习——Actor Critic Method

import gym, os
from itertools import count
import paddle
import paddle.nn as nn
import paddle.optimizer as optim
import paddle.nn.functional as F
from paddle.distribution import Categorical

device = paddle.get_device()
env = gym.make("CartPole-v0")  ### 或者 env = gym.make("CartPole-v0").unwrapped 开启无锁定环境训练

state_size = env.observation_space.shape[0]
action_size = env.action_space.n
lr = 0.001

class Actor(nn.Layer):
    def __init__(self, state_size, action_size):
        super(Actor, self).__init__()
        self.state_size = state_size
        self.action_size = action_size
        self.linear1 = nn.Linear(self.state_size, 128)
        self.linear2 = nn.Linear(128, 256)
        self.linear3 = nn.Linear(256, self.action_size)

    def forward(self, state):
        output = F.relu(self.linear1(state))
        output = F.relu(self.linear2(output))
        output = self.linear3(output)
        distribution = Categorical(F.softmax(output, axis=-1))
        return distribution


class Critic(nn.Layer):
    def __init__(self, state_size, action_size):
        super(Critic, self).__init__()
        self.state_size = state_size
        self.action_size = action_size
        self.linear1 = nn.Linear(self.state_size, 128)
        self.linear2 = nn.Linear(128, 256)
        self.linear3 = nn.Linear(256, 1)

    def forward(self, state):
        output = F.relu(self.linear1(state))
        output = F.relu(self.linear2(output))
        value = self.linear3(output)
        return value

def compute_returns(next_value, rewards, masks, gamma=0.99):
    R = next_value
    returns = []
    for step in reversed(range(len(rewards))):
        R = rewards[step] + gamma * R * masks[step]
        returns.insert(0, R)
    return returns


def trainIters(actor, critic, n_iters):
    optimizerA = optim.Adam(lr, parameters=actor.parameters())
    optimizerC = optim.Adam(lr, parameters=critic.parameters())
    for iter in range(n_iters):
        state = env.reset()
        log_probs = []
        values = []
        rewards = []
        masks = []
        entropy = 0
        env.reset()

        for i in count():
            # env.render()
            state = paddle.to_tensor(state,dtype="float32",place=device)
            dist, value = actor(state), critic(state)

            action = dist.sample([1])
            next_state, reward, done, _ = env.step(action.cpu().squeeze(0).numpy()) 

            log_prob = dist.log_prob(action);
            # entropy += dist.entropy().mean()

            log_probs.append(log_prob)
            values.append(value)
            rewards.append(paddle.to_tensor([reward], dtype="float32", place=device))
            masks.append(paddle.to_tensor([1-done], dtype="float32", place=device))

            state = next_state

            if done:
                if iter % 10 == 0:
                    print('Iteration: {}, Score: {}'.format(iter, i))
                break


        next_state = paddle.to_tensor(next_state, dtype="float32", place=device)
        next_value = critic(next_state)
        returns = compute_returns(next_value, rewards, masks)

        log_probs = paddle.concat(log_probs)
        returns = paddle.concat(returns).detach()
        values = paddle.concat(values)

        advantage = returns - values

        actor_loss = -(log_probs * advantage.detach()).mean()
        critic_loss = advantage.pow(2).mean()

        optimizerA.clear_grad()
        optimizerC.clear_grad()
        actor_loss.backward()
        critic_loss.backward()
        optimizerA.step()
        optimizerC.step()
    paddle.save(actor.state_dict(), 'model/actor.pdparams')
    paddle.save(critic.state_dict(), 'model/critic.pdparams')
    env.close()



if __name__ == '__main__':
    if os.path.exists('model/actor.pdparams'):
        actor = Actor(state_size, action_size)
        model_state_dict  = paddle.load('model/actor.pdparams')
        actor.set_state_dict(model_state_dict )
        print('Actor Model loaded')
    else:
        actor = Actor(state_size, action_size)
    if os.path.exists('model/critic.pdparams'):
        critic = Critic(state_size, action_size)
        model_state_dict  = paddle.load('model/critic.pdparams')
        critic.set_state_dict(model_state_dict )
        print('Critic Model loaded')
    else:
        critic = Critic(state_size, action_size)
    trainIters(actor, critic, n_iters=201)

实验结果:

Iteration: 0, Score: 60
Iteration: 10, Score: 40
Iteration: 20, Score: 14
Iteration: 30, Score: 35
Iteration: 40, Score: 45
Iteration: 50, Score: 40
Iteration: 60, Score: 128
Iteration: 70, Score: 61
Iteration: 80, Score: 175
Iteration: 90, Score: 199
Iteration: 100, Score: 117
Iteration: 110, Score: 199
Iteration: 120, Score: 137
Iteration: 130, Score: 199
Iteration: 140, Score: 199
Iteration: 150, Score: 199
Iteration: 160, Score: 199
Iteration: 170, Score: 199
Iteration: 180, Score: 199
Iteration: 190, Score: 194
Iteration: 200, Score: 199
运行时长:66.338秒结束时间:2021-10-21 15:56:09

您可能感兴趣的与本文相关的镜像

PaddlePaddle-v3.3

PaddlePaddle-v3.3

PaddlePaddle

PaddlePaddle是由百度自主研发的深度学习平台,自 2016 年开源以来已广泛应用于工业界。作为一个全面的深度学习生态系统,它提供了核心框架、模型库、开发工具包等完整解决方案。目前已服务超过 2185 万开发者,67 万企业,产生了 110 万个模型

<think>好的,我现在要处理用户关于强化学习Actor-Critic方法的原理和实现的查询。首先,我需要回忆Actor-Critic的基本概念。记得它结合了策略梯度(Actor)和价值函数(Critic)的优点,Actor负责选择动作,Critic评估动作的好坏,提供反馈。用户可能需要了解这两部分如何协同工作。 接下来,原理部分需要详细说明。要提到策略梯度方法,比如REINFORCE算法,以及其高方差的问题,这自然引出引入Critic来减少方差的原因。然后,优势函数的概念应该在这里出现,因为它能帮助评估动作的相对好坏。可能需要区分QAC、A2C等变种,引用中提到的资料里有这些内容,应该参考引用[1]和[2]。 在实现部分,用户可能需要一个代码示例。考虑到用户之前提供的示例是Python,所以继续用Python比较合适。代码需要展示ActorCritic的网络结构,比如使用PyTorch。要说明参数更新的过程,包括策略梯度计算和Critic的损失函数。这里要确保代码结构清晰,注释到位,比如Actor输出动作的概率分布,Critic评估状态价值。 然后,关于优化方法,用户可能想知道如何进一步改进,比如使用优势函数代替Q值,或者异步框架如A3C。这些内容在引用中有提到,可以引用[1]中的优势函数AC和A2C部分。 用户可能存在的疑问包括:为什么Actor-Critic比单纯的策略梯度好?这时候需要解释方差减少带来的训练稳定性。此外,实现中的具体细节,比如如何选择折扣因子和学习率,也是需要注意的地方。 最后,生成相关问题需要考虑用户可能深入的方向,比如不同变种的区别、实现中的挑战、实际应用案例等。需要确保问题覆盖原理、实现细节、优化方法和应用场景,这样用户可以有进一步探索的方向。 需要检查是否符合用户给的系统级指令:数学公式用$...$,独立公式用$$...$$,正确的中文回答,生成相关问题。同时,引用标记要自然添加,比如在提到优势函数时引用[^1],或者在讨论策略梯度时引用[^2]。 现在组织回答结构,先讲原理,分ActorCritic部分,再讲算法流程,接着实现示例,最后优化方法。确保每个部分都清晰,并自然地融入引用。代码部分要用正确的格式,避免语法错误。最后的问题要围绕用户可能感兴趣的点展开。</think>### 强化学习 Actor-Critic 方法原理与实现 #### 一、核心原理 Actor-Critic 方法结合了**策略梯度(Policy Gradient)**和**价值函数(Value Function)**的优点,通过两个组件协同工作: 1. **Actor(策略网络)** 负责生成动作策略 $\pi_\theta(a|s)$,通过梯度上升优化策略参数 $\theta$,公式为: $$ \nabla_\theta J(\theta) = \mathbb{E}\left[ \nabla_\theta \log \pi_\theta(a|s) \cdot Q_w(s,a) \right] $$ 其中 $Q_w(s,a)$ 是 Critic 提供的动作价值估计[^1]。 2. **Critic(价值网络)** 评估状态或动作的价值,常用时序差分(TD)误差更新参数 $w$,损失函数为: $$ L(w) = \mathbb{E}\left[ \left( r + \gamma V_w(s') - V_w(s) \right)^2 \right] $$ 通过最小化该损失,Critic 提供更准确的反馈信号。 #### 二、算法流程 1. Actor 根据当前策略选择动作 $a$ 2. 环境反馈奖励 $r$ 和转移至新状态 $s'$ 3. Critic 计算 TD 误差 $\delta = r + \gamma V(s') - V(s)$ 4. **同步更新**: - Actor 参数:$\theta \leftarrow \theta + \alpha_\theta \delta \nabla_\theta \log \pi_\theta(a|s)$ - Critic 参数:$w \leftarrow w - \alpha_w \delta \nabla_w V_w(s)$ #### 三、Python 实现示例(PyTorch) ```python import torch import torch.nn as nn import torch.optim as optim class Actor(nn.Module): def __init__(self, state_dim, action_dim): super().__init__() self.net = nn.Sequential( nn.Linear(state_dim, 64), nn.ReLU(), nn.Linear(64, action_dim), nn.Softmax(dim=-1) ) def forward(self, state): return self.net(state) class Critic(nn.Module): def __init__(self, state_dim): super().__init__() self.net = nn.Sequential( nn.Linear(state_dim, 64), nn.ReLU(), nn.Linear(64, 1) ) def forward(self, state): return self.net(state) # 训练参数 actor = Actor(state_dim=4, action_dim=2) critic = Critic(state_dim=4) optimizer_actor = optim.Adam(actor.parameters(), lr=1e-3) optimizer_critic = optim.Adam(critic.parameters(), lr=1e-2) gamma = 0.99 def update(state, action, reward, next_state, done): state = torch.FloatTensor(state) next_state = torch.FloatTensor(next_state) # Critic 更新 value = critic(state) target = reward + (1 - done) * gamma * critic(next_state).detach() loss_critic = nn.MSELoss()(value, target) optimizer_critic.zero_grad() loss_critic.backward() optimizer_critic.step() # Actor 更新 prob = actor(state)[action] advantage = (target - value).detach() # 使用优势函数替代原始Q值[^1] loss_actor = -torch.log(prob) * advantage optimizer_actor.zero_grad() loss_actor.backward() optimizer_actor.step() ``` #### 四、关键优化方向 1. **优势函数(A2C)** 用 $A(s,a) = Q(s,a) - V(s)$ 替代原始 Q 值,降低方差[^1] 2. **异步框架(A3C)** 多个 Actor 并行探索环境提升样本效率 3. **经验回放(Off-Policy AC)** 允许重复利用历史数据,提高稳定性
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值