突破空间限制!从2D到3D:北大等开源Lift3D,助力精准具身智能操作!

文章链接:https://arxiv.org/pdf/2411.18623
项目链接:https://lift3d-web.github.io/

亮点直击

  • 提出了Lift3D,通过系统地提升隐式和显式的3D机器人表示,提升2D基础模型,构建一个3D操作策略。

  • 对于隐式3D机器人表示,设计了一个任务感知的MAE(Masked Autoencoder),它掩盖了任务相关的可操作性区域,并重建了深度几何信息,从而增强了2D基础模型的3D空间感知能力。

  • 对于显式3D机器人表示,提出了一种2D模型提升策略,利用2D基础模型的预训练位置嵌入(PEs)来编码3D点云数据,用于操作模仿学习。

总结速览

亟需解决的问题:

  • 缺乏大规模的机器人3D数据:现有的3D数据资源不足,限制了机器人在复杂空间任务中的应用。

  • 空间几何信息的丢失:在处理和提取3D特征时,可能会丢失一些重要的空间几何信息,影响机器人对环境的感知与操作。

提出的方案:

  • Lift3D框架:该框架通过逐步增强2D基础模型,结合隐式和显式的3D机器人表示,来构建一个鲁棒的3D操作策略。
    • 任务感知mask自动编码器:首先设计了一个mask自动编码器,通过掩盖任务相关的可操作性区域,重建深度信息,从而增强2D基础模型的隐式3D机器人表示。

    • 2D模型提升策略:通过建立输入3D点与2D模型位置嵌入之间的映射关系,使Lift3D能够将3D点云数据直接编码到2D基础模型中,从而构建显式的3D机器人表示。

应用的技术:

  • 任务感知mask自动编码器:用于掩盖和重建任务相关的3D特征,增强模型对空间关系的理解。

  • 自监督微调:通过自监督学习的方式对2D模型进行微调,以增强其对3D空间的感知。

  • 2D模型提升策略:建立2D与3D的映射关系,将2D基础模型与3D点云数据结合,提取3D机器人表示。

达到的效果:

  • 提高3D操作策略的鲁棒性:Lift3D能够更好地处理和理解3D空间中的复杂配置,构建更加稳定的机器人操作策略。

  • 提升性能:在多个仿真基准和实际场景中,Lift3D的表现 consistently 优于现有的最先进方法,展示了在3D机器人操作中的优势。

这个框架通过增强2D模型的3D能力,减少了空间信息的损失,在实际应用中展现了显著的提升。

Lift3D Method

本节介绍了提出的Lift3D框架的问题陈述。接着详细介绍了任务感知的MAE和2D模型提升策略,这两者分别增强了隐式和显式的3D机器人表示。

问题陈述

对于隐式的3D机器人表示,遵循之前的MAE方法,首先将mask图像输入到2D基础模型中。然后将输出特征输入到解码器进行深度重建,,其中。这个过程增强了2D模型的3D空间感知能力,并有助于后续的3D模仿学习。

对于显式的3D机器人表示,直接利用2D基础模型来编码3D点云数据和机器人状态。然后使用一个简单的策略头来预测动作。遵循之前的操作研究,采用了7自由度(DoF)的动作表示机器人臂末端执行器的姿态,包括3自由度的平移,3自由度的旋转,以及1自由度的夹爪状态(开或关)。

任务感知masked自动编码器 (Task-aware Masked Autoencoder)

一些研究表明,2D基础模型在各种下游机器人任务中展示了强大的表示能力和泛化能力。在此基础上,Lift3D首先增强了2D基础模型中的隐式3D机器人表示。现有的机器人MAE重建方法采用了激进的mask策略,其中大量的输入图像补丁被随机mask。然而,这些mask的区域大多包含与任务无关的背景信息,阻碍了前景物体表示的有效学习。与之前的方法不同,Lift3D旨在掩盖任务相关的可操作性区域,并重建深度几何信息,从而增强2D基础模型的3D空间感知能力。

具体而言,利用来自机器人操作的大规模数据集来构建MAE训练数据集,该数据集包括从视频中随机抽取的100万个训练样本,包含配对的图像和深度数据。如下图2 a)所示,一旦获得数据,使用多模态模型(例如,CLIP)基于任务特定的文本描述生成图像关注图。例如,图2中提取关注图的文本提示是:“机器人臂将红色碗放入灰色碗中”。然后,这些关注图会被双线性缩放并反投影到输入图像上,用于引导MAE的mask策略。

