VoxPoser:使用大语言模型(GPT-4)来对机器人操作的可组合三维值图【论文解读】

这是最近斯坦福的李飞飞团队的一篇论文:VoxPoser: Composable 3D Value Maps for Robotic Manipulation with Language Models
主要是通过大语言模型LLM和视觉语言模型VLM结合,来对机器人做各种日常操作,我们可以先来看下实际效果:大语言模型加视觉模型的通用机器人
可以看到在不同的实际场景中都可以很好的进行日常操作,而且具备对机器人不需要进行训练的优势。对于这篇论文的解读,尽量通俗的按照自己的理解来表达,希望对大家有帮助,当然水平有限,有误之处,欢迎指正,一起进步。

1、VoxPoser开发的初衷

在以往的机器人操作当中,我们都是需要先预定义轨迹,这就使得机器人变得比较局限,更重要的是大规模的机器人数据的获取都是比较困难的,这就限制了机器人领域的发展。而ChatGPT4的出色回答,让我们感到让机器人成为通用机器人成为可能,可以利用这样的LLM来进行推理,然后给出机器人一些有用的步骤,再通过VLM来规划路径,这样理论上就做到了,机器人可以通过自然语言而跟现实世界进行交互了。所以VoxPoser就被开发出来了,这个工作的目标就是合成机器人轨迹,也就是接下来将要介绍的使用6自由度的末端执行器规划路径点序列,还开放了指令集和对象集。
我们先来看一张VOXPOSER示意图:

左边是VoxPoser的概览图,右边是一些操作的演示。
可以看到我们是在大语言模型提取了支持和约束(这里的支持就是机器人的操作目标,下面也可能有叫功能或功能可见性等叫法,意思是一样的,约束就是机器人在操作过程中要避开的东西),也可能叫做回避,比如这里的“Open the top drawer, and watch out for that vase!”(打开最上面的抽屉,小心那个花瓶!),故这里的抽屉就是支持,花瓶就是约束。
得到的步骤如下:
        1、应抓住最上面的抽屉把手
        2、把手需要向外平移
        3、机器人应远离花瓶
这些步骤再结合视觉语言模型,使用VOXPOSER提供的代码接口就能够规划出机器人的轨迹。

2、VoxPoser原理实现

上面我们大概介绍了VOXPOSER,接下来具体介绍VOXPOSER的原理,上面的示意图我们仔细观察左边那个机器人所在的空间,会发现每个区域的颜色是有区别的,看那个颜色条,左边是high cost,右边是high reward,也就是成本越高颜色是红颜色,高奖励的地方是蓝色,这样就会让机器人对此作出路径规划。

2.1、LLM+VLM

那具体是如何去实现的呢?同样的,来看一张示意图:

这里给出了两个函数的代码,affordance_map()constraint_map(),分别表示需要操作的目标和需要避开的目标的映射。
大语言模型生成与视觉语言模型交互的代码,以此来生成基于机器人观察空间的一系列3D功能图和约束图(统称为值图),然后,合成的值图作为运动规划者合成机器人操作轨迹的目标函数。
从两个函数来看,大同小异,都是先初始化一个三维数组(张量)映射,然后各自检测目标detect('handle')detect('vase'),不同点就是affordance_map是需要将目标对象的位置(top_handle.pos)都设置为1,在constraint_map里面是将检测到的对象所占用的格子(vase.occupancy_grid)的位置都设置为-1,最后两个分别返回其对应的值图。
经过上述处理之后,就有了Motion Planning运动规划:一种在机器人学和自动控制领域中用于规划物体在空间中的运动路径的方法,以避免碰撞并满足其他约束条件。

2.2、方法与公式

我们知道语言所表达出来的东西是比较自由的,或者说比较的宽泛,而机器人需要的是,具体的有针对性的操作指令。

比如说,“打开最上面的抽屉”,单纯根据这句话可能生成轨迹就很困难,所以我们将一个问题进行分解,拆分成具体的子任务,明确地去指定操作任务,可以分解为“抓住顶层抽屉的把手”和“拉开抽屉”,这种由高级规划器(如LLM或基于搜索的规划器)得到的具体子任务就变得可操作性了。
接下来就是将每个子任务进行优化,这里的子任务是LLM语言指令和机器人的运动路径,其中运动路径是由操作空间控制器执行的密集末端执行器路径点序列,每个路径点是由6自由度末端执行器姿态、末端执行器速度和夹持器动作组成

