分层强化学习 综述论文阅读 Hierarchical Reinforcement Learning: A Comprehensive Survey

news/2024/5/19 1:12:18 标签: 论文阅读, 强化学习

分层强化学习 综述论文阅读 Hierarchical Reinforcement Learning: A Comprehensive Survey

  • 摘要
  • 一、介绍
  • 二、基础知识回顾
    • 2.1 强化学习
    • 2.2 分层强化学习
      • 2.2.1 子任务符号
      • 2.2.2 基于半马尔可夫决策过程的HRL符号
    • 2.3 通用项定义
  • 三、分层强化学习方法
    • 3.1 学习分层策略 (LHP)
      • 3.1.1 封建分层方法 (基于goal)
      • 3.1.2 策略树方法(基于option)
    • 3.2 同时子任务发现+分层策略学习
      • 3.2.1 统一策略树方法
      • 3.2.2 封建方法的统一学习
    • 3.3 独立子任务发现
      • 3.3.1 子目标发现
      • 3.3.2 不同技能发现
    • 3.4 迁移分层强化学习
      • 3.4.1 迁移+子任务策略蒸馏
      • 3.4.2 迁移+智能体空间子任务
    • 3.6 方法调查主要收获
  • 4. 未来研究的开放问题

摘要

分层强化学习可以通过将困难的长期决策任务分解为更简单的子任务,提升强化学习算法的性能。

分层强化学习方法主要涉及:使用HRL学习分层策略、子任务发现、迁移学习和多智能体学习四个主要挑战。

一、介绍

  1. 强化学习算法的一个痛点:如果任务的长度很长,状态空间和动作空间很大,由于难以探索,强化学习算法很难获得好的效果。
  2. 分层强化学习的优点:分层强化学习将整个任务分成多个子任务。子任务本身更容易学习,所学习的子任务会导致更结构化的探索。
  3. 分层强化学习效果好的原因:HRL在长期任务中效果优于标准RL,其优势在于改进了探索。
  4. 分层强化学习的主要挑战:在固定好的子任务中学习策略、自主发现子任务、迁移学习和使用HRL的多智能体学习。
  5. 这篇文章额外考虑方面:学习策略层次的技术、使用变分推理的子任务的发现、统一HRL、使用HRL的迁移学习、多智能体HRL等。
  6. 贡献:
    (1)进行分层强化学习分类:策略的学习层次结构、独立子任务发现、统一HRL、带HRL的多任务/迁移学习以及多智能体HRL的方法。
    (2)分类角度:单智能体与多智能体、单任务与多任务,以及无子任务发现与有子任务发现。
    (3)确定了重要的开放问题,为HRL的可扩展性、效率和理论稳健性的研究提供了方向。

二、基础知识回顾

2.1 强化学习

2.2 分层强化学习

  1. 当状态和行动空间较大,任务范围较长时,使用标准RL方法进行探索会变得具有挑战性。
  2. 高级别策略选择主任务的子任务,该策略根据子任务顺序执行主任务,使用在主任务中获得的奖励。在低级别中,较高级别选择的子任务本身是一个强化学习问题。较低级别的策略学习使用与其相关的内部奖励执行该子任务。
  3. 一个三个等级的分层强化学习的例子:
    在这里插入图片描述

2.2.1 子任务符号

π ω \pi_{\omega} πω:子任务的策略
r ω r_{\omega} rω:子任务的奖励
g ω g_{\omega} gω:子任务的目标
I ω I_{\omega} Iω:子任务的开始条件
β ω \beta_{\omega} βω:子任务的结束条件

2.2.2 基于半马尔可夫决策过程的HRL符号

HRL的一般问题定义是找到最优分层策略π层次结构和最优子任务空间Ω层次结构作为问题的解,即找到能使累计奖励最大的分层方法和决策策略。

半马尔可夫决策过程(SMDP)与MDP的区别在于多了时间概念。SMDP的转移方程为:
在这里插入图片描述
其中c是子任务的步长。
每个子任务的奖励为:
在这里插入图片描述
其中r是每一步的奖励。
每个子任务的状态动作价值函数为:
在这里插入图片描述
每个上层决策的状态动作价值函数为:
在这里插入图片描述
一个三层的HRL示例为:

在这里插入图片描述

2.3 通用项定义

  1. 技能:为执行子任务而学习的基本动作策略。
  2. 通用策略:通过将相应的子目标或指令作为输入,可以学习所有可能的子任务的策略。
  3. 状态。
  4. 奖励:主要任务的一部分给予的奖励对子任务策略是隐藏的,并且只由最高级别的策略接收。

三、分层强化学习方法

从三个角度考虑:

  1. 有子任务发现或没有子任务发现的方法。
  2. 训练单个或多个代理的方法。
  3. 单任务或多任务学习方法。
    这些方法进一步分为五大类——LHP、UNI、ISD、MAHRL和TransferHRL。

具体分类:

  1. 单智能体,单任务,没有子任务发现。学习分层策略(LHP)。LHP方法解决了使用手工制作的子任务下学习HRL代理的分层策略π层次结构的挑战。
  2. 单智能体,单任务,没有子任务发现。学习分层策略(LHP)。LHP方法解决了使用手工制作的子任务下学习HRL代理的分层策略π层次结构的挑战。
  3. 单智能体、单任务和有子任务发现。可以分为两类,第一类称为学习分层策略与子任务发现的统一(UNI),通过端到端的方式一边学习层级一边学习策略。第二类称为独立子任务发现(ISD),分层方法和策略学习是分开进行的。
  4. 多智能体、单任务和有子任务发现方法。
  5. 单个代理,多个任务,无子任务发现。
  6. 单个代理,多个任务,有子任务发现。学习在多个任务之间转移HRL代理的分层策略、子任务或其他知识的挑战,其中子任务可以是手工制作的或在多个工作上从头开始发现的。

3.1 学习分层策略 (LHP)

  1. LHP在没有子任务发现下学习策略,难点在于:设计算法来学习分层中各个级别的策略(包括奖励传播、价值函数分解、状态/行动空间设计等),处理由于同时改变策略而导致的非平稳性,确保分级策略作为一个整体的最优性、分级策略的可解释性等问题。
  2. LHP方法大致可以分为两个子类。
  3. 第一个类为封建等级制度,其中更高级别政策的行动空间由与各种子任务相对应的子目标组成。上级策略选择子目标,子目标作为下级策略的输入来进行下级决策。因此是管理者来管理工人的封建概念。
  4. 第二类为策略树。在策略树中,较高级别策略的操作空间由子任务的不同较低级别策略组成,而不是子任务。上级策略和下级策略形成一个“树”高级策略直接选择较低级别的策略来执行,而不需要中间子目标。
  5. 方法一览:
    在这里插入图片描述

3.1.1 封建分层方法 (基于goal)

  1. 概念:管理器选择子任务的目标,工人进行决策达到子任务的目标,其中子目标只是原始或抽象状态空间中的一个状态。工人的目标是达到给定的子目标。**任务奖励只能由最高级别的经理观察,而其他级别的员工则可以学习使用达到子目标的奖励。**在网格世界环境中的迷宫导航任务中评估Feudal RL。封建RL比标准Q学习更快地收敛到迷宫中的主目标状态的更短路径。
  2. [51] 提出h-DQN的方法来解决蒙特祖马的复仇中的稀疏奖励的问题。它的上层控制器决定一个目标值g,上层观测是全局观测,上层奖励是游戏奖励。它的下层控制器控制智能体到达g,下层观测是全局观测+g,奖励是到达g则为1否则为0。
  3. 但同时学习多个级别的政策会导致非平稳性问题。因为较低级别的策略不是固定的,它对(状态,子目标)对的响应在学习过程中会发生变化。
  4. 为解决这个问题,[69]提出HIRO,通过策略修正来解决非平稳问题,并使用状态空间而不是表征空间作为子目标。其中,上层决策决策的目标g是未来c步做出的变化,即c步后的状态 s t + c = s t + g s_{t+c}=s_{t}+g st+c=st+g。针对下层策略更新后不匹配上层策略的问题,这里对每个动作对应的g进行修改,使用修正的目标转移函数h来生成新的g进行训练。
  5. [51] 提出HAC,不平稳问题原因为:(1) 智能体在H个时间步到达的状态取决于下一层策略,上层在不同阶段提出相同的子目标,最终可能到达不同的状态,导致只有最底层的策略是稳定的。(2)每当底层策略使用探索型的策略去完成子目标的时候,上层的状态转移和奖励可能会发生变化。方法:(1) 将事后实现的子目标状态作为上层中的动作,而不是最初提出的子目标状态。(2) 将最后一步的奖励作为底层奖励,防止稀疏。(3) 子目标测试,如果子目标无法达到则给一个惩罚。
  6. [41] 提出了一种称为语言层次抽象(HAL)的方法,通过使用自然语言指令而不是子目标状态来实现。