为了区分任务相关的可操作性token和背景token,应用了一个阈值(即)来过滤所有token的关注值。注意,每个token的关注值是通过平均其像素级的值来计算的。与之前方法[28]中使用的mask比例一致,也随机掩盖背景token以达到所需的比例(即)。

可见的()token被输入到2D基础模型中,然后与masktoken()拼接,这些masktoken被送入解码器进行重建。重建目标在mask图像建模中起着至关重要的作用,直接影响特征表示的学习。之前的机器人MAE方法通常使用低级的RGB信息[52, 60, 62]作为重建目标。为了增强2D基础模型的3D空间感知能力,重建了任务相关的可操作性区域和随机选择的背景区域的深度信息()。最后,为了保持基础模型的固有能力,本文引入了蒸馏损失,约束本文模型的可见token输出与预训练的现成模型(2D)的对应特征之间的距离。如图2 a)所示,在阶段1的训练过程中,使用重建损失和蒸馏损失对注入的适配器和解码器进行微调,公式为:

2D模型提升策略 (2D Model-lifting Strategy)

在赋予2D基础模型隐式的3D机器人感知能力之后,提出了一种提升策略,使2D模型能够显式地理解点云数据。最近的研究,无论是将3D点云投影到多视图图像中,还是将2D特征提升到3D空间中,都面临着由于模态转换而丢失空间信息的问题。因此,高效地编码3D数据一直是3D机器人领域的关键研究方向。

对于基于Transformer的2D模型,位置嵌入(PEs)起着重要作用,因为它们为注意力机制中的输入token提供了位置信息。然而,直接创建新的3D位置嵌入来编码3D token可能会引入语义差异,这些差异源于预训练的2D基础模型与新添加的3D位置嵌入之间的不同,从而可能导致大规模预训练知识的丧失。

因此,受[23, 24, 71]启发,将3D token投影到多个虚拟平面上。与之前的工作不同,投影过程并不是为了构造模型的输入。相反,它建立了输入3D点与每个虚拟平面上的预训练2D位置嵌入之间的位置对应关系。然后,这些2D位置嵌入被用来直接编码3D token。

具体而言,如前面图2 b)所示,将原始点云转换到高维空间(即),通过轻量级的3D分词器获得(128)个3D token,遵循之前的方法[91, 97]。3D 分词器由最远点采样(用于下采样点的数量)、k-最近邻算法(用于局部聚合)和可学习的线性层(用于特征编码)组成。此外,使用来表示每个3D token的3D坐标。

随后,每个3D坐标被投影到个虚拟平面上,获得相应的3D到2D坐标。该投影机制是无参数的且高效的。采用具有6个面的立方体投影方法,有效地捕捉了空间信息。这些个虚拟平面对应于个原始的2D位置嵌入。使用3D到2D坐标,将每个3D token分配到个原始2D位置嵌入,记为。

在将每个3D token与个2D位置嵌入对齐后,简单地对它们进行平均,创建一个统一的位置信号,记为,其公式为:

将与3D token结合,并将其输入到2D基础模型中。通过这种方式,利用个结合的原始2D位置嵌入来编码3D token,有效地提供了2D空间中的多样化位置关系,并减轻了空间信息丢失。2D基础模型输出的特征(即)通过一个简单的策略头处理,以预测模仿学习的姿态。本文使用一个三层的多层感知器(MLP)来构建策略头。需要注意的是,Lift3D编码器可以很容易地适应不同的解码器或策略头;这里使用MLP头进行简单验证。

最后,监督损失的公式为:

其中,T、R和G分别表示7自由度末端执行器姿态中的平移、旋转和夹持器状态。如图2 b)所示,在第二阶段的模仿学习中,冻结2D基础模型的参数,仅更新3D分词器、注入适配器和策略头。Lift3D也可以在不注入适配器的情况下操作,这会导致操作性能略微下降。

实验

通过展示模拟任务和真实任务中的实验设置和结果,评估了Lift3D的操作能力。每个组件的有效性通过消融研究得到了验证。通过在不同的操作实例、背景场景和光照条件下测试模型,检验了Lift3D的泛化能力。最后通过逐步增加2D基础模型的参数来探索模型的可扩展性。

模拟实验