我们将这些表述为如下的一个公式: 

T_i :环境状态的演化
T_i^r \subseteq T_i :机器人轨迹
C(T_i) :相关的动力学和运动学约束,subject to 受制于的意思。
F_{task} :T_i 完成指令的程度进行评分
F_{control} :指定控制成本,例如,鼓励 T_i^r 最小化总控制时间

通过对每个子任务求解这个优化问题,我们得到一系列机器人轨迹,这些轨迹共同完成指令L指定的总体任务。

对于自由形式的语言指令,计算F_{task}是极具挑战性的,不仅因为语义语言可以传达的空间丰富,而且因为缺乏机器人标记数据。然而,我们提供了一个关键的观察结果,即在机器人的观察空间中,大量的任务可以用一个体素值映射V \in R^{w*h*d}来表征。这里的体素值可以理解成空间三维的数组或坐标,然后做映射。

“抓住顶层抽屉把手”(由LLMs推断)。“感兴趣的实体”是机器人的末端执行器,体素值映射应该反映对抽屉手柄的吸引力。通过进一步命令“小心花瓶”,地图也可以更新,以反映来自花瓶的排斥。
我们表示“感兴趣的实体”为e,其轨迹为T^e,使用给定指令的体素值映射, F_{task}任务可以通过累加遍历的e值来近似,公式如下:

其中的p_j^e\in N^3e在第j步的离散(x, y, z)的位置,由于这些位置是稀疏的,我们通过平滑操作来增加体素地图的密度,鼓励运动规划器优化更平滑的轨迹。
由于VoxPoser使用具有丰富常识的大语言模型来合成机器人轨迹,因此零射击合成轨迹 T_0^r 可以作为行动抽样分布 P(a_t | o_t,T_0^r) 的有用的先验偏差,这可以显著加快学习过程。在实践中,这可以通过在 T_0^r 附近的采样动作来实现,通过添加小噪声ε来鼓励局部探索,而不是在整个行动空间中探索。

2.3、重建点云

LLM使用他们自己生成的代码,其中每个语言模型程序language model program(LMP)负责一个独特的功能(例如,处理感知调用)。本论文用的是OpenAI的GPT-4开放的API。
我们先来看下对比基线的实验结果:

可以看到VoxPoser有着很高的执行日常任务的成功率,不仅在可见任务有着高成功率,而且在不可见的任务中同样有着差不多的成功率。
具体有哪些操作呢?
给定来自LLM的对象/部件的查询,我们首先调用open-vocab检测器OWL-ViT获取边界框,将其馈入到Segment Anything (Meta的分割一切对象模型)获取掩码,并使用视频跟踪器XMEM (基于Atkinson-Shiffrin记忆模型的长视频对象分割)跟踪掩码。利用跟踪掩码与RGB-D观测相结合,重建目标或部分的点云。

2.4、值图(映射)与运动规划器

我们定义了以下类型的值图:affordance功能可见、avoidance回避、end-effector velocity末端执行器速度、end-effector rotation末端执行器旋转和gripper action抓取动作。
每种类型使用不同的语言模型程序(LMP),它接受指令并输出形状为(100,100,100,k)的体素图,其中k对于每个值图是不同的(例如,k=1用于功能可见和回避,k=4用于旋转)
我们将Euclidean distance欧氏距离变换应用于功能可见性的映射,高斯滤波器则应用于回避映射。在值映射LMP的基础上,我们定义了两个高级LMPs来协调它们的行为:planner规划器以用户指令L作为输入(例如,“打开抽屉”)并输出一系列子任务l_{1:N},然后composer以子任务l_i为输入并调用相关的值映射LMPs,并进行详细的语言参数化。

接下来就是构造运动规划器,在规划器优化中只考虑可见性映射和回避映射,使用贪心搜索找到一系列无碰撞的末端执行器位置p_{1:N} \in R^3。然后我们通过剩余的值映射(例如,旋转映射,速度映射)在每个p上强制其他参数化。运动规划器使用的代价映射被计算为权值为2和1的归一化可视性和回避映射的加权和的负数,合成6自由度轨迹后,执行第一个航路点,然后以5Hz的频率重新规划新的轨迹。