3.1.2 策略树方法(基于option)

  1. [93] 提出Option框架,不同于使用goal,这里使用Option作为子任务进行上层决策。子任务 ω \omega ω定义为元组 ( < I ω , π ω , β ω > ) (<I_{\omega}, \pi_{\omega}, \beta_{\omega}>) (<Iω,πω,βω>)。其中I为起始状态, π \pi π为策略, β \beta β为终止条件。(有理论证明)
  2. MAXQ方法对任务进行值函数分解,分解为多个子任务,每个子任务对应一个MDP。将目标马尔可夫决策过程(MDP)反组合为较小MDP的层次结构,并将目标MDP的值函数反组合为较小MDP值函数的加性组合(有理论证明)
  3. [73]提出HAM,将MDP问题使用先验知识建立一个状态转换机。这个状态转换机分为四种状态:行为状态:执行action;调用状态:调用其它的状态机;选择状态:则选择下一个状态和停止状态:中止当前的状态机,然后返回到之前的调用状态。问题是设计起来过于复杂,需要对任务本身有足够多的理解。

3.2 同时子任务发现+分层策略学习

为了使HRL智能体能够部署在特定任务上,而不需要预定义或手工制作的子任务,需将子任务发现与子任务的策略同时统一学习。存在问题:发现保持分层策略最优性的子任务空间,从头开始在发现过程中学习子任务的各个组成部分(终止条件、启动条件、子目标等),发现动态数量的子任务,以及其他问题。

3.2.1 统一策略树方法

  1. 基于Option的子任务 ω \omega ω核心为 I ω , π ω I_{\omega}, \pi_{\omega} Iω,πω β ω \beta_{\omega} βω,统一Option发现主要涉及学习与每个选项 ω \omega ω 相关的 π ω \pi_{\omega} πω β ω \beta_{\omega} βω,同时学习上层任务策略。
  2. [17] 提出一种图形模型。其中有三个参数 θ O \theta_{O} θO决定选择哪个option, θ A \theta_{A} θA决定当前option的策略, θ B \theta_{B} θB决定当前option是否终止。使用EM算法来更新参数。
  3. [50] 提出一种技能链的方法,通过从任务目标开始向前推出可以成功的Option,创造技能树。这里的Option的初始条件是当前Option是否可以到达goal,决策由RL进行,结束目标为下一子任务的初始集合。
  4. 以上方法中,智能体不能在学习的初始阶段使用子任务,因为必须首先收集经验轨迹,以用于发现初始选项集。
  5. [3] 提出Option Critic的方法,通过参数化学习Option的数量、中止函数和两层的策略。OC不使用子目标或特定于选项的奖励,使用策略梯度进行学习,并且理论上保证使用策略梯度来学习最优分层策略。同时有理论证明是最优分层策略。
  6. OC框架使用值方法进行优化,但没有验证基于策略的方法,同时大多数需要使用特定的强化学习方法进行。[55] 提出DAC的方法,使用同一个critic和两个actor-critic分别处理上下层决策的框架。但与OC类似,DAC要求预定义选项的数量。
  7. 当每个选项在长时间的训练后终止的概率变得非常高时,OC和DAC会遇到更高级别的政策退化现象。更高级别的策略几乎在每个时间步长都从一个选项切换到另一个选项,并且所学习的选项不会专门针对任何可识别的行为。
  8. [36]提出IOC,学习时间扩展选项时引入选项成本正则化因子,即在更换option时施加一个惩罚。该方法使用政策梯度来学习每个option的启动条件,从而使各种选项能够专门针对不同的行为,从而防止退化。