基准测试:从三个广泛使用的操作模拟基准中选择了30多个任务:MetaWorld 和 Adroit 在MuJoCo模拟器中的任务,以及 RLBench 在CoppeliaSim模拟器中的任务。点云数据通过使用相机外参和内参从单视图RGBD数据中获得。对于MetaWorld,选择了一个包含Sawyer臂和双指夹持器的桌面环境,并从不同难度级别中选择了15个任务。这些任务从两个角落摄像头视角捕捉,任务分类如下:

  • 简单任务:按钮按压、抽屉打开、到达、拉手柄、插头拔出、拉杆和旋钮转动。

  • 中等任务:锤子、清扫、垃圾桶取物、推墙和箱子关闭。

  • 难度较高任务:组装、手伸入和架子放置。

对于Adroit任务,重点是使用与[52]中相同摄像头视角的灵巧手操作,包括了三个任务:锤子、门和钢笔。对于RLBench,它使用Franka Panda机器人和前视摄像头。由于篇幅限制,RLBench的结果和详细信息已在附录B.1中提供。

数据收集:MetaWorld中使用了脚本化策略,收集了25个演示,每个演示包含200个步骤。对于Adroit任务,轨迹是通过强化学习算法训练的智能体获得的。具体来说,DAPG应用于门和锤子任务,而VRL3用于钢笔任务。研究者们收集了100个演示,每个演示包含100个步骤。RLBench中的演示是通过预定义的路径点和Open Motion Planning Library收集的,共收集了100集,每集包含若干个关键帧。

基线
Lift3D的创新之处在于系统性地增强了隐式和显式的3D机器人表示。为了评估其有效性,将Lift3D与来自三个类别的9种方法进行了比较:

  1. 2D 机器人表示方法:选择了CLIP(ViT-base),它是一个2D基础模型。此外,还包括了R3M和VC1,这两者都是2D机器人预训练方法。

  2. 3D 机器人表示方法:借鉴了[95],采用了基础的3D模型,包括PointNet、PointNet++和PointNext。此外,还检验了SPA ,这是之前的SOTA 3D机器人预训练方法。与[52]相同,所有机器人表示方法均使用与Lift3D相同的三层策略头和训练损失。

  3. 3D 策略方法:Lift3D与之前的SOTA 3D扩散策略(DP3)在MetaWorld和Adroit上进行了比较,并在RLBench上与RVT-2进行了比较。

训练和评估细节
为了公平比较,所有基线方法在相同配置下进行了训练和评估,而3D策略方法则遵循其原始设置。2D和3D视觉输入分别由RGB图像和具有1,024个点的单视图点云组成。机器人状态包括末端执行器姿态、关节位置和速度,这些信息与视觉特征一起连接。使用CLIP和DINOV2(ViT-base)作为2D基础模型。根据[52]的先前工作,使用Adam优化器,参数(, ) = (0.9, 0.999),学习率为1e-3。MetaWorld采用恒定学习率,而Adroit则应用带有0.1预热因子的余弦退火调度器。每种方法训练100个epoch,每10个epoch执行25次回合。本文报告最佳执行策略模型在整个训练过程中的平均成功率。对于MetaWorld,进一步对两个摄像头视角的得分进行平均。

定量结果 在下表1中,Lift3D(CLIP)在MetaWorld基准测试中达到了平均成功率83.9,其中中等任务的准确率为78.8,难度较大的任务准确率为82.0。与其他机器人表示方法相比,Lift3D在最顶尖的2D方法和3D方法基础上分别提高了8.8和14.4的平均成功率。此外,与之前的SOTA 3D策略(DP3)相比,Lift3D实现了18.6的准确率提升。这些结果表明,Lift3D有效地增强了2D基础模型的操作能力,通过利用大规模预训练知识,使其对机器人3D场景有更深入的理解。

此外,Lift3D在灵巧手任务上也表现出优越的性能,超过了以前的机器人表示和策略方法。需要注意的是,灵巧手的自由度在任务间有所不同,其中锤子、门和钢笔任务的自由度分别为26、28和24。结果证明,本文的方法对于更复杂的灵巧手操作任务也很有效,这得益于强大的3D机器人表示能力。

Lift3D(DINOV2)也显示出了良好的结果,证明了该方法对其他2D基础模型的实用性。

真实世界实验