具体来说,我们首先使用VoxPoser合成k个不同的轨迹,每个轨迹都表示为一系列末端执行器路径点。然后,我们学习了一个MLP动态模型,通过迭代过程从o_ta_t预测o_{t+1},其中代理在数据收集和模型学习之间交替进行。在MPC的动作抽样分布中,我们加入o_{t+1},将初始合成轨迹作为先验到T_0^r中的每个路径点,鼓励本地探索,使用这些轨迹作为先验探索,我们可以在不到3分钟的在线交互中学习有效的动力学模型,从而获得较高的最终成功率。相比之下,如果没有先验,学习动态模型是非常困难的,因为大多数动作不会导致有意义的环境变化。

3、应对突发状况

大模型的一些不可预测现象,如何应对,这里我们使用了LLM,有着丰富的世界知识。特别是,我们将研究重点放在VoxPoser独有的行为能力上。我们观察到以下能力:

1.估计物理性质:给定两个未知质量的块,机器人的任务是使用可用的工具进行物理实验,以确定哪个块更重。
2.行为常识推理:在机器人布置桌子的任务中,用户可以指定行为偏好,例如“我是左撇子”,这需要机器人在任务的上下文中理解其含义。
3.细粒度的语言纠错:对于“用壶盖盖住茶壶”等要求高精度的任务,用户可以给机器人精确的指令,比如“你向左偏差了1cm”,这种精确的要求也可以没有问题的。
4.多步可视化程序:给定一个“精确打开抽屉一半”的任务,由于对象模型不可用,信息不足,VoxPoser可以提出多步操作策略,根据视觉反馈,首先在记录手柄位移的同时将抽屉完全打开,然后将其关闭回中点以满足要求。

上述的应急能力,对应体现在如下图:

4、VoxPoser局限性 

在这项工作中,我们提出了VoxPoser,一个通用的机器人操作框架,从LLM中提取功能和约束,为开放集指令和对象提供了显著的泛化优势。特别是,我们使用代码编写LLMVLM进行交互,以组成基于观测空间的3D值图,用于合成日常操作任务的轨迹。此外,我们展示了VoxPoser可以通过有效地学习一个动态模型来完成丰富的接触任务,从而从在线交互中受益。
当然VoxPoser也存在下面几点的限制:

首先,它依赖于外部感知模块,这在需要整体视觉推理或理解细粒度物体几何形状的任务中受到限制。
其次,虽然适用于高效的动态学习,但仍然需要一个通用的动态模型来实现具有相同泛化水平的多接触任务。
第三,我们的运动规划器只考虑末端执行器轨迹,而全臂规划也是可行的,可能是更好的设计选择。

5、VoxPoser的Transforms3d

其中VoxPoser的核心就是向LLM提供代码支持,除了有NumpyTransforms3d库之外,还提供了很多APIs
Transforms3d库的详细说明:
http://matthew-brett.github.io/transforms3d/index.html
安装transforms3d命令,带上阿里云镜像速度快点:
pip install transforms3d -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com 

再检验下是否安装成功:

import transforms3d
transforms3d.__version__
#'0.4.1'
dir(transforms3d)
#['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_version', 'affines', 'axangles', 'euler', 'quaternions', 'reflections', 'shears', 'taitbryan', 'utils', 'zooms']

这个库主要是矩阵变换、欧拉角、四元数等等的转换,具体详细用法可以看前面给出的链接。

6、VoxPoser的APIs

我们来看下VoxPoser提供了哪些对外接口:
detect(obj name):接受一个对象名并返回一个字典列表,其中每个字典对应于匹配对象的一个实例,包含中心位置、占用网格和平均法向量(正态均值向量)

execute(movable,affordance map,avoidance map,rotation map,velocity map,gripper map):接受“感兴趣的实体”作为“可移动的”(由detect返回的字典)和(可选的)值映射列表,并调用运动规划器来执行轨迹。请注意,在MPC设置中,“可移动”和输入值映射是可以重新评估以反映最新环境观察的函数,另外这里的感兴趣实体就是机器人的末端执行器,通过它的移动来操作目标。

cm2index(cm,direction):沿方向获取所需的偏移距离(以厘米为单位),并返回以体素坐标反映位移的三维向量

index2cm(index,direction):接受一个整数“索引”和一个“方向”向量,并返回被体素坐标中的“整数”所取代的世界坐标中的距离

