推荐文章:网站建设文章内容要如何去规划

优采云 发布时间: 2022-11-27 16:42

  推荐文章:网站建设文章内容要如何去规划

  原文在搜索引擎中,相似

  度小于40%的内容,搜索引擎会认为它是原创文章,相似度的质量越高越差,搜索引擎会判断它是伪原创采集

。当然,原创文章的定义不仅在这里,搜索引擎已经发展了十几年,还有一定的识别文章的能力,当文章的内容是从杂词拼凑出来的,阅读起来没有意义时,就会被认为是垃圾内容,不收录。因此,对用户有价值的文章才是真正的原创文章。石家庄网站建设

  

" />

  伪原创文章伪原创

  只是一个概念,详细每个站长都用伪原创来达到SEO效果,但最终的结果却不一样。简单的伪原创方法如替换关键词、改变段落顺序、修改标题等,效果会逐渐减弱,因为搜索引擎在进步,这种机会主义的方式肯定不会受到搜索引擎的欢迎。我认为优秀的伪原创文章应该用自己的理解,自己的文字来表达,甚至在看了别人的优秀原创文章后,扩展自己的观点,其实这样的文章在一定程度上已经达到了搜索引擎的原创水平。

  

" />

  捕获内容

  对于个别站长来说,精力是SEO最大的障碍,他们都知道采集

是互联网的垃圾内容生产者,他们都知道采集

对网站权威的提升不利,但又摆脱不了他。其实,依赖采集

的新网站是没有活路的,搜索引擎对采集

有一定程度的考虑,同样是采集

,大网站采集

可以收录,你的不行;更新文章也是一样,大网站只用采集

作为更新内容的一种方式,你把所有的代码都放在采集

上。

  解决方案:MAPPO学习笔记(1):从PPO算法开始

  本文采集

  大家伙整理教程主要介绍MAPPO学习笔记(1):从PPO算法入手,大家伙教程大佬觉得很不错,现在分享给大家,给大家参考。

  由于这一时期的学习内容涉及MAPPO算法,我

  对MAPPO算法这个多智能体算法的信息交互机制了解不多,我写这一系列笔记是为了巩固知识,做一些肤浅有趣的总结。

  1. PPO算法简介 1.1.PG 算法

  如果要分类,根据学习方法的不同,强化学习可以分为基于价值的方法、基于策略的方法和基于AC框架的Actor-Critic方法。下面简单介绍一下。

  基于价值的方法:

  典型的代表是------Q-learning、Ssarsa和DQN,之所以叫“基于价值”的方法,是因为在这种方法中,我们所有的决策都是基于一个“表”,其中“表”是一个比较抽象的陈述,大致可以理解为:我们现在处于什么样的状态,在这种状态下,我们采取什么样的行动才会产生很大的“收获”。然后我们将根据这种“收益”情况采取行动。基于策略的方法:

  这里的典型代表是PPO算法,在Q学习和DQN中,我们输出一个Q值,代表状态当前的行动收入,但基于策略的算法放弃了这个Q值思想,而是输出当前状态可以采取的所有行动的概率,这意味着:你现在很饿, 但你不知道你想吃什么,你只知道你是食肉动物,我想多吃点肉。那么“想吃肉”就是你的策略(政策),至于吃什么样的肉,鸡、鸭、鱼、猪肉、牛肉和羊肉......这完全取决于你的心情。

  Actor-Critic 方法:这种方法最显著的特点是 AC 框架,简而言之,最简单的 AC 框架由两部分组成:Actor 和 Critic,如果我们把 Critic 看作老师,Actor 可以看作是学生,老师会评估学生在当前状态下的行为,然后学生会用这个“评估”更新他们的参数。这是更新 AC 框架的最简单方法。

  我们这里来谈谈 PG 算法,我们不妨把一个“策略”近似为概率分布,也许每个不同的情况对应一个概率分布,那么我们的目的就变成了用一个带有 θ 参数的函数来近似策略,可以通过调整参数 θ 来调整近似最优策略。

  那么接下来要做的是优化策略函数,让目标函数在最大值的方向上优化。以食物为例:你还是一个很饿的人,不知道吃什么,于是你尝试了一家从未吃过的餐厅,突然发现这家餐厅很好吃,以后可能会经常回来。为什么这不是策略更新的过程?

  话虽如此,我们只有一个目标:通过更新策略参数 θ 来最大化我们的 ReWARD。当然,可以推导出的公式是有一堆的,但是我最不喜欢的就是推公式,所以从头到尾就不推了,直接说结论。也就是说,我们可以通过更新公式更新策略参数θ,从而达到优化策略的目的。

  1.2. PPO 算法

  上面介绍的 PG 算法看起来非常理想可行,但 PG 算法有一个很大的缺点:每当我们更新策略参数 θ 时,那么我们之前的策略就可以说是“直接失效”了。那么这样做的后果是什么呢,众所周知,我们的政策更新是通过旧政策在环境中采样的,一旦政策更新,旧数据,旧政策采样的数据,对新政策的更新不再有任何指导意义,所以我们需要新一轮的抽样。这使得传统的PG方法需要大量的时间来采样,从而大大降低了数据的利用率。

  为了解决这个问题,出现了“异构战略”的概念。简单地说,使用另一种策略与环境交互以完成“采集