3.2.2 封建方法的统一学习

  1. [99]提出了一种封建的神经网络层次结构,其中一个称为“管理者”的更高级别网络在学习的潜在子目标空间中对子目标进行采样。子目标可以是潜在空间中的点,也可以是表示潜在空间中方向的单位向量。
  2. 封建网络不能保证所学习的子目标空间导致最优的分层,[70]在HIRO[69]的基础上开发的子目标表示学习方法中解决了这个问题。基于分层策略的次最优的理论界限推导出了优化目标。该目标用于学习将状态空间转换为低维子目标空间的函数。学习的子目标空间表示最小化了次最优,并且基于HIRO的分层策略解决了非平稳性问题。

在这里插入图片描述

在这里插入图片描述

3.3 独立子任务发现

  1. 通过预训练来发现子任务,主要问题有:确保子任务发现过程是数据高效的,发现独立于任何特定任务和对状态空间进行不同探索的子任务,学习连续子任务空间,通过对目标任务上的新子任务进行采样来进行泛化。
  2. 独立子任务发现的一部分方法也可以用作统一学习方法。

3.3.1 子目标发现

基于离散状态的频率统计:

  1. [64] 使用初始策略探索状态空间,并收集从各种初始状态到各种终端状态的轨迹,每个轨迹根据是否到达目标被分为正或负。使用多样密度(DD)度量来估计在正轨迹上发生状态的概率与在负轨迹上发生的概率。选择DD较高的状态作为瓶颈子目标。

  2. [84] 提出了一种基于频率的瓶颈发现方法,该方法可能更具数据效率,因为他们根据成功和不成功的经验构建了部分状态-动作转换图。在这个图中,每个节点是一个状态,每个边是一个动作。该图可以通过简单地跟踪各个节点之间的连接来模拟新的轨迹。

  3. 频率统计需要生成大量轨迹来估计各种状态的发生频率。一种更有效的方法是简单地构造一次状态-动作转换图,其中每个节点是一个状态,每个边是一个动作,然后通过分析不同子图之间的连通性来找到瓶颈。

  4. [66] 提出Q-cut建立全局环境的状态转移图,使用最大流或最小切方法找到瓶颈。每个瓶颈都被视为子任务的子目标,并学习子任务的策略来达到它。由于需要构建全局图,Q-cut不容易扩展到大的和/或连续的状态空间,这需要不同的探索。

  5. [85]提出了一种类似的图割方法来寻找瓶颈,但他们使用局部子图,而不是在整个状态空间上构建的全局图。L-cut可以增量地发现局部瓶颈,并且可以应用于大型状态空间,因为代理不需要构建全局图。然而,它不能容易地缩放到连续状态空间,因为算法使用的图需要离散状态作为节点。

  6. 子目标不一定仅仅在信息瓶颈上:[60]提出了一种寻找分布在状态空间不同区域而不仅仅是瓶颈处的子目标的方法。该方法使用原值函数(Proto Value Functions PVF),子目标位于状态空间上定义的不同PVF的局部最大值处。PVF是从状态转移图的拉普拉斯矩阵8的本征分解导出的。

  7. [5]提出了直接在状态空间中进行无监督聚类,以发现不同区域上的子目标。代理使用在线自适应资源分配矢量量化(ARA-VQ)算法探索状态空间并形成状态集群[57]。各种聚类的中心被用作子目标。探索和集群过程不依赖于任何特定的任务,因此子目标发现是任务不可知或独立的。作者还提供了一种使用已经发现的子目标学习分层策略的算法。在该算法中,子目标构成了使用任务奖励学习的更高级别策略的行动空间。较低级别由多个策略组成,其中每个策略可以专门化以达到子目标空间的一个子集,并使用子目标成就的奖励进行学习。学习映射函数,将子目标分配给适当的较低级别策略。还有一项关于亚目标重新标记的规定,类似于HIRO或HaC,用于处理非平稳性。完整的方法称为子目标到子策略的分层分配学习(HASLE)。

  8. 以上方法局限于离散方法,[88]提出了一种称为分层自玩(HSP)的方法,以使用不对称自玩学习子目标的连续嵌入。使用两个策略,其中一个策略的结果为另一个策略的子目标。