pointat2quat(vector):为末端执行器获取所需的指向方向,并返回一个令人满意的目标四元数

set_voxel_by_radius(voxel_map,voxel_xyz,radius_cm,value):从“voxel_map体素图”中的“voxel_xyz”中为“半径”内的voxel体素分配值。

get_empty_affordance_map():返回初始化为0的功能可见性图(映射),其中高值将吸引实体。
其中对affordance的翻译比较多,有功能可见性,功能可供性,自解释性,启示等,初次接触可能有点懵,没有关系,这里的关键点是需要知道具体是什么意思就行了。意思是说这个东西自己呈现出来的功能,自然会联想到怎么去使用它,比如看到抽屉手柄,就会想着去拉或者推;看到家里的水龙头,就可能是旋转进行关停;看到按钮就知道是按压,这就是所谓的功能可见性。

get_empty_avoidance_map(): 返回初始化为0的避障图(映射),其中高值将排斥实体。

get_empty_rotation_map():返回用当前末端执行器四元数初始化的默认旋转映射。

get_empty_gripper_map():返回用当前抓取器动作初始化的默认抓取器映射,其中1表示“关闭”,0表示“打开”

get_empty_velocity_map():返回一个初始化为1的默认功能映射,其中数字表示比例因子(例如,0.5表示默认速度的一半)

reset_to_default_pose():重置机器人为休息姿势

7、Prompts提示

最后是将上述在日常操作任务中,需要用到的提示,以及一些不可见的属性之类的,分解成具体的步骤。当然目前站点对下面这些代码还没有公开,后期应该会很快开放。

7.1、planner计划器

接收用户指令L并生成一系列子任务l_i,这些子任务l_i被送入composer(注意,在模拟中不使用计划器,因为评估的任务由单个操作阶段组成)。
https://voxposer.github.io/prompts/real_planner_prompt.txt
摘要如下

import numpy as np
from env_utils import execute
from perception_utils import parse_query_obj
import action_utils import composer

objects = ['blue block', 'yellow block', 'mug']# ['蓝色块','黄色块','马克杯']
# Query: place the blue block on the yellow block, and avoid the mug at all time.
# 把蓝色块放在黄色块上,并且一直避免杯子

composer("grasp the blue block while keeping at least 15cm away from the mug")#抓住蓝色方块,同时与杯子保持至少15厘米的距离
composer("back to default pose")#回到默认姿势
composer("move to 5cm on top of the yellow block while keeping at least 15cm away from the mug")#移动到黄色方块上方5厘米处,同时与杯子保持至少15厘米的距离
composer("open gripper")# 打开抓取器

可以看到,提供的方法还是很清晰简洁的,首先就是保存需要关注和避开的objects对象列表,然后通过composer去解析每条具体的语言指令。

7.2、composer编写器

接受子任务指令l_i,调用必要的值映射LMPs组成功能映射和约束映射。
下面都将分为模拟器和真实环境
simulation: https://voxposer.github.io/prompts/sim_composer_prompt.txt
real-world: https://voxposer.github.io/prompts/real_composer_prompt.txt
摘要如下:

import numpy as np
from env_utils import execute, reset_to_default_pose
from perception_utils import parse_query_obj
from plan_utils import get_affordance_map, get_avoidance_map, get_velocity_map, get_rotation_map, get_gripper_map

# Query: move ee forward for 7cm.
# 将对象ee向前移动7厘米
movable = parse_query_obj('ee')
affordance_map = get_affordance_map(f'a point 7cm in front of {movable.position}')
execute(movable, affordance_map)

7.3、parse_query_obj

接受对象/部件名称的文本查询并返回一个字典列表,其中每个字典对应于包含中心位置、占用网格和正态均值向量的匹配对象的一个实例。
simulation: https://voxposer.github.io/prompts/sim_parse_query_obj_prompt.txt
real-world: https://voxposer.github.io/prompts/real_parse_query_obj_prompt.txt
摘要如下:

import numpy as np
from perception_utils import detect

objects = ['green block', 'yellow line']
# Query: ee.
ee = detect('ee')[0]
ret_val = ee

objects = ['drawer', 'blue block', 'yellow block']
# Query: topmost handle.
# 顶层把手
handles = detect('drawer handle')
# topmost so sort by z, take the last one
# 最上面:按z排序取最后一个
handles = sorted(handles, key=lambda x: x.position[2])
top_handle = handles[-1]
ret_val = top_handle