数据”的任务。然后,需要训练的策略可以使用此数据进行有效更新。但!如上一段所述,传统的PG方法不能利用不同策略采集

的数据进行自我更新,这就需要我们引入一些其他技术,使这种“高效”的更新方法成为可能。

  第一个技巧是重要性抽样。假设我们有两种策略,一种称为$p$,另一种称为$q$。我们知道我们这里有一个函数 $f(X)$,函数中的 $x$ 由策略 $p$ 采样。然后,如果我们想得到函数的平均值 $f(X)$,我们可以从分布 $p$ 中采集

尽可能多的样本数据 $x^i$,通过计算所有 $f(x^i)$ 的平均值,我们可以近似$f(X)$的期望值。由以下公式表示:

  $E_{x sim p}[f(X)] approx frac{1}{N} sum_{i=1}^{N} fleft(x^{i}right)$

  但要注意!由于我们使用的是异构策略方法,这里我们使用策略 $q$ 进行采样,所以我们没有办法直接使用上面的公式来得到 $f(X)$ 的近似值。此时,需要对所需公式进行一些转换。

  现在我们假设所有 $x$ 都是由策略 $p$ 采样的,那么我们可以将 $f(X)$ 的期望值表示为以下公式:

  $int f(X) p(X) d x$

  将其转换为:$int f(X) p(X) d x=int f(X) frac{p(X)}{q(X)} q(X

  ) d x=E_{x sim q}left[f(X) frac{p(X)}{q(X)}right]$

  可提供表面处理:$E_{x sim p}[f(X)]

  =E_{x sim q}left[f(X) frac{p(X)}{q(X)}right]$

  通过这样的变换,我们可以通过策略 $q$ 进行采样,然后计算$f(X) frac{p(X)}{q(X)}$,最后找到它的平均值,也可以得到 $f(X)$ 的期望近似值。

  看!这样,在不同策略的前提下计算出$p$策略下函数$f(X)$的期望近似值,并计算$q$策略采集

的数据。

  我们简单地总结了这种方法:通过将策略采集

的每个数据$q$乘以“重要性权重”:$frac{p(X)}{q(X)}$,可以纠正两种策略之间的差异。通过这样的修正方法,策略 $p 和策略 $q$ 之间的关系大致可以看作是“参与者”和“信息采集

者”,参与者通过信息采集

