PPO算法拆解

PyTorch深度强化学习算法合集:PPO、DQN、SAC、DDPG源码拆解与调参实践 深度强化学习是人工智能领域的重要分支,其核心在于智能体通过与环境的交互学习最优策略。在工程实践中,基于PyTorch框架实现的主流算法如PPO、DQN、SAC和DDPG,因其各自独特的更新策略和适用场景,成为研究和应用的热点。理解这些算法背后的原理,如经验回放、目标网络、策略梯度及最大熵框架,对于解决训练不收敛、样本效率低等问题至关重要。统一算法框架能够显著降低代码理解成本,便于对比实验和超参数调优。本文围绕一套结构清晰的PyTorch算法合集,从环境搭建、网络设计、训练循环到日志可视化,完整拆解其关键实现 阅读详情

在强化学习legged_gym中rsl_rl所实现的PPO算法源码如下:

# SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: BSD-3-Clause
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Copyright (c) 2021 ETH Zurich, Nikita Rudin

import torch
import torch.nn as nn
import torch.optim as optim

from rsl_rl.modules import ActorCritic
from rsl_rl.storage import RolloutStorage

class PPO:
    actor_critic: ActorCritic
    def __init__(self,
                 actor_critic,
                 num_learning_epochs=1,
                 num_mini_batches=1,
                 clip_param=0.2,
                 gamma=0.998,
                 lam=0.95,
                 value_loss_coef=1.0,
                 entropy_coef=0.0,
                 learning_rate=1e-3,
                 max_grad_norm=1.0,
                 use_clipped_value_loss=True,
                 schedule="fixed",
                 desired_kl=0.01,
                 device='cpu',
                 ):

        self.device = device

        self.desired_kl = desired_kl
        self.schedule = schedule
        self.learning_rate = learning_rate

        # PPO components
        self.actor_critic = actor_critic
        self.actor_critic.to(self.device)
        self.storage = None # initialized later
        self.optimizer = optim.Adam(self.actor_critic.parameters(), lr=learning_rate)
        self.transition = RolloutStorage.Transition()

        # PPO parameters
        self.clip_param = clip_param
        self.num_learning_epochs = num_learning_epochs
        self.num_mini_batches = num_mini_batches
        self.value_loss_coef = value_loss_coef
        self.entropy_coef = entropy_coef
        self.gamma = gamma
        self.lam = lam
        self.max_grad_norm = max_grad_norm
        self.use_clipped_value_loss = use_clipped_value_loss

    def init_storage(self, num_envs, num_transitions_per_env, actor_obs_shape, critic_obs_shape, action_shape):
        self.storage = RolloutStorage(num_envs, num_transitions_per_env, actor_obs_shape, critic_obs_shape, action_shape, self.device)

    def test_mode(self):
        self.actor_critic.test()
    
    def train_mode(self):
        self.actor_critic.train()

    def act(self, obs, critic_obs):
        if self.actor_critic.is_recurrent:
            self.transition.hidden_states = self.actor_critic.get_hidden_states()
        # Compute the actions and values
        self.transition.actions = self.actor_critic.act(obs).detach()
        self.transition.values = self.actor_critic.evaluate(critic_obs).detach()
        self.transition.actions_log_prob = self.actor_critic.get_actions_log_prob(self.transition.actions).detach()
        self.transition.action_mean = self.actor_critic.action_mean.detach()
        self.transition.action_sigma = self.actor_critic.action_std.detach()
        # need to record obs and critic_obs before env.step()
        self.transition.observations = obs
        self.transition.critic_observations = critic_obs
        return self.transition.actions
    
    def process_env_step(self, rewards, dones, infos):
        self.transition.rewards = rewards.clone()
        self.transition.dones = dones
        # Bootstrapping on time outs
        if 'time_outs' in infos:
            self.transition.rewards += self.gamma * torch.squeeze(self.transition.values * infos['time_outs'].unsqueeze(1).to(self.device), 1)

        # Record the transition
        self.storage.add_transitions(self.transition)
        self.transition.clear()
        self.actor_critic.reset(dones)
    
    def compute_returns(self, last_critic_obs):
        last_values= self.actor_critic.evaluate(last_critic_obs).detach()
        self.storage.compute_returns(last_values, self.gamma, self.lam)

    def update(self):
        mean_value_loss = 0
        mean_surrogate_loss = 0
        if self.actor_critic.is_recurrent:
            generator = self.storage.reccurent_mini_batch_generator(self.num_mini_batches, self.num_learning_epochs)
        else:
            generator = self.storage.mini_batch_generator(self.num_mini_batches, self.num_learning_epochs)
        for obs_batch, critic_obs_batch, actions_batch, target_values_batch, advantages_batch, returns_batch, old_actions_log_prob_batch, \
            old_mu_batch, old_sigma_batch, hid_states_batch, masks_batch in generator:


                self.actor_critic.act(obs_batch, masks=masks_batch, hidden_states=hid_states_batch[0])
                actions_log_prob_batch = self.actor_critic.get_actions_log_prob(actions_batch)
                value_batch = self.actor_critic.evaluate(critic_obs_batch, masks=masks_batch, hidden_states=hid_states_batch[1])
                mu_batch = self.actor_critic.action_mean
                sigma_batch = self.actor_critic.action_std
                entropy_batch = self.actor_critic.entropy

                # KL
                if self.desired_kl != None and self.schedule == 'adaptive':
                    with torch.inference_mode():
                        kl = torch.sum(
                            torch.log(sigma_batch / old_sigma_batch + 1.e-5) + (torch.square(old_sigma_batch) + torch.square(old_mu_batch - mu_batch)) / (2.0 * torch.square(sigma_batch)) - 0.5, axis=-1)
                        kl_mean = torch.mean(kl)

                        if kl_mean > self.desired_kl * 2.0:
                            self.learning_rate = max(1e-5, self.learning_rate / 1.5)
                        elif kl_mean < self.desired_kl / 2.0 and kl_mean > 0.0:
                            self.learning_rate = min(1e-2, self.learning_rate * 1.5)
                        
                        for param_group in self.optimizer.param_groups:
                            param_group['lr'] = self.learning_rate


                # Surrogate loss
                ratio = torch.exp(actions_log_prob_batch - torch.squeeze(old_actions_log_prob_batch))
                surrogate = -torch.squeeze(advantages_batch) * ratio
                surrogate_clipped = -torch.squeeze(advantages_batch) * torch.clamp(ratio, 1.0 - self.clip_param,
                                                                                1.0 + self.clip_param)
                surrogate_loss = torch.max(surrogate, surrogate_clipped).mean()

                # Value function loss
                if self.use_clipped_value_loss:
                    value_clipped = target_values_batch + (value_batch - target_values_batch).clamp(-self.clip_param,
                                                                                                    self.clip_param)
                    value_losses = (value_batch - returns_batch).pow(2)
                    value_losses_clipped = (value_clipped - returns_batch).pow(2)
                    value_loss = torch.max(value_losses, value_losses_clipped).mean()
                else:
                    value_loss = (returns_batch - value_batch).pow(2).mean()

                loss = surrogate_loss + self.value_loss_coef * value_loss - self.entropy_coef * entropy_batch.mean()

                # Gradient step
                self.optimizer.zero_grad()
                loss.backward()
                nn.utils.clip_grad_norm_(self.actor_critic.parameters(), self.max_grad_norm)
                self.optimizer.step()

                mean_value_loss += value_loss.item()
                mean_surrogate_loss += surrogate_loss.item()

        num_updates = self.num_learning_epochs * self.num_mini_batches
        mean_value_loss /= num_updates
        mean_surrogate_loss /= num_updates
        self.storage.clear()

        return mean_value_loss, mean_surrogate_loss