7.4、get_affordance_map

从编写器接受自然语言参数化并返回NumPy数组用于任务提供映射。
simulation: https://voxposer.github.io/prompts/sim_get_affordance_map_prompt.txt
real-world: https://voxposer.github.io/prompts/real_get_affordance_map_prompt.txt
摘要如下:

import numpy as np
from perception_utils import parse_query_obj
from plan_utils import get_empty_affordance_map, set_voxel_by_radius, cm2index

# Query: a point 10cm in front of [10, 15, 60].
# 在[10,15,60]位置前面10cm处的一个点
affordance_map = get_empty_affordance_map()
# 10cm in front of so we add to x-axis
# 在前面10cm处,我们添加到x轴
x = 10 + cm2index(10, 'x')
y = 15
z = 60
affordance_map[x, y, z] = 1
ret_val = affordance_map

# Query: a point on the right side of the table.
# 表右侧的一个点
affordance_map = get_empty_affordance_map()
table = parse_query_obj('table')
(min_x, min_y, min_z), (max_x, max_y, max_z) = table.aabb
center_x, center_y, center_z = table.position
# right side so y = max_y
x = center_x
y = max_y
z = center_z
affordance_map[x, y, z] = 1
ret_val = affordance_map

7.5、get_avoidance_map

从编写器接受自然语言参数化并返回NumPy数组用于任务回避映射。
simulation: https://voxposer.github.io/prompts/sim_get_avoidance_map_prompt.txt
real-world: https://voxposer.github.io/prompts/real_get_avoidance_map_prompt.txt
摘要如下:

import numpy as np
from perception_utils import parse_query_obj
from plan_utils import get_empty_avoidance_map, set_voxel_by_radius, cm2index

# Query: 10cm from the bowl.
# 离碗10cm
avoidance_map = get_empty_avoidance_map()
bowl = parse_query_obj('bowl')
set_voxel_by_radius(avoidance_map, bowl.position, radius_cm=10, value=1)
ret_val = avoidance_map

7.6、get_rotation_map

从编写器中接受自然语言参数化,并返回末端执行器旋转图的NumPy数组。
simulation: https://voxposer.github.io/prompts/sim_get_rotation_map_prompt.txt
real-world: https://voxposer.github.io/prompts/real_get_rotation_map_prompt.txt
摘要如下:

import numpy as np
from plan_utils import get_empty_rotation_map, set_voxel_by_radius, cm2index, vec2quat
from perception_utils import parse_query_obj
from transforms3d.euler import euler2quat, quat2euler
from transforms3d.quaternions import qmult, qinverse

# Query: face the support surface of the bowl.
# 面朝碗的支撑面
rotation_map = get_empty_rotation_map()
bowl = parse_query_obj('bowl')
target_rotation = vec2quat(-bowl.normal)
rotation_map[:, :, :] = target_rotation
ret_val = rotation_map

7.7、get_gripper_map

从编写器接受自然语言参数化,并为抓手动作图返回NumPy数组
simulation: https://voxposer.github.io/prompts/sim_get_gripper_map_prompt.txt
real-world: https://voxposer.github.io/prompts/real_get_gripper_map_prompt.txt
摘要如下:

import numpy as np
from perception_utils import parse_query_obj
from plan_utils import get_empty_gripper_map, set_voxel_by_radius, cm2index

# Query: open everywhere except 1cm around the green block.
# 除绿色块周围1cm外,所有地方都打开
gripper_map = get_empty_gripper_map()
# open everywhere
gripper_map[:, :, :] = 0
# close when 1cm around the green block
green_block = parse_query_obj('green block')
set_voxel_by_radius(gripper_map, green_block.position, radius_cm=1, value=1)
ret_val = gripper_map

7.8、get_velocity_map

从编写器中接受自然语言参数化,并返回末端执行器速度图的NumPy数组。
simulation: https://voxposer.github.io/prompts/sim_get_velocity_map_prompt.txt
real-world: https://voxposer.github.io/prompts/real_get_velocity_map_prompt.txt
摘要如下:

import numpy as np
from plan_utils import get_empty_velocity_map, set_voxel_by_radius, cm2index
from perception_utils import parse_query_obj