器获得的数据来优化自己的策略。

  第二个技巧是KL背离,当我们介绍上述重要性抽样时,似乎所有问题都解决了,但需要注意的是,用于抽样的策略$q$与用于决策的策略$p$之间的差距不能太大。因为即使两个分布之间的均值和方差之差太大,训练过程也会引起各种问题。这就像我是一个肉食者,但我从我的素食朋友喜欢的餐馆名单中决定今天吃什么。因此,有必要引入KL背离来约束训练过程,使策略$p$和策略$q$之间的差异不能太大。

  第三招是优势函数。我们必须了解的第一件事是,PPO生成随机策略,即参与者在每种情况下采取某些行动的概率。但这会产生一个更严重的问题:好的越来越好,坏的越来越坏,以至于我们会忽略某些州一些更合适的行动。通俗地说,我们生成的分布将更愿意选择那些在许多情况下表现更好的动作,并且很有可能采取这样的动作,并以非常小的概率采取一些表现较差的行动,甚至是“次优解决方案”。这使得我们“努力工作”的随机性优势不再存在。因此,在计算状态-操作对分数时,我们应该人为地引入一个“基线”,而这个“基线”就是该状态下状态-操作对分数的平均值。通过引入这样的“基线”,我们可以得到优势函数:也就是说,我们在这种状态下采用的策略比一般情况下好多少。

  现在优势函数可以与重要性抽样相结合(KL 散度将在后面添加),更新策略使用的梯度可以表示为:$E_{left(s_{t}, a_{t}right) sim pi_{theta^{primE}}}left[frac{p_{theta}left(s_{t}, a_{t}right)}{p_{theta^{primE}}left(s_{t}, a_{t}right)} A^{theta}left(s_{t}, a_{t}right)

  nabla log p_{theta}left(a_{t}^{n} mid s_{t}^{n}right)right]$

  其中 $theta^{primE}$ 代表旧策略,是我们用来采样的策略,$θ$ 代表我们当前的策略,上等式是我们使用策略梯度更新 $θ$ 时使用的梯度。这里的 $A$ 是主导函数。

  然后我们之前也说过两个策略的差距不要太大,所以我们在PPO算法中引入了KL散度,得到的优化目标如下:

  $begin{aligneD} J_{mathrm{PPO}}^{theta^{primE}}(theta) &=J^{theta^{primE}}(theta)-beta mathrm{KL}left(theta, theta^{primE}right) \ J^{theta^{primE}}(theta) &=E_{left(s_{t }, a_{t}right) sim pi_{theta^{primE}}}left[frac{p_{theta}left(a_{t} mid s_{t}right)}{p_{theta^{primE}}left(a_{t} mid s_{t}right)} A^{theta^{primE}}left(s_{t}, a_{t}right)right ] end{aligneD}$

  在构建代码时,我们可以直接将损失设置为负 $J(θ)$,这在 PG 中实现了梯度更新。

  值得一提的是,一般来说,我们不直接构造KL散度,而是使用PPO惩罚或PPO剪辑来优化和替换传统的KL散度。

  对于这两种方法,可以参考这位大佬的文章:详细近政策优化(PPO,满满干货)-建书()大佬写干货满了!!!像我这样的温斯顿可以相对顺利地理解它。

  2. PPO 算法代码

  PPO算法的代码比较容易理解,这里就不赘述了,贴出来看一看,让大家好理解。但请注意,此代码使用我们前面提到的近端优化裁剪方法 (PPO-clip)

  网络结构:点击查看代码

  class FeedForWARDNN(nn.ModulE):

def __init__(self, in_dim, out_dim):

super(FeedForWARDNN, self).__init__()

self.layer1 = nn.Linear(in_dim, 64)

self.layer2 = nn.Linear(64, 64)

self.layer3 = nn.Linear(64, out_dim)

def forWARD(self, obs):

if isinstance(obs, np.ndarray):

obs = torch.tensor(obs, dtype=torch.float)

activation1 = F.relu(self.layer1(obs))

activation2 = F.relu(self.layer2(activation1))

output = self.layer3(activation2)

return output

  PPO 算法类:

  点击查看代码

  class PPO:

def __init__(self, policy_class, env, **hyperparameters):

# PPO 初始化用于训练的超参数

