基于深度强化学习的室内场景目标驱动视觉导航

摘要

深度强化学习的两个不太被重视的问题是(1)缺乏对新目标的泛化能力,以及(2)数据效率低,即模型需要几个(并且通常是昂贵的)反复试验才能收敛,这使得它不适用于现实世界的场景。在本文中,我们解决了这两个问题,并将我们的模型应用于目标驱动的视觉导航。为了解决第一个问题,我们提出了一个行动者-批评家模型,其策略是目标和当前状态的函数,这允许更好的推广。为了解决第二个问题,我们提出了AI2-托尔框架,它提供了一个具有高质量3D场景和物理引擎的环境。我们的框架使代理能够采取行动并与对象交互。因此,我们可以有效地收集大量的训练样本。

我们表明,我们提出的方法(1)比最先进的深度强化学习方法收敛更快,(2)适用于所有目标和场景,(3)适用于具有少量微调的真实机器人场景(尽管模型是在模拟中训练的),(4)是端到端可训练的,不需要特征工程、帧间特征匹配或环境的3D重建。

介绍

机器人学中的许多任务涉及与物理环境和物体的交互。这种相互作用的一个基本组成部分是理解一个代理人的行动和作为行动结果的环境变化之间的相关性和因果关系。自20世纪70年代以来,人们一直在尝试建立一个能够理解这种关系的系统。最近,随着深度学习模式的兴起,基于学习的方法得到了广泛的普及[1],[2]。

在这篇文章中,我们主要研究的问题是如何在一个空间中仅仅通过视觉输入来找到一个给定的目标。成功的导航需要学习行动和环境之间的关系。这使得该任务非常适合深度强化学习(DRL)方法。然而,一般的DRL方法(例如[2],[3])被设计为学习仅依赖于当前状态的策略,并且目标被隐含地嵌入模型参数中。因此,有必要为新目标学习新的模型参数。这是个问题,因为训练DRL特工的计算成本很高。

为了实现更高的适应性和灵活性,我们引入了目标驱动模型。我们的模型以视觉任务目标为输入。这样我们就可以避免对每个新目标进行再训练。我们的模型学习联合嵌入目标和当前状态的策略。本质上,一个代理学习采取下一个动作取决于它的当前状态和目标,而不仅仅是它的当前状态。因此,没有必要为新目标重新训练模型。我们依赖的一个关键直觉是,不同的训练集共享信息。例如,特工在训练阶段探索共同的路线,同时接受寻找不同目标的训练。各种场景也共享相似的结构和统计数据(例如,冰箱可能靠近微波炉)。简而言之,我们利用了这样一个事实,即通过为其他目标训练的模型,学习新目标会更容易。

不幸的是,在真实环境中训练和定量评估DRL算法通常是乏味的。一个原因是在物理空间中运行系统很耗时。此外,通过常见的图像数据集收集技术,在真实环境中获取大规模动作和交互数据并不容易。为此,我们开发了第一个具有高质量3D场景的模拟框架,称为交互之家(AI2-托尔)。我们的模拟框架使我们能够在不同的环境中收集大量的行动和反应的视觉观察。例如,代理可以在各种逼真的室内场景中自由导航(即,移动和旋转),并且能够与对象进行低级和高级交互(例如,施加力或打开/关闭微波)。

我们针对以下任务评估我们的方法:(1)目标概括,目标是导航到场景内训练期间未使用的目标。(2)场景泛化,目标是导航到场景中未用于训练的目标。(3)现实世界的概括,我们演示使用真实机器人导航到目标。我们的实验表明,就训练的数据效率而言,我们优于最先进的DRL方法。我们还展示了我们模型的一般化方面。

总之,我们介绍了一种新的强化学习模型,它可以在目标和场景之间进行推广。为了学习和评估强化学习模型,我们创建了一个具有高质量渲染的仿真框架,使代理能够进行可视化交互。我们还使用我们的模型演示了真实的机器人导航,该模型通过少量的微调推广到真实世界。

相关工作