3.3.2 不同技能发现

  1. 子目标发现方法不适合在没有明确子目标的情况下找到子任务。比如在交通中,它是到达目的地的长期任务的一部分,子目标不太适合。因此,需要能够直接发现一组不同技能的通用方法,而不是通过子目标来学习这些技能,它代表了做好某件事的能力。
  2. 发现不同技能的一种策略是最大化技能ω与使用该技能达到的状态或产生的轨迹之间的相互信息。这是通过使用潜在技能向量zω,并将技能策略定义为πω(s)=π(s,zω)来实现的。zω通常是一个onehot向量。最大化zω和通过遵循π(s,zω)所达到的状态或产生的轨迹之间的MI,会发现一组与不同终端状态或轨迹相关的不同技能。以下方法都是此思路。
  3. [25]提出了SSN4HRL方法,其中通用策略π(s,zω)使用随机神经网络表示。通过最大化MI奖励P(zω|(x,y))来学习的,(x,y)是代理在空间环境中的位置,P(zΩ|(x,y))是通过观察(x,y)预测zω的概率。只有当通过执行不同技能到达的位置足够不同时,这种概率才能最大化。
  4. [31]提出变分本质控制(VIC),通过最大化目标来发现技能,该目标包含技能向量zω和策略π(s,zω)达到的终端状态sT之间的MI项p(zω|s0, sT),条件是起始状态s0。
  5. [24]提出Diversity Is All You Need(DIAYN)的方法,该方法通过优化目标函数来发现技能,该目标函数旨在最大化技能向量zω和π(s,zω)生成的轨迹中的每个状态之间的MI,而不考虑轨迹中状态的顺序。
  6. 以上方法局限性为:只能发现预定义数量的技能,并且它们的MI目标要么忽略轨迹,要么不考虑轨迹中的状态顺序。
  7. 为解决以上问题,[1] 提出强化选项的变分自动编码学习(VALOR)。将zω编码为轨迹的编码器,轨迹表示为τ。它被送到解码器,解码器将它映射回zω,实现一个旨在最大化P(zω|τ)的优化目标。因此,V ALOR发现了一组不同的技能,这些技能本质上与轨迹的多样性相关。
  8. 以上方法只能发现一组离散的技能。因为为了估计MI,计算技能的连续空间上的概率分布是复杂的。然而,发现技能的连续空间对于泛化很重要,这样新技能就可以很容易地在这样的连续空间中插值。
  9. [77]提出了一种称为自洽轨迹自动编码器(SeCTAR)方法,LSTM将状态轨迹{st,st+1,…}编码为低维隐空间向量。潜在向量表示相似的轨迹,因此,从潜在向量解码的策略被认为表示一种技能。通过使用产生不同轨迹的探索机制来学习不同的潜在空间。在预训练阶段之后,编码器模块被移除,并且编码的潜在空间可用作技能的连续空间。HRL代理的更高级策略在该连续空间中对技能进行采样,然后由解码器模块以策略的形式对其进行解码。除了独立的技能发现之外,作者还将SeCTAR扩展到特定任务的统一学习。这是通过探索任务相关状态及其邻域的探索器策略实现的,使得由SeCTAR编码器模块编码的轨迹与给定任务相关。通过这种方式,发现的技能空间同时在任务中训练。
  10. [38]提出了一种变分推理方法来学习不同的技能,同时不断地嵌入这些技能。用于学习的目标是最小化以一个热门技能向量为条件的潜在嵌入上的分布和以执行该技能生成的轨迹为条件的潜伏嵌入上的分配之间的交叉熵。

3.4 迁移分层强化学习