数据集收集
在真实世界实验中,使用Franka Research 3臂进行实验,并通过Intel RealSense L515 RGBD摄像头从静态前视角捕捉图像。执行了十个任务:

  • 将瓶子放置到架子上
  • 倒水
  • 拔掉充电器
  • 堆积积木
  • 拾取并放置物品
  • 滑动积木
  • 给植物浇水
  • 擦拭桌面
  • 打开抽屉
  • 关上抽屉

这些任务涉及不同类型的交互对象和操作行为。对于每个任务,在不同空间位置收集了40个演示,轨迹以30fps的速度记录。选择了30个回合,并提取关键帧来构建每个任务的训练集。输入的点云数据和图像示例如图4所示。

训练与评估细节
实现细节与模拟实验中的相同。对每个任务从头开始训练每种方法。在训练过程中,使用世界坐标系下的点云数据和操作姿态作为输入和监督信号。评估时,使用最终epoch的模型,并在不同空间位置上进行20次评估。

定量结果 如下图3所示,将Lift3D(CLIP)与DP3、VC-1和PointNet进行了比较。结果表明,Lift3D在多个任务中表现出色。特别是在“将瓶子放置到架子上”任务中,该任务需要准确的3D位置和旋转预测,Lift3D达到了90%的成功率。结果表明,Lift3D能够有效理解3D空间场景,并在真实世界中做出准确的姿态预测。对于更复杂的任务(如擦拭桌面),由于需要操作可变形的物体,所有方法的精度都面临一定的局限性。尽管如此,Lift3D仍然达到了40%的成功率。

定性结果 如下图4所示,展示了六个真实世界任务的操作过程。本文的方法准确预测了连续的7自由度末端执行器姿态,使得任务得以沿着轨迹顺利完成。例如,在“给植物浇水”任务中,Lift3D首先准确抓住了浇水壶的手柄。接着,它平稳地抬起壶并将其定位到植物上方。最后,夹持器逐渐旋转以控制“水流”。

消融实验

在下表2中,针对MetaWorld仿真任务(包括装配和关箱任务)进行了一系列消融实验,并计算了平均操作准确率。

Task-aware MAE
在Ex2到Ex4中,观察到深度重建和RGB+深度重建相较于Ex1(仅RGB重建)分别提高了6%和5%的成功率,而仅使用RGB重建并未显示出显著改善。这突出了在操作任务中重建几何信息的重要性,因此选择将深度图像作为重建目标。通过比较Ex2和Ex5,发现基于任务的引导掩膜策略相比随机掩膜策略提高了4%的成功率,证明了专注于与任务相关的可操作区域来学习几何信息更加高效。

视觉token蒸馏
与Ex5相比,通过视觉token蒸馏进行预训练(Ex6)使成功率提高了8%,这表明防止灾难性遗忘已经预训练的知识对于将2D基础模型赋予隐式3D机器人意识至关重要。

2D模型提升策略
对于2D模型提升策略,与仅输入图像的Ex1相比,Ex7引入了显式点云编码的提升策略,显著提高了操作性能。这表明3D空间信息对于实现稳健的操作至关重要。Ex8相较于Ex7也展示了明显的提升,验证了隐式3D表示学习能够促进后续显式3D模仿学习。

位置编码(PE)影响 最后,与Ex8相比,Ex9采用了没有预训练的新增PE(位置编码),结果性能下降了6%,验证了提升策略最有效地利用了大规模的2D预训练知识。

泛化能力探索

通过利用2D基础模型的大规模预训练知识和全面的3D机器人表示,Lift3D展现了强大的现实世界泛化能力。正如下表3所示,设计了三种不同于训练场景的实际测试场景来验证其泛化能力。

  1. 不同的操作实例
    Lift3D在多种操作物体中展现了强大的鲁棒性,且表现出最小的准确率损失。这一成功主要归功于预训练的2D基础模型的语义理解能力。

  2. 复杂的背景场景
    背景干扰显著降低了所有方法的准确性,但Lift3D显示出最小的下降,操作成功率仍然保持在50%以上。这可以归因于在3D空间中有效利用了大规模预训练知识。此外,基于任务的引导掩膜策略通过重建增强了模型对前景区域空间几何的理解,同时减少了背景干扰的影响。

  3. 不同的光照条件
    光照变化影响2D图像的数据分布,同时也会影响深度捕捉,从而影响点云数据。在光照变化的影响下,Lift3D仅显示出平均20%的准确率下降,证明了其强大的3D机器人表示能力。

模型可扩展性探索