self._init_hyperparameters(hyperparameters)

# 提取环境信息

self.env = env

self.obs_dim = env.observation_space.shape[0]

self.act_dim = env.action_space.shape[0]

# 初始化演员和评论家网络

self.actor = policy_class(self.obs_dim, self.act_dim)

self.critic = policy_class(self.obs_dim, 1)

# 为演员和评论家初始化优化器

self.actor_optim = Adam(self.actor.parameters(), lr=self.lr)

self.critic_optim = Adam(self.critic.parameters(), lr=self.lr)

# 初始化协方差矩阵,用于查询actor网络的action

self.cov_var = torch.full(size=(self.act_dim,), fill_value=0.5)

self.cov_mat = torch.diag(self.cov_var)

# 这个记录器将帮助我们打印出每个迭代的摘要

self.logger = {

'delta_t': time.time_ns(),

't_so_far': 0, # 到目前为止的时间步数

'i_so_far': 0, # 到目前为止的迭代次数

<p>

" />

'batch_lens': [], # 批次中的episoDic长度

'batch_rews': [], # 批次中的rews回报

'actor_losses': [], # 当前迭代中演员网络的损失

}

def learn(self, @R_441_10586@l_timesteps):

print(f"Learning... Running {self.max_timesteps_per_episodE} timesteps per episode, ", end='')

print(f"{self.timesteps_per_batch} timesteps per batch for a @R_441_10586@l of {@R_441_10586@l_timesteps} timesteps")

t_so_far = 0 # 到目前为止仿真的时间步数

i_so_far = 0 # 到目前为止,已运行的迭代次数

while t_so_far < @R_441_10586@l_timesteps:

# 收集批量实验数据

batch_obs, batch_acts, batch_log_probs, batch_rtgs, batch_lens = self.rollout()

# 计算收集这一批数据的时间步数

t_so_far += np.sum(batch_lens)

# 增加迭代次数

i_so_far += 1

# 记录到目前为止的时间步数和到目前为止的迭代次数

self.logger['t_so_far'] = t_so_far

self.logger['i_so_far'] = i_so_far

# 计算第k次迭代的advantage

V, _ = self.evaluate(batch_obs, batch_acts)

A_k = batch_rtgs - V.detach()

# 将优势归一化 在理论上不是必须的,但在实践中,它减少了我们优势的方差,使收敛更加稳定和快速。

# 添加这个是因为在没有这个的情况下,解决一些环境的问题太不稳定了。

A_k = (A_k - A_k.mean()) / (A_k.std() + 1e-10)

# 在其中更新我们的网络。

for _ in range(self.n_updates_per_iteration):

V, curr_log_probs = self.evaluate(batch_obs, batch_acts)

# 重要性采样的权重

ratios = torch.exp(curr_log_probs - batch_log_probs)

surr1 = ratios * A_k

surr2 = torch.clamp(ratios, 1 - self.clip, 1 + self.clip) * A_k

# 计算两个网络的损失。

actor_loss = (-torch.min(surr1, surr2)).mean()

critic_loss = nn.MSELoss()(V, batch_rtgs)

# 计算梯度并对actor网络进行反向传播

# 梯度清零

self.actor_optim.zero_grad()

# 反向传播,产生梯度

actor_loss.BACkWARD(retain_graph=TruE)

# 通过梯度下降进行优化

self.actor_optim.step()

# 计算梯度并对critic网络进行反向传播

self.critic_optim.zero_grad()

critic_loss.BACkWARD()

self.critic_optim.step()

self.logger['actor_losses'].append(actor_loss.detach())

self._log_sumMary()

if i_so_far % self.save_freq == 0:

torch.save(self.actor.state_Dict(), './ppo_actor.pth')

torch.save(self.critic.state_Dict(), './ppo_critic.pth')

def rollout(self):

"""

这就是我们从实验中收集一批数据的地方。由于这是一个on-policy的算法,我们需要在每次迭代行为者/批评者网络时收集一批新的数据。

"""