视觉导航方面有大量的工作。我们提供了一些相关工作的简要概述。基于地图的导航方法需要环境的全局地图来做出导航决策(例如,[4]、[5]、[6]、[7])。与这些方法相比,我们的方法的主要优点之一是它不需要环境的先验地图。另一类导航方法是动态重建地图,并将其用于导航[8]、[9]、[10]、[11]、[12],或者在人类的指导下通过训练阶段来构建地图[13]、[14]。相比之下,我们的方法不需要环境地图,因为它没有任何关于环境地标的假设,也不需要人工指导的训练阶段。无地图导航方法也很常见[15],[16],[17],[18],[19]。这些方法主要关注给定输入图像的避障。我们的方法被认为是无地图的。然而,它拥有隐含的环境知识。视觉导航方法的调查可以在[20]中找到。

请注意,我们的方法不是基于特征匹配或3D重建,例如不像[21],[22]。此外,与例如[23]、[24]不同,我们的方法不需要用于识别独特地标的监督训练

强化学习已经被广泛应用。[25]提出了一种用于四足机器人运动策略梯度RL方法。[26]讨论学习运动原语的策略梯度方法。[27]提出了一种使用单目摄像机进行障碍物检测的基于逆向物流的方法。[28]将强化学习应用于自动直升机飞行。[29]使用RL自动执行数据收集流程以进行制图。[30]针对大规模设置提出一种基于核的强化学习算法。[31]在雅达利游戏中使用RL进行决策。与这些方法相反,我们的模型使用深度强化学习来处理高维感官输入。

最近,将深度学习方法与逆向学习相结合的方法已经显示出有希望的结果。【2】提出深度Q网玩雅达利游戏。[32]提出一种新的基于蒙特卡洛树搜索与深度RL相结合的搜索算法,在围棋比赛中击败世界冠军。[3]提出一种深度反向链路方法,其中深度网络的参数由环境中代理的多个异步副本更新。[1]使用深度逆向工程方法将原始图像直接映射到机器人电机的扭矩上。我们的工作处理比TARI游戏复杂得多的输入,或者是在实验室背景受限的情况下拍摄的图像。此外,我们的方法可以推广到新的场景和新的目标,而上述方法应该为新的游戏重新训练,或者在游戏规则发生变化的情况下。

已经做出了一些努力来开发可以推广到不同目标任务的学习方法[33],[34]。类似于UVFA [35],我们的模型直接将目标目标作为输入,不需要重新训练。

最近,物理引擎已经被用来从图像[36]、[37]、[38]中学习现实世界场景的动力学。在这项工作中,我们表明,在模拟中训练的模型可以推广到现实世界的场景。

AI2-THOR框架

为了训练和评估我们的模型,我们需要一个在3D环境中执行动作和感知其结果的框架。将我们的模型与不同类型的环境相集成是我们模型一般化的主要要求。因此,这个框架应该有一个即插即用的架构,这样不同类型的场景可以很容易地结合在一起。此外,框架应该有一个详细的场景物理模型,这样运动和物体的相互作用才能得到正确的表现。

为此,我们提出了交互之家(AI2-托尔)框架,它是通过将物理引擎(统一3D)与深度学习框架相结合而设计的。总的想法是,物理引擎的渲染图像被流式传输到深度学习框架,深度学习框架基于视觉输入发出控制命令,并将其发送回物理引擎中的代理。[39],[40],[44],[42],[41]已经提出了类似的框架,但是我们的框架的主要优点如下:(1)物理引擎和深度学习框架直接通信(与[38]中物理引擎和控制器分离相反)。直接沟通很重要,因为来自环境的反馈可以立即用于在线决策。(2)我们试图尽可能地模仿真实世界图像的外观分布。例如,[39]致力于雅达利游戏,这是2D环境,外观有限。[43]是合成场景的集合,这些合成场景不具有照片真实感,并且在照明、物体外观、纹理和背景杂乱等方面不符合真实世界场景的分布。这对于使我们能够推广到现实世界的图像很重要。

为了给我们的框架创建室内场景,我们向艺术家提供了参考图像,以创建一个纹理和照明与图像相似的3D场景。到目前为止,我们有32个场景,属于家庭环境中的4种常见场景类型:厨房、客厅、卧室和浴室。平均而言,每个场景包含68个对象实例。