主要用于一个任务转移到另一个任务,以加速后一个任务的学习。目前主要挑战:(1) 在终身迁移学习过程中有效扩展到大量子任务。(2) 跨具有不同状态空间的任务域传输子任务。(3) 在多个相关任务上从头开始学习子任务。

3.4.1 迁移+子任务策略蒸馏

  1. 当从一个任务转移到另一个任务时,如终身学习,HRL代理可能会学习并积累大量的子任务策略。由于需要存储多个子任务策略,将大量子任务直接添加到更高级别策略的动作空间可能导致内存效率低下。
  2. [96]提出了一种称为分层深度强化学习网络(H-DRLN)的深度HRL框架,用于对与各种子任务相对应的一组预训练策略进行内存高效转移和保留。策略是使用手动定义的目标预训练的,通过多技能蒸馏实现。
  3. [81]使用多技能提取,使H-DRLN能够有效地将几个子任务的策略组合成一个提取的策略。这使得H-DRLN存储器高效。当执行目标任务时,H-DRLN代理使用更高级别的策略来选择由提取的策略执行的子任务。H-DRLN的主要限制是子任务的策略需要使用手动定义的目标进行预训练。此外,H-DRLN能够将现有策略提炼成目标策略,但不提供连续发现新子任务的方法。

3.4.2 迁移+智能体空间子任务

  1. [49]提出可以转移到具有不同状态空间的各种任务的选项。不变性是通过使用两个独立的状态表示来实现:一个在任务空间中,另一个在智能体空间中。智能体空间包括依赖于智能体的信息,在所有任务中可以使用,任务空间包括和当前任务相关的高层决策。
  2. [29]提出了一种深度HRL方法,用于通过对多个相关任务的元学习来发现选项。这种方法被称为元学习共享层次结构(MLSH),包含一组选项,这些选项的参数在不同的任务中共享,通过联合最大化在所有任务中获得的预期回报来从头开始学习(元学习)。MLSH不使用任何其他手工制作的奖励或子目标。学习到的选项将通过使用特定于任务的更高级别策略转移到看不见的任务。MLSH的主要限制是选项的数量需要固定。

3.6 方法调查主要收获

  1. 没有统一的框架来学习分级政策。封建等级制度方法使用子目标来表示各种可能的子任务,这种方法具有通过使用大量子目标或使用低维连续子目标空间来扩大子任务空间的范围。策略树方法不局限于只学习基于子目标的子任务。不同的子任务策略可以代表不同类型的行为,如基于子目标的、基于轨迹的、一般技能等。
  2. 各种原理可以用于子任务发现,发现的子任务的质量没有单一的标准。HRL研究人员对用于子任务发现的原理有多种想法:划分状态-动作-转移图、聚类、多样化探索、变分推理等。
  3. 新的趋势可能会沿着大规模技能发现的方向出现。近年来,强化学习社区对连续控制和机器人操纵问题表现出越来越大的兴趣。在这种兴趣之后,HRL研究也开始产生发现机器人技能的方法和学习连续控制的分层策略。这一趋势可能在不久的将来继续下去,特别是在各种任务领域中大规模获取机器人连续控制技能,如“跳跃”、“奔跑”、“移动物体”、“在交通中行驶”、“停车”等,以及UNI方法的适配,以实现对大量此类技能的端到端学习。这一趋势很重要,因为不同的机器人技能对于HRL的各种现实应用是必要的,例如仓库管理、手术机器人、自动驾驶等。