在计算机视觉中,随着2D基础模型参数的增大,通常会提高下游任务的性能 [56, 61]。基于这一点,探讨了Lift3D政策是否也表现出可扩展性。在非常困难的MetaWorld仿真任务——“置物架任务”上进行了实验。

对于这一复杂任务,Lift3D (DINOV2-ViTbase) 仅达到28%的准确率。ViT-base的参数数量为86M,而ViT-large和ViT-giant分别有304M和1B的参数。通过将2D基础模型替换为DINOV2-ViT-large和DINOV2-ViT-giant,Lift3D在“置物架任务”中分别达到了48%和58%的准确率,并且展现了更快的收敛速度,如下图5所示。这些改进证明了Lift3D政策模型的可扩展性,并且Lift3D框架能够通过更大的2D基础模型生成更强健的操作策略。

结论与局限性

本文提出了Lift3D,一种将大规模预训练的2D基础模型与强大的3D操作能力相结合的创新框架。首先,设计了一种任务感知的MAE(Masked Autoencoder),它通过掩盖与任务相关的有用区域并重建深度几何信息,增强了隐式的3D机器人表示。其次,提出了一种2D模型提升策略,通过利用预训练的2D基础模型显式地编码3D点云数据,用于操作模仿学习。Lift3D在仿真和实际实验中持续超越现有方法,并在多种实际场景中展现了强大的泛化能力。

局限性
然而,Lift3D框架专注于将2D视觉模型提升至3D操作任务,这意味着它无法理解语言条件。然而,本文的方法可以适应像CLIP这样的多模态模型,能够将Lift3D编码器与语言模型结合,为未来的3D视觉-语言-行动模型的实现铺平道路。

参考文献

[1] Lift3D Foundation Policy: Lifting 2D Large-Scale Pretrained Models for Robust 3D Robotic Manipulation

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/485769.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker desktop打包配置国内镜像地址