使用物理引擎来建模世界的优势在于它具有很高的可伸缩性(在真实的房子里训练机器人不容易伸缩)。此外,训练模型可以更便宜和更安全地进行(例如,机器人的动作可能损坏物体)。使用合成场景的一个主要缺点是真实世界的细节建模不足。然而,图形社区的最新进展使得对真实世界的外观和物理的丰富表示成为可能,缩小了真实世界和模拟之间的差异。图2提供了我们框架中的场景与其他框架和数据集中的示例场景之间的定性比较。如图所示,我们的场景更好地模拟了真实世界场景的外观属性。在这项工作中,我们专注于导航,但该框架可以用于更细粒度的物理交互,如施加力、抓取或对象操作,如打开和关闭微波炉。图3显示了高级交互的几个例子。我们将为Python APIs提供人工智能代理与3D场景交互的框架。

目标驱动导航模型

在本节中,我们首先定义目标驱动视觉导航的公式。然后我们描述了我们为这个任务而建立的深厚的暹罗演员-评论家网络。

A.问题陈述

我们的目标是找到将代理从其当前位置移动到由RGB图像指定的目标的最小长度的动作序列。我们开发了一个深度强化学习模型,将当前观察的一个RGB图像和目标的另一个RGB图像作为输入。模型的输出是3D中的一个动作,如向前移动或向右转。注意,模型学习从2D图像到3D空间中的动作的映射。

在这里插入图片描述

B.公式问题

基于视觉的机器人导航需要从感觉信号到运动命令的映射。先前关于强化学习的工作通常不考虑高维感知输入[48]。最近的深度强化学习(DRL)模型[2]提供了一个端到端的学习框架,将像素信息转化为行动。然而,DRL在很大程度上专注于学习独立处理个人任务的特定目标模型。这种训练设置对任务目标的变化相当不灵活。例如,正如莱克等人[49]所指出的,改变游戏规则将对基于DRL的围棋系统产生毁灭性的性能影响[32]。这种限制源于这样的事实,即标准DRL模型[2],[3]旨在找到从状态表示s到策略π的直接映射(由深度神经网络π表示)。在这种情况下,目标被硬编码在神经网络参数中。因此,目标的改变需要根据更新网络参数。

这种限制对于移动机器人导航尤其成问题。当将DRL应用于多个导航目标时,应针对每个目标重新训练网络。实际上,在一个场景中耗尽每个目标是禁止的。这是由于缺乏通用性而导致的问题——即,当包含新目标时,我们必须重新训练新模型。因此,最好有一个单一的导航模型,**它学习导航到新的目标,而无需重新训练。为此,我们将任务目标(即导航目的地)指定为模型的输入,**而不是将目标植入模型参数中。我们把这个问题称为目标驱动的视觉导航。在形式上,目标驱动模型的学习目标是学习一个随机策略函数 π π π,它接受两个输入,当前状态的表示代表目标g的表示,并在动作空间 π ( s t , g ) π(s_t,g) π(stg)上产生一个概率分布。为了测试,移动机器人不断采取策略分发中的动作,直到到达目的地。这样,行动既取决于状态,也取决于目标。因此,不需要对新目标进行再培训。

在这里插入图片描述

C.学习设置

在介绍我们的模型之前,我们首先描述强化学习设置的关键要素:行动空间、观察和目标以及奖励设计。

1)动作空间:现实世界的移动机器人要和低级力学打交道。然而,这些机械的细节使学习变得更具挑战性。一种常见的方法是在某个抽象级别学习,其中底层物理由较低级别的控制器(例如,3D物理引擎)处理。我们用命令级动作训练我们的模型。对于我们的视觉导航任务,我们考虑四个动作:前进、后退、左转和右转。我们使用恒定的步长(0.5米)和转角(90度)。这实质上将场景空间离散成网格世界表示。为了模拟现实世界系统动力学中的不确定性,我们在每个位置的步长N (0,0.01)和转弯N (0,1.0)上添加高斯噪声。

2)观察和目标:观察和目标都是代理的RGB相机在其第一人称视图中拍摄的图像。使用图像作为目标描述的好处是可以灵活地指定新的目标。给定目标图像,任务目标是导航到拍摄目标图像的位置和视点。

3)奖励设计:我们专注于最小化到导航目标的轨迹长度,尽管也可以考虑其他因素,例如能量效率。我们只在任务完成时提供达到目标的奖励(10.0)。为了鼓励更短的轨迹,我们增加了一个小的时间惩罚(-0.01)作为即时奖励。

D.模型

