• [第5期高维向量数据] total time limit: 50 seconds是指每个测试集50秒还是一共50秒
    total time limit: 50 seconds是指每个测试集50秒还是一共50秒
  • [第5期高维向量数据] 得分为0,反馈信息也没有,
    但是本地测试一些简单的样例后,结果确实是正确的。baseline有分数,但是使用一些近似检索算法后就一直得分为0。。图1是baseline,图2 是改进代码,没有调用额外的库。
  • [常见FAQ] python程序在上传之后显示”初始化超时“
    在本地运行没有任何问题,本次初始化5ms都不到的初始化程序,在提交到系统之后一直显示”初始化超时“,求指导,该怎么办?
  • [应用开发] SegFormer-B0 OM模型在MDC300F上推理时间为1000ms
    在将segformer-b0算法模型转OM后,在MDC300F MINI上推理耗时1000ms。ONNX中MatMul算子的输入数据的shape带batch维度,将算子的type类型更改为 BatchMatMul后,转OM时,发现MatMul算子前后各出现一个trans_TransData算子。通过profiling计算算子耗时,发现TransposeD、ArgMaxD、TransData、SoftmaxV2、BatchMatMul占用大量的推理时间。请问如何避免带batch维度的MatMul产生TransData算子?针对现在算子耗时,有什么优化的方法吗?
  • [技术干货] 深度优先搜索(DFS)与广度优先搜索(BFS)及其应用场景
    在算法领域中,深度优先搜索(DFS)和广度优先搜索(BFS)是两种常见且重要的图遍历算法。它们各自具有独特的特点和适用场景。本文将详细介绍这两种算法,并探讨它们的最佳应用场景。一、深度优先搜索(DFS)深度优先搜索是一种用于遍历或搜索树或图的算法。这个算法会尽可能深地搜索图的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。DFS的应用场景:图的连通性检查:给定一个无向图,判断是否存在从节点A到节点B的路径。 生成树的构造:在计算机网络中,DFS可以用来发现网络的拓扑结构,并生成一棵生成树。 解决迷宫问题:在迷宫问题中,DFS可以用来找到从入口到出口的路径。 树的遍历:对于二叉树、多叉树等数据结构,DFS是一种非常有效的遍历方式。二、广度优先搜索(BFS)广度优先搜索是另一种用于遍历或搜索树或图的算法。它从根(或任意节点)开始并探索最近的节点,然后进行下一层的邻居节点,这样一层一层地进行。BFS使用队列数据结构来保存信息。BFS的应用场景:最短路径问题:在图中找到从一个节点到另一个节点的最短路径。例如,在地图中找到从起点到终点的最短路线。 层次遍历:对于二叉树、多叉树等数据结构,BFS可以用来进行层次遍历。 图的连通性检查:与DFS相似,BFS也可以用来检查图的连通性,但它通常用于找到从起点到所有其他可达节点的最短路径。 网络爬虫:在网页搜索中,BFS被用来遍历网页之间的链接,从而找到与给定网页相关的所有网页。总结DFS和BFS各有优缺点,选择哪种算法取决于具体的问题和应用场景。DFS通常用于深度探索,而BFS则更适用于广度探索。在实际应用中,我们需要根据问题的特性来选择最合适的算法。希望本文能帮助您更好地理解深度优先搜索和广度优先搜索,以及它们在不同场景下的应用。
  • [大赛资讯] 关于A题
    节点被自动删除后,新生成的节点编号还会复用此前的吗?比如样例中3号节点在4号pod被删除后就删除了,那再新生成一个节点编号是3还是4?
  • [技术干货] 开源项目分享之Hello算法(hello-algo)
    动画图解、一键运行的数据结构与算法教程项目地址: GitHub在线阅读                                   下载PDF《Hello 算法》:动画图解、一键运行的数据结构与算法教程,支持 Java, C++, Python, Go, JS, TS, C#, Swift, Rust, Dart, Zig 等语言。​关于本书本项目旨在打造一本开源免费、新手友好的数据结构与算法入门教程。全书采用动画图解,内容清晰易懂、学习曲线平滑,引导初学者探索数据结构与算法的知识地图。源代码可一键运行,帮助读者在练习中提升编程技能,了解算法工作原理和数据结构底层实现。鼓励读者互助学习,提问与评论通常可在两日内得到回复。推荐语
  • [互动交流] 雪花算法生成的ID为什么能保证全局唯一?
    雪花算法生成的ID为什么能保证全局唯一?
  • [其他] 浅谈AdaBoost算法
     Adaboost是一种迭代算法,其核心思想是针对同一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起来,构成一个更强的最终分类器(强分类器)。其算法本身是通过改变数据分布来实现的,它根据每次训练集之中每个样本的分类是否正确,以及上次的总体分类的准确率,来确定每个样本的权值。将修改过权值的新数据集送给下层分类器进行训练,最后将每次训练得到的分类器最后融合起来,作为最后的决策分类器。使用adaboost分类器可以排除一些不必要的训练数据特征,并放在关键的训练数据上面。 AdaBoost用于短决策树。创建第一棵树之后,使用树在每个训练实例上的性能来得到一个权重,决定下一棵树对每个训练实例的注意力。 难以预测的训练数据被赋予更多权重,而易于预测的实例被赋予更少的权重。模型是一个接一个地顺序创建的,每个模型更新训练实例上的权重,这些权重影响序列中下一个树所执行的学习。构建完所有树之后,将对新数据进行预测。 因为着重于修正算法的错误,所以重要的是提前清洗好数据,去掉异常值。 Adaboost是一种迭代算法,其核心思想是针对同一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起来,构成一个更强的最终分类器(强分类器)。  算法应用  对adaBoost算法的研究以及应用大多集中于分类问题,同时也出现了一些在回归问题上的应用。就其应用adaBoost系列主要解决了: 两类问题、多类单标签问题、多类多标签问题、大类单标签问题、回归问题。它用全部的训练样本进行学习。 应用示例  adaboost 是 bosting 的方法之一,bosting就是把若干个分类效果并不好的分类器综合起来考虑,会得到一个效果比较好的分类器。 下图,左右两个决策树,单个看是效果不怎么好的,但是把同样的数据投入进去,把两个结果加起来考虑,就会增加可信度。  adaboost 的栗子,手写识别中,在画板上可以抓取到很多 features,例如 始点的方向,始点和终点的距离等等。  training 的时候,会得到每个 feature 的 weight,例如 2 和 3 的开头部分很像,这个 feature 对分类起到的作用很小,它的权重也就会较小。  而这个 alpha 角 就具有很强的识别性,这个 feature 的权重就会较大,最后的预测结果是综合考虑这些 feature 的结果。 
  • [技术干货] wrf非压缩版安装
    wrf压缩版和非压缩版的区别?wrf运行的输出文件是否被压缩wrf压缩版和非压缩版的关键压缩wrf的中输出文件由netcdf处理输出,所以两者区别在于netcdf的不同。社区文档默认安装压缩版的netcdf,现在记录下非压缩版netcdf的安装压缩版netcdf-c,主要添加--disable-netcdf-4./configure --prefix=${NETCDT_DIR} --build=aarch64-unknown-linux-gnu --disable-netcdf-4 --enable-shared --enable-netcdf-4 --disable-dap --with-pic --disable-doxygen --enable-static --enable-pnetcdf --enable-largefile CPPFLAGS="-O3 -I${HDF5_DIR}/include -I${PNETCDF_DIR}/include" LDFLAGS="-L${HDF5_DIR}/lib -L${PNETCDF_DIR}/lib -Wl,-rpath=${HDF5_DIR}/lib -Wl,-rpath=${PNETCDF_DIR}/lib" CFLAGS="-O3 -L${HDF5_DIR}/lib -L${PNETCDF_DIR}/lib -I${HDF5_DIR}/include -I${PNETCDF_DIR}/include"压缩版netcdf-fortran,主要添加--disable-fortran-type-check./configure --prefix=${NETCDT_DIR} --build=aarch64-unknown-linux-gnu --disable-fortran-type-check --enable-shared --with-pic --disable-doxygen --enable-largefile --enable-static CPPFLAGS="-O3 -I${HDF5_DIR}/include -I${NETCDT_DIR}/include" LDFLAGS="-L${HDF5_DIR}/lib -L${NETCDT_DIR}/lib -Wl,-rpath=${HDF5_DIR}/lib -Wl,-rpath=${NETCDT_DIR}/lib" CFLAGS="-O3 -L${HDF5_DIR}/lib -L${NETCDT_DIR}/lib -I${HDF5_DIR}/include -I${NETCDT_DIR}/include" CXXFLAGS="-O3 -L${HDF5_DIR}/lib -L${NETCDT_DIR}/lib -I${HDF5_DIR}/include -I${NETCDT_DIR}/include" FCFLAGS="-O3 -L${HDF5_DIR}/lib -L${NETCDT_DIR}/lib -I${HDF5_DIR}/include -I${NETCDT_DIR}/include"其余安装步骤与压缩版netcdf移植。检查netcdf是否是压缩版命令行输入: nc-config --all 非压缩版如下图:压缩版如下图:判断wrf是否是压缩版:./configure 之后出现以下信息: 非压缩版: 压缩版:
  • [技术干货] One-Class SVM介绍【转】
    传统意义上,很多的分类问题试图解决两类或者多类情况,机器学习应用的目标是采用训练数据,将测试数据属于哪个类进行区分。但是如果只有一类数据,而目标是测试新的数据并且检测它是否与训练数据相似。One-Class Support Vector Machine在过去20里逐渐流行,就是为了解决这样的问题。本篇博客对One-Class SVM进行介绍,而One-Class SVM也会应用到我的论文中。1. Just One Class?首先先看下我们的问题,我们希望确定新的训练数据是否属于某个特定类?怎么会有这样的应用场景呢?比方说,我们要判断一张照片里的人脸,是男性还是女性,这是个二分类问题。就是将一堆已标注了男女性别的人脸照片(假设男性是正样本,女性是负样本),提取出有区分性别的特征(假设这种能区分男女性别的特征已构建好)后,通过svm中的支持向量,找到这男女两类性别特征点的最大间隔。进而在输入一张未知性别的照片后,经过特征提取步骤,就可以通过这个训练好的svm很快得出照片内人物的性别,此时我们得出的结论,我们知道要么是男性,不是男性的话,那一定是女性。以上情况是假设,我们用于训练的样本,包括了男女两类的图片,并且两类图片的数目较为均衡。现实生活中的我们也是这样,我们只有在接触了足够多的男生女生,知道了男生女生的性别特征差异后(比方说女性一般有长头发,男性一般有胡子等等),才能准确判断出这个人到底是男是女。但如果有一个特殊的场景,比方说,有一个小和尚,他从小在寺庙长大,从来都只见过男生,没见过女生,那么对于一个男性,他能很快地基于这个男性与他之前接触的男性有类似的特征,给出这个人是男性的答案。但如果是一个女性,他会发现,这个女性与他之前所认知的男性的特征差异很大,进而会得出她不是男性的判断。但注意这里的“她不是男性”不能直接归结为她是女性。再比如,在工厂设备中,控制系统的任务是判断是是否有意外情况出现,例如产品质量过低、机器产生奇怪的震动或者温度上升等。相对来说容易收集到正常场景下的训练数据,但故障系统状态的收集示例数据可能相当昂贵,或者根本不可能。 如果可以模拟一个错误的系统状态,但必然无法保证所有的错误状态都被模拟到,从而在传统的两类问题中得到识别。2. Schölkopf的OCSVMThe Support Vector Method For Novelty Detection by Schölkopf et al. 基本上将所有的数据点与零点在特征空间分离开,并且最大化分离超平面到零点的距离。这产生一个binary函数能够获取特征空间中数据的概率密度区域。当处于训练数据点区域时,返回+1,处于其他区域返回-1.该问题的优化目标与二分类SVM略微不同,但依然很相似其中表示松弛变量, 类似于二分类SVM中的,同时:它为异常值的分数设置了一个上限(训练数据集里面被认为是异常的)是训练数据集里面做为支持向量的样例数量的下届因为这个参数的重要性,这种方法也被称为。采用Lagrange技术并且采用dot-product calculation,确定函数变为:这个方法创建了一个参数为的超平面,该超平面与特征空间中的零点距离最大,并且将零点与所有的数据点分隔开。3. SVDDThe method of Support Vector Data Description by Tax and Duin (SVDD)采用一个球形而不是平面的方法,该算法在特征空间中获得数据周围的球形边界,这个超球体的体积是最小化的,从而最小化异常点的影响。产生的超球体参数为中心和半径 ,体积 被最小化,中心 是支持向量的线性组合;跟传统SVM方法相似,可以要求所有数据点 到中心的距离严格小于 ,但同时构造一个惩罚系数为 的松弛变量,优化问题如下所示:在采用拉格朗日算子求解之后,可以判断新的数据点是否在类内,如果z到中心的距离小于或者等于半径。采用Gaussian Kernel做为两个数据点的距离函数:转自 https://zhuanlan.zhihu.com/p/32784067
  • [技术干货] 情感分析神器!再也不怕女朋友生气 【转】
    背景介绍众所周知,人类自然语言中包含了丰富的情感色彩:表达人的情绪(如悲伤、快乐)、表达人的心情(如倦怠、忧郁)、表达人的喜好(如喜欢、讨厌)、表达人的个性特征和表达人的立场等等。情感分析在商品喜好、消费决策、舆情分析等场景中均有应用。利用机器自动分析这些情感倾向,不但有助于帮助企业了解消费者对其产品的感受,为产品改进提供依据;同时还有助于企业分析商业伙伴们的态度,以便更好地进行商业决策。被人们所熟知的情感分析任务是将一段文本分类,如分为情感极性为 正向、负向、其他的三分类问题:情感分析任务正向:表示正面积极的情感,如高兴,幸福,惊喜,期待等。负向:表示负面消极的情感,如难过,伤心,愤怒,惊恐等。其他:其他类型的情感。实际上,以上熟悉的情感分析任务是句子级情感分析任务。情感分析预训练模型SKEP近年来,大量的研究表明基于大型语料库的预训练模型(Pretrained Models, PTM)可以学习通用的语言表示,有利于下游NLP任务,同时能够避免从零开始训练模型。随着计算能力的发展,深度模型的出现(即 Transformer)和训练技巧的增强使得 PTM 不断发展,由浅变深。情感预训练模型SKEP(Sentiment Knowledge Enhanced Pre-training for Sentiment Analysis)。SKEP利用情感知识增强预训练模型, 在14项中英情感分析典型任务上全面超越SOTA,此工作已经被ACL 2020录用。SKEP是百度研究团队提出的基于情感知识增强的情感预训练算法,此算法采用无监督方法自动挖掘情感知识,然后利用情感知识构建预训练目标,从而让机器学会理解情感语义。SKEP为各类情感分析任务提供统一且强大的情感语义表示。论文地址:https://arxiv.org/abs/2005.05635百度研究团队在三个典型情感分析任务,句子级情感分类(Sentence-level Sentiment Classification),评价目标级情感分类(Aspect-level Sentiment Classification)、观点抽取(Opinion Role Labeling),共计14个中英文数据上进一步验证了情感预训练模型SKEP的效果。具体实验效果参考:https://github.com/baidu/Senta#skep情感分析任务还可以进一步分为句子级情感分析、目标级情感分析等任务。在下面章节将会详细介绍两种任务及其应用场景。句子级情感分析 &目标级情感分析本项目将详细全面介绍情感分析任务的两种子任务,句子级情感分析和目标级情感分析。记得给 PaddleNLP点个小小的 Star⭐开源不易,希望大家多多支持~GitHub地址:https://github.com/PaddlePaddle/PaddleNLPAI Studio平台后续会默认安装PaddleNLP最新版,在此之前可使用如下命令更新安装。!pip install--upgrade paddlenlp -i https://pypi.org/simple1 句子级情感分析对给定的一段文本进行情感极性分类,常用于影评分析、网络论坛舆情分析等场景。如:① 选择珠江花园的原因就是方便,有电动扶梯直接到达海边,周围餐馆、食廊、商场、超市、摊位一应俱全。酒店装修一般,但还算整洁。泳池在大堂的屋顶,因此很小,不过女儿倒是喜欢。包的早餐是西式的,还算丰富。服务吗,一般 1② 1 5.4寸笔记本的键盘确实爽,基本跟台式机差不多了,蛮喜欢数字小键盘,输数字特方便,样子也很美观,做工也相当不错 1③ 房间太小。其他的都一般。。。。。。。。。 0其中1表示正向情感,0表示负向情感。句子级情感分析任务常用数据集ChnSenticorp数据集是公开中文情感分析常用数据集, 其为二分类数据集。PaddleNLP已经内置该数据集,一键即可加载。frompaddlenlp.datasets importload_datasettrain_ds, dev_ds, test_ds = load_dataset( "chnsenticorp", splits=[ "train", "dev", "test"])print(train_ds[ 0])print(train_ds[ 1])print(train_ds[ 2]){ 'text': '选择珠江花园的原因就是方便,有电动扶梯直接到达海边,周围餐馆、食廊、商场、超市、摊位一应俱全。酒店装修一般,但还算整洁。 泳池在大堂的屋顶,因此很小,不过女儿倒是喜欢。 包的早餐是西式的,还算丰富。 服务吗,一般', 'label': 1, 'qid': ''}1.1 SKEP模型加载PaddleNLP已经实现了SKEP预训练模型,可以通过一行代码实现SKEP加载。句子级情感分析模型是SKEP fine-tune 文本分类常用模型SkepForSequenceClassification。其首先通过SKEP提取句子语义特征,之后将语义特征进行分类。from paddlenlp.transformers import SkepForSequenceClassification, SkepTokenizer# 指定模型名称,一键加载模型model = SkepForSequenceClassification.from_pretrained(pretrained_model_name_or_path= "skep_ernie_1.0_large_ch", num_classes=len(train_ds.label_list)) # 同样地,通过指定模型名称一键加载对应的Tokenizer,用于处理文本数据,如切分token,转token_id等。tokenizer = SkepTokenizer.from_pretrained(pretrained_model_name_or_path= "skep_ernie_1.0_large_ch")SkepForSequenceClassification可用于句子级情感分析和目标级情感分析任务。其通过预训练模型SKEP获取输入文本的表示,之后将文本表示进行分类。pretrained_model_name_or_path:模型名称。支持"skep_ernie_1.0_large_ch","skep_ernie_2.0_large_en"。"skep_ernie_1.0_large_ch":是SKEP模型在预训练ernie_1.0_large_ch基础之上在海量中文数据上继续预训练得到的中文预训练模型;"skep_ernie_2.0_large_en":是SKEP模型在预训练ernie_2.0_large_en基础之上在海量英文数据上继续预训练得到的英文预训练模型;num_classes: 数据集分类类别数。关于SKEP模型实现详细信息参考:https://github.com/PaddlePaddle/PaddleNLP/tree/develop/paddlenlp/transformers/skep1.2 数据处理同样地,我们需要将原始ChnSentiCorp数据处理成模型可以读入的数据格式。SKEP模型对中文文本处理按照字粒度进行处理,我们可以使用PaddleNLP内置的SkepTokenizer完成一键式处理。importosfromfunctools importpartialimportnumpy asnpimportpaddleimportpaddle.nn.functional asFfrompaddlenlp.data importStack, Tuple, Padfromutils importcreate_dataloaderdefconvert_example(example,tokenizer,max_seq_length= 512,is_test=False) :# 将原数据处理成model可读入的格式,enocded_inputs是一个dict,包含input_ids、token_type_ids等字段encoded_inputs = tokenizer(text=example[ "text"], max_seq_len=max_seq_length)# input_ids:对文本切分token后,在词汇表中对应的token idinput_ids = encoded_inputs[ "input_ids"]# token_type_ids:当前token属于句子1还是句子2,即上述图中表达的segment idstoken_type_ids = encoded_inputs[ "token_type_ids"]ifnotis_test:# label:情感极性类别label = np.array([example[ "label"]], dtype= "int64")returninput_ids, token_type_ids, labelelse:# qid:每条数据的编号qid = np.array([example[ "qid"]], dtype= "int64")returninput_ids, token_type_ids, qid# 批量数据大小batch_size = 32 # 文本序列最大长度max_seq_length = 256# 将数据处理成模型可读入的数据格式trans_func = partial(convert_example,tokenizer=tokenizer,max_seq_length=max_seq_length)# 将数据组成批量式数据,如# 将不同长度的文本序列padding到批量式数据中最大长度# 将每条数据label堆叠在一起batchify_fn = lambda samples, fn=Tuple(Pad(axis=0, pad_val=tokenizer.pad_token_id), # input_idsPad(axis=0, pad_val=tokenizer.pad_token_type_id), # token_type_idsStack # labels): [data for data in fn(samples)]train_data_loader = create_dataloader(train_ds,mode='train',batch_size=batch_size,batchify_fn=batchify_fn,trans_fn=trans_func)dev_data_loader = create_dataloader(dev_ds,mode='dev',batch_size=batch_size,batchify_fn=batchify_fn,trans_fn=trans_func)1.3 模型训练和评估定义损失函数、优化器以及评价指标后,即可开始训练。推荐超参设置:max_seq_length=256batch_size=48learning_rate=2e-5epochs=10实际运行时可以根据显存大小调整batch_size和max_seq_length大小。importtimefromutils importevaluate# 训练轮次epochs = 1# 训练过程中保存模型参数的文件夹ckpt_dir = "skep_ckpt"# len(train_data_loader)一轮训练所需要的step数num_training_steps = len(train_data_loader) * epochs# Adam优化器optimizer = paddle.optimizer.AdamW(learning_rate= 2e-5,parameters=model.parameters) # 交叉熵损失函数criterion = paddle.nn.loss.CrossEntropyLoss # accuracy评价指标metric = paddle.metric.Accuracy# 开启训练global_step = 0tic_train = time.time forepoch inrange( 1, epochs + 1):forstep, batch inenumerate(train_data_loader, start= 1):input_ids, token_type_ids, labels = batch# 喂数据给modellogits = model(input_ids, token_type_ids)# 计算损失函数值loss = criterion(logits, labels)# 预测分类概率值probs = F.softmax(logits, axis= 1)# 计算acccorrect = metric.compute(probs, labels)metric.update(correct)acc = metric.accumulateglobal_step += 1ifglobal_step % 10== 0:print("global step %d, epoch: %d, batch: %d, loss: %.5f, accu: %.5f, speed: %.2f step/s"% (global_step, epoch, step, loss, acc,10/ (time.time - tic_train)))tic_train = time.time# 反向梯度回传,更新参数loss.backwardoptimizer.stepoptimizer.clear_gradifglobal_step % 100== 0:save_dir = os.path.join(ckpt_dir, "model_%d"% global_step)ifnotos.path.exists(save_dir):os.makedirs(save_dir)# 评估当前训练的模型evaluate(model, criterion, metric, dev_data_loader)# 保存当前模型参数等model.save_pretrained(save_dir)# 保存tokenizer的词表等tokenizer.save_pretrained(save_dir)globalstep 10, epoch: 1, batch: 10, loss: 0.59440, accu: 0.60625, speed: 0.76step/sglobalstep 20, epoch: 1, batch: 20, loss: 0.42311, accu: 0.72969, speed: 0.78step/sglobalstep 30, epoch: 1, batch: 30, loss: 0.09735, accu: 0.78750, speed: 0.72step/s··········globalstep 290, epoch: 1, batch: 290, loss: 0.14512, accu: 0.92778, speed: 0.71step/sglobalstep 300, epoch: 1, batch: 300, loss: 0.12470, accu: 0.92781, speed: 0.77step/seval loss: 0.19412, accu: 0.926671.4预测提交结果使用训练得到的模型还可以对文本进行情感预测。importnumpy asnpimportpaddle# 处理测试集数据trans_func = partial(convert_example,tokenizer=tokenizer,max_seq_length=max_seq_length,is_test= True)batchify_fn = lambdasamples, fn=Tuple(Pad(axis= 0, pad_val=tokenizer.pad_token_id), # inputPad(axis= 0, pad_val=tokenizer.pad_token_type_id), # segmentStack # qid): [data fordata infn(samples)]test_data_loader = create_dataloader(test_ds,mode= 'test',batch_size=batch_size,batchify_fn=batchify_fn,trans_fn=trans_func)# 根据实际运行情况,更换加载的参数路径params_path = 'skep_ckp/model_500/model_state.pdparams'ifparams_path andos.path.isfile(params_path):# 加载模型参数state_dict = paddle.load(params_path)model.set_dict(state_dict)print( "Loaded parameters from %s"% params_path)label_map = { 0: '0', 1: '1'}results = [] # 切换model模型为评估模式,关闭dropout等随机因素model.evalforbatch intest_data_loader:input_ids, token_type_ids, qids = batch# 喂数据给模型logits = model(input_ids, token_type_ids)# 预测分类probs = F.softmax(logits, axis= -1)idx = paddle.argmax(probs, axis= 1).numpyidx = idx.tolistlabels = [label_map[i] fori inidx]qids = qids.numpy.tolistresults.extend(zip(qids, labels))res_dir = "./results"ifnotos.path.exists(res_dir):os.makedirs(res_dir) # 写入预测结果with open(os.path.join(res_dir, "ChnSentiCorp.tsv"), 'w', encoding="utf8") as f:f.write( "index\tprediction\n")forqid, label inresults:f.write(str(qid[ 0])+ "\t"+label+ "\n")2 目标级情感分析在电商产品分析场景下,除了分析整体商品的情感极性外,还细化到以商品具体的“方面”为分析主体进行情感分析(aspect-level),如下:这个薯片口味有点咸,太辣了,不过口感很脆。关于薯片的口味方面是一个负向评价(咸,太辣),然而对于口感方面却是一个正向评价(很脆)。我很喜欢夏威夷,就是这边的海鲜太贵了。关于夏威夷是一个正向评价(喜欢),然而对于夏威夷的海鲜却是一个负向评价(价格太贵)。目标级情感分析任务常用数据集千言数据集已提供了许多任务常用数据集。其中情感分析数据集下载链接:https://aistudio.baidu.com/aistudio/competition/detail/50/?isFromLUGE=TRUESE-ABSA16_PHNS数据集是关于手机的目标级情感分析数据集。PaddleNLP已经内置了该数据集,加载方式,如下:train_ds, test_ds = load_dataset( "seabsa16", "phns", splits=[ "train", "test"])2.1 SKEP模型加载目标级情感分析模型同样使用SkepForSequenceClassification模型,但目标级情感分析模型的输入不单单是一个句子,而是句对。一个句子描述“评价对象方面(aspect)”,另一个句子描述"对该方面的评论"。如下图所示。# 指定模型名称一键加载模型model = SkepForSequenceClassification.from_pretrained('skep_ernie_1.0_large_ch', num_classes=len(train_ds.label_list)) # 指定模型名称一键加载tokenizertokenizer = SkepTokenizer.from_pretrained( 'skep_ernie_1.0_large_ch')2.2 数据处理同样地,我们需要将原始SE_ABSA16_PHNS数据处理成模型可以读入的数据格式。SKEP模型对中文文本处理按照字粒度进行处理,我们可以使用PaddleNLP内置的SkepTokenizer完成一键式处理。fromfunctools importpartialimportosimport timeimportnumpy asnpimportpaddleimportpaddle.nn.functional asFfrompaddlenlp.data importStack, Tuple, Paddefconvert_example(example,tokenizer,max_seq_length= 512,is_test=False,dataset_name= "chnsenticorp") :encoded_inputs = tokenizer(text=example[ "text"],text_pair=example[ "text_pair"],max_seq_len=max_seq_length)input_ids = encoded_inputs[ "input_ids"]token_type_ids = encoded_inputs[ "token_type_ids"]ifnotis_test:label = np.array([example[ "label"]], dtype= "int64")returninput_ids, token_type_ids, labelelse:returninput_ids, token_type_ids# 处理的最大文本序列长度max_seq_length= 256# 批量数据大小batch_size= 16# 将数据处理成model可读入的数据格式trans_func = partial(convert_example,tokenizer=tokenizer,max_seq_length=max_seq_length) # 将数据组成批量式数据,如# 将不同长度的文本序列padding到批量式数据中最大长度# 将每条数据label堆叠在一起batchify_fn = lambdasamples, fn=Tuple(Pad(axis= 0, pad_val=tokenizer.pad_token_id), # input_idsPad(axis= 0, pad_val=tokenizer.pad_token_type_id), # token_type_idsStack(dtype= "int64") # labels): [data fordata infn(samples)]train_data_loader = create_dataloader(train_ds,mode= 'train',batch_size=batch_size,batchify_fn=batchify_fn,trans_fn=trans_func)2.3 模型训练定义损失函数、优化器以及评价指标后,即可开始训练。# 训练轮次epochs = 3# 总共需要训练的step数num_training_steps = len(train_data_loader) * epochs # 优化器optimizer = paddle.optimizer.AdamW(learning_rate= 5e-5,parameters=model.parameters) # 交叉熵损失criterion = paddle.nn.loss.CrossEntropyLoss # Accuracy评价指标metric = paddle.metric.Accuracy# 开启训练ckpt_dir = "skep_aspect"global_step = 0tic_train = time.time forepoch inrange( 1, epochs + 1):forstep, batch inenumerate(train_data_loader, start= 1):input_ids, token_type_ids, labels = batch# 喂数据给modellogits = model(input_ids, token_type_ids)# 计算损失函数值loss = criterion(logits, labels)# 预测分类概率probs = F.softmax(logits, axis= 1)# 计算acccorrect = metric.compute(probs, labels)metric.update(correct)acc = metric.accumulateglobal_step += 1ifglobal_step % 10== 0:print("global step %d, epoch: %d, batch: %d, loss: %.5f, acc: %.5f, speed: %.2f step/s"% (global_step, epoch, step, loss, acc,10/ (time.time - tic_train)))tic_train = time.time# 反向梯度回传,更新参数loss.backwardoptimizer.stepoptimizer.clear_gradifglobal_step % 100== 0:save_dir = os.path.join(ckpt_dir, "model_%d"% global_step)ifnotos.path.exists(save_dir):os.makedirs(save_dir)# 保存模型参数model.save_pretrained(save_dir)# 保存tokenizer的词表等tokenizer.save_pretrained(save_dir)2.4 模型预测使用训练得到的模型还可以对评价对象进行情感预测。@paddle.no_graddef predict(model, data_loader, label_map):model.evalresults = []forbatch indata_loader:input_ids, token_type_ids = batchlogits = model(input_ids, token_type_ids)probs = F.softmax(logits, axis= 1)idx = paddle.argmax(probs, axis= 1).numpyidx = idx.tolistlabels = [label_map[i] fori inidx]results.extend(labels)returnresults# 处理测试集数据label_map = { 0: '0', 1: '1'}trans_func = partial(convert_example,tokenizer=tokenizer,max_seq_length=max_seq_length,is_test= True)batchify_fn = lambdasamples, fn=Tuple(Pad(axis= 0, pad_val=tokenizer.pad_token_id), # input_idsPad(axis= 0, pad_val=tokenizer.pad_token_type_id), # token_type_ids): [data fordata infn(samples)]test_data_loader = create_dataloader(test_ds,mode= 'test',batch_size=batch_size,batchify_fn=batchify_fn,trans_fn=trans_func)# 根据实际运行情况,更换加载的参数路径params_path = 'skep_ckpt/model_900/model_state.pdparams'ifparams_path andos.path.isfile(params_path):# 加载模型参数state_dict = paddle.load(params_path)model.set_dict(state_dict)print( "Loaded parameters from %s"% params_path)results = predict(model, test_data_loader, label_map)动手试一试是不是觉得很有趣呀。小编强烈建议初学者参考上面的代码亲手敲一遍,因为只有这样,才能加深你对代码的理解呦。本次项目对应的代码:https://aistudio.baidu.com/aistudio/projectdetail/1968542除此之外, PaddleNLP提供了多种预训练模型,可一键调用,来更换一下预训练试试吧:https://paddlenlp.readthedocs.io/zh/latest/model_zoo/transformers.html更多PaddleNLP信息,欢迎访问GitHub点star收藏后体验:https://github.com/PaddlePaddle/PaddleNLP转自 https://www.sohu.com/a/476337708_827544
  • [技术干货] 关于集群分布式torchrun命令踩坑记录【转】
     项目场景: 在训练或者微调模型的过程中,单节点的显存溢出,或者单节点的显卡较少,算力有限。需要跨节点用多个节点多块显卡来运行这项任务。这里就需要使用分布式命令,将这项任务分布到多个节点上来处理。  问题描述 在此我仅记录我在运行分布式过程中遇到的一些问题。  首先,对于pytorch深度学习框架的分布式进程是有一套标准的流程的,简单来讲就是先通过dist进行初始化,再将模型进行分布式分配。具体所用的API为:  import torch.distributed as dist from torch.nn.parallel import DistributedDataParallel as DDP 对于预训练(或者微调)的脚本,我参考了官方文档中的测试代码,测试代码实际非常简单,搭建了一个非常小的网络,同时对其使用分布式进程,非常适合拿来做测试。链接为:官方文档  dist.init_process_group()是PyTorch中用于初始化分布式训练的函数之一。它用于设置并行训练环境,连接多个进程以进行数据和模型的分布式处理。我们通过init_process_group()函数这个方法来进行初始化,其参数包括以下内容  backend(必需参数):指定分布式后端的类型,可以是以下选项之一:  ‘tcp’:使用TCP协议进行通信。 ‘gloo’:使用Gloo库进行通信。 ‘mpi’:使用MPI(Message Passing Interface)进行通信。 ‘nccl’:使用NCCL库进行通信(适用于多GPU的分布式训练)。 ‘hccl’:使用HCCL库进行通信(适用于华为昇腾AI处理器的分布式训练)。  init_method(可选参数):指定用于初始化分布式环境的方法。它可以是以下选项之一: ‘env://’:使用环境变量中指定的方法进行初始化。 ‘file:// ’:使用本地文件进行初始化。 ‘tcp://  :’:使用TCP地址和端口进行初始化。 ‘gloo:// :’:使用Gloo地址和端口进行初始化。 ‘mpi:// :’:使用MPI地址和端口进行初始化。 rank(可选参数):指定当前进程的排名(从0开始)。  world_size(可选参数):指定总共使用的进程数。  timeout(可选参数):指定初始化的超时时间。  group_name(可选参数):指定用于连接的进程组名称。  这里由于服务器采用的slurm系统,我们开始计划使用mpi去实现分布式分发,同时torch的初始化也支持mpi,原始想法是通过mpirun来进行分布式计算。但是,如果要使用mpi来实现分布式功能,必须要通过github上的源代码进行编译,通过conda和pip进行下载的pytorch自身是不携带mpi的 通过上面的参数,可以看到backend是有多重通信方式的,常用的有gloo和mpi和nccl,但是这三者是有区别的,这里我们可以参考官方文档:官方文档  这里我们直接放出结论,以供参考:  对于分布式 GPU 训练,使用 NCCL 后端。 对于分布式 CPU 训练,使用 Gloo 后端。 如果你的主机是 GPU 主机并且具有 InfiniBand 互连: 使用 NCCL,因为它是目前唯一支持 InfiniBand 和 GPUDirect 的后端。 如果你的主机是 GPU 主机并且具有以太网互连: 使用 NCCL,因为它目前提供了最好的分布式 GPU 训练性能,特别是对于多进程单节点或多节点分布式训练。 如果你遇到 NCCL 的任何问题,使用 Gloo 作为备选选项。(注意,Gloo 目前运行速度比 NCCL 慢) 如果你的主机是 CPU 主机并且具有 InfiniBand 互连: 如果你的 InfiniBand 启用了 IP over IB,使用 Gloo,否则,使用 MPI。我们计划在即将发布的版本中为 Gloo 添加 InfiniBand 支持。 如果你的主机是 CPU 主机并且具有以太网互连: 使用 Gloo,除非你有特定的理由使用 MPI​。 我们可以根据文档的提示,得出,MPI是最不推荐使用的一种方法,对于英伟达的显卡,最优先的还是使用NCCL方法。和Mpi相匹配的有一种torch官方自带的方法,在torch2.0之前使用的API叫:torch.distributed.launch在使用时显示未来的版本将会弃用这个API,取而代之的是torchrun。因此我们将命令由mpi改为torchrun方法,在dist初始化使用nccl后端通信。  这里我们可以参考torchrun的官方运行方法:官方文档 经过近两周的调试与踩坑,先是在测试节点上对官方测试脚本进行分布式测试,运行成功后再将相同的环境和文件迁移到计算节点上,再在计算节点上对分布式命令进行测试,期间还测试了root用户和子用户对torchrun命令是否会有影响。  假设我们有三个节点,node02,node03,node04,每个节点上有四张GPU。现在我们将官方测试文档中的代码写为test_mpi.py。最终通过torchrun实现的命令如下:  torchrun --nproc_per_node=4 --nnodes=3 --node_rank=0 --master_addr=192.168.0.101 --master_port=29500 test_mpi.py 1 我们没有必要和torchrun的官方文档一样去设置**–rdzv-backend** 和**–rdzv-id**,因为这不是必须的,用默认的即可。我们只需要设置的参数只有上面这几个。具体参数介绍如下: –nproc_per_node=4:指定每个节点(机器)上的进程数,这里是4个。意味着每个机器将启动4个进程来参与分布式训练。  –nnodes=3:指定总共的节点数,这里是3个。意味着总共有3个机器参与分布式训练。 –node_rank=0:指定当前节点(机器)的排名,这里是0。排名从0开始,用于在分布式环境中区分不同的节点。 –master_addr=192.168.0.101:指定主节点的IP地址,这里是192.168.0.101。主节点用于协调分布式训练过程。 –master_port=29500:指定主节点的端口号,这里是29500。主节点使用指定的端口来与其他节点进行通信。 通过设置这些参数,该命令将在3个节点的分布式环境中启动4个进程,并指定192.168.0.101作为主节点进行协调和通信。 这里的主节点地址我随便写的,可以根据实际情况进行修改。主节点的地址的- --node_rank必须设置为0,也就是上述这行命令,必须要先在主节点上线运行。  举个例子,假如我的主节点是node02,那么我就要先在node02节点的终端上运行上述torchrun命令,同时–master_addr要为node02的ip地址(查看IP地址可以通过:ip addr),然后node03,node04的顺序就不重要了,在其节点的终端上将–node_rank=0改为–node_rank=1和–node_rank=2运行即可。  这里出现第一个问题,即是,通讯超时(具体表现为:ERROR:torch.distributed.elastic.multiprocessing.api:failed (exitcode: -11))。假如我们的节点之前ping方法没有问题,同时节点并没有处于被占用的情况,那么分析超时就比较困难了。我会在之后的解决方法中,提供我是如何解决的。  在命令确认无误之后,我们需要将这个命令,写成脚本提交到后台,挂在服务器上运行,而不是在终端上一直在线处理。  由于我们服务器使用的slurm系统,slurm系统自带一套可以提交作业的方法。于是就要将这个命令进行sbatch脚本打包。打包的bash脚本如下所示:  #!/bin/bash#SBATCH --job-name=pytorch_job # 创建一个任务名#SBATCH -N 3 # 需要使用的节点数#SBATCH --ntasks-per-node=4 # 每个节点上的任务数#SBATCH --output=job_output.out # 标准输出文件#SBATCH --error=job_error.err # 标准错误文件#SBATCH --nodelist=node02,node03,node04 # 指定节点列表# 加载任何必要的模块,例如:# module load python# module load pytorch# source ……export TORCH_DISTRIBUTED_DEBUG=INFOexport NCCL_IB_DISABLE=1# 设置主节点# 节点列表NODELIST=$(scontrol show hostname $SLURM_JOB_NODELIST)# 对第一个节点赋值为主节点MASTER_NODE=$(head -n 1 <<< "$NODELIST")# 计数器NODE_COUNT=0# 一共的节点数NODE_NUM=($(echo $NODELIST | tr " " "\n" | wc -l))# 打印echo $SLURM_NODEIDecho $NODELISTecho $MASTER_NODEecho $NODE_NUMfor NODE in $NODELIST; do if [ "$NODE" == "$MASTER_NODE" ]; then srun --nodes=1 --ntasks=1 -w $NODE torchrun --nproc_per_node=4 --nnodes=$NODE_NUM --node_rank=0 --master_addr=192.168.0.101 --master_port=29500 test_mpi.py & else ((NODE_COUNT++)) srun --nodes=1 --ntasks=1 -w $NODE torchrun --nproc_per_node=4 --nnodes=$NODE_NUM --node_rank=$NODE_COUNT --master_addr=192.168.0.101 --master_port=29500 test_mpi.py & fidonewait脚本的逻辑为:通过srun在启动的每个节点上运行torchrun命令,运行的同时还需要进行判断,判断提交的节点是不是主节点,如果是主节点则node_rank的值要为0,如果不是主节点则node_rank的值为1,2……其实并不推荐使用sbatch嵌套srun()  这里出现第二个问题,假如不是不是在主节点第一个运行命令,则会发生超时,具体情况如下:  我会在之后的解决方法中,提供我是如何解决的。  原因分析: 对于上述的两种超时问题,首先要做的是在节点之间进行ping操作确认,确认不是服务器本身的问题,则考虑是不是节点之间的通信问题。因为NCCL也是有内部通信的,NVIDIA的NCCL库支持多种传输方式,以便在不同的硬件和网络配置中实现最优的通信性能。以下是一些主要的传输方式:  InfiniBand (IB):如前所述,InfiniBand是一种高性能、低延迟的网络传输技术,常用于高性能计算(HPC)和数据中心。  TCP/IP:这是最常见的网络通信协议,可以在任何支持TCP/IP的网络(包括常见的以太网)上运行。  Shared Memory (SHM):在同一台机器上的GPU之间,NCCL可以使用共享内存进行通信。这通常比通过网络传输更快。  CUDA Inter-Process Communication (IPC):对于同一节点上的多个GPU,NCCL可以使用CUDA IPC进行通信。这是一种允许不同CUDA进程共享GPU内存的机制,可以提高通信效率。  NVLink:NVLink是NVIDIA的一种高速互连技术,用于连接GPU和GPU,或GPU和CPU。它提供了比传统PCIe更高的带宽,适用于需要高速GPU间通信的应用。  这些传输方式可以根据具体的硬件配置和通信需求进行选择和配置。  解决方案: 我们可以在之前的脚本中,添加环境变量,进入调试模型,查看具体的原因:  export NCCL_DEBUG=INFO export NCCL_DEBUG_SUBSYS=ALL export TORCH_DISTRIBUTED_DEBUG=INFO 1 2 3 对于第一个问题,再次运行我们的命令,即可获得NCCL的INFO信息,我们详细对比信息可以发现,在主节点上,我们使用的通信方式是NET/IB,如下图所示:  而在其他节点,我们使用的方式是 NET/Socket  NET/IB 和 NET/Socket 是两种不同的网络通信接口。NET/IB 通常指的是 InfiniBand,这是一种高性能、低延迟的网络通信接口,常用于高性能计算和数据中心。而 NET/Socket 则是一种更常见的网络接口,它在各种网络环境中都可以使用。如果你的两个节点一个使用 NET/IB,另一个使用 NET/Socket,那么这两个节点之间的通信可能会受到影响。因为 NCCL 默认使用最快的可用传输方法,如果两个节点的网络接口不同,那么可能无法建立有效的通信。具体情况可能需要根据你的网络环境和配置进行测试。这里建议使用同一种通信方式。 我们将IB禁用即可:  export NCCL_IB_DISABLE=1 1 对于第二个问题,我们只需要写判断语句,确保主节点运行node_rank=0的命令即可,在上述给出的代码我已经写好了判断语句。 ———————————————— 版权声明:本文为CSDN博主「萌新玉玉玉」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/Komach/article/details/130765773 
  • 自动驾驶综述|定位、感知、规划常见算法汇总【转】
     自驾车自动驾驶系统的体系结构一般分为感知系统和决策系统。感知系统一般分为许多子系统,负责自动驾驶汽车定位、静态障碍物测绘、移动障碍物检测与跟踪、道路测绘、交通信号检测与识别等任务。决策系统通常被划分为许多子系统,负责诸如路径规划、路径规划、行为选择、运动规划和控制等任务。  一、 自动驾驶汽车体系结构概述 这一部分概述了自动驾驶汽车自动化系统的典型体系结构,并对感知系统、决策系统及其子系统的职责进行了评述。 下图显示了自动驾驶汽车系统的典型架构框图,其中感知和决策系统显示为不同颜色的模块集合。感知系统负责使用车载传感器捕获的数据,如光探测和测距(LIDAR)、无线电探测和测距(雷达)、摄像机、全球定位系统(GPS),惯性测量单元(IMU)、里程表,以及有关传感器模型、道路网络、交通规则、汽车动力学等的先验信息的决策。 决策系统负责将汽车从初始位置导航到用户定义的最终目标,考虑到车辆状态和环境的内部表现,以及交通规则和乘客的舒适度。为了在整个环境中导航汽车,决策系统需要知道汽车在其中的位置。定位器模块负责根据环境的静态地图估计车辆状态(姿态、线速度、角速度等)。这些静态地图在自动操作之前自动计算,通常使用自动驾驶汽车本身的传感器,尽管需要手动注释(即人行横道或红绿灯的位置)或编辑(即移除传感器捕获的非静态物体)。自动驾驶汽车可以使用一个或多个不同的离线地图,如占用网格地图、缓解地图或地标地图,进行定位。 定位模块接收离线地图、传感器数据和平台里程计作为输入,并生成自动驾驶汽车的状态作为输出。需要注意的是,虽然GPS可能有助于定位控制器的处理,但由于树木、建筑物、隧道等造成的干扰,使得GPS定位不可靠,仅GPS在城市环境中进行适当的定位是不够的。映射器模块接收离线地图和状态作为输入,并生成在线地图作为输出。该在线地图通常是离线地图中的信息和使用传感器数据和当前状态在线计算的占用网格地图的合并。在线地图最好只包含环境的静态表示,因为这可能有助于决策系统的某些模块的操作。为了允许检测和移除在线地图中的移动对象,通常使用移动对象跟踪模块或MOT。  行为选择器模块负责选择当前的驾驶行为,如车道保持、交叉口处理、红绿灯处理等。行为选择器根据当前驾驶行为选择目标,并在决策时间范围内避免与环境中的静态和移动障碍物发生碰撞。运动规划模块负责计算从当前车辆状态到当前目标的轨迹,该轨迹遵循行为选择器定义的路径,满足车辆的运动学和动力学约束,并为乘客提供舒适性。  二、感知模块 在这一部分中,我们研究了文献中提出的自动驾驶汽车感知系统的重要方法,包括定位(或定位)、离线障碍物映射、道路映射、移动障碍物跟踪和交通信号检测与识别。 定位模块负责估计自动驾驶汽车相对于地图或道路的姿态(位置和方向)(例如,由路缘或道路标记表示)。大多数通用定位子系统都是基于GPS的。然而,总的来说,它们不适用于城市自动驾驶汽车,因为GPS信号不能保证在封闭区域,如树下、城市峡谷(被大型建筑物包围的道路)或隧道中。文献中提出了各种不依赖GPS的定位方法。它们主要分为三类:基于激光雷达的、基于激光雷达加相机的和基于相机的。基于激光雷达的定位方法完全依赖于激光雷达传感器,具有测量精度高、处理方便等优点。然而,尽管激光雷达行业努力降低生产成本,但与相机相比,它仍然有很高的价格。在典型的基于LIDAR+camera的定位方法中,LIDAR数据仅用于建立地图,并使用相机数据估计自动驾驶汽车相对于地图的位置,从而降低了成本。基于摄像机的定位方法是廉价和方便的,尽管通常不太精确和可靠。  1、定位 1、基于激光雷达的定位 经典方法提出了一种结合三维点配准算法的多层自适应蒙特卡罗定位(ML-AMCL)方法。为了估计汽车姿态,从三维激光雷达测量中提取水平层,并使用单独的AMCL实例将层与使用三维点注册算法构建的三维点云地图的二维投影对齐。对于每个姿态估计,对一系列的里程测量进行一致性检查。将一致的姿态估计融合到最终的姿态估计中。该方法在实际数据上进行了评估,得到相对于GPS参考的位置估计误差为0.25m。然而,地图是昂贵的存储,因为它是一个三维地图。Veronese等人提出了一种基于MCL算法的定位方法,该方法通过二维在线占有栅格地图和二维离线占有栅格地图之间的地图匹配来校正粒子的姿态,如下图所示。评估了两种地图匹配距离函数:改进了传统的两个栅格地图之间的似然场距离,以及两个高维向量之间的自适应标准余弦距离。对IARA自动驾驶汽车的实验评价表明,利用余弦距离函数,定位方法可以在100hz左右工作,横向和纵向误差分别为0.13m和0.26m。  2、激光雷达和相机方式定位 一些方法利用激光雷达数据建立地图,利用摄像机数据估计自动驾驶汽车相对于地图的位置。Xu等人提出了一种立体图像与三维点云地图匹配的定位方法。地图由一家地图公司(http://www.whatmms.com)生成,由几何数据(纬度、经度和海拔)和从里程表、RTK-GPS和2D激光雷达扫描仪获取的缓解数据组成。他们将地图的三维点从真实坐标系转换到摄像机坐标系,并从中提取深度和强度图像。采用MCL算法,通过将汽车摄像机拍摄的立体深度和强度图像与从3D点云地图中提取的深度和强度图像进行匹配来估计汽车的位置。该方法在实际数据上进行了评估,并给出了0.08 m到0.25 m之间的位置估计误差。VIS16提出了一种将地面全景图与一年中不同季节拍摄的卫星图像相匹配的自动驾驶汽车定位方法。在他们的方法中,激光雷达数据被分为地面/非地面类别。接下来,利用激光雷达数据将全景相机拍摄的自驾车地面图像分割成地面/非地面区域,然后进行扭曲以获得鸟瞰图。利用kmeans聚类将卫星图像分割成地面/非地面区域。然后利用MCL将鸟眼图像与卫星图像进行匹配,估计姿态。该方法在NavLab11自动驾驶汽车上进行了验证,获得了3m~4.8m的位置估计误差。 3、基于相机的定位方式 有些方法主要依靠摄像机数据来定位自驾车。Brubaker等人提出了一种基于视觉里程和道路地图的定位方法。他们使用OpenStreetMap,从中提取出感兴趣区域内连接他们的所有十字路口和所有可行驶道路(以分段线性段表示)。然后建立了一个基于图的路线图表示法和一个汽车如何通过该图的概率模型。利用这个概率模型和视觉里程测量,他们估计汽车相对于路线图的位移。使用递归贝叶斯滤波算法,通过利用图形的结构和车辆如何移动的模型(通过视觉里程计测量)在图形中执行推断。该算法能够通过增加当前姿势位于与最新汽车运动(直线行驶距离和最近的曲线)相关的图形点的概率,并通过降低其位于不相关的点的概率来精确定位汽车在图形中的位置。定位方法在KITTI视觉里程数据集上进行评估,并在行驶52秒后能够在包含2150公里可行驶道路的18平方公里地图上定位车辆,精度为4米。一些方法使用相机数据来构建特征地图。Ziegler等人描述了自主车辆Bertha在历史悠久的Bertha-Benz纪念路线上自主驾驶所使用的定位方法。提出了两种基于互补视觉的定位技术:基于点特征的定位(PFL)和基于车道特征的定位(LFL)。在PFL中,使用从当前相机图像中提取的DIRD描述符,将当前相机图像与先前在映射过程中获取的相机图像序列的图像进行比较。从映射过程中捕获的图像的全局位置恢复全局位置估计。在LFL中,地图半自动计算,提供道路标记特征(水平道路信号)的全局几何表示。通过检测从摄像机图像的鸟瞰图中提取的道路标记特征并将其与存储在地图中的水平道路信号相关联,将当前摄像机图像与地图匹配。然后,由PFL和LFL获得的位置估计被Kalman滤波器组合(作者不提供组合定位误差的估计)。Jo等人提出了类似于LFL的定位方法。一些方法使用相机数据来构造特征地图,但采用了其他类型的特征。Radwan等人提出了一种基于文本特征检测的定位方法。现成的文本提取技术用于识别环境中的文本标签。采用MCL算法对多个观测值进行融合。该方法在实际数据上进行了评估,并给出了1 m到25 m之间的位置估计误差。Spangenberg等人提出使用杆状地标作为主要特征,因为它们是独特的、长期稳定的,并且可以被立体摄像机检测到。此外,它们允许内存高效的映射表示。特征检测主要由立体摄像机完成。定位采用MCL算法结合Kalman滤波器进行鲁棒性和传感器融合。该方法在自主车辆上进行了评估,得到了0.14m到0.19m之间的位置估计误差。一些方法建议使用神经网络对自动驾驶汽车进行定位。它们由相关的摄像机图像和相关的全局位置组成。在映射阶段,神经网络建立环境的表示。为此,它学习一系列图像和图像被捕获的全局位置,这些位置存储在一个神经地图中。在定位阶段,神经网络利用神经网络地图提供的先验知识来估计当前观测图像的全局位置。这些方法存在仪表刻度误差,难以实现大面积自主车辆的定位。  2、离线障碍物地图 离线障碍物地图子系统负责自动驾驶汽车环境中障碍物地图的计算。该子系统对于允许自主车辆在公共道路上安全行驶而不与障碍物(如路标、路缘)碰撞至关重要。障碍地图包含与汽车可能或可能无法导航的位置相关的信息,区分自由(可穿越)空间和占用空间。汽车必须总是在空余的地方。障碍物地图由地图绘制阶段的传感器数据构建,并存储在自主操作阶段供以后使用。状态空间的表示通常区别于拓扑和度量表示。拓扑表示将状态空间建模为一个图,其中节点表示重要位置(或特征),边表示它们之间的拓扑关系(例如位置、方向、邻近性和连接性)。这些分解的分辨率取决于环境的结构。度量表示通常将状态空间分解为规则间隔的单元。这种分解不依赖于特征的位置和形状。度量表示的空间分辨率往往高于拓扑表示的空间分辨率。这样的多功能性和高效性使得它们成为最常见的空间表现形式。  3、道路建模 道路地图子系统负责收集自驾车周围道路和车道的信息,并将其表示在具有几何和拓扑特性的地图中,包括相互连接和限制。道路制图子系统的主要内容是地图表示和地图创建。 1) 道路图表示与障碍地图一样,道路图通常区分为度量地图和拓扑地图。 a) 度量表示路线图的简单度量表示是一个网格图,它将环境离散为一个固定大小的单元矩阵,该矩阵包含有关是否属于某条道路的信息以及移动到其相邻单元的成本。道路网格地图简单易懂。然而,如果移动成本在路线图的大范围内是一致的,那么使用网格表示可能需要浪费内存空间和处理时间。路线点序列是压缩大型道路网格地图中路径描述的一种替代方法。路线点是沿路线栅格地图中的路径的点。路线点序列可以手动定义,也可以自动从道路网格地图中提取。对于2005年DARPA大挑战,提出了路线数据定义文件(RDDF),它是一个格式化文件,包含指定自主车辆运行路径的航路点坐标和其他相关信息(纬度、经度、横向边界偏移和航速)。Carneiro等人为无人驾驶汽车IARA提出一个路线图,以推断城市道路中车道的位置和相关特性,该路线图同时使用了道路网格图和RDDF路径,如下图所示。IARA的道路网格地图包含0.2×0.2 m的正方形单元格。为属于车道的每个单元格分配一个非零代码。从1到16的代码表示单元格到车道中心的相对距离,以及单元格中存在的车道标记类型(断开、实心或无)。IARA的RDDF路径包含间距为0.5米的航路点,并通过奖励靠近车道中心的单元格的算法自动从道路网格地图中提取。IARA的道路网格图和RDDF路径在联邦圣埃斯皮里托大学(UFES)主校区的环形道路上进行了3.7公里的自动测试。  b) 拓扑表示路线图的一种更复杂的表示是拓扑图,它将环境描述为一个图形模型,其中顶点表示位置,边表示它们之间的拓扑关系。拓扑图可以包含更复杂的信息,包括多车道、车道交叉口和车道合并。针对2007年DARPA城市挑战赛,提出了路线网络定义文件(RNDF),这是一个拓扑图,定义为指定无人驾驶汽车运行路段的格式化文件。根据该文件,道路网络包括一个或多个路段,每个路段包括一个或多个车道。路段的特征是车道数、街道名称和速度限制。车道的特征是车道的宽度、车道标线和一组航路点。车道之间的连接以出口和入口航路点为特征。厄姆森等人。URM08使用RNDF的图表模型作为自动驾驶汽车的老板(卡内基梅隆大学的汽车在2007年DARPA城市挑战赛中获得第一名)。图中的每个节点表示一个航路点,方向边缘表示将该节点连接到它可以到达的所有其他航路点的车道。基于多个因素的组合,将成本分配给边缘,这些因素包括穿过与边缘相关联的车道的预期时间、车道长度和环境的复杂性。Ramm等人。[RAM11]提出了OpenStreetMap(OSM),它使用节点、方式和关系这三个基本体用拓扑图来建模环境。节点表示地理点,方式表示节点列表(多段线),关系由任意数量的成员组成,这些成员可以是三种类型中的任何一种,并且具有指定的角色。其他道路特性(如行驶方向和车道数)作为元素的特性给出。Bender等人。BEN14提出了一个高度详细的拓扑路线图,称为lanelet地图,用于自动车辆泊位。lanelet地图包括道路的几何和拓扑特征,如道路、车道和交叉口,使用原子互联的可驾驶路段,称为lanelets,如下图所示。lanelet的几何图形由左边界和右边界定义,每个边界对应一个点列表(多段线)。此表示隐式定义每个车道的宽度和形状及其驾驶方向。lanelet的邻接构成一个加权有向图,其中每个lanelet表示一个顶点,lanelet的长度表示其出边的权重。其他元素描述了限制条件,如速度限制和交通规则,如交叉口和合并权。lanelet地图在历史悠久的Bertha-Benz纪念路线上进行了103公里的自动测试。高清地图(HD-maps)是为无人驾驶汽车提供动力的新一代拓扑地图。高清地图具有厘米级的高精度,包含丰富的信息,如车道位置、道路边界和道路曲率。由于创建高清地图的成本很高,因此有一些平台可以作为服务提供高清地图。Dharia对顶级供应商进行了评估和排名,分别是Google、HERE、TomTom和Apple。  2) 路线图创建创建路线图的最简单方法是从航空图像中提取道路形状的手动注释。然而,大型城市道路网所需的大量人工操作可能会使人工标注变得不可行。为此,人们提出了从航空图像自动生成道路图的方法。 a) Urmson等人使用从航空图像中提取的道路形状的手动注释,以便为自动驾驶汽车的驾驶台创建道路图。得到的局部道路形状是准确的,但由于图像的分辨率和全局配准的影响,全局位置不太准确。为此,他们的定位方法采用位置滤波处理道路模型误差。Bender等人。BEN14还采用了自动车辆泊位的lanelet地图的所有元素和属性的手动标注。使用OSM格式和java OSM编辑器,使用虚拟顶视图图像作为LANELET的手动注释的基础。 b) 自动生成从航空图像自动生成路线图的方法很多。韦格纳等人使用高阶条件随机场(CRF)通过将图像分割为超级像素并添加连接这些超级像素的路径来模拟道路网络的结构。Mnih和Hinton使用卷积神经网络(CNN)获得路段。道路分割的一个补充任务是从俯视图或正面图像中检测车道。Aeberhard等人对于宝马的自动驾驶汽车,使用地面栅格地图,其中每个单元表示具有高反射率的地面位置的概率。采用二次多项式模型提取道路边界。车道定位与数字地图结合使用,以获得对环境的更高层次的理解。地图主要由两层组成:语义几何层和定位层。语义几何层包含车道模型几何和车道连通性等高层语义信息。定位层包含车道标线和道路边界,与GPS和车辆里程计一起,可用于将车辆匹配到地图上。 Lee等人还使用激光雷达缓解数据来检测车道标记和摄像机图像,以防车道划分不明确。道路上的车道标记是为了在夜间与前照灯一起使用具有良好反光效果的特殊油漆而制成的。有了这个特性,激光雷达可以检测到道路标记,即使是在光照因雨或阴影而改变的情况下。基于摄像机图像的车道标线检测技术只在易受攻击的情况下运行(如背光和低光)。这种方法在韩国首尔2公里的航程中得到了成功的测试。Carneiro等人使用深度神经网络(DNN)来推断自主车辆IARA水平信号不良或无水平信号的车道的位置和相关特性。DNN将LIDAR缓解栅格地图分割为道路栅格地图,将非零代码(从1到16)分配给属于车道的地图单元,这些单元表示到车道中心的相对距离和单元中车道标记的类型。利用数十公里的道路标线数据集对DNN进行训练,使DNN的精度足以满足IARA的实际自主驾驶。道路分割并不直接提供路线图,它定义地图单元是否是道路的一部分。为了解释道路分割、提取拓扑结构和构建路线图,需要一个复杂的后处理流水线。巴斯塔尼等人提出了道路追踪方法,该方法寻求直接从CNN生成路线图,而不是依赖中间图像表示。它使用一个迭代的图形构建过程,一次添加一个单独的路段,并使用CNN来决定下一个要添加的路段。对15个城市24平方公里的航空影像进行的逐点匹配检验,平均误差为5%。  4、移动物体跟踪 运动目标跟踪(MOT)子系统(也称为多目标检测与跟踪-DATMO)负责检测和跟踪自动驾驶汽车周围环境中运动障碍物的姿态。该子系统对于使自主车辆做出决策和避免与潜在移动物体(如其他车辆和行人)碰撞至关重要。随着时间的推移,移动障碍物的位置通常是根据测距传感器(如激光雷达和雷达)或立体相机捕获的数据来估计的。单目摄像机的图像能够提供丰富的视觉信息,可以用来改进运动障碍假设。针对传感器测量的不确定性,采用Bayes滤波器(如Kalman和粒子滤波器)进行状态预测。MOT方法主要分为六类:传统的、基于模型的、基于立体视觉的、基于栅格地图的、基于传感器融合的和基于深度学习的。 1、Traditional Based MOT 传统的MOT方法主要包括三个步骤:数据分割、数据关联和过滤。在数据分割阶段,利用聚类或模式识别技术对传感器数据进行分割。在数据关联步骤中,使用数据关联技术将数据段与目标(移动障碍物)关联。在滤波阶段,对于每个目标,通过取分配给目标的数据的几何平均值来估计位置。位置估计通常由卡尔曼滤波或粒子滤波进行更新。 2、Model Based MOT 基于模型的方法直接从传感器数据中推断,使用传感器的物理模型和对象的几何模型,并使用非参数滤波器(如粒子滤波器)。不需要数据分割和关联步骤,因为几何对象模型将数据关联到目标。 3、Stereo Vision Based MOT 基于立体视觉的方法依靠立体图像对提供的颜色和深度信息来检测和跟踪环境中的运动障碍物。Ess等人提出了一种障碍物检测和识别方法,该方法仅使用来自前视立体摄像机的同步视频。他们的工作重点是基于行人和汽车探测器每帧输出的障碍物跟踪。对于障碍物检测,他们采用了一种带有方向梯度直方图(HOG)特征的支持向量机(SVM)分类器,将每个图像区域分类为障碍物或非障碍物。对于障碍物跟踪,他们应用一种假设和验证策略,将一组轨迹拟合到可能检测到的障碍物上,使得这些轨迹一起具有很高的后验概率。候选轨迹集由扩展卡尔曼滤波器(EKFs)生成,EKFs由障碍物检测初始化。最后,使用模型选择技术仅保留一组解释过去和现在观测结果的最小且无冲突的轨迹。对于MOT,采用半全局匹配(SGM)方法从立体图像对中重构出稠密视差图像。三维环境中的所有障碍物都由一组称为超级像素或stixels的垂直方向的薄矩形来近似。使用Kalman滤波器跟踪随时间变化的stixel。最后,使用空间、形状和运动约束将stixel分割为静态背景和移动障碍物。在时空分析的基础上,提出了一种基于外观的检测与识别方案,该方案利用特定类别(行人和车辆)模型,提高了视觉感知的鲁棒性。 实时识别主要包括三个阶段:感兴趣区域(ROI)、障碍物分类和目标跟踪。Chen等人使用半全局匹配算法从立体图像对计算视差图。在视差图的辅助下,简单线性迭代聚类产生的图像分割边界分为共面边界、铰链边界和遮挡边界。利用改进的随机样本一致性(RANSAC)算法在自我运动估计过程中获得运动点。最后,根据边界类型和运动情况,采用超像素合并的方法提取运动障碍物。 4、Grid Map Based MOT 基于栅格地图的方法首先构建动态环境的占用栅格地图。地图构建步骤之后是数据分割、数据关联和过滤步骤,以便提供场景的对象级表示。Nguyen等人提出了一种基于网格的立体摄像机运动目标检测与跟踪方法。他们的工作重点是行人检测和跟踪。从立体图像对重建三维点。利用逆传感器模型,基于相关的三维点估计网格地图中每个单元的占用概率。采用分层分割的方法,根据网格单元之间的区域距离,将网格单元划分成若干段。最后,采用交互式多模型(IMM)方法对移动障碍物进行跟踪。Azim和Aycard使用基于八叉树的3D局部占用栅格地图,该地图将环境划分为占用、自由和未知体素。在构建局部网格地图后,基于局部网格地图中自由空间和占用空间的不一致性,可以检测出移动障碍物。动态体素被聚集成移动的物体,这些物体被进一步划分成层。使用从每个层提取的几何特征,将移动对象分类为已知类别(行人、自行车、汽车或公共汽车)。 5、Sensor Fusion Based MOT 基于传感器融合的方法融合来自各种传感器(如激光雷达、雷达和照相机)的数据,以探索它们各自的特点,提高环境感知能力。Darms等人介绍了自动驾驶汽车“Boss”采用的基于传感器融合的运动车辆检测与跟踪方法(卡内基梅隆大学的汽车在2007年DARPA城市挑战赛中获得第一名)。MOT子系统分为两层。传感器层从传感器数据中提取特征,这些特征可用于根据点模型或盒模型描述移动障碍物假设。传感器层还尝试将特征与来自融合层的当前预测假设相关联。无法与现有假设关联的功能用于生成新的建议。对与给定假设相关联的每个特征生成观察,封装更新假设状态估计所需的所有信息。融合层根据传感器层提供的建议和观测,为每个假设选择最佳跟踪模型,并使用卡尔曼滤波器估计(或更新)假设状态的估计。Cho等人描述卡内基梅隆大学新的实验性自主车辆使用的新MOT子系统。以前的MOT子系统,由Darms等人提出。Mertz等人使用可直接从二维激光雷达、从三维激光雷达投影到二维平面或从多个传感器(激光雷达、雷达和相机)融合获得的扫描线。扫描线被转换成世界坐标并被分割。为每个线段提取直线和角点特征。分段与现有障碍物相关联,并使用卡尔曼滤波器更新目标的运动学。Byun等人合并由多个传感器(如雷达、二维激光雷达和三维激光雷达)生成的移动障碍物轨迹。将二维激光雷达数据投影到二维平面上,利用联合概率数据关联滤波器(JPDAF)跟踪运动障碍物。三维激光雷达数据被投影到一幅图像上,并使用区域增长算法分割成运动障碍物。最后,利用迭代最近点(ICP)匹配或基于图像的数据关联来估计或更新轨迹的姿态。Xu等人。XU15描述了卡内基梅隆大学的新型无人驾驶实验车对用于保持距离的移动障碍物的上下文感知跟踪。给定行为上下文,在道路网络中生成ROI。找到感兴趣区域内的候选目标并将其投影到道路坐标中。通过将来自不同传感器(激光雷达、雷达和摄像机)的所有候选目标关联起来,获得距离保持目标。薛等人融合激光雷达和摄像机数据,提高行人检测的准确性。他们利用行人高度的先验知识来减少错误检测。他们根据针孔摄像机方程,结合摄像机和激光雷达的测量来估计行人的高度。 6、Deep Learning Based MOT 基于深度学习的方法利用深度神经网络检测运动障碍物的位置和几何特征,并基于当前摄像机数据跟踪其未来状态。  5、交通信号检测与识别 交通信号检测识别子系统负责对交通规则中定义的标志进行检测和识别,使车辆能够根据交通规律做出正确的决策。与交通信号相关的任务有很多,在本文中,我们将探讨三个主要主题:交通灯、交通标志和自动驾驶汽车周围环境中的路面标记。 1、Traffic Light Detection and Recognition 红绿灯检测和识别包括检测汽车周围环境中一个或多个红绿灯的位置(例如,在图像中表示)并识别其状态(红色、绿色和黄色)。文献中提出了各种交通灯检测和识别方法。在这里,我们只回顾最新的和相关的。交通信号灯的检测与识别方法主要分为两类:基于模型的方法和基于学习的方法。交通灯在颜色和形状信息方面有一个明确的结构。一个普通的红绿灯有三个灯泡(每个州一个:红色、绿色和黄色)和一个清晰的形状。因此,早期的交通灯检测和识别方法大多是基于模型的。这些方法依赖于手工制作的特征工程,它试图利用人类掌握的关于物体颜色和形状的信息来建立一个能够检测和/或识别物体的模型。当假设没有严格遵守时,使用颜色和形状信息的方法是不可靠的。为了增强其鲁棒性,提出了一种不同特征(如颜色、形状和结构)的组合。例如提出了一个多特征系统,该系统结合了颜色(使用颜色分割)、形状/结构(使用黑盒检测)和地理信息(仅在预期有已知红绿灯时使用该系统)。然而,他们的系统在基于模型的方法中普遍存在大量的超参数,这通常意味着在某些情况下需要重新校准。作者在一个内部私有数据集上进行了实验,并指出故障是由于过度曝光、遮挡、交通灯的非标准安装以及其他一些在现实情况下并不罕见的情况造成的。在基于模型的方法的背景下,这种结合表明是不够的。因此,研究者开始引入基于学习的方法。在基于学习的方法中,特征仍然是手工制作的,但是检测和/或识别过程从基于规则变为基于学习。主要方法包括传统机器学习方式和深度学习方式。 2、Traffic Sign Detection and Recognition 交通标志检测与识别包括检测环境中交通标志的位置并识别其类别(如限速、停车和让行标志)。与基于模型的方法相比,基于学习的方法得到了改进并取得了更好的结果。随着深度学习在一般计算机视觉任务中的兴起,卷积神经网络已成为交通标志检测和识别领域的研究热点,在GTSRB和BTS的识别任务中分别达到了F1分数的99.71%和98.86%。 3、Pavement Marking Detection and Recognition 路面标线检测与识别包括检测路面标线的位置并识别其类型(如车道标线、道路标线、信息和人行横道)。路面标线检测与识别包括检测路面标线的位置并识别其类型(如车道标线、道路标线、信息和人行横道)。 大多数研究一次只处理一种路面标线,而不是同时处理所有标线。这可能是因为既没有一个广泛使用的数据库,也没有一个共识,即研究人员在处理路面标线检测和识别时,应该关注哪些符号集。一个重要的路面标记是道路中的车道定义。早些时候,大多数车道标记检测方法都是基于模型或学习的。形状和颜色是最常见的特征,直线和曲线是最常见的车道表示。在BER17c中,作者提出了一个完整的自我车道分析系统。在这些系统的特点中,作者声称能够检测车道及其属性、人行横道、车道变换事件和一些路面标线。作者还发布了用于评估这些类型系统的数据集。深度学习是最近流行的另一种方法,像GUR16这样的方法已经显示出很好的效果。作者建议(i)使用两个横向安装的下向摄像机,(ii)将横向距离估计建模为一个分类问题,其中他们使用CNN来处理该任务。在这种情况下,他们主张在一个私人数据库中以小于2像素的平均绝对误差(MAE)达到亚厘米的精度。许多用于车道标记检测的方法也尝试用于道路标记检测。它们通常使用几何和光度特征。此外,各种道路标线检测与识别方法都采用了逆透视映射(IPM),降低了透视效果,从而使问题更容易求解,提高了结果的准确性。最近,一些方法使用最大稳定极值区域(MSER)来检测感兴趣区域(即可能包含道路标记的区域)和用于识别道路标记的卷积网络。在BAI17中,作者提出了IPM、MSER和DBSCAN相结合的算法来检测道路标线,并将PCANet与支持向量机或线性回归相结合进行分类。在单独评估分类任务时,它们的准确率高达99.1%,而在同时报告检测和识别性能时,其准确率则降至93.1%。在道路标记的上下文中,消息通常是单独处理的。一些消息检测和识别方法AHM17将不同的消息视为不同的类别(即,它们首先检测消息在场景中的位置,然后识别其类别),而大多数方法首先识别字母,然后使用基于OCR的方法进行写作。前者通常对天气和光照条件更为敏感,但后者可以识别看不见的信息。在道路标线的设置中,行人过街经常被单独调查。大多数人行横道检测方法利用人行横道通常呈现的规则形状和黑白图案。因此,在许多实际应用中,这项任务被放在了有利于鲁棒行人检测器的位置。  三、决策模块 在本节中,我们将对文献中所报道的自动驾驶汽车决策系统的相关技术进行研究,包括路线规划、行为选择、运动规划和控制子系统。  1、Route Planning 路线规划子系统负责计算从自驾车的初始位置到用户操作员定义的最终位置之间通过道路网络的路线。如果用一个加权有向图来表示道路网,其边权表示通过一个路段的代价,那么计算一条路线的问题就可以归结为在加权有向图中寻找最短路径的问题。然而,对于大型道路网络,经典的最短路径算法,如Dijkstra和A的复杂度是不切实际的。在过去的十年中,道路网络中的路线规划算法的性能有了显著的进步。新开发的算法可以在毫秒或更短的时间内计算出行驶方向。道路网中的路径规划方法在查询时间、预处理时间、空间利用率和对输入变化的鲁棒性等方面提供了不同的权衡。它们主要可分为四类:goal-directed, separator-based, hierarchical, bounded-hop, and combinations。 1、Goal-Directed Techniques 目标导向技术通过避免扫描不在目标顶点方向上的顶点来引导从源顶点到目标顶点的搜索。A是一种经典的目标导向最短路径算法。与Dijkstra算法相比,该算法在每个顶点上使用一个较低的距离函数,从而使更接近目标的顶点更早地被扫描,从而获得更好的性能。ALT(A*、地标和三角形不等式)算法通过选取一小组顶点作为地标来增强A*。在预处理阶段,计算所有地标和所有顶点之间的距离。在查询阶段,利用包含地标的三角形不等式估计任意顶点的有效下界距离。查询性能和正确性取决于是否明智地选择顶点作为标记。另一个目标定向算法是Arc Flags。在预处理阶段,图被划分成具有少量边界顶点和平衡(即类似)顶点的单元。通过从每个边界顶点向后生长最短路径树,为树的所有弧(或边)设置第i个标志,计算单元i的弧标志。在查询阶段,该算法将修剪没有为包含目标顶点的单元格设置标志的边。arc flags方法具有较高的预处理时间,但在目标定向技术中查询时间最快。 2、Separator-Based Techniques 基于分隔符的技术基于顶点或边分隔符。顶点(或边)分隔符是顶点(或边)的一个小子集,其移除将图分解为几个平衡的单元。基于顶点分隔符的算法使用顶点分隔符来计算覆盖图。快捷边将添加到覆盖图中,以便保留与完整图的任何顶点对之间的距离。覆盖图比完整图小得多,用于加速查询算法。HPML(High Performance multivel Routing,高性能多级路由)算法是这种方法的一个变种,它显著减少了查询时间,但代价是增加了空间使用量和预处理时间,在不同的级别上为图添加了更多的快捷方式。 基于弧分隔符的算法使用边界分隔符将图分解为平衡的单元,试图最小化连接不同单元边界顶点的切割边数。快捷方式将添加到覆盖图中,以保持每个单元内边界顶点之间的距离。CRP(Customizable Route Planning,可定制路线规划)算法DEL15是为满足现实道路网络的需求而设计的,例如处理转弯成本和执行成本函数的快速更新。它的预处理有两个阶段。第一阶段计算多层分区和覆盖的拓扑。第二阶段通过自下而上和并行处理单元来计算团边的代价。查询作为覆盖图中的双向搜索进行处理。 3、Hierarchical Techniques 层次技术利用了道路网络固有的层次结构,其中主要道路(如公路)组成一个小的干线子网。一旦源顶点和目标顶点距离较远,查询算法只扫描子网的顶点。预处理阶段根据实际的最短路径结构计算顶点或边的重要性。CH(compression Hierarchies)算法是一种分层技术,它实现了创建快捷方式以跳过重要性较低的顶点的思想。它重复执行顶点压缩操作,如果图中最短路径唯一且包含要压缩的顶点,则从图中删除最不重要的顶点并在每对相邻顶点之间创建快捷方式。CH是通用的,因此可以作为其他点到点算法和扩展查询的构建块。REACH算法是一种分层技术,在预处理阶段计算顶点的中心度度量(REACH值),并在查询阶段使用它们来修剪基于Dijkstra的双向搜索。设P是从源顶点s到包含顶点v的目标顶点t的最短路径。v相对于P的到达值是r(v,P)=min{距离(s,v),距离(v,t)}。 4、Bounded-Hop Techniques 有界跳技术通过向图中添加虚拟快捷方式来预计算顶点对之间的距离。由于预先计算所有顶点对之间的距离对于大型网络是不可行的,因此有界跳技术的目标是在跳数很少的情况下获得任何虚拟路径的长度。 5、算法的结合 可以将各种技术组合到利用不同图形特性的混合算法中。REAL algorithm结合了REACH和ALT。REACH Flags algorithm结合了REACH和Arc标志。SHARC算法[BAU09]将快捷方式的计算与多级弧标志结合起来。CHASE算法[BAU10]结合了CH和Arc标志。TNR+AF算法结合了TNR和Arc标志。PHAST算法可以与多种技术相结合,利用多核cpu和gpu的并行性来加速它们。巴斯特等人。使用众所周知的欧洲大陆大小的基准西欧和现实世界道路网络的简化模型,对这里描述的许多路线规划技术进行了实验性评估。  2、Motion Planning 运动规划子系统负责计算从自动驾驶汽车的当前状态到行为选择子系统定义的下一个局部目标状态的路径或轨迹。该运动方案执行局部驾驶行为,满足汽车的运动学和动力学约束,为乘客提供舒适性,避免与环境中的静态和移动障碍物发生碰撞。 运动计划可以是路径或轨迹。路径是汽车状态的序列,它不定义汽车状态如何随时间演变。此任务可委托给其他子系统(如行为选择子系统)或速度剖面可定义为曲率和接近障碍物的函数。轨迹是一条指定汽车状态随时间演化的路径。 1、Path Planning 路径规划包括从汽车当前状态到下一个目标状态生成一系列状态,这并不定义汽车状态随时间的演变。路径规划通常分为全局和局部路径规划。在全局路径规划中,在车辆开始移动之前,使用环境的脱机全局地图计算全局路径。在局部路径规划中,当汽车行驶时,利用周围环境的在线局部地图生成局部路径,使汽车能够处理行驶中的障碍物。路径规划的方法主要分为两类:基于图搜索的和基于插值曲线的方法。 2、轨迹规划 轨迹规划包括从自动驾驶汽车的当前状态到下一个目标状态的序列生成,该序列指定汽车状态随时间的演变。轨迹规划方法主要分为四类:基于图搜索的、基于采样的、基于插值曲线的和基于数值优化的方法。 3、Control 在自动驾驶汽车领域,控制是指工程领域自动控制背后的理论,它涵盖了在没有持续的直接人为干预的情况下,应用各种机制来操作和调节过程。在最简单的自动控制类型中,控制子系统将过程的输出与期望的输入进行比较,并使用误差(过程的输出与期望的输入之间的差异)来改变过程的输入,从而使过程在受到干扰的情况下保持在其设定点。在自主车辆中,自动控制理论一般应用于路径跟踪和硬件驱动方法。路径跟踪方法的作用是在车辆模型存在误差等情况下稳定运动计划的执行。硬件驱动控制的作用是计算在执行器模型和其他模型不准确的情况下执行运动计划的转向、节气门和制动执行器输入。路径跟踪方法也被称为控制技术,因为它们采用自动控制理论,并将路径视为要控制的信号。然而,在自主车辆领域,将其称为路径跟踪方法更为合适,以区别于硬件驱动控制方法。 ———————————————— 版权声明:本文为CSDN博主「Tom Hardy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_29462849/article/details/105941077 
  • [技术干货] 彻底搞透视觉三维重建:原理剖析、代码讲解、及优化改进【转】
     前言 这是公众号【3D视觉工坊】出品的第一门课,视觉三维重建,基于colmap框架,保姆级教程,详细内容请见大纲,课程购买链接:彻底搞透视觉三维重建:原理剖析、代码讲解、及优化改进;  介绍 视觉三维重建 = 定位定姿 + 稠密重建 + surface reconstruction +纹理贴图。三维重建技术是计算机视觉的重要技术之一,基于视觉的三维重建技术通过深度数据获取、预处理、点云配准与融合、生成物体表面等过程,把真实场景刻画成符合计算机逻辑表达的数学模型。  然而,由于视觉三维重建对图像、光学、成像理论、以及重要数学公式的的推导要求较高,其次,三维重建也有其应用上的痛点、难点,比如成本预算、大场景、物体运动、纹理缺失、暗环境等,因而其涉及的算法也多种多样。鉴于视觉三维重建学习相关教材寥寥无几,网上资料也比较零散,国内外几乎没有系统讲解三维重建相关的课程。 为此,3D视觉工坊推出了国内首个《彻底搞透基于colmap的视觉三维重建:原理剖析、代码讲解、及优化改进》,本课程是国内首个深入剖析colmap原理、代码讲解、并对开源代码进行优化改进的课程,由资深三维重建算法工程师主讲及指导。 开课时间:6月5号20点开课,课程历时4个月,一年内有效。 课程购买链接:彻底搞透视觉三维重建:原理剖析、代码讲解、及优化改进  课程讲师 李城,资深三维重建算法工程师,担任过知名企业的图形图像算法工程师,高精度地图算法工程师。  课程大纲  适合人群 理工科相关专业,熟悉三维重建、线性代数、概率论等相关理论知识、有一定c++、python编程基础; 已经入门三维重建研究领域的本科、硕士及博士研究生; 希望通过此课程能够快速实现三维重建算法,并能在项目中应用的研究人员; 学后收获 掌握视觉三维重建整个流程,对colmap框架能够有较深的理解,其它开源视觉框架也能快速着手。 掌握colmap中的多视图几何算法、光束法平差算法以及内在的实现技巧,为后续思考colmap框架的优化方法铺垫了夯实的基础。 锻炼举一反三能力,将colmap中的优秀算法融合到实际问题中,如恢复尺度、雷达和相机的标定等。 学会借鉴其它开源框架的优点,如openmvg、opensfm 等,将其原理融合到colmap 中。 还能收获什么? 优质的学习圈子 但凡购买本课程的学员,同时将会被赠予高额的《3D视觉从入门到精通》知识星球优惠券一张(100~180元优惠券)。星球汇集了国内外各个高校的研究生、博士生,包括但不限于清华大学、上海交通大学、华中科技大学、武汉大学、南京大学、北京理工大学、北京航空航天大学;以及国外留学的小伙伴,主要就读于南加州大学、墨尔本大学、慕尼黑工业大学、亚琛工业大学等。除此之外,还有很多一线工作的算法工程师、开发人员,包括但不限于百度、旷视、华为、奥比中光、云从、阿丘科技等。3D视觉从入门到精通知识星球是一个技术社区,在这里你可以讨论任何3D视觉相关的难题、前沿技术。星球邀请了国内外高校博士(北航、慕尼黑工业大学等)、CV独角兽公司CTO/CEO、以及各大厂的算法工程师解惑。在这里,你可以一对一和大佬交流,提出自己在工作学习上的疑问。 课程服务 主讲及助理全程答疑 可以在专属微信群或者知识星球内,每天晚上8~10点为集中答疑时间。 课程亮点 亮点一:算法原理结合代码详解,线下设置答疑群,可以面对面和讲师沟通难题,更能和国内外各大高校学员一起交流,创造一个优异的学习环境;  亮点二:作者不仅仅只停留在讲解原算法本身,会对算法处理数据存在的问题进行改进;  亮点三:举一反三,会与目前主流的应用(如自动驾驶、VR)进行结合;  vslam或lslam的 prior pose 加上colmap 进行重定位地图的建立 利用colmap 进行激光雷达和相机的标定 利用colmap 进行相机和GPS 的时间同步(或者说顾忌曝光延迟的gps约束) 恢复单目的绝对尺度,应用到实际场景中(也可隶属课程亮点2中) i、利用先验的gps 恢复绝对尺度 ii、利用GCP 或者Marker 来恢复绝对尺度 iii、利用已知的模型比例(scale)来恢复绝对尺度 亮点四:采用问答方式来解析重点部分的代码和算法原理 ———————————————— 版权声明:本文为CSDN博主「Tom Hardy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_29462849/article/details/116568555 
总条数:208 到第
上滑加载中