batch_obs = []

batch_acts = []

batch_log_probs = []

batch_rews = []

batch_rtgs = []

batch_lens = []

# 一回合的数据。追踪每一回合的奖励,在回合结束的时候会被清空,开始新的回合。

ep_rews = []

# 追踪到目前为止这批程序我们已经运行了多少个时间段

t = 0

# 继续实验,直到我们每批运行超过或等于指定的时间步数

while t < self.timesteps_per_batch:

ep_rews = [] 每回合收集的奖励

# 重置环境

obs = self.env.reset()

done = false

  

" />

# 运行一个回合的最大时间为max_timesteps_per_episode的时间步数

for ep_t in range(self.max_timesteps_per_episodE):

if self.render and (self.logger['i_so_far'] % self.render_every_i == 0) and len(batch_lens) == 0:

self.env.render()

# 递增时间步数,到目前为止已经运行了这批程序

t += 1

# 追踪本批中的观察结果

batch_obs.append(obs)

# 计算action,并在env中执行一次step。

# 注意,rew是奖励的简称。

action, log_prob = self.get_action(obs)

obs, rew, done, _ = self.env.step(action)

# 追踪最近的奖励、action和action的对数概率

ep_rews.append(rew)

batch_acts.append(action)

batch_log_probs.append(log_prob)

if Done:

break

# 追踪本回合的长度和奖励

batch_lens.append(ep_t + 1)

batch_rews.append(ep_rews)

# 将数据重塑为函数描述中指定形状的张量,然后返回

batch_obs = torch.tensor(batch_obs, dtype=torch.float)

batch_acts = torch.tensor(batch_acts, dtype=torch.float)

batch_log_probs = torch.tensor(batch_log_probs, dtype=torch.float)

batch_rtgs = self.compute_rtgs(batch_rews)

# 在这批中记录回合的回报和回合的长度。

self.logger['batch_rews'] = batch_rews

self.logger['batch_lens'] = batch_lens

return batch_obs, batch_acts, batch_log_probs, batch_rtgs, batch_lens

def compute_rtgs(self, batch_rews):

batch_rtgs = []

# 遍历每一回合,一个回合有一批奖励

for ep_rews in reversed(batch_rews):

# 到目前为止的折扣奖励

discounted_reWARD = 0

# 遍历这一回合的所有奖励。我们向后退,以便更顺利地计算每一个折现的回报

for rew in reversed(ep_rews):

discounted_reWARD = rew + discounted_reWARD * self.gAMMa

batch_rtgs.insert(0, discounted_reWARD)

# 将每个回合的折扣奖励的数据转换成张量

batch_rtgs = torch.tensor(batch_rtgs, dtype=torch.float)

return batch_rtgs

def get_action(self, obs):

mean = self.actor(obs)

# 用上述协方差矩阵中的平均行动和标准差创建一个分布。

dist = MultivariateNormal(mean, self.cov_mat)

action = dist.sample()

log_prob = dist.log_prob(action)

return action.detach().numpy(), log_prob.detach()

def evaluate(self, batch_obs, batch_acts):

"""

估算每个观察值,以及最近一批actor网络迭代中的每个action的对数prob。

"""

# 为每个batch_obs查询critic网络的V值。V的形状应与batch_rtgs相同。

V = self.critic(batch_obs).squeeze()

# 使用最近的actor网络计算批量action的对数概率。

mean = self.actor(batch_obs)

dist = MultivariateNormal(mean, self.cov_mat)

log_probs = dist.log_prob(batch_acts)

# 返回批次中每个观察值的值向量V和批次中每个动作的对数概率log_probs

return V, log_probs

</p>

  大佬总结道

  以上是大家伙教程(1)大家伙采集

整理的MAPO学习笔记: 从PPO算法入手,希望本文能帮大家解决PPO算法从PPO算法出发遇到的程序开发问题。

  如果你认为大佬教程的内容

  网站不错,欢迎向程序员朋友推荐大家伙教程。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线