我们专注于通过深度强化学习来学习目标驱动的策略函数π。我们设计了一个新的深度神经网络作为π的非线性函数逼近器,其中在时间t的动作a可以由下式画出:
在这里插入图片描述
其中u是模型参数, s t s_t st是当前观测的图像,g是导航目标的图像。当目标g属于有限离散集时,π可以看作是一个混合模型,其中g为每个目标索引正确的参数集。然而,现实世界中的目标数量往往不计其数(由于许多不同的位置或高度可变的对象外观)。因此,最好学习将目标转换成嵌入空间的投影。这种投影使得知识能够在这个嵌入空间中传递,因此允许模型推广到新的目标。

导航决策需要理解当前位置和目标位置之间的相对空间位置,以及对场景布局的整体感觉。我们开发了一个新的深度siamese演员-评论家网络来捕捉这样的直觉。图4说明了我们的目标驱动导航任务模型。总的来说,网络的输入是两个图像,代表代理当前的观察和目标。我们推理当前位置和目标之间的空间排列的方法是将它们投影到相同的嵌入空间中,在那里它们的几何关系被保留。深度连体网络是一种用于区分嵌入学习的双流神经网络模型[50]。我们使用两个权重共享的暹罗层流来将当前状态和目标转换到相同的嵌入空间中。来自两个嵌入的信息被融合以形成联合表示。该联合表示通过场景特定的层传递(参见图4)。具有场景特定层的目的是捕捉对导航任务至关重要的场景的特殊特征(例如,房间布局和对象排列)。最后,该模型产生类似于优势行动者-批评者模型的政策和价值输出[3]。在这个模型中,所有场景中的目标共享相同的通用暹罗层,场景中的所有目标共享相同的场景特定层。这使得模型能够更好地在目标和场景之间进行归纳。

E.训练协议

传统的逆向学习模型在分离中学习个别任务,导致目标变化的不灵活性。由于我们深厚的演员-评论家网络共享不同任务的参数,它可以从同时学习多个目标中受益。A3C [3]是一种强化学习模型,它通过并行运行多个训练线程副本来学习,并以异步方式更新一组共享的模型参数。已经表明,这些并行训练线程相互稳定,在视频游戏领域实现了最先进的性能。我们使用类似A3C的训练协议。然而,每个线程运行的导航目标不同,而不是运行一个游戏的副本。因此,梯度从演员-评论家输出反向传播回较低层。场景特定的图层由场景内导航任务的渐变更新,通用暹罗图层由所有目标更新。

F.网络架构

暹罗层的底部是imagenet pretreated Resnet-50[51]层(截断了softmax层),在224×224×3 RGB图像上产生2048-d特征。我们在训练过程中冻结这些ResNet参数。我们连接4个历史帧的特征来说明代理的过去动作。这两个流的8192-d输出向量被投影到512-d嵌入空间。融合层采用状态和目标的1024-d级联嵌入,生成512-d联合表示。该向量进一步通过两个完全连接的场景特定层,产生4个策略输出(即动作概率)和一个单值输出。我们用学习率为7×104的共享RMSProp优化器来训练这个网络。

实验

我们目标驱动导航的主要目标是找到从当前位置到目标的最短轨迹。我们首先用基于启发式和标准深度学习模型的基线导航模型来评估我们的模型。我们提出的模型的一个主要优点是能够推广到新的场景和新的目标。我们进行了另外两个实验来评估我们的模型跨目标和跨场景传递知识的能力。此外,我们展示了我们的模型对连续空间的扩展。最后,我们用一个真实的机器人演示了我们的模型在复杂的真实环境中的性能。

A.导航结果