1. 场景比喻

假设你经营着一家披萨店,店里有一位新来实习的学徒,你想教会他如何做出好吃的披萨。你可以把学徒想象成一个「神经网络」,你就是想要训练他的「大脑」,让他学会每次做披萨时都能做出正确的决策(怎么揉面、放多少酱料、何时烤制等)。

但是你不想一下子就把他灌输所有的知识,你希望通过一种“试错”(互动)方式,让学徒自己从实际操作里学到什么决策才是好的、什么决策是坏的。

在这个过程中,你会:

  1. 让学徒去做一段时间披萨(相当于“收集经验”)。
  2. 看学徒表现(把“做披萨”的过程数据存下来)。
  3. 给学徒打分或奖励(如果披萨好吃,就给高分;不好吃,就给低分)。
  4. 在一段时间之后把这些数据拿出来统一进行一次“复盘”,并根据得失进行调整(更新学徒的做法)。

PPO(Proximal Policy Optimization)就是这么一个试错 + 打分 + 调整的过程。代码中,主要有以下角色:

  1. 学徒的大脑(actor_critic):
  • actor(演员):决定下一步行动时该做什么(比如:在披萨上放多少酱料)。
  • critic(评论员):决定学徒当前动作做得好不好,用价值来衡量(比如:预计这样做出来的披萨有多好吃)。
  1. 记事本或账本(RolloutStorage):
  • 记录学徒每一步的操作、获得的分数、以及一些当时的环境信息、学徒的心态等等。
  1. PPO 这个管理者(PPO类本身):
  • 负责告诉学徒什么时候去做披萨,什么时候来复盘学习。
  • 负责管理学徒的日常训练计划,比如学习率、奖励计算、经验数据存储等。
  • 训练中的“奖惩原则”或“学习规则”也都在这里。