打包遇到无法访问外网资源,直接配置国内镜像地址 直接加入如下代码就行: {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"registry-m…

MATLAB数学建模之画图汇总

MATLAB是一种强大的数学软件,广泛应用于工程计算、控制设计、信号处理等领域。在数学建模中,MATLAB的绘图功能可以帮助我们直观地展示数据和模型结果。 1. 二维数据曲线图 1.1 绘制二维曲线的基本函数 plot函数用于绘制二维平面上的线性坐标曲线图&am…

喆塔科技携手国家级创新中心,共建高性能集成电路数智化未来

集创新之力成数智之塔 近日,喆塔科技与国家集成电路创新中心携手共建“高性能集成电路数智化联合工程中心”并举行签约揭牌仪式。出席此次活动的领导嘉宾包含:上海市经济和信息化委员会、上海市集成电路行业协会、复旦大学微电子学院、国家集成电路创新中…

2.STM32通信接口之SPI通信---SPI实战《精讲》

SPI仅支持一主多从(无应答机制) 参照:《第十一部分》1.STM32通信接口之SPI通信---SPI介绍《精讲》-CSDN博客 在采用一主多从的模式下。从机未被选中,SN1时,从机的MISO会处于高阻态状态,SN0时,M…

【Unity 动画】Animation state 动画片段属性面板的解释

1. Motion 描述: 这是分配给该状态的动画剪辑或混合树。 例子: 假设你正在制作一个角色行走的动画。你可以将一个名为“Walk”的动画剪辑拖放到“Motion”属性中。这样,当角色进入“行走”状态时,就会播放“Walk”动画。 2. Speed 描述: 该状态下的动…

Flutter动画(二)内建隐式动画Widget

动画效果介绍中给出了选择动画的决策树: 使用动画框架不在我们讨论的话题内。flutter支持的动画包括隐式动画和显式动画。 隐式动画和显式动画 隐式动画和显示动画是两种不同的动画实现方式,它们的主要区别在于控制权和动画的重复性。 隐式动画&#…

如何解决Redis缓存穿透

如何解决Redis缓存穿透 本篇将带大家了解如何在不同的业务场景下防范Redis缓存穿透,以查询商品业务场景为例子,分别使用缓存null和布隆过滤器的方法来防范缓存穿透 缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样请求到达缓存…

Spring Boot 3.0 + MySQL 8.0 + kkFileView 实现完整文件服务

Spring Boot 3.0 MySQL 8.0 kkFileView 实现完整文件服务 背景:比较常见的需求,做成公共的服务,后期维护比较简单,可扩展多个存储介质,上传逻辑简单,上传后提供一个文件id,后期可直接通过此i…

spring6:3容器:IoC

spring6:3容器:IoC 目录 spring6:3容器:IoC3、容器:IoC3.1、IoC容器3.1.1、控制反转(IoC)3.1.2、依赖注入3.1.3、IoC容器在Spring的实现 3.2、基于XML管理Bean3.2.1、搭建子模块spring6-ioc-xml…

ROS2创建 base 包用于其他模块的参数配置和头文件依赖

Demo 背景 ROS2项目开发中存在以下需求:有多个包需要读取一些共同的配置项(以txt或者yaml形式存在),且依赖于一些公用的utils工具代码(C)。Solution: 创建一个 base_config 包来“存放” 配置文件和公用的头文件。gitee address: Gitee/CDal…

相机动态/在线标定

图1 图2 基本原理 【原理1】平行线在射影变换后会交于一点。如图所示,A为相机光心,蓝色矩形框为归一化平面,O为平面中心。地面四条黄色直线为平行且等距的车道线。HI交其中两条车道线于H、I, 过G作HI的平行线GM交车道线于M。HI、GM在归一化平面上的投影分别为JK、PN,二者会…

记录下nginx接口代理配置问题

其中api和api1是前面定义的upstream,ip相同只是端口不同。 一开始/api1/直接 像api一样 proxy_pass http://api1这样是不行的,因为会代理到 后端的 /api1/...接口,而后端实际接口地址是 /api/..... 所以必须像上面写法才能将外网的 /api…

【Mac】安装Gradle

1、说明 Gradle 运行依赖 JVM,需要先安装JDK,Gradle 与 JDK的版本对应参见:Java Compatibility IDEA的版本也是有要求Gradle版本的,二者版本对应关系参见:Third-Party Software and Licenses 本次 Gradle 安装版本为…

【JavaEE】多线程(7)

一、JUC的常见类 JUC→java.util.concurrent,放了和多线程相关的组件 1.1 Callable 接口 看以下从计算从1加到1000的代码: public class Demo {public static int sum;public static void main(String[] args) throws InterruptedException {Thread …

Linux-实用操作

文章目录 一. 各类实用小技巧(快捷键)1. ctrl c 强制停止2. ctrl d 退出登出3. history 查看历史命令4. !命令前缀,自动匹配上一个命令5. ctrl r,搜索历史命令6. ctrl a | e,光标移动到命令开始或结束7. ctrl ← | →,左右跳…

李飞飞首个“空间智能”模型发布:一张图,生成一个3D世界 | LeetTalk Daily

“LeetTalk Daily”,每日科技前沿,由LeetTools AI精心筛选,为您带来最新鲜、最具洞察力的科技新闻。 在人工智能技术迅速发展的背景下,李飞飞创立的世界实验室于近期发布了首个“空间智能”模型,这一创新成果引发了3D生…

C语言程序设计P5-3【应用函数进行程序设计 | 第三节】——知识要点:函数的嵌套调用和递归调用

知识要点:函数的嵌套调用和递归调用 视频 目录 一、任务分析 二、必备知识与理论 三、任务实施 一、任务分析 本任务要求用递归法求 n!。 我们知道n!n(n-1)(n-2)……1n(n-1)!递归公式为: 1.上面公式分解为n!n(n-1)!,即将求n!的问题变为…

css部分

前面我们学习了HTML,但是HTML仅仅只是做数据的显示,页面的样式比较简陋,用户体验度不高,所以需要通过CSS来完成对页面的修饰,CSS就是页面的装饰者,给页面化妆,让它更好看。 1 层叠样式表&#…

单片机的中断系统

作者简介 彭煜轩,男,银川科技学院计算机与人工智能学院,2022级计算机与科学技术8班本科生,单片机原理及应用课程第3组。 指导老师:王兴泽 电子邮件:1696409709qq.com 前言 本篇文章是参考《单片机原理…

【技巧】Mac上如何显示键盘和鼠标操作

在制作视频教程时,将键盘和鼠标的操作在屏幕上显示出来,会帮助观众更容易地理解。 推荐Mac上两款开源的小软件。 1. KeyCastr 这款工具从2009年至今一直在更新中。 https://github.com/keycastr/keycastr 安装的话,可以从Github上下载最…