我们在Tensorflow [47]中实现我们的模型,并在英伟达GeForce GTX泰坦X GPU上对它们进行训练。我们遵循第12节中描述的训练协议。为了用100个线程训练我们的深度暹罗演员-评论家模型(见图4),每个线程为不同的目标学习。在所有线程上通过一百万个训练帧大约需要1.25个小时。我们将性能报告为从随机起点到达目标所需的平均步数(即平均轨迹长度)。导航性能是在我们的数据集中从20个室内场景中随机抽样的100个不同目标上报告的。我们将最终模型与启发式策略、标准深度学习模型以及我们模型的变体进行比较。我们比较的模型有:

  1. 随机漫步是最简单的导航启发式。在这个基线模型中,代理在每一步随机抽取四个动作中的一个。

  2. 最短路径为我们的导航模型提供了上限性能。因为我们用一个恒定的步长来离散行走空间(见第12节)。我们可以计算从起始位置到目标位置的最短路径。请注意,为了计算最短路径,我们可以访问环境的完整地图,而我们系统的输入只是一幅RGB图像。

  3. A3C [3]是一个异步优势演员-评论家模型,在雅达利游戏中实现最先进的结果。实验结果表明,使用更多的线程可以提高训练过程中的数据效率。因此,我们在两个设置中评估A3C模型,其中我们使用1个线程和4个线程为每个目标进行训练。

  4. 一步Q [3]是深度Q网[2]的异步变种。

  5. 目标驱动的单分支是我们的深度暹罗模型的变体,它没有场景特定的分支。在这种情况下,所有目标将使用和更新相同的场景特定参数,包括两个光纤通道层和策略/值输出层。

  6. 目标驱动决赛是我们在Sec推出的深度连体演员-评论家模型。

对于所有的学习模型,我们在经过100M帧(跨所有线程)的训练后,报告它们的表现。性能通过所有目标的平均轨迹长度(即,采取的步骤数)来衡量。当代理到达目标时,或者经过10,000步后,一集结束。对于每个目标,我们随机初始化代理的起始位置,并评估10集。结果列于表一

在这里插入图片描述
我们用图5中的学习曲线分析了几个深度RL模型的数据效率。Q-learning收敛慢。A3C比Q-learning表现更好;此外,将每个目标的参与者学习线程数从1增加到4可以提高学习效率。我们提出的目标驱动导航模型在100米帧的训练中明显优于标准深度RL模型。我们假设这是因为跨目标的权重分配方案和异步训练协议都有助于学习可推广的知识。相比之下,专门构建的RL模型的数据效率较低,因为没有简单的机制来跨不同场景或目标共享信息。最终模型的平均轨迹长度比单分支模型短三倍。它证明了场景特定层的使用是合理的,因为它捕获了场景的特定特征,这些特征可能在场景实例之间有所不同。

在这里插入图片描述
为了理解模型学到了什么,我们检查了由通用暹罗层学到的嵌入。图6示出了根据在四个不同方向的不同位置的观察计算的嵌入向量的t-SNE可视化[52]。我们观察到这些嵌入向量的空间排列和它们相应的t-SNE投影之间有显著的空间对应关系。因此,我们假设模型学会将观察图像投影到嵌入空间中,同时保留它们的空间配置。为了验证这个假设,我们比较了成对投影嵌入的距离和它们对应的场景坐标的距离。皮尔逊相关系数为0.62,p值小于0.001,表明嵌入空间保留了观测值原始位置的信息。这意味着模型学习环境的粗略地图,并具有相对于该地图的定位能力。

在这里插入图片描述

B.跨目标的概括

除了目标驱动的RL模型的数据效率之外,它还具有内置的概括能力,这是优于专门构建的基线模型的一个显著优势。我们从两个方面来评价它的泛化能力:1 .推广到场景中的新目标。推广到新的场景。我们在这一节集中讨论跨目标的概括,并在下一节解释场景概括。

我们测试模型以导航到新的目标。这些目标没有经过训练,但它们可能与经过训练的目标共享共同的路线,从而允许知识转移。我们在数据集中选取了10个最大的场景,每个场景大约有15个目标。我们使用我们的目标驱动模型逐渐增加训练目标的数量(从1、2、4到8)。所有模特都是20M帧训练。在测试期间,我们为10个新目标各运行100集。这些新目标是从一组与最近的训练目标有恒定距离(1、2、4和8步)的位置中随机选择的。结果如图7所示。我们使用成功率(短于500步的轨迹的百分比)来衡量性能。我们选择这一指标是因为我们的模型在新目标上的两极行为——它要么很快达到新目标,要么完全失败。因此,这个度量比平均轨迹长度更有效。在图7中,我们观察到随着训练目标(x轴)数量的增加,成功率不断增加的趋势。在每个直方图组中,成功率与训练目标和新目标之间的邻接度正相关。表明该模型对训练目标周围的邻近区域比远处有更清晰的认识。

在这里插入图片描述

C.跨场景概括