下面我们就从头到尾讲一下,这段代码是如何在“店里”训练“学徒”的。

2. init:初始化工具

当我们新开店时,会先做一些准备工作。比如,买工具、准备原材料、制定培训计划等等。对应的代码在 init 里完成了这些事:

  • actor_critic:学徒的大脑。本质是一个神经网络,里边包含了“做决定”和“估算好坏”两部分。
  • 一系列超参数:
    • clip_param: PPO 对行动调整幅度的限制。就像你告诉学徒:每次改进可以,但是不要一次性改太激进。
    • gamma: 相当于给奖励打折扣的一个因子。比如说,后面才拿到的好处价值会稍微折扣一下。
    • lam: 用来计算平滑的优势函数(GAE),帮助学徒知道具体哪一步做得好或不好。
    • value_loss_coef, entropy_coef:在总的学习目标里,你要告诉学徒更重视哪部分,比如更重视“预测准确”还是更重视“保持灵活”。
    • learning_rate: 学徒学习的速度。学徒如果一次学太多会消化不良,但学太慢又效率太低,需要找个合适的值。
  • optimizer:训练学徒的方式,这里选择了Adam,就像是你给学徒设定了“连续改进”的学习方式。
  • storage 和 transition:相当于一本“流水账本”和一个“临时记录纸片”,把学徒每个动作和相应的结果记下来,再定期汇总进行系统学习。

3. init_storage(…):开本新账

你开了一本新的“流水账本”(RolloutStorage)用来记录学徒每一步做的事、得到的结果。就像开了一个新笔记本,专门记录学徒试做披萨的过程。

4. act(…):让学徒操作并记录

当顾客来了,学徒开始做披萨了,这里就要让学徒根据所见的环境“观察”(obs、critic_obs)来决定“行动”(动作),并把一些关键信息记到“临时纸片”上。

  • 决定行动(actor):学徒看到饼皮大小、顾客口味等信息后,决定接下来要怎么做(放多少料、怎么搅拌)。
  • 评价好坏(critic):学徒内心也会有个估计,“我觉得这一步做出来的披萨会如何?”
  • 记录下来(transition):把“我的动作”,“我估计的评分”,“当前状态”都先写在一张纸片上。
    等真正送到顾客或烤炉那一步后,学徒会拿到实际的结果,这时再把纸片上写的东西正式抄进账本。

5. process_env_step(…):真正获取反馈并写入账本

就像披萨烤好了,顾客吃完了,你收到了评分(rewards),知道这次表现好不好,还有没有把披萨糊掉(dones 表示这一回合结束没有)。

  • 把奖励记上去:这次顾客给了几星?这就是代码里 self.transition.rewards = rewards.clone()。
  • 记录回合是否结束:如果这块披萨已完成,就要标记 dones,并重置学徒的状态(相当于一单结束重新来)。
  • 处理超时:如果中间某些情况导致“时限到”,还会有一些额外的计算,把学徒自己估计的价值加回奖励(time_outs 的部分)。
  • 正式记账:最后一行 self.storage.add_transitions(self.transition) 就像把那张“临时纸片”正式贴到我们的账本里。
  • 清空纸片:学徒准备下一单做披萨了。

6. compute_returns(…):结账时算总分

等学徒连着做完了若干个披萨,或者一个回合结束了,就需要来做一个小结:这段时间里学徒做得怎么样?要不要给一些鼓励或指导?

  • 这里的 compute_returns 会把最终的回报(return)算出来,结合过去的估计,算出更精确的“优势函数”(优势:到底哪个操作比平庸的操作高出多少分)。
  • 这些数据会留在账本里,以便稍后的整体学习。