# Query: faster when on the right side of the table and slower when on the left side of the table.
# 在桌子右边时速度更快,在桌子左边时速度更慢
velocity_map = get_empty_velocity_map()
table = parse_query_obj('table')
center_x, center_y, center_z = table.position
# faster on right side so 1.5 when y > center_y, slower on left side so 0.5 when y < center_y
velocity_map[:, center_y:, :] = 1.5
velocity_map[:, :center_y, :] = 0.5
ret_val = velocity_map

更多的细节,建议看论文原文,这里主要是个人对其的理解,有错误之处,还请指正。
引用:
voxposer:https://voxposer.github.io/
XMem:https://github.com/hkchengrex/XMem

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2023牛客多校第三场 B.Auspiciousness

传送门 前题提要:没得说,赛时根本没想到dp,赛后翻各大题解看了很久,终于懂了dp的做法,故准备写一篇题解. 首先,先定义一下我们的 d p dp dp方程,考虑将处于 [ 1 , n ] [1,n] [1,n]的数当做小数,将处于 [ n 1 , 2 ∗ n ] [n1,2*n] [n1,2∗n]的数当做大数.那么对于我们的摸牌结…

使用低代码开发,需要注意哪些?

低代码平台的历史相对较短&#xff0c;大约始于 2000 年初&#xff0c;源于快速应用程序开发工具。随着低代码平台和工具的日益普及和优势&#xff0c;它不断发展以满足各种领域和角色的需求。 本文将研究各种低代码和无代码应用程序开发方法、业务用例、挑战和未来预测等。 一…

java重试机制实现方案

本文内容是目前团队内小磊同学对重试机制实现方案的梳理总结。 从为什么需要重试的背景开始&#xff0c;到重试的场景&#xff0c;大致的一些设计思路&#xff0c;最后通过两个成熟的retry组件进行案例讲解&#xff0c;理论实战。 背景 重试是系统提高容错能力的一种手段。在一…

LeetCode208.Implement-Trie-Prefix-Tree<实现 Trie (前缀树)>

题目&#xff1a; 思路&#xff1a; tire树&#xff0c;学过&#xff0c;模板题。一种数据结构与算法的结合吧。 代码是&#xff1a; //codeclass Trie { private:bool isEnd;Trie* next[26]; public:Trie() {isEnd false;memset(next, 0, sizeof(next));}void insert(strin…

区块链服务网络的顶层设计与应用实践

日前&#xff0c;2023全球数字经济大会专题论坛&#xff1a;Web3.0发展趋势专题论坛暨2023区块链、元宇宙蓝皮书发布会在北京举行。本次论坛上隆重发布了《中国区块链发展报告&#xff08;2023&#xff09;》&#xff0c;对我国区块链行业在2022年的发展状况进行了总结梳理&…

springboot中配置bpmsjs插件-activiti7流程图绘制插件/IDEA中运行bpmnjs

BPMNJS的安装和使用需要依赖nodejs插件,需要先安装NODEJS,因为bpmnjs插件的运行需要使用到NODEJS中的npm命令。 安装nodejs 安装和使用bpmnjs插件,绘制activiti工作流需要的流程图。 1、安装和配置nodejs 2.1、下载nodejs https://nodejs.org/en 1.2、安装nodejs,默认安…

MacDroid for Mac:在Mac上访问和传输Android文件的最简单方式

MacDroid for Mac是一款帮助用户在Mac和Android设备之间传输文件的软件。由于Mac OS X本身并不支持MTP协议&#xff0c;所以透过USB将Android设备连接到Mac电脑上是无法识别的&#xff0c;更别说读取里面的文件了。 MacDroid可以帮助您轻松搞定这个问题&#xff0c;您可以将An…

【Python】数据分析+数据挖掘——探索Pandas中的索引与数据组织

前言 在数据科学和数据分析领域&#xff0c;Pandas是一个备受喜爱的Python库。它提供了丰富的数据结构和灵活的工具&#xff0c;帮助我们高效地处理和分析数据。其中&#xff0c;索引在Pandas中扮演着关键角色&#xff0c;它是一种强大的数据组织和访问机制&#xff0c;使我们…

【JavaWeb】正则表达式