4. 未来研究的开放问题

  1. HRL的可扩展性、效率和理论稳健性方面仍然存在不同的问题。
  2. 建立可转移技能的终身知识库。建立终身技能知识库需要整合多种操作,如技能发现、技能转移和分层学习,将相关技能作为执行新任务的子任务。目前,必要的操作由不同的方法提供,特别是用于无监督的技能发现[1,38,83]、技能转移[29,96]、技能组合[6]、技能重用[37]和在训练HRL代理时选择性启动技能[45]。有必要进行进一步的研究和开发,以设计一个综合的HRL框架,将这些操作全面结合起来,以维护可转移技能的终身知识库。
  3. 利用高水平的规划来改善学习和适应。使用学习到的子任务到子任务(或子目标到子目标)的过渡动力学,用基于模型的规划取代HRL代理的无模型高级策略,可以潜在地加速代理在长期任务上的学习,并适应具有共享动力学的新任务[23,86]。
  4. 总之,在将高层规划与HRL相结合时,需要考虑多个方面。自动发现子任务至关重要。需要更多的研究来自动学习子任务之间的依赖关系,而不是手工制作它们。还应制定新的方法,将更高级别的规划和更低级别的政策学习端到端地统一起来。为HRL提供理论支持。

http://www.niftyadmin.cn/n/5072025.html

相关文章

(面试)谈谈我对C++面向对象特性的理解

&#x1f4af; 博客内容&#xff1a;C读取一行内个数不定的整数的方式 &#x1f600; 作  者&#xff1a;陈大大陈 &#x1f680; 个人简介&#xff1a;一个正在努力学技术的准前端&#xff0c;专注基础和实战分享 &#xff0c;欢迎私信&#xff01; &#x1f496; 欢迎大家&…

vue启动项目,npm run dev出现error:0308010C:digital envelope routines::unsupported

运行vue项目&#xff0c;npm run dev的时候出现不支持错误error:0308010C:digital envelope routines::unsupported。 在网上找了很多&#xff0c;大部分都是因为版本问题&#xff0c;修改环境之类的&#xff0c;原因是对的但是大多还是没能解决。经过摸索终于解决了。 方法如…

手机总是提醒系统更新,到底要不要更新呢?

不知道你们会不会和我一样&#xff0c;在收到手机系统更新的通知时&#xff0c;犹豫要不要更新? 更新完了手机会变卡顿吗? 每次都要更新吗?怎样才能关闭它呢&#xff1f; 01 手机系统更新啥内容? 手机系统更新可以分为大版本更新和小版本更新。 (1) 大版本更新 如iOS15升…

体验华为云CodeArts Check IDE插件国际化展示效果

作者&#xff1a; yd_257945187 原文链接&#xff1a;体验CodeArts Check IDE插件国际化展示效果-云社区-华为云 开发者自述 俗话说“工欲善其事&#xff0c;必先利其器”&#xff0c;把自己的IDE配置的即逼格又好看&#xff0c;是每个程序员的梦想&#xff01;IDE插件亦是如…

一本没有任何数学公式的自然语言处理入门书

ChatGPT 时代来了&#xff0c;AI 从旧时王谢堂前燕&#xff0c;飞入寻常百姓家。越来越多非 AI 领域 的软件开发者涌进 NLP(自然语言处理)领域。在这个快速发展的时代&#xff0c;如果这些软件开发 者要像读书那样先读 4 年本科、2 年硕士、3 年博士才能搞 AI&#xff0c;风口早…

FreeRTOS入门教程(信号量的概念及API函数使用)

文章目录 前言一、什么是信号量二、信号量种类和对比三、信号量和队列的区别四、信号量相关的函数1.创建函数2.删除函数3.获取和释放信号量函数 总结 前言 本篇文章正式带大家开始学习什么是信号量&#xff0c;并且掌握信号量函数的基本使用方法&#xff0c;并且将和队列进行一…

Spark 弹性分布式数据集 RDD

1.RDD简介 `RDD` 全称为 Resilient Distributed Datasets,是 Spark 最基本的数据抽象,它是只读的、分区记录的集合,支持并行操作,可以由外部数据集或其他 RDD 转换而来,它具有以下特性: 一个 RDD 由一个或者多个分区(Partitions)组成。对于 RDD 来说,每个分区会被一个…

常见的开源规则引擎简介

Java 业务规则引擎 Drools Drools 是用 Java 语言编写的开放源码规则引擎&#xff0c;使用 Rete 算法对所编写的规则求值。 规则引擎 Apache Camel Apache Camel 是一个非常强大的基于规则的路由以及媒介引擎。 业务流程管理(BPM)和工作流系统 Activiti Activiti是一个业务…