7. update(…):复盘学习,改进手法

这就是学徒真正集体反思和学习的阶段。
类似于:让学徒把前面做每个披萨的经历都翻出来,好好对比“我当初决定的做法”和“实际得到的结果”之间的差异,然后根据理论(PPO 策略)做改进:

  1. 拿出之前所有的记账:这里会把刚才存进账本的所有记录分成若干小段(mini-batch)。
  2. 对每个小段数据,学徒先计算现在的想法:
    • 学徒看看“如果再来一次,我可能会怎么做(新的动作分布)?”
    • 把这个新的想法跟之前实际做的动作对比,并计算变化率(ratio)。
  3. 防止学徒“一次改进过猛”:
    • PPO 有一个 clip_param(剪切范围),像是你对学徒说:“慢慢改,不要一次把配方改得面目全非。”
    • 因此在计算“损失函数”时,会把变化过大的地方剪一下。
  4. 价值函数的改进:
    • 学徒还要学会更准确地“预估”自己每个动作带来的结果。这会涉及一个专门的价值损失(value loss)。
    • 如果开启了“剪切价值”,也会对这部分做类似的限制,防止一口气把学徒内心的评分标准改得太离谱。
  5. 加入熵增强探索:
    • 让学徒保持对各种可能性的探索,不要太快陷入“老是放同样的料”的习惯。我们给一点额外奖励鼓励多元做法,叫 entropy_coef。
  6. 合并成一个总的损失:
    • 学徒这次的整体学习目标,就是“在保证做披萨决策改得恰当”的同时,也要让“评价系统更准”。
    • 然后再在这个损失上进行一次梯度下降,更新学徒的脑袋(神经网络参数)。
  7. 自适应学习率(可选):
    • 如果发现学徒跟之前想法的差异太大(KL 散度过大),就降低学习率;如果差异过小,就提高学习率。就像如果学徒老是变动太大,你劝他先沉住气,别急;如果学徒一直不变动,你希望他大胆一些。

复盘完之后,学徒又变聪明了一些。代码里记录了最后的 mean_value_loss, mean_surrogate_loss 作为“这次复盘学习”的指标,下次你可以继续追踪。

8. 总结

  1. 像学徒制作披萨一样:学徒(Actor-Critic 网络)在不同的状态(环境观测)做出不同决策(动作),得到不同反馈(奖励)。
  2. 像记录流水账:每一步操作都记录在 storage 中,以便后续反思与学习。
  3. 像定期复盘:等学徒完成一段时间练习,就进行一次PPO更新(update),在这过程中分析旧做法与新做法的差异,用“剪切”等安全措施避免学徒一下子完全推翻自己之前的经验。
  4. 持续循环:多次“做批量披萨→记录→复盘更新”,学徒的“脑子”慢慢就学会了做出更好的披萨,动作也更合理,分数越来越高。

前半部分在做“采集经验”和“记账”
后半部分在做“学习更新和改进策略”
用生活经验理解,就是一直在“做→记→评→学→再做→再评”的螺旋式改进过程。

一文解释电路中常用电子元器件应用和选型01 电容和二极管是电路中最常用的两个电子元器件,种类和系列众多,这里简单总结一下应用场景和选型方式 电容(Capacitor) 电容的种类(20种以上)和应用非常广泛,但是我经常遇到的无非就是下面这几种: 应用 1.隔直流。 2.旁路(去耦) 3.耦合 4.滤波 5.温度补偿 6.计时 7.调谐 8.整流 9.储能 种类 1. 陶瓷电容 2. 云母电容 3. 铝电解电容 4. 钽 阅读详情

相关推荐

Blender软件导出地形到Gazebo中

Blender软件导出地形到Gazebo中,并配置纹理、刚度、高度。

m0_70652514的博客 3376

拆解PPO算法:从核心公式到实战调优

本文深入解析PPO(近端策略优化)算法,通过核心公式拆解其“剪切”机制如何实现稳定训练。文章从算法原理出发,详细阐述了PPO-Clip目标函数、广义优势估计(GAE)的作用,并结合实战经验,提供了网络结构设计、数据收集、损失函数构成等关键工程细节与超参数调优指南,旨在帮助读者从理论到实践全面掌握这一强化学习领域的稳定器。

weixin_29057237的博客 377

浪涌电流测试仪的工作原理

浪涌电流脉冲形成的开始由同步电路 13 确定,该同步电路 13 发送命令以打开和第二开关 10 和 11,向发生器 14 发送控制命令以生成被测半导体器件 5 的控制信号和参考信号整形器 9 的触发脉冲。电流源的功率输出并联连接,以对流经被测半导体样品的电流求和。此外,使用数字控制扩展了测试仪的功能,能够产生各种形状的电流脉冲,例如梯形电流脉冲,以估计被测晶闸管的导通状态扩展时间。由于晶体管3的栅极是连接的,并且平衡电阻4包含在晶体管3的源中,因此通过每个晶体管3的电流脉冲大致相同,并重复参考信号的形状。

Jesse0257的博客 1256

【动手学具身智能】legged_gym项目代码阅读

legged_gym提供了用于训练ANYmal(和其他机器人)使用NVIDIA的Isaac Gym在崎岖地形上行走的环境。 它包括模拟到真实传输所需的所有组件:执行器网络、摩擦和质量随机化、噪声观测和训练过程中的随机推送。其中该项目需要用到Isaac_gym(已停止维护)与rsl_rl1.2.0(大版本已不是最新),可能更适合用于学习。legged_gym/ ├── envs/ ├── scripts/ ├── utils/ ├─

ModestCoder_的博客 5132

基于 openEuler 24.03 LTS 源码编译安装 Zabbix 7.4

Zabbix是一款开源的企业级分布式监控系统,支持网络、服务器、应用等多种IT资源的监控。核心功能包括数据采集、告警通知、可视化展示等,采用Server/Agent架构,支持多种操作系统。本文详细介绍了在openEuler 24.03系统上部署Zabbix 7.4.2的完整流程,包括环境准备、MySQL配置、PHP/Apache安装、Zabbix编译安装等步骤,为构建企业级监控系统提供了实践指导。

广然笔记 1191

实战测评:4大搜索API(You.com/Tavily/Exa/Perplexity)谁更适合你的AI项目?附Python调用代码

本文实战测评了You.com、Tavily、Exa和Perplexity四大搜索API在AI项目中的集成应用,详细对比了它们的技术特性和Python调用方法。针对LLM实时数据需求,You.com的优化设计表现突出,支持32k大上下文窗口和快速响应。文章提供了完整的代码示例和场景化选型建议,帮助开发者高效集成搜索API到AI项目中。

weixin_42569329的博客 479

legged_gym代码阅读及解释

legged_gym是苏黎世联邦理工大学(ETH)机器人系统实验室开源的基于英伟达推出的仿真平台Issac gym(目前该平台已不再更新维护)的足式机器人仿真框架。注意:该框架完全运行起来依赖强化学习框架rsl_rl和Issac gym,本文不对强化学习框架rsl_rl和仿真平台脚本进行描述解释。legged_gym ├──envs ├──__init__.py └──机器人文件夹

Guanhj_BIT_1995的博客 1万+

SiC MOSFET驱动设计实战:从特性解析到电路优化

本文深入解析SiC MOSFET的核心特性及其驱动电路设计要点,涵盖高温稳定性、快速开关能力等关键特性,并提供驱动电压配置、电流能力计算、布局优化等实用方案。特别针对第三代电力电子半导体SiC MOSFET的驱动要求,分享STGAP1AS等典型驱动方案的应用技巧,助力工程师解决高频应用中的EMI和热管理挑战。

weixin_29230865的博客 366

【具身相关】legged_gym, isaacgym、rsl_rl关系梳理及相关笔记

【legged_gym】legged_gym, isaacgym代码逻辑梳理 总体关系 IsaacGym legged_gym rsl_rl 三者的关系 legged_gym代码库介绍 环境模块env

几度热忱的博客 7451

AI颠覆市场调研:生成式智能体如何重构商业决策?

AI正在将市场调研从"成本中心"转变为"战略武器"。当企业能够用生成式智能体实时模拟百万级虚拟用户时,传统调研的样本偏差、时间滞后、成本高昂等问题将不复存在。对于开发者而言,这不仅是技术的狂欢,更是参与商业规则重构的历史机遇。行动建议立即体验Simile/Aaru的智能体平台,验证虚拟样本效果参与LLM持续性记忆架构的开源项目(如Memory Llama)关注AI调研API的标准化进程(如Hugging Face的Market Research Toolkit)

这里汇聚了前沿的技术分享与实用的开发技巧,带你探索从创意到企业的技术创业之路。 614

复制幻灯片到另一个PPT编程

请确保将源PPT文件和目标PPT文件的文件名修改为你实际使用的文件名。运行上述代码后,目标PPT将包含源PPT中的所有幻灯片和形状。这里假设源PPT文件名为"source.pptx",目标PPT文件名为"target.pptx"。方法将每个幻灯片的布局添加到目标PPT中。是一个强大的库,可以用于创建、修改和操作PPT文件。要将一个PPT中的幻灯片复制到另一个PPT,可以使用Python的。这段代码遍历源PPT的每个幻灯片,并使用。步骤 3: 打开源PPT和目标PPT。这将保存修改后的目标PPT文件。

ByteSparkX的博客 1322

humanoid-gym/legged-gym中断训练后继续训练的方法

legged-gym官网有说中断训练后基于之前的训练成果继续训练的方法是在运行命令中添加:--resume 和 --load_run,但是并没有说具体的使用命令。本地humanoid-gym/logs/XBot_ppo下面的。或者基于已有模型训练。

luoyueer的博客 1050

ANPC三电平拓扑双脉冲试验的原理与实施

ANPC三电平拓扑因损耗低、谐波小、应力均衡而广泛应用,但其存在短、长两类换流通道,寄生电感和开关应力差异显著。短通道尖峰小、可靠性高;长通道应力严苛。因此需分别制定两套独立双脉冲测试方案,针对不同时段和器件(如T1、T5、T6、T4及对应二极管)全面考核开关特性。

嵌入式老牛的博客 350

Ubuntu20.04 运行 Legged Gym(腿足强化学习)

在Ubuntu20.04 安装和运行腿足机器人强化学习源码Legged Gym,以及配套的 RSL RL。

冀晓武的博客 3855

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

RLHF中的PPO算法过程微观拆解

强化学习中的PPO算法微观拆解。在强化学习中,Rollout是指在给定的策略下模拟环境的过程。在PPO中,Rollout的过程对应于根据当前的语言模型(策略)生成文本(轨迹)。这个过程依赖于在prompt库中抽取的一个batch的数据Batch Prompt和当前的语言模型LM。语言模型接收一个prompt作为输入,并生成一个Response。这些Response就构成了我们的"轨迹"。Evaluate是在强化学习中对生成的轨迹(在我们的例子中就是文本)进行评估的步骤。在PPO中,这个评估过程由一个。

qq_34603425的博客 5236

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

PPO (Proximal Policy Optimization) 算法模块详细拆解

重要性采样:用旧策略收集的数据更新新策略裁剪目标:限制更新幅度,保证稳定性GAE优势估计:平衡偏差和方差多epoch更新:提高样本效率Actor-Critic架构:同时学习策略和价值。

ZPC8210的博客 470

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

拆解大语言模型RLHF中的PPO算法

来自:PaperWeekly©作者 |陶然单位 |字节跳动研究方向 |NLP、大语言模型为什么大多数介绍大语言模型 RLHF 的文章,一讲到 PPO 算法的细节就戛然而止了呢?要么直接略过,要么就只扔出一个 PPO 的链接。然而 LLM x PPO 跟传统的 PPO 还是有些不同的呀。其实在 ChatGPT 推出后的相当一段时间内,我一直在等一篇能给我讲得明明白白的文章,但是一直未能如愿。我...

zenRRan的博客 1542

PPO算法工程落地:从理论公式到PyTorch实战的完整拆解

本文深入解析PPO算法(Proximal Policy Optimization)的核心原理与工程应用,从理论公式到PyTorch实战实现完整拆解。通过策略约束机制、优势估计优化及内存管理等关键技术,解决强化学习中的稳定性问题,并分享工业级优化技巧与典型问题排查指南,助力开发者高效落地PPO算法。

weixin_29061509的博客 84

拆解大语言模型RLHF中的PPO

理解大模型RLHF中的PPO

风少_Hpy的博客 1587

从李宏毅课程出发:拆解PPO算法核心原理与实战推演

本文从李宏毅课程出发,深入拆解PPO算法的核心原理与实战应用。通过对比TRPO与PPO的数学演进,详细解析了PPO-Clip的目标函数设计及其重要性采样机制。文章还分享了PPO在实战中的实现细节、调参技巧及常见陷阱,帮助读者更好地掌握这一强化学习领域的流行算法。

weixin_29083373的博客 121

为什么ChatGPT的强化学习选择了PPO?深入拆解算法设计中的工程智慧

本文深入探讨了ChatGPT在RLHF技术栈中选用近端策略优化算法的工程智慧。面对大模型高维动作空间、稀疏奖励信号和天价训练成本等独特挑战,PPO以其计算友好、实现简洁和稳定鲁棒的特性脱颖而出。其核心的裁剪机制替代了复杂的约束求解,完美契合大规模分布式训练框架,成为工业级大模型强化学习微调的首选算法。

u0v1w2x3的博客 965

PPO算法实战:从理论到代码实现(附核心流程拆解)

本文深入解析PPO算法(Proximal Policy Optimization)在强化学习中的应用,从理论到代码实现全面拆解核心流程。通过策略更新裁剪机制和GAE优势估计,PPO有效解决了训练不稳定和样本效率低的问题,适用于机器人控制、游戏AI等多个领域。文章包含详细的代码示例和实战调参技巧,帮助开发者快速掌握这一强化学习首选算法。

info6的博客 631

从“乱猜”到“懂你”:深度拆解大模型旋转利器PPO算法

PPO通过简单而有效的“剪切”机制,解决了强化学习训练中的顽疾。它在大模型阶段的成功,证明了“新生更新”比“激进进化”更具生命力。虽然现在出现了如DPO(直接偏好优化)等更轻量化的方案,但PPO在处理复杂奖励逻辑时的上限依然无可替代。在实际实践中,如果只是停留在“了解大模型原理”,其实很难真正感受到模型能力的差异。我个人比较推荐直接上手做一次微调,比如用这种低门槛大模型微调平台,把自己的数据真正“喂”进模型里,生产出属于自己的专属模型。

kanna1209的博客 482

彻底搞懂PPO|强化学习基线算法,拆解常见认知误区

排查时可以顺着计算链路往回看:奖励是否合理,终止状态有没有处理对,回报和 GAE 是否算对,旧策略的 log_prob 是否真的固定,再看策略损失、价值损失和 KL 的变化。我觉得理解 PPO,重点不是背住 ε=0.2、γ=0.99 这些常见参数,而是想清楚它在防什么:一批轨迹被重复训练时,新策略会逐渐偏离产生数据的旧策略,而 clip通过截断越界更新的收益,让这种偏离不至于轻易失控。某一步,它在状态 s 下选择动作 a,结果比预期更好,那么最直接的想法就是:提高以后在相同状态下选择这个动作的概率。

soaring_casia的专栏 377

为什么AI不再“满口翻译腔”?深度拆解PPO算法如何教会机器说人话

PPO算法不仅是数学上的成功,更是AI实现人类文明的一条桥梁。它让模型从简单的“概率预测机”变成了能够理解人类情绪与偏好的“对话者”。虽然PPO训练需要消耗巨大的计算资源(即所谓的“三驾马车”:策略模型、价值模型、奖励模型同时运行),但它带来的体验跨越是革命性的。对于开发者来说,RLHF 是目前大模型调优的最高殿堂。如果你想在自己的垂直领域(如医疗、法律)训练一个有温度的专家 AI,提供的气压工具箱绝对是你电梯的加速器,它的架构是从基础指令授权到进阶 RLHF 的全栈技术支持。总结:建议。

kanna1209的博客 775

从零到一:用大白话拆解PPO算法的核心思想与实战

本文用通俗易懂的语言,深入浅出地讲解了PPO(Proximal Policy Optimization)算法的核心思想。文章从On-policy与Off-policy学习的对比入手,通过生动的比喻揭示了PPO利用重要性采样复用历史经验、并通过概率比裁剪(clip_range)约束策略更新幅度以保证训练稳定的核心机制。最后,文章提供了从CartPole环境到Atari游戏的实战代码与调参指南,帮助读者快速上手这一强大的强化学习算法。

i1j2k的博客 490
上一篇: priority_queue的使用方法
下一篇: PPO算法损失函数的设计
ZHAOCHENHAO-
博客等级 码龄10年 2774粉丝 72原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值