找到
39
篇与
admin
相关的结果
-
深入浅出阅读OpenAI强化学习经典论文《Proximal Policy Optimization Algorithms》 本文深入浅出地解析了OpenAI强化学习经典论文《Proximal Policy Optimization Algorithms》,从工程视角将PPO算法中的“策略”类比为控制器,帮助非专业背景的读者理解其核心思想。文章详细介绍了PPO的提出背景,指出其在解决传统强化学习算法(如DQN、策略梯度方法和TRPO)的稳定性与复杂性难题中的优势。重点分析了PPO的核心创新——“裁剪”目标函数,通过限制策略更新幅度,在保证训练稳定性的同时简化实现。此外,文章还阐述了PPO的三步工作流程(数据收集、优势计算和优化)及其在连续控制任务和雅达利游戏中的卓越实验效果,最终总结了PPO在样本效率、易用性和性能之间的平衡,奠定了其作为强化学习领域主流算法的地位。 小陶本人不是计算机或者数学专业的,其实学习这些经典算法的时候,一个个公式直接看晕乎了。对于有机械工程或者控制工程背景的我们工科生来说,可以将强化学习中的“策略(Policy)”想象成一个控制器,它的目标是学会如何操作一个复杂的系统(比如机器人或游戏角色),以获得最大的累计奖励(比如最快到达终点或获得最高分)。PPO算法就是一种设计这个“控制器”的优秀方法。本文结合论文的原文并且适当使用AI进行整理。如果明显的错误,欢迎指出交流。 论文原文:Proximal Policy Optimization Algorithms - arXiv:1707.06347 PPO的提出背景:为什么我们需要PPO? 在PPO被提出之前,主流的强化学习算法主要有三类,但它们都各有短处: (1)深度Q学习 (DQN): 这类算法在处理像雅达利(Atari)游戏这样拥有离散动作(比如上、下、左、右)的环境中表现优异 。但它很难被应用到动作是连续的场景中(比如控制机器人关节的角度) ,并且在一些简单问题上有时也表现不佳 。 (2)“香草”策略梯度 (Vanilla Policy Gradient, PG): 这类算法可以直接优化策略,能处理连续动作问题。但它有一个很大的缺点:训练过程非常不稳定,对参数敏感。想象一下你在调试一个控制器参数,稍微调大一点,系统就可能直接崩溃。PG算法就有类似的问题,它在更新策略时步子迈得太大,很容易导致策略“学废了”,性能急剧下降 。 (3)信任区域策略优化 (Trust Region Policy Optimization, TRPO): TRPO是为了解决PG算法不稳定的问题而设计的。它的核心思想是:在更新策略时,给新策略加一个“信任区域”的约束,确保新策略不会和旧策略偏离太远,从而保证了学习过程的稳定。TRPO效果很好,但它的算法实现异常复杂 ,需要用到二阶优化,并且与一些常见的网络结构(如参数共享、Dropout)不兼容 。 PPO的目标就是: 创造一种新算法,既能拥有TRPO的稳定性和可靠性能,又能像PG算法一样简单,只用一阶优化(也就是我们常用的梯度下降/上升),更容易实现和应用 。 PPO的核心思想:神奇的“裁剪”目标函数 PPO的精髓在于它设计了一个巧妙的“代理”目标函数(Surrogate Objective Function)。在更新策略时,我们优化的不是真实的回报,而是这个代理目标,通过优化它来间接提升策略。 要理解这个目标函数,我们先来看一个关键的比率:概率比率 (Probability Ratio)。 $$ r _ { t } ( \theta ) = \frac { \pi _ { \theta } ( a _ { t } | s _ { t } ) } { \pi _ { \theta _ { o l d } } ( a _ { t } | s _ { t } ) } $$ 分子是新策略在状态St下采取动作at的概率; 分母是旧策略在同样状态下采取同样动作的概率; 这个比值 $r _ { t }$ 度量了新旧策略的差异。如果 $r_t>1$,说明新策略更倾向于采取这个动作;如果$ r_t<1$,则说明新策略更不倾向于采取这个动作 。 传统的策略梯度算法的目标函数可以简化为 : $$ L ^ { C P I } ( \theta ) = r _ { t } ( \theta ) \hat { A } _ { t } $$其中 $ \hat { A } _ { t } $ 是优势函数 (Advantage Function),它衡量了在状态$ s _ { t } $采取动作$ a _ { t } $究竟有多好。如果 $ \hat { A } _ { t } $ \>0,说明这个动作比平均水平要好;反之则不好。 所以,优化的目标就是:如果一个动作是“好”的,就增大它的概率,如果一个动作是“坏”的,就减小它的概率。 那么,问题来了,如果毫无限制地增大$r _ { t }$,就可能导致策略更新步子太大,这就是PG算法不稳定的根源 。PPO的解决方案是裁剪 (Clipping)。 PPO的目标函数如下: $$ L ^ { C L I P } ( \theta ) = \hat { \mathbb { E } } _ { t } \left[ \operatorname* { m i n } \left( r _ { t } ( \theta ) \hat { A } _ { t } , \operatorname { c l i p } ( r _ { t } ( \theta ) , 1 - \epsilon , 1 + \epsilon ) \hat { A } _ { t } \right) \right] $$这里的$\epsilon$是一个超参数,通常取0.2左右 。这个公式看起来复杂,但思想很直观,我们可以把它看作一个“带有限位器的激励系统”(如下图所示): 带有限位器的激励系统图片 当动作是“好”的 $( \hat { A } _ { t } > 0 )$: 目标函数变为$ \operatorname* { m i n } ( r _ { t } \hat { A } _ { t } , ( 1 + \epsilon ) \hat { A } _ { t } ) $ 我们希望增大$r _ { t }$来获得更大的回报,但函数外部的 min 操作给这个回报设置了一个上限。一旦$r _ { t }$超过 1+ϵ,回报就不会再增加了。 这就好比: 你做得好,就给你奖励,但奖励有个上限,防止你因为一次超常发挥就变得过于激进,从而保证了稳定性。 当动作是“坏”的$( \hat { A } _ { t } < 0 )$: 目标函数变为${ m i n } ( r _ { t } \hat { A } _ { t } , ( 1 - \epsilon ) \hat { A } _ { t } )$ 我们希望减小$r _ { t }$,但如果优化的过程中,算法错误地增大了$r _ { t }$(比如超过了 1+ϵ),$r _ { t } \hat { A } _ { t }$这一项会变成一个很大的负数,给予一个严厉的惩罚。 clip 的作用是,当$r _ { t }$减小到1−ϵ 以下时,目标函数的值不再变化 。这同样限制了单步更新的幅度。 这就好比: 你做得不好,就要接受惩罚。这个机制确保了你不会因为想逃避惩罚而做出过于保守或奇怪的动作,同时也对错误方向的更新给予重罚。 通过上述的约束,这个“裁剪”的目标函数通过限制策略更新的幅度,巧妙地将TRPO的“信任区域”思想用一种更简单的方式实现了,使得算法既稳定又易于实现 。 PPO如何Work:三步走的循环 PPO作为一个“演员-评论家(Actor-Critic)”风格的算法,其工作流程非常清晰 : 第一步:数据收集 首先,我们有N个并行的“演员”(Actor),它们使用当前的策略$\pi _ { \theta _ { o l d } }$与环境互动,各自收集T个时间步的数据(状态、动作、奖励等) 。 第二步:优势计算 利用收集到的数据,计算每个时间步的优势函数估计值$( \hat { A } _ { t } $。这通常通过一种叫做“广义优势估计 (GAE)”的技术来完成 。 第三步:优化 将收集到的 NT 条数据作为一个批次(batch),用这个批次的数据来优化上面提到的 目标函数 $L ^ { C L I P } $。 关键点:PPO会用同一批数据,通过随机梯度上升(如Adam优化器)进行多轮(K epochs)的优化 。这极大地提高了数据的利用率,也是它相比于PG算法数据效率更高的原因。因为有“裁剪”机制的保护,多轮更新也不会导致策略崩溃 。 这三步完成后,更新策略参数,然后无限循环下去,策略就会变得越来越好。 PPO实验效果 它真的好用吗?答案是肯定的。论文通过大量的实验证明了PPO的有效性。 在连续控制任务上(如模拟机器人行走):论文首先验证了“裁剪”目标函数的有效性。不带任何限制的版本性能很差,甚至比随机策略还糟糕,而带有裁剪的版本(ϵ=0.2)在所有变体中得分最高 。在与其他主流算法(如TRPO, A2C)的对比中,PPO在绝大多数任务上都取得了最好的性能,学习速度更快,最终表现也更优越 (具体可见论文Figure 3的曲线图)。 PPO的有效性图片 在雅达利游戏上(离散控制任务),PPO同样表现出色。论文在49个游戏上对比了PPO, A2C和ACER。如果衡量“学习速度”(整个训练过程的平均分),PPO在30个游戏中胜出,遥遥领先 。如果衡量“最终性能”(训练最后100个回合的平均分),PPO的表现也极具竞争力,虽然胜出游戏数量少于ACER,但考虑到PPO的实现简单得多,这个结果已经非常惊人了 。 雅达利游戏上(离散控制任务)图片 论文总结 PPO通过引入一个创新的裁剪代理目标函数,成功地实现了与复杂算法TRPO相媲美的稳定性和性能,同时保持了代码实现的简洁性 。它解决了传统策略梯度方法更新步长难以确定、容易崩溃的问题,也避免了信任区域方法的复杂计算。总的来说,PPO在样本效率、实现简单性和性能表现之间找到了一个绝佳的平衡点 ,这也是它至今仍然是强化学习研究和应用领域最常用和最受欢迎的算法之一的原因。 -
ICCV 2025 论文分享《RIPE: Reinforcement Learning on Unlabeled Image Pairs for Robust Keypoint Extraction》 本文介绍了一种创新的弱监督关键点提取框架 RIPE,它利用强化学习技术,仅需图像对的二元场景匹配标签(是否为同一场景)即可完成训练,无需依赖精确的位姿、深度信息或复杂的人工数据增强。RIPE 将关键点选择建模为强化学习问题,通过概率性采样关键点、多尺度描述符生成以及基于几何验证的奖励机制,有效提升了模型在剧烈光照、天气变化等真实场景下的鲁棒性。实验表明,RIPE 在 MegaDepth、HPatches、Aachen Day-Night 和 Boreas 等多个基准测试中取得了与现有全监督方法相当甚至更优的性能,显著推动了弱监督关键点提取技术的发展。 开源地址: RIPE - Github 论文阅读:RIPE: Reinforcement Learning on Unlabeled Image Pairs for Robust Keypoint Extraction 一、 解决的问题 传统的关键点检测方法(如 SIFT 、ORB )依赖手工设计的特征,在面对剧烈的光照变化、天气变化或长时间跨度的图像匹配任务时,性能会显著下降 。为了克服这些限制,研究人员转向了基于深度学习的方法。 然而,当前主流(SOTA)的深度学习方法大多存在以下依赖问题: 依赖强大的监督信息: 许多方法如 DeDoDe、DISK 和 ALIKED 依赖于具有精确位姿和深度信息的数据集(如 MegaDepth )。这些数据集的构建过程复杂,通常需要通过运动恢复结构(SfM)技术生成,而SfM本身又依赖于SIFT等传统关键点 。这限制了训练数据的规模和多样性。 依赖人工数据增强: 另一类方法如 SuperPoint 和 SiLK 通过对图像进行人工变换(如单应性变换)来生成训练数据 。这种方式难以完全模拟真实世界中复杂的光照、天气和季节变化,导致模型在真实场景中的泛化能力不足 。 RIPE 旨在解决的核心问题是: 如何在弱监督条件下,仅利用“是否为同一场景”的二元标签,训练出一个在各种真实世界条件下都表现鲁棒的关键点检测与描述模型,从而摆脱对精确位姿、深度信息或复杂人工数据增强的依赖 。 二、 使用的方法 整体图片 关键点提取图片 为了解决关键点选择过程不可微的问题,并适应弱监督的训练方式,RIPE 创新地将关键点提取任务构建为一个强化学习(RL)问题 。其核心思想是,将网络看作一个“智能体”,它“学习”在一幅图像(状态)中选择最佳的关键点位置(动作),并通过匹配结果(奖励)来优化其选择策略。该方法主要包含以下几个关键部分: (1)基于强化学习的概率性关键点选择: 模型(一个Encoder-Decoder网络)为输入图像生成一个热力图(heatmap)。 热力图被划分为网格单元(grid cells),在每个单元格内,模型会基于logit值概率性地采样一个关键点位置 。 同时,模型会学习一个“接受概率”,用于判断该单元格是否适合提取关键点,从而可以主动放弃天空、过曝等区域 。 这个过程在代码 ripe/models/ripe.py 中的 KeypointSampler 类中实现。 (2)基于多尺度特征的描述符生成 为了让描述符更具辨别力,RIPE不只使用编码器最后一层的特征,而是采用超列(Hyper-column)技术 。 从编码器的多个中间层提取特征,并将这些不同尺度的特征在关键点位置进行插值和拼接,形成一个包含丰富上下文信息的描述符。 这部分在代码 ripe/models/upsampler/hypercolumn_features.py 中实现。 (3)基于几何约束的奖励机制 这是整个强化学习框架的核心。奖励(Reward)直接来源于图像对的匹配结果。 对于一对图像,模型提取的关键点和描述符会先进行相互最近邻匹配(Mutual Nearest Neighbor, MNN) 。 然后,通过 RANSAC 算法结合基本矩阵(Fundamental Matrix)估计来滤除不符合对极几何约束的匹配点 。 最终的奖励信号就是通过几何验证的内点(inliers)数量 。 对于正样本对(同一场景),奖励为正,鼓励网络找到更多可匹配且符合几何一致性的关键点 。对于负样本对(不同场景),奖励为负(惩罚),抑制网络在不同场景间找到错误的匹配 。 这个奖励计算过程虽然不可微,但在强化学习中仅用作一个标量信号,通过 REINFORCE 算法 更新网络权重。 (4)辅助性的描述符损失函数 为了进一步增强描述符的判别能力,RIPE还引入了一个辅助的对比损失函数(Descriptor Loss)。 对于正样本对,它会拉近匹配内点描述符之间的距离,同时推远它们与其他描述符的距离 。 对于负样本对,它会推远所有错误匹配的描述符之间的距离 。 该损失函数的实现在 ripe/losses/contrastive_loss.py 中。 三、具体实现的流程 mgd5yoqf.png图片 (1)网络结构 编码器(Encoder): 使用在 ImageNet 上预训练的 VGG-19 网络 。代码位于ripe/models/backbones/vgg.py。 解码器(Decoder): 借鉴了 DeDoDe 的设计,使用了深度可分离卷积的精炼模块(ConvRefiner)来从编码器特征生成热力图 。代码位于ripe/models/backbones/vgg_utils.py。 整体模型: 将上述模块组合在 ripe/models/ripe.py 的 RIPE 类中。 (2)数据处理与训练流程 (ripe/train.py) 1)数据加载: 训练数据是成对的图像,每对带有一个二元标签(1表示同一场景,-1表示不同场景)。代码中通过DatasetCombinator (ripe/data/datasets/dataset_combinator.py) 可以灵活地组合来自不同数据集(如 MegaDepth、Tokyo 24/7)的数据。 2)前向传播:一对图像 (I, I') 分别输入到 RIPE 网络中,得到各自的热力图、粗描述符等输出 。通过KeypointSampler 概率性地采样关键点位置 kpts1, kpts2 及其对数概率 logprobs1, logprobs2 。使用 HyperColumnFeatures 在采样出的关键点位置提取多尺度描述符 desc1, desc2 。 3)匹配与奖励计算:使用 Kornia 库的DescriptorMatcher 进行MNN匹配,得到初始匹配对 。使用 PoseLib 库进行鲁棒的基本矩阵估计(RANSAC),筛选出内点(inliers)。这部分由 ripe/matcher/concurrent_matcher.py 调度。根据内点数量和样本对的标签(正/负),计算出奖励矩阵 dense_rewards。该逻辑在 ripe/utils/utils.py 的 get_rewards 函数中。 4)损失计算与反向传播: 策略损失(Policy Loss): 将奖励 dense_rewards 与关键点的联合对数概率 dense_logprobs 相乘,这是 REINFORCE 算法的核心。目标是最大化奖励期望 。 描述符损失(Descriptor Loss): 计算辅助的对比损失 loss_desc_stack。 正则化项: 包含一个小的惩罚项 loss_kp_stack,防止网络生成概率过低的关键点 。 最终损失: L = L_policy + L_kp + ψ * L_desc ,其中 ψ 是平衡权重的超参数 。 通过 Fabric(PyTorch Lightning 的一个库)进行反向传播和梯度更新。 四、 最终的效果 RIPE 在多个基准测试中取得了具有竞争力的结果,证明了其弱监督学习框架的有效性。 标准基准测试: MegaDepth-1500(相对位姿估计): 在这个广泛使用的基准上,RIPE 的性能(以AUC@角度误差度量)与当前顶尖的稀疏特征方法 ALIKED 非常接近,并且优于同样基于VGG的DeDoDe 。值得注意的是,RIPE 是唯一一个在不使用位姿/深度或人工单应性变换监督的情况下达到该性能水平的方法 。 HPatches(单应性估计): 在此数据集上,RIPE 的表现同样与 SOTA 方法 SiLK 和 DeDoDe 相当 。 真实世界挑战场景: Aachen Day-Night(昼夜户外定位): 这是 RIPE 方法优势最突出的地方。当仅使用 MegaDepth 数据集训练时,RIPE 的夜间定位性能已明显优于 DeDoDe 。当在训练数据中混入 20% 的 Tokyo 24/7 数据集(一个包含昼夜变化的图像对,但没有位姿信息)后,RIPE 的夜间定位精度获得了大幅提升 。这充分证明了 RIPE 能够有效利用多样化的弱监督数据来增强模型的鲁棒性 。 Boreas(恶劣天气户外定位): 在包含雨、雪、黑夜等恶劣天气条件的 Boreas 数据集上,RIPE 同样展现了其竞争力。通过在训练中加入 ACDC 数据集(一个包含恶劣天气图像的数据集),RIPE 的性能也得到了提升 。 总结来说,RIPE 最大的亮点在于它简化了数据依赖,仅需简单的二元标签就能进行有效训练。这使得模型可以利用更多样、更贴近真实世界的训练数据,从而在光照和天气变化剧烈的挑战性场景中展现出更强的泛化能力和鲁棒性 。尽管其监督信号远弱于其他方法,但最终性能却能与SOTA方法相媲美,标志着关键点提取领域的一个重要进步 。 真实世界实验图片 -
平均调整兰德指数(aARI)完全指南:聚类与视觉模型评估的核心指标 平均调整兰德指数(Average Adjusted Rand Index, aARI)是机器学习中评估聚类模型与真实标签一致性的重要指标。本文详细解析aARI的计算原理、公式推导及其在语义分割和聚类分析中的实际应用。通过对比准确率、IoU和F1-Score等传统指标,阐述aARI在抗类别不平衡和评估聚类结构方面的独特优势。文章还提供aARI的数学模型、使用场景及与其他指标的对比分析,为研究人员和从业者提供了一套完整的模型评估解决方案,帮助提升模型性能评估的准确性和可靠性。 引言 在计算机视觉和机器学习领域,准确评估模型性能是至关重要的。特别是在语义分割任务中,我们不仅需要知道模型预测的准确性,还需要了解它对不同类别的分割效果。今天,要学习一个强大而实用的评估指标——平均调整兰德指数(Average Adjusted Rand Index, aARI)。 关于指标的结果:平均调整兰德指数的数值越大,代表聚类结果与真实标签的相似度越高,也就是说聚类效果越好。 ARI的提出和改进 兰德指数(Rand Index)最初由William M. Rand在1971年提出,用于衡量两个数据聚类结果的相似性。它的基本思想很直观:比较两个聚类方案中每对数据点的分组情况。 兰德指数是一个用来衡量两个数据聚类结果(比如,一个是算法给出的聚类结果,另一个是数据的真实类别标签)相似度的指标。它通过考虑数据点对(pairs of data points)来计算。具体来说,它衡量的是“一致”决策的比例: 真正例 (True Positives, TP):在真实标签中属于同一类,在聚类结果中也被分到同一簇的点对数量。 真负例 (True Negatives, TN):在真实标签中属于不同类,在聚类结果中也被分到不同簇的点对数量。 公式: $$ \begin{array} { r } { R I = \frac { T P + T N } { T P + F P + F N + T N } } \end{array} $$取值范围:0 到 1 之间。1 表示两个聚类结果完全相同,0 表示完全不同。 兰德指数有一个缺点,即当随机进行聚类时,它的期望值不是一个常数(通常不是0)。即使一个聚类结果是完全随机产生的,RI值也可能看起来还不错,这会让人误判聚类效果。调整兰德指数通过引入一个基于随机情况的期望值来修正这个问题,使得完全随机的聚类结果的ARI期望值为0。 改进版本的计算公式: $$ A R I = \frac { R I - E [ R I ] } { \operatorname* { m a x } ( R I ) - E [ R I ] } $$其中,E[RI] 是在随机分配情况下的兰德指数的期望值。 取值范围:-1 到 1 之间。 1:表示聚类结果与真实标签完全一致,是最好的情况。 接近 0:表示聚类结果与随机分配差不多。 负值:表示聚类结果比随机分配还要差。 平均调整兰德指数 (aARI) 这个指标通常出现在需要多次评估或在不同数据集分区上评估聚类算法性能的场景中,例如: 交叉验证 (Cross-Validation):在进行K折交叉验证时,每一折都会产生一个ARI值。将这K个ARI值取平均,就得到了平均调整兰德指数。 多次重复实验:对于一些带有随机性的聚类算法(如K-Means,其初始中心是随机选择的),为了得到一个稳定且可靠的性能度量,通常会多次运行算法,每次计算一个ARI值,最后取其平均值。 因此,平均调整兰德指数(aARI)就是对多次实验或多个数据集子集上计算出的调整兰德指数(ARI)的平均值。它继承了ARI的所有特性。 aARI vs 其他指标 指标优点缺点适用场景准确率(Accuracy)直观易懂受类别不平衡影响严重类别平衡的简单分类IoU/mIoU考虑重叠区域对小目标不够敏感目标检测、语义分割F1-Score平衡精确率和召回率不考虑聚类结构二分类或多分类aARI考虑聚类结构,抗类别不平衡计算相对复杂语义分割、聚类任务聚类任务图片 此部分内容需要付费后才能阅读 您当前未登录,游客身份购买的内容仅在当前浏览器生效 (7天)。 清除Cookie或更换设备后需重新购买。 为获得永久阅读权限, 建议注册账户 后购买。 支付 0.01 元阅读 请使用支付宝扫描二维码支付 金额:0.01 元 二维码2小时内有效,支付成功后页面将自动刷新 if(typeof payit_generate_qr === "undefined") { function payit_generate_qr(id, url, cid, price) { var container = document.getElementById(id); var qrContainer = container.querySelector(".payit-qrcode-container"); var qrCodeDiv = container.querySelector(".payit-qrcode"); var btn = container.querySelector(".payit-button"); btn.disabled = true; btn.innerText = "二维码生成中..."; var xhr = new XMLHttpRequest(); xhr.open("POST", url, true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { try { var res = JSON.parse(xhr.responseText); if(res.code === 0 && res.qr_code) { qrContainer.style.display = "block"; container.querySelector(".payit-mask").style.display = "none"; new QRCode(qrCodeDiv, { text: res.qr_code, width: 150, height: 150 }); payit_check_status(id, "https://www.hubtools.cn/payit/check", res.out_trade_no); } else { alert("二维码生成失败: " + (res.msg || "未知错误")); btn.disabled = false; btn.innerText = "支付 " + price + " 元阅读"; } } catch (e) { alert("从服务器获取数据时出错。"); btn.disabled = false; btn.innerText = "支付 " + price + " 元阅读"; } } else { alert("请求服务器失败。"); btn.disabled = false; btn.innerText = "支付 " + price + " 元阅读"; } } }; xhr.send("cid=" + cid + "&price=" + price); } } if(typeof set_payit_cookie === "undefined") { function set_payit_cookie(name, value, days) { var expires = ""; if (days) { var date = new Date(); date.setTime(date.getTime() + (days*24*60*60*1000)); expires = "; expires=" + date.toUTCString(); } document.cookie = name + "=" + (value || "") + expires + "; path=/"; } } if(typeof payit_check_status === "undefined") { function payit_check_status(id, url, order_id) { var interval = setInterval(function() { var xhr = new XMLHttpRequest(); xhr.open("POST", url, true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { try { var res = JSON.parse(xhr.responseText); if (res.code === 0) { clearInterval(interval); // 如果是游客,前端设置cookie if (res.token) { var cookieName = "payit_cid_" + res.cid; set_payit_cookie(cookieName, res.token, res.expire); } document.getElementById(id).innerHTML = "支付成功,正在刷新页面..."; setTimeout(function() { location.reload(); }, 200); } } catch (e) { /* 支付未成功,不处理 */ } } }; xhr.send("out_trade_no=" + order_id); }, 3000); } } .payit-wrapper { border: 2px dashed #e67e22; background-color: #fdf5ee; padding: 20px; text-align: center; margin: 20px 0; border-radius: 8px; } .payit-wrapper .payit-guest-notice { font-size: 13px; color: #555; background-color: rgba(0,0,0,0.03); border: 1px solid rgba(0,0,0,0.05); padding: 10px; margin: 15px auto; border-radius: 5px; max-width: 95%; line-height: 1.6; } .payit-wrapper .payit-guest-notice p { margin: 5px 0; } .payit-wrapper .payit-guest-notice a { color: #e67e22; font-weight: bold; text-decoration: none; } .payit-wrapper .payit-guest-notice a:hover { text-decoration: underline; } .payit-mask .payit-notice { font-size: 18px; color: #e67e22; font-weight: bold; margin-bottom: 15px; display: flex; align-items: center; justify-content: center; } .payit-mask .payit-button { background-color: #e67e22; color: #ffffff; border: none; padding: 12px 25px; font-size: 16px; cursor: pointer; border-radius: 5px; transition: opacity 0.2s; } .payit-mask .payit-button:hover { opacity: 0.9; } .payit-mask .payit-button:disabled { opacity: 0.6; cursor: not-allowed; } .payit-qrcode-container { color: #333; } .payit-qrcode-container p { margin: 10px 0; } .payit-qrcode { width: 150px; height: 150px; margin: 10px auto; padding: 5px; background: white; border: 1px solid #ddd; border-radius: 3px;} -
强化学习小白入门笔记3:深入理解时序差分学习的原理和应用Temporal Difference Learning 时序差分学习(Temporal Difference Learning,简称TD学习)是强化学习中最重要的概念之一,也是现代强化学习算法的核心基础。如果说强化学习是一栋大厦,那么TD学习就是这栋大厦的地基。本文主要是面向初学者,深入理解这个看似复杂但实际上非常直观的学习方法。 学习的本质是什么? 在开始之前,让我们思考一个问题:人类是如何学习的? 想象你第一次学开车。你不会等到考完驾照才开始总结经验,而是在每次练车过程中不断调整: 刚开始转弯时总是转得太急,几次练习后学会了提前减速 停车时总是停不准,通过观察后视镜的反馈不断改进 每次小的改进都基于当时的反馈,而不是等到所有练习结束 这就是TD学习的核心思想:用当前的经验来改进我们的预测,而不是等到所有事情结束。 TD学习的核心思想 时序差分这个名字听起来很学术,但概念其实很简单: 时序:涉及时间序列,我们在不同时刻有不同的预测 差分:比较不同时刻预测之间的差异 TD学习的核心就是:用"更准确的后续预测"来改进"当前的预测"。简单来说就是“有事及时处理”。 生活化的类比:天气预报学习 假设你想学会预测天气,但你不是气象专家,只能通过观察来学习。 传统方法(等到月底再学习): 月初预测:这个月平均气温25度 等到月底:实际平均气温27度 月底学习:调整下个月的预测策略 TD方法(每天都学习): 1号预测:这个月平均25度,明天26度 2号实际:昨天确实26度,今天预测这个月平均25.1度,明天27度 发现:昨天预测月平均25度,但今天的新信息(实际26度+预测明天27度)暗示月平均可能更高 立即调整:把对这个月平均气温的预测从25度调到25.1度 关键洞察:我们不需要等到月底,每天的新信息都能帮助我们改进长期预测! 天气预报图片 TD学习的数学原理 TD学习的核心公式看起来是这样的: V(s) ← V(s) + α × [r + γ × V(s') - V(s)]各部分含义: V(s):我们对状态s的价值估计 α:学习率(0-1之间,比如0.1) r:在状态s执行动作后获得的即时奖励 γ:折扣因子(0-1之间,比如0.9) V(s'):我们对下一状态s'的价值估计 核心思想:新估计 = 旧估计 + 学习率 × (更好的估计 - 旧估计) 公式中的 [r + γ × V(s') - V(s)] 被称为TD误差(TD Error),这是TD学习的核心: r + γ × V(s') :基于当前经验的"更好估计" r:我们实际获得的奖励 γ × V(s'):未来价值的折扣估计 V(s):我们之前的估计 TD误差:两者的差值,告诉我们估计的准确程度 TD误差的含义: 如果TD误差 > 0:我们低估了当前状态的价值,应该调高 如果TD误差 < 0:我们高估了当前状态的价值,应该调低 如果TD误差 = 0:我们的估计刚好准确 机器人学习走迷宫 问题设置 想象一个简单的3×3迷宫: [S][ ][G] [ ][#][ ] [ ][ ][ ]S:起始位置 G:目标位置(奖励+10) \#:障碍物 空格:可以通行(每步奖励-1) 学习目标:学会评估每个位置的价值(从该位置到达目标的期望累计奖励) 初始状态 刚开始时,机器人对所有位置的价值估计都是0: 价值估计表: V(S) = 0, V(G) = 10, V(其他位置) = 0 学习率 α = 0.1 折扣因子 γ = 0.9第一次探索过程 步骤1:从S向右移动 当前状态:S,价值估计V(S) = 0 执行动作:向右 获得奖励:r = -1(移动成本) 到达新状态:中间位置,价值估计V(中间) = 0 TD更新: TD误差 = r + γ × V(中间) - V(S) = -1 + 0.9 × 0 - 0 = -1 更新V(S) = V(S) + α × TD误差 = 0 + 0.1 × (-1) = -0.1步骤2:从中间向右移动到目标 当前状态:中间,价值估计V(中间) = 0 执行动作:向右 获得奖励:r = 10(到达目标) 到达新状态:目标G,价值估计V(G) = 10 TD更新: TD误差 = r + γ × V(G) - V(中间) = 10 + 0.9 × 10 - 0 = 19 更新V(中间) = V(中间) + α × TD误差 = 0 + 0.1 × 19 = 1.9第二次探索过程 现在价值估计表变成了: V(S) = -0.1, V(中间) = 1.9, V(G) = 10再次从S向右移动: TD误差 = r + γ × V(中间) - V(S) = -1 + 0.9 × 1.9 - (-0.1) = -1 + 1.71 + 0.1 = 0.81 更新V(S) = -0.1 + 0.1 × 0.81 = -0.019学习过程的直观理解 通过这个例子,我们可以看到: 即时学习:每走一步都更新价值估计,不用等到到达终点 信息传播:目标的高价值(+10)逐渐"传播"到前面的状态 渐进改进:每次更新都让估计更准确一点点 最终收敛:经过足够多的探索,所有状态的价值估计会趋于真实值 TD学习的优势与局限 主要优势 模型无关:不需要知道环境的转移概率和奖励函数 在线学习:可以在与环境交互过程中实时学习 内存高效:不需要存储完整的轨迹历史 快速响应:能够快速适应环境的变化 理论保证:在一定条件下保证收敛到最优解 主要局限 探索问题:如何平衡探索未知状态和利用已知信息 函数近似:在大状态空间中需要函数近似,可能不稳定 参数调整:学习率、折扣因子等参数需要仔细调整 收敛速度:虽然每步都学习,但总体收敛可能较慢
-
强化学习小白入门笔记1:必须要理解的核心概念 本文系统介绍了强化学习的核心基础概念,包括智能体(Agent)、环境(Environment)、状态(State)、动作(Action)、奖励(Reward)等关键术语。通过生活化的找路例子,详细解释了强化学习的工作原理及其在人工智能领域的应用价值。文章还阐述了状态转移、策略、回报、价值函数等进阶概念,为工科研究生和初学者提供了全面的强化学习入门指南,为后续学习Q-learning、Policy Gradient等算法奠定坚实基础。 什么是强化学习? 在开始介绍具体概念之前,让我们先用一个生活化的例子来理解强化学习的本质。 想象一下你刚刚搬到一个新城市,需要找到从家到实验室的最佳路线。一开始你对这个城市一无所知,只能凭直觉选择方向。走错路时你会感到沮丧(负奖励),找到捷径时你会感到高兴(正奖励)。经过多次尝试后,你逐渐学会了如何在不同的交通状况下选择最优路线。这个过程就是强化学习的核心思想:通过与环境互动,根据得到的反馈来改进决策策略。 核心概念详解 (1) Agent(智能体)和Environment(环境) Agent(智能体)是强化学习中的"学习者"和"决策者"。在上面的例子中,你就是Agent。在实际应用中,Agent可以是机器人、游戏AI、推荐系统等任何需要做出决策的系统。 Environment(环境)则是Agent所处的外部世界,包含了Agent需要应对的所有外部因素。继续用找路的例子,城市的道路网络、交通信号灯、其他车辆和行人构成了你的环境。 这两者的关系是互动的:Agent观察环境,在环境中采取行动,环境则给予Agent反馈。 (2) State(状态) State(状态)是对环境当前情况的完整描述。它包含了Agent做出决策所需的所有相关信息。 在找路例子中,状态可能包括:当前位置、目的地、时间、天气、交通拥堵情况等。在下棋游戏中,状态就是当前的棋盘布局。在机器人控制中,状态可能包括机器人的位置、速度、传感器读数等。 需要注意的是,状态应该具有马尔可夫性质,即"未来只依赖于现在,而不依赖于过去"。简单来说,只要知道当前状态,就能对未来做出最好的决策,不需要知道是如何到达当前状态的。 (3) Action(动作) Action(动作)是Agent在给定状态下可以执行的所有可能操作。 在找路例子中,你的动作可能是"直行"、"左转"、"右转"、"掉头"等。在下棋中,动作就是在棋盘上的合法落子位置。在机器人控制中,动作可能是各种运动指令。 动作可以是离散的(如选择特定的路径),也可以是连续的(如设置具体的速度值)。 (4) Reward(奖励) Reward(奖励)是环境对Agent动作的即时反馈,用一个数值来表示动作的好坏。 这是强化学习中最关键的概念之一,因为Agent的目标就是最大化累积奖励。在找路例子中,快速到达目的地可能得到正奖励,走错路或遇到堵车得到负奖励。在游戏中,获胜得到正奖励,失败得到负奖励。 奖励的设计需要非常小心,因为Agent会严格按照奖励信号来优化自己的行为。如果奖励设计不当,可能会导致Agent学会"钻空子"而不是解决真正的问题。 (5) State Transition(状态转移) State Transition(状态转移)描述了环境如何从一个状态变化到另一个状态。当Agent在状态s下执行动作a时,环境会转移到新状态s',这个过程可能是确定的,也可能是随机的。 在找路例子中,如果你在十字路口选择左转,确定性的状态转移会让你到达左边的街道。但如果考虑到突发的交通事故或道路施工,状态转移就可能带有随机性。 (6) Policy(策略) Policy(策略)是Agent的"行动指南",它定义了在每个状态下应该采取什么动作。策略通常用π来表示。 策略可以是确定性的(在给定状态下总是执行同一个动作)或随机性的(根据概率分布选择动作)。在找路例子中,你的策略可能是"在工作日早高峰时避开主干道,选择小路"。 (7) Return(回报) Return(回报)是从某个时刻开始的累积奖励。与即时奖励不同,回报考虑的是长期收益。 假设Agent在时刻t得到奖励序列:r_{t+1}, r_{t+2}, r_{t+3}, ...,那么从时刻t开始的回报通常定义为: G_t = r_{t+1} + γr_{t+2} + γ²r_{t+3} + ... 其中γ(gamma)是折扣因子(0 ≤ γ ≤ 1),用来平衡即时奖励和未来奖励的重要性。 γ越接近1,Agent越重视未来奖励;γ越接近0,Agent越重视即时奖励。 (8) Value Function(价值函数) 价值函数评估状态或动作的"好坏程度",是强化学习中的核心概念。 State-value Function(状态价值函数)V^π(s)表示在状态s下,遵循策略π能够获得的期望回报。简单来说,它回答了"在这个状态下,按照当前策略行动,我能期望获得多少总奖励?" 在找路例子中,如果某个路口的状态价值很高,说明从这个路口出发,按照你当前的策略,很可能快速到达目的地。 (9) Action-value Function(动作价值函数) Action-value Function(动作价值函数)Q^π(s,a)表示在状态s下执行动作a,然后遵循策略π的期望回报。它回答了"在当前状态下,如果我执行这个特定动作,然后按照策略继续行动,我能期望获得多少总奖励?" Q函数比V函数提供了更细粒度的信息,因为它不仅告诉你状态的价值,还告诉你在该状态下不同动作的价值。 (10) Optimal Action-value Function(最优动作价值函数) Optimal Action-value Function(最优动作价值函数), Q*(s,a)表示在状态s下执行动作a,然后遵循最优策略的期望回报。这是在给定状态和动作下能够获得的最大可能回报。 强化学习的另一个主要目标就是学习到最优Q函数Q,因为一旦有了Q,就可以通过选择使Q*(s,a)最大的动作a来获得最优策略。 迭代优化图片 概念的关系 Environment ←→ Agent ↓ ↓ State → Action ↓ ↓ Reward ← Policy ↓ Return ↓ Value FunctionsAgent观察Environment的State,根据Policy选择Action,Environment给出Reward并转移到新State。通过积累Reward形成Return,进而计算Value Functions来评估Policy的好坏,最终优化Policy。 训练是学什么? 强化学习的核心目标是: 学习最优策略π*:知道在每个状态下应该采取什么动作 学习最优Q函数Q*:知道在每个状态下,每个动作的真实价值 这两个目标是相互关联的。如果我们有了最优Q函数,就可以通过贪婪策略(即选择Q值最大的动作)得到最优策略。反之,如果我们有了最优策略,也可以通过该策略评估出最优Q函数。 小结 强化学习是一个让智能体通过与环境互动来学习最优决策策略的框架。理解这些核心概念是深入学习强化学习算法的基础: Agent和Environment构成了学习的基本框架 State、Action、Reward是互动的基本要素 Policy是我们要学习的决策规则 Value Functions帮助我们评估决策的好坏 Return连接了即时奖励和长期目标 在后续的学习中,你会发现所有的强化学习算法,无论是Q-learning、Policy Gradient还是Actor-Critic,都是围绕着如何更好地学习π*或Q*而设计的。掌握了这些基础概念,你就为进一步学习具体算法打下了坚实的基础。 -
Qt出现No suitable kits found解决方案,qmake可行但是CMake没有可用的kits 本文详细解决Qt Creator新建项目时提示“No suitable kits found”的问题,尤其针对CMake项目报错而qmake项目正常的情况。核心原因是Qt未正确安装或配置CMake。解决方案分三步:(1)通过临时切换qmake构建系统验证问题;(2)使用 Qt Maintenance Tool 安装缺失的CMake组件(勾选Build Tools > CMake);(3)在Qt Creator中自动检测或手动配置CMake路径(选项 > Kits > CMake)。文中对比了qmake与CMake的适用场景,建议新手用qmake快速开发,长期项目学习CMake。适用于Qt 6及以上版本。 状况描述 新建项目提示: No suitable kits found.Add a kit in the gptions or via the maintenance tool of the SDK 取消Hide unsuitable kits的时候,下面出现了很多的Kits,例如Desktop Qt 6.9.1 llvm-mingw 64-bit、安卓 Qt 6.9.1 Clang x86_64等等 状况描述图片 问题排查 在 选项 > Kits 界面,先选择 编译器(Compilers) 标签页,看一下详细页: CMake未配置图片 从Qt 6开始,新建项目的默认构建系统是CMake。如果Qt Creator没有找到或正确配置CMake程序本身,那么它会认为所有Kit都无法用于创建一个基于CMake的项目,因此会报告“No suitable kits found”。 没有有效的CMake图片 创建项目时手动选择qmake,是一个有效的诊断方法,同时也是一个备用方案。如果问题确实出在CMake上,那么切换到Qt传统的构建系统qmake应该就能成功。如果此时发现之前灰色的Kit(如MinGW和MSVC)现在可以正常选择了,那就100%可以确定是您的CMake配置出了问题。可以继续使用qmake完成项目创建,或者返回解决方案一去修复CMake的配置。 问题修复 找到Qt Maintenance Tool: Qt Maintenance Tool图片 一定要勾选Build Tools里的CMake。然后进行安装即可。 CMake安装图片 然后回到Qt中看看有没有。 执行自动检测(首选方法) 在窗口右侧,您应该能看到一些按钮。请点击 自动检测 (Auto-detect)。 这个功能会自动扫描常用路径,找到这个自带的CMake并将其添加到列表中。 如果成功,列表中会立刻出现一个新条目,包含了CMake的名称和可执行文件路径。 如果“自动检测”没有找到任何东西,您需要手动添加它: 点击 Add... (或 手动设置) 按钮。 会弹出一个文件选择对话框,要求您找到 cmake.exe 文件。 它最可能位于您的Qt安装目录中。请浏览到类似下面的路径: D:\Qt\Tools\CMake_64\bin\cmake.exe 检测到cmake图片 至此,问题解决。 不想安装CMake只用qmake? 完全可以直接使用 qmake 来代替 cmake 进行Qt开发,尤其是对于初学者和中小型项目来说。它们都是构建系统生成器 (Build System Generator)。作用是读取您的项目配置文件,然后为您的操作系统和编译器生成相应的构建指令(例如,在Windows上生成Visual Studio的 .sln 文件或MinGW的 Makefile)。 特性qmakeCMake易用性⭐⭐⭐⭐⭐ (非常简单)⭐⭐ (较复杂)功能/灵活性⭐⭐⭐ (够用)⭐⭐⭐⭐⭐ (非常强大)对Qt的支持⭐⭐⭐⭐⭐ (原生支持)⭐⭐⭐⭐ (官方重点支持)第三方库集成⭐⭐ (比较麻烦)⭐⭐⭐⭐⭐ (非常方便)未来趋势维护状态官方推荐,行业主流当前建议直接使用,立刻开始!有空再配置,作为长期技能学习Qmake是Qt的“亲儿子”,是Qt官方创造并长期使用的构建系统。主要服务于Qt项目。如果您想在一个项目里集成大量非Qt的第三方库,qmake 的配置会变得比较复杂和笨拙。Qt官方已经宣布,未来的开发重心将转向CMake,qmake 目前处于维护状态,不再添加新功能。 CMake是一个独立于Qt的、开源的、跨平台的构建系统。被广泛应用于C++社区的各种项目,例如LLVM、OpenCV、KDE等。