我们进一步评估了我们的模型对场景进行归纳的能力。由于通用暹罗层在所有场景中共享,我们检查了将知识从这些层转移到新场景的可能性。此外,我们研究了训练场景的数量将如何影响通用层参数的可转移性。我们将训练场景的数量从1个逐渐增加到16个,并在4个看不见的场景上进行测试。我们从每个场景中随机选择5个目标进行训练和测试。为了适应看不见的场景,我们训练场景特定的层,同时修复普通的暹罗层。图8显示了结果。随着训练场景数量的增加,我们观察到更快的收敛。与从头开始的培训相比,转移通用层显著提高了在新环境中学习的数据效率。我们还在相同的设置中评估单分支模型。由于单个分支模型包括单个场景特定的层,我们可以将训练好的模型(在16个场景上训练)应用于新场景,而无需额外的训练。然而,这导致了比偶然更差的性能,表明了适应场景特定层的重要性。单分支模型比从头开始训练的收敛速度稍快,但比我们最终的模型慢得多。
在这里插入图片描述

D.连续空间

空间离散化消除了处理复杂系统动力学的需要,例如电机控制中的噪声。在本节中,我们展示了经验结果,即同一模型能够应对更具挑战性的连续空间。

为了说明这一点,我们在一个大客厅场景中为找门任务训练了相同的目标驱动模型,目标是通过一扇门到达阳台。我们使用了与之前相同的4个动作(参见第10节)。IV-C);然而,代理的移动和转向是由物理引擎控制的。在这种情况下,该方法应该明确处理力和碰撞,因为代理可能会被障碍物阻止或沿着重物滑动。虽然这种设置需要更多的训练帧(约50M)来训练单个目标,但同一模型平均需要15步才能到达门口,而随机代理平均需要719步。我们在视频中提供了示例测试集。

E.机器人实验

为了验证我们的方法对现实世界设置的通用性,我们使用由[53]修改的SCITOS移动机器人进行了实验(见图9)。我们在三种不同的环境下训练我们的模型:1)从零开始在真实图像上训练;2)仅训练场景特定的层,同时冻结在20个模拟场景上训练的通用层参数;以及3)训练场景特定层和微调通用层参数。

在这里插入图片描述

我们在场景中的28个离散位置上训练我们的模型(禁用向后动作),这些位置在每个维度上彼此相距大约30英寸。在每个位置,机器人用头部摄像头拍摄4幅RGB图像(90度间隔)。在测试过程中,机器人根据模型的预测移动和转动。我们评估房间里有两个目标的机器人:门和微波炉。尽管该模型是在离散化空间上训练的,但它对随机起点、噪声动态、变化的步长、照明和对象布局的变化等表现出鲁棒性。视频中提供了示例测试集。由于真实场景的规模较小,所有三种设置都收敛到接近最优的策略。然而,我们发现从模拟到真实数据的参数传递和微调提供了这三种设置中最快的收敛(比从头开始训练快44%)。这为模拟在学习真实世界交互中的价值提供了支持性证据,并展示了通过少量微调从模拟推广到真实图像的可能性。

结论

我们提出了一个用于目标驱动视觉导航的深度强化学习(DRL)框架。最先进的DRL方法通常应用于视频游戏和不模拟自然图像分布的环境。这项工作是朝着更现实的设置迈出的一步。

最先进的DRL方法有一些限制,使其无法应用于现实环境。在这项工作中,我们已经解决了其中的一些限制。我们解决了跨目标和跨场景的一般化问题,与最先进的DRL方法相比提高了数据效率,并提供了AI2-托尔框架,该框架能够廉价高效地收集动作和交互数据。

我们的实验表明,我们的方法适用于在模型的端到端训练中没有使用的新目标和场景。我们还表明,与最先进的DRL方法相比,我们的方法用更少的训练样本收敛。此外,我们证明了该方法在离散域和连续域都有效。我们还表明,经过模拟训练的模型可以通过少量的微调来适应真实的机器人。我们提供的可视化显示,我们的DRL方法隐含地执行定位和映射。最后,我们的方法是端到端可训练的。与常见的视觉导航方法不同,它不需要显式的特征匹配或环境的3D重建。

我们未来的工作包括增加框架中高质量3D场景的数量。我们还计划在距离更远和动态变化的环境中评估我们的模型,并建立模型来学习框架中的物理交互和对象操作。

猜你喜欢

转载自blog.csdn.net/wangyifan123456zz/article/details/114760329
今日推荐