&#x1f384;欢迎来到边境矢梦的csdn博文&#xff0c;本文主要讲解Java 中正则表达式 的相关知识&#x1f384; &#x1f308;我是边境矢梦&#xff0c;一个正在为秋招和算法竞赛做准备的学生&#x1f308; &#x1f386;喜欢的朋友可以关注一下&#x1faf0;&#x1faf0;&am…

spring启动流程 (6完结) springmvc启动流程

SpringMVC的启动入口在SpringServletContainerInitializer类&#xff0c;它是ServletContainerInitializer实现类(Servlet3.0新特性)。在实现方法中使用WebApplicationInitializer创建ApplicationContext、创建注册DispatcherServlet、初始化ApplicationContext等。 SpringMVC…

Selenium多浏览器处理

Python 版本 #导入依赖 import os from selenium import webdriverdef test_browser():#使用os模块的getenv方法来获取声明环境变量browserbrowser os.getenv("browser").lower()#判断browser的值if browser "headless":driver webdriver.PhantomJS()e…

【多模态】19、RegionCLIP | 基于 Region 来实现视觉语言模型预训练

文章目录 一、背景二、方法2.1 Region-based Language-Image Pretraining2.2 目标检测的迁移学习 三、效果3.1 数据集3.2 实现细节3.3 结果 论文&#xff1a; RegionCLIP: Region-based Language-Image Pretraining 代码&#xff1a;https://github.com/microsoft/RegionCLIP …

手写线程池 - C++版 - 笔记总结

1.线程池原理 创建一个线程&#xff0c;实现很方便。 缺点&#xff1a;若并发的线程数量很多&#xff0c;并且每个线程都是执行一个时间较短的任务就结束了。 由于频繁的创建线程和销毁线程需要时间&#xff0c;这样的频繁创建线程会大大降低 系统的效率。 2.思考 …

Maven基础之项目创建、packaging

文章目录 创建 maven 项目流程骨架是浮云&#xff0c;packaging 是关键 创建 maven 项目流程 通过骨架&#xff08;archetype&#xff09;创建 maven 工程 第一步&#xff1a;选择 new → maven → Maven Project 第二步&#xff1a;New Maven Project 窗口不作任何设置&…

Zabbix监控ActiveMQ

当我们在线上使用了ActiveMQ 后&#xff0c;我们需要对一些参数进行监控&#xff0c;比如 消息是否有阻塞&#xff0c;哪个消息队列阻塞了&#xff0c;总的消息数是多少等等。下面我们就通过 Zabbix 结合 Python 脚本来实现对 ActiveMQ的监控。 一、创建 Activemq Python 监控…

Java 异常处理的使用和思考

概念 异常处理的概念起源于早期的编程语言&#xff0c;如 LISP、PL/I 和 CLU。这些编程语言首次引入了异常处理机制&#xff0c;以便在程序执行过程中检测和处理错误情况。异常处理机制随后在 Ada、Modula-3、C、Python、Java 等编程语言中得到了广泛采用和发展。在 Java 中&a…

Unity Addressable

Unity重要目录 工程中的几个重要目录 Assets存放资源、代码、配置Library大部分的资源导入到Assets目录之后&#xff0c;会转化成Unity认可的文件&#xff0c;转化后的文件会存储在这个目录Logs日志文件Packages第三方插件ProjectSettings存放各种项目设定UserSettings用户偏好…

基于Truss+Docker+Kubernetes把开源模型Falcon-7B送上云端(译)

背景 到目前为止&#xff0c;我们已经看到了ChatGPT的能力及其所能提供的强大功能。然而&#xff0c;对于企业应用来说&#xff0c;像ChatGPT这样的封闭源代码模型可能会带来风险&#xff0c;因为企业自身无法控制他们的数据。尽管OpenAI公司声称用户数据不会被存储或用于训练…

python 将pdf文件转图片

有小伙伴问了怎么将 pdf文件转图片的问题&#xff0c;我百度了一波儿&#xff0c;搞了以下python代码给他封装成exe工具了。 中途打包踩了个坑&#xff0c;python进程池的问题&#xff0c;本地运行没啥问题&#xff0c;打包好的exe文件双击就会使电脑内存爆破卡死&#xff0c;…

缩略所写的代码

有一长串的代码需要进行缩略 可以在要缩略的代码的前一行加上注释。并在其中写上 #region。 在最后一行的下一行加上注释&#xff0c;并在其中写上 #endregion。 最终结果&#xff1a;