• [技术干货] 开源项目分享之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 
  • [技术干货] 超详细的计算机视觉学习书籍pdf汇总(涉及CV、深度学习、多视图几何、SLAM、点云处理等)【转】
     计算机视觉入门的一些pdf书籍,【计算机视觉工坊】按照不同领域帮大家划分了下,涉及深度学习基础、目标检测、Opencv、SLAM、点云、多视图集合、三维重建等~  计算机视觉 1、 计算机视觉算法与应用(第二版)  2、 OpenCV3编程入门  3、 数字图像处理(冈萨雷斯,第三版)  深度学习 1、 深度学习(花书)  2、 深度学习、优化与识别  3、 吴恩达DeepLearning.ai中文版笔记  4、 《神经网络与深度学习》(邱锡鹏)  目标检测 1、 深度学习之PyTorch物体检测实战  SLAM 1、 视觉SLAM十四讲  2、 概率机器人(中文版)  3、 基于视觉的自主机器人导航  多视图几何 1、计算机视觉中的多视图几何  点云处理 1、 点云库PCL学习教程  机器视觉 1、 机器视觉算法与应用(第一版)  2、 机器视觉算法与应用(第二版)  编程语言 1、 C Primer Plus(第五版)  2、 C++Primer中文版  3、 C++ STL源码剖析  3、 Effective C++(中文版第三版)  4、 泛型编程与STL中文版 ———————————————— 版权声明:本文为CSDN博主「Tom Hardy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_29462849/article/details/112439461 
  • [技术干货] 3D目标检测深度学习方法数据预处理综述【转】
     前言 这一篇的内容主要要讲一点在深度学习的3D目标检测网络中,我们都采用了哪些数据预处理的方法,主要讲两个方面的知识,第一个是representation,第二个数据预处理内容是数据增广。 作为本篇博文的引言,我们先给一种博主制作的比较重要的3D检测方法图鉴,如下,就笔者的个人理解,今年的CVPR出现了很多的one-stage的方法,同时出现了很多融合的方法,这里的融合有信息融合,有representation融合,同时根据近两年的发展来看,voxel-based的方法占据了主导地位,这是得益于卷积结构优越性(point-based方法采用pointnet++结构,是MLP搭建的),但是今年的oral文章3D-SSD是一篇在point-based方法上很有建树的文章,所以在3D检测中了解主要的representation代表方法也是很重要的。  1.representation 做3D视觉的,尤其是基于点云做3D视觉任务的同学们都比较清楚的知道,点云因为其具有稀疏性和无规则性使得在二维上非常成熟的CNN结构不能直接的运用在点云中。我们先了解一下点云的这两个特性,如下图所示,下图中的(i)表示二维图像的排列方式,(ii),(ii),(iv)表示的是点云的数据,可以看出点云的排列稀疏性,对比(ii)和(iii)可以得知虽然点云数据的排列顺序假使是一样的,但是其对应的几何结构不同,而(iii)和(iv)则可以看出尽管几何结构表示同一个,但是排列顺序却是可以不一样的。  知道了上述的两个点云数据的两种特性,所以设计一种合适的点云表达形式是比寻找到一个高效的深度学习框架更加重要的内容,就3D检测方面而言,到CVPR20,至少有三种比较重要和值得探究的representation方式,分表示pointrepresentation,voxel representation和graph representation。 1.1 point representation 如题,就是采用最原始的点作为深度学习网络的输入,不采用任何的预处理工作,这类工作都是在pointnet++的基础上进行的。 这里首选插入一点采用point-based方法的基础backbone,如下所示,左图表示的是pointnet的特征提取结构,也就是point-based的基础模块,右图就是point-based方法的基础架构,由point-encoder层和point-decoder层组成,encoder层主要逐渐下采样采点特取语义信息,decoder过程是将encoder过程得到的特征信息传递给没有被采样到的点。使得全局的点都具有encoder的特征信息。最后再通过每个点作为anchor提出候选框。  最早的工作是CVPR18上的F-pointnet,该文章的作者也是pointnet/pointnet++的作者,具体做法如下可知,首先通过二维的检测框架得到二维目标检测结果,然后将二维检测结果通过视锥投影到三维,再采用三维破pointnet++延伸结构检测为三维目标框。算是三阶段的基于point输入的目标检测方法  随后的CVPR19的比较经典的Point_based方法是point-rcnn,该工作不仅仅采用point作为representation,同时和上诉的F-pointnet比较没有采用二维信息,仅仅采用点云作为网络输入。如下图所示,该工作是一个两阶段的检测方法,第一阶段根据语义分割信息对每一个点都提出一个候选框,随后再采用多特征融合进一步优化proposals。  除了CVPR会议,在IROS和ICRA机器人相关的会议上也有很多这方面的研究,其中有一篇在F-pointnet上做出更细致的优化的文章F-ConvNet也是很优秀的工作,有兴趣的同学可以去了解下;这里直接介绍今年CVPR20上的基于Pointrepresentation的文章 3D-SSD,如下图所示,平平无奇的一阶段encoder过程,也就是把pointnet++的decoder部分给去除掉(这样做的目的是减少网络前馈时间,在KITTI上达到35FPS),本文的最主要的贡献点在于将Pointnet++的采样方法由欧式空间度量改为特征空间度量和欧式空间度量相结合的方法,同样的也采用了anchor-free的设计方法,使得显存占用更少。  point representation方法小总结 就笔者个人对这方面的理解,该类方法的优点是作为最原始的点云数据,保留了最细致的几何结构信息,网络的输入信息损失几乎是所有representation方法中最小的。但是缺点也很明显,第一点,MLP的感知能力不如CNN,因此主流的effective的方法都是voxel-based的,第二点,pointnet++结构的采样是很耗时的,所以在实时性上也不及voxel-based的方法。所以今年的CVPR oral文章3D-SSD为了实时性,丢掉了FP层,同时设计了新的SA模块。  1.2 voxel representation 1.2.1 Voxelization 步骤 在3D目标检测中,对整个场景的point2voxel的过程可以简单描述为如下: 1.设置Voxelization参数(每个voxel可以存放点的个数(max_points_number),voxel长宽高的大小(whl)) 2.对依次每一个点,根据其对应的坐标(x,y,z)得到该点在voxel的索引。 3.根据索引判断该voxel种是否已经存在max_points_number个点,如果存在,则将该点直接丢弃,如果不满足,则将该点加入到该voxel中。 4. 计算voxel特征 采用voxelnet的图表示为如下:  ​1.2.2 Voxelization 参数 上文中的体素化过程涉及到两个重要的内容,一个是体素参数,另外一个是voxel特征根据该voxel中的特征如何求取。 Voxelization对参数的要求比较高,就发展历史来说,VoxelNet(CVPR18)是第一篇采用voxel-representation作为点云输入的网络结构,该文章中max_points_number设置的为35,voxel大小设置为0.5;采用的voxel特征提取方式为增加一个pointnet对每个voxel中的35个点特征提取得到相应的voxel特征(如下图中的featurelearning network所示的内容),但是该参数很明显是会丢失比较多的几何结构信息,但是以这样的参数划分在当时还受到VoxelNet网络后续的3D卷积的显存占用的影响(3D卷积很占显存,因此网络预处理的参数受到影响)。  18年的SECOND提出的3D稀疏卷积大大减少了3D卷积的内存占用,(我们知道,3D卷积本身会对空间中每一个voxel都进行卷积,但是3D稀疏卷积只保留了空间中非空的voxel,采用map映射的方式得到卷积后的voxel空间索引);因此参数的设置自由了很多,就目前在KITTI和Nuscence上的sota的内容而言,我们一般采用的参数和特征提取方为: max−points−number=5,(w,l)=(0.05,0.05),h=0.1 采用的voxel特征直接为mean特征,即对每一个voxel中的所有点的坐标求均值即可。 1.2.3 related paper 这里只介绍一些在voxelrepresentation上做文章的研究内容,而不是采用voxel作为网络输入的研究工作,因此voxel-based的研究方法比较多,后续笔者会出一篇在这方面的研究综述,所以这里推荐的几篇文章都是在voxel-representation上的做出研究的工作。 voxel-based的先驱的两篇文章voxelnet和second的主要贡献分别是第一个提出采用voxel作为网络输入的方法和引入稀疏卷积替代3D卷积。这里补充一点voxel-based方法的backbone,目前几乎所有的voxel-based方法都采用如下的encoder的backone作为特征提取器。下图左图表示的是点的voxel表示,经过Voxelization化后,经过逐步下采样的encoder过程降为二维 feature map,最后再根据二维的feature的每一个像素点作为anchor point提出候选框。  在voxel-representation上做文章的研究工作,如下图,这是一篇发表在sensors2020上的文章Voxel-FPN:multi-scale voxel feature aggregation in 3D object detection frompoint clouds,该研究工作的主要内容是通过不同scale的体素划分,最后将其整合成到RPN网络结构中的FPN网络中,需要注意的是,这里的scale的大小要和最初划分的scale对应起来。  同样采用该思想的还有今年的CVPR20的文章HVNet,如下图所示,也是对场景中点云采用multi-scale的体素划分,最后也会形成一个FPN的结构,但是不同的细节和实现之处还是有很多的,HVNet采用了多线程同时并行处理每一个scale的体素划分,同时对于voxel的特征提取和Voxel-FPN也是不一样的。  在voxel划分上做研究的工作还有如下的waymo组的MVF工作,可以看到,之前的研究工作如果对于一个voxel中点数没有占据max_points_number实际上也会采用全0占据空间,而这一篇文章的一点创新则是修改成可自适应的储存点,不必强行每个voxel的空间占用一样大,可以节省不少内存占用。  1.2.4 voxelrepresentation方法小结 voxel-representation的方法的优点即是性能好又高效,不仅仅在精度上有着point-based的方法目前无法比拟的精度,在速度上也是很可观的,尤其是在稀疏卷积和3D流型卷积引入到3D目标检测后,发展更为迅速。但是缺点则是该类方法对参数比较敏感,预处理划分voxel的时候需要设置合适的参数,当然从信息论的方面理解,体素划分必然带来信息的丢失,尤其是局部细节信息的丢失,因此今年CVPR20上至少有三篇文章(SA-SSD,pointpainting,HVnet)在细节几何结构上做了一定的研究工作。  1.3 graph represention 这是一个比较新的representation,在3D检测中,今年CVPR20第一次出现了以graph作为representation的网络结构,如下图所示,graphrepresentation的核心问题也在于构建一个graph网络,即下图中的图左所示的内容。这也是很多在语义分割中遇到的问题,在目前的建图中大多是采用的knn的方法构建图结构,后续再送入到图卷积进行特种提取,最后根据pointrpn-head提出proposals。 ​ 就该类方法而言,目前的研究还不是很多,因为GCN非常耗时,可以理解为时pointnet++特征提取网络的升级版,不仅仅提取点之间的信息,同时根据‘点-边’信息提取到更加局部细节的信息,但是优点也可以理解到,3D shape实际上在增加边信息后,会更加容易感知(对比mesh结构可知),但是采用何种方式构建合适的graph都还是很需要研究的内容。  1.4 point-voxel fusion 既然我们知道point-based的方法具有保持了几何structure的能力,同时voxel-based的方法具有高效的感知能力,那么最新的研究就在考虑如何做这方面的fusion工作,PV-RCNN(CVPR20)采用的将voxel特征经过multi-scale的形式赋予到point上,最后再refine阶段将点的局部信息融合到pointnet中。SA-SSD采用voxel2point添加附加任务使得voxelbackbone具有structure aware能力。实际上根据representation fusion的经验,应该还是大有可做的。  2 Augmentation 实际上3D目标检测的数据增广方式和二维目标检测的方式大多相同,我们总结为如下一些比较常见的数据增广方式,根据动态图很容易的看到的出来数据增广的方式,这里笔者着重介绍一下groundtruth augmentor的方法,这应该是根据3D点云的稀疏空间特性所特有的数据增广方式。  ​​​​​​​​ground truth augmentor 就KITTIobject 3D的数据而言,每一帧的object数量从无到二十多个不等,ground truth augmentor的想法则是先从所有训练集中根据类别把groundtruth建立成一个data base,然后在训练的时候将data base中的gt按照类别丢一定数量的gt到当前训练的帧中,这里笔者给出一般在KITTI上数据增广的数量如下。即表示一般会选择在场景中丢进去15个car,丢进10个Pedestrians和Cyclists。 SAMPLE_GROUPS: [‘Car:15’,‘Pedestrian:10’, ‘Cyclist:10’] 因为该数据增广的工作在3D目标检测中比较重要,后续还延伸到一些涉及到该方面的研究工作,笔者做一点简单介绍. 这一篇文章(Class-balanced Grouping and Sampling for Point Cloud 3D Object Detection)的后续研究工作做成了一个detectionzoo,在github上叫det3D,但是该文章的初始问题是想解决在nuscene数据中的数据不平衡问题,根据作者的采样得到如下图表,这里也就是目标检测的longtail问题,数据不平衡问题  ​这里作者采用的gt数据增广方式采样如下个数的gt来平衡数据集本身存在的long tail问题,并最终在nuscence上取得了榜一的成绩。  笔者再介绍一篇今年CVPR20上涉及到gt augmentation的工作(oral)(What You See is What You Get:Exploiting Visibility for 3D Object Detection),,如下图,在本文gt数据增广后,俯视图下由(a)变成了(b),但是作者指出这里出现的问题在于有的增广的物体出现在墙后,这在Lidar扫描过程中是不符合规律的,因此作者采取的增广策略是把对应的墙体去掉,如(d)图所示的内容。这就比较符合lidar扫描的特性,即遇到object就会反弹。  3 笔者的思考 实际上数据预处理在深度学习中也是比较重要的内容,就representation来说,voxel的方法高效但存在信息丢失,point-basde的方法感知能力不及cnn但输入为最原始的结构,Graph构建了更容易感知的结构,但也要承担GCN网络过长的前馈时间;就augmentation来说,gtaugmentation尽管在涨点上成了众人皆知的trick,但是要能很好的用起来该方法还是有一些值得研究的trick在里面,就比如上述提到的两篇文章。最后写一个flag,后续尽快写一个voxel-based方法研究的发展概述,主要也是笔者的理解。  推荐文献 [1]VoxelNet: End-to-End Learning for Point Cloud Based 3D Object Detection [2]Frustum PointNets for 3D Object Detection from RGB-D Data [3]PointRCNN: 3D Object Proposal Generation and Detection from Point Cloud’ [4]3DSSD: Point-based 3D Single Stage Object Detector [5]Point-GNN: Graph Neural Network for 3D Object Detection in a Point Cloud ———————————————— 版权声明:本文为CSDN博主「Tom Hardy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_29462849/article/details/106439643 
  • [技术干货] 基于点云方式的6D姿态识别【转】
    前言 除了对应点方式,还可以将点云将与整个形状对齐,获得6D姿态。通常,首先进行粗配准以提供初始对准,然后进行密集配准方法,如迭代最近点(ICP),以获得最终的6D姿态。针对点云方式,挑选了一些相关的paper,在这里做下基本思想分享。  1、Go-ICP: A Globally Optimal Solution to 3D ICP Point-Set Registration 迭代最近点(ICP)算法是目前应用最广泛的点集配准方法之一。然而,基于局部迭代优化的ICP算法易受局部极小值的影响。它的性能严重依赖于初始化的质量,并且只保证局部最优性。本文提出了在ICP定义的L2误差度量下,两个三维点集欧氏(刚性)配准的第一个全局最优算法Go-ICP。Go-ICP方法基于搜索整个3D运动空间SE(3)的分枝定界(BnB)方案。利用SE(3)几何的特殊结构,推导了新的配准误差函数的上下界。在BnB方案中引入局部ICP,在保证全局最优的同时加快了新方法的速度。本文还讨论了扩展,解决了异常值健壮性问题。实验结果表明,该方法能够在不考虑初始值的情况下产生可靠的配准结果。Go-ICP可应用于需要最佳解决方案或无法始终获得良好初始化的情况。    2、SUPER 4PCS Fast Global Pointcloud Registration via Smart Indexing 大规模场景中的数据采集通常需要通过多次扫描积累信息。一种常见的方法是使用迭代最近点(ICP)算法(或其变体)局部对齐扫描对,但需要静态场景和扫描对之间的小运动。这可防止在多个扫描会话和/或不同采集模式(如立体声、深度扫描)之间积累数据。或者,可以使用允许扫描处于任意初始姿势的全局注册算法。然而,最先进的全局配准算法4PCS在数据点的数量上具有二次时间复杂度,这大大限制了它在获取大型环境方面的适用性。本文提出了Super 4PCS全局点云配准,它可以在线性时间(数据点的数目)中运行,并且在基于扫描对的(未知)重叠对齐问题的复杂性上输出敏感。算法简单,内存利用率高,速度快。本文证明,Super 4PCS比其他方法有显著的加速效果,并允许在以前不可能的尺度上非结构化高效地获取场景。   3、3DRegNet: A Deep Neural Network for 3D Point Registration 本文提出了一种三维扫描配准的深度学习算法3DRegNet。近年来随着廉价的3D商品传感器的出现,开发一种基于学习的3D配准算法将是非常有益的。本文在给定一组三维点对应关系的情况下,利用深度残差层和卷积层建立深度网络3DRegNet,主要完成两项任务: (1)将点对应关系分类为正确/错误的点对应关系 (2)可以回归将扫描对齐到公共参考帧的运动参数 与经典方法相比,3DRegNet有几个优点。首先,由于3DRegNet的工作原理是点对应,而不是原始扫描,因此明显快于许多传统方法。其次,论文证明该算法可以扩展到多视图场景,即同时处理两次以上扫描的注册。与使用四元数表示旋转的四变量位姿回归网络不同,本文使用李代数仅使用三个变量表示旋转。在两个具有挑战性的数据集(ICL-NUIM和SUN3D)上进行的大量实验表明3DRegNet性能优于其他方法,并取得了最新的结果。   4、3DMatch: Learning Local Geometric Descriptors from RGB-D Reconstructions(斯坦福大学,代码开源) 由于三维扫描数据的噪声、低分辨率和不完整性,在真实深度图像上进行局部几何特征匹配是一项具有挑战性的任务。这些困难限制了目前最先进的方法的性能,这些方法通常基于几何特性上的直方图。本文提出了一个数据驱动的模型3DMatch,该模型学习局部体块描述符以建立部分3D数据之间的对应关系。为了积累模型的训练数据,提出了一种自监督的特征学习方法,利用现有的RGB-D重建中发现的数百万个对应标签。实验表明,该描述子不仅能够匹配新场景中的局部几何特征进行重建,而且可以推广到不同的任务和空间尺度(如Amazon Picking Challenge的实例级对象模型对齐和网格曲面对应)。结果表明,3DMatch始终优于其他最先进的方法,具有显著的优势。    ———————————————— 版权声明:本文为CSDN博主「Tom Hardy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_29462849/article/details/104537112 
  • [技术干货] 基于RGB图像的机器人抓取算法汇总【转】
     前言 近期读取了一些最新基于RGB图像下的机器人抓取论文,在这里分享下思路。  1、Optimizing Correlated Graspability Score and Grasp Regression for Better Grasp Prediction 本文提出了一种新的深度卷积网络结构,该结构通过引入新的丢失量,利用抓取质量评价来改进抓取回归。除此之外发布了Jacquard+,它是Jacquard数据集的一个扩展,允许在一个可变装饰上放置多个对象的模拟场景中评估抓取检测模型。Jacquard+通过物理模拟创建的,允许在完全可复制的条件下进行测试。实验结果表明,所提出的抓取检测方法无论在Jacquard数据集还是Jacquard+上都明显优于现有的抓取检测方法;  网络结构:  实验结果:   2、Real-time Grasp Pose Estimation for Novel Objects in Densely Cluttered Environment 现有抓取方式主要为从物体的质心抓取以及沿物体的长轴抓取,但是这类方式对复杂形状物体常常失败。本文提出了一种用于机器人拾取和定位的新目标实时抓取姿态估计策略。该方法在点云中估计目标轮廓,并在图像平面上预测抓取姿态和目标骨架。被测试对象主要有球形容器,网球,甚至复杂形状的对象,如鼓风机(非凸形)。结果表明,该策略对复杂形状物体的抓取效果良好,并与上述策略进行了比较,预测出了有效的抓取配置。实验验证了该抓取技术在两种情况下的有效性,即物体被清晰地放置和物体被放置在密集的杂波中。抓取准确率分别为88.16%和77.03%。所有的实验都是用一个真实的UR10机械手和WSG-50双指抓取器进行的。   3、GRIP: Generative Robust Inference and Perception for Semantic Robot Manipulation in Adversarial Environments 本文提出了一种两阶段的生成性鲁棒推理与感知(GRIP)方法,以探索在生成对抗环境中进行物体识别和姿态估计。生成鲁棒推理与感知(GRIP)作为一个两阶段的目标检测与姿态估计系统,目的是结合CNN的可区分相对优势和生成推理方法来实现鲁棒估计。在GRIP中,将推理的第一阶段表示为基于CNN的识别分布。CNN识别分布用于第二阶段的生成性多假设优化,这种优化是作为一个静态过程的粒子滤波器来实现的。本文证明,GRIP方法在不同光照和拥挤遮挡的对抗场景下,相对于最先进的姿态估计系统PoseCNN和DOPE,达到了SOTA。使用密歇根进度抓取机器人演示了抓取和目标定向顺序操作在对象拾取和放置任务中的兼容性。  4、Domain Independent Unsupervised Learning to grasp the Novel Objects 本文提出了一种基于无监督学习的可行抓取区域选择算法,监督学习在没有任何外部标签的情况下推断数据集中的模式。论文在图像平面上应用k-均值聚类来识别抓取区域,然后用轴指派方法。除此之外,定义了一个新的抓取决定指数(GDI)概念来选择图像平面上的最佳抓取姿势,并在杂乱或孤立的环境中对Amazon Robotics Challenge 2017 和Amazon Picking Challenge 2016的标准物体进行了多次实验。论文还将结果与基于先验学习的方法进行比较,以验证提出的算法对于不同领域中的各种新对象的鲁棒性和自适应性。   5、Multi-View Picking: Next-best-view Reaching for Improved Grasping in Clutter(代码开源) 摄像机视点选择是视觉抓取检测的一个重要方面,特别是在杂波中存在许多遮挡的情况下。现有方法使用静态相机位置或固定数据收集例程,本文的多视图拾取(MVP)控制器通过使用主动感知方法直接基于实时抓取姿势估计的分布来选择信息视点,从而减少杂波和遮挡造成的抓取姿势的不确定性。在从杂波中抓取20个目标的实验中,MVP控制器获得了80%的抓取成功率,比单视点抓取检测器的性能提高了12%。论文还证明了提出的方法比考虑多个固定视点的方法更准确和高效。   6、ROI-based Robotic Grasp Detection for Object Overlapping Scene 本文提出了一种基于感兴趣区域(ROI)的机器人抓取检测算法ROI-GD。ROI-GD使用ROI中的特征来检测抓取,而不是整个场景。它分为两个阶段:第一阶段是在输入图像中提供ROI,第二阶段是基于ROI特征的抓取检测器。通过标注视觉操作关系数据集,论文还构建了一个比康奈尔抓取数据集大得多的multi-object抓取数据集。实验结果表明,ROI-GD算法在对象重叠场景中有较好的表现,同时与康奈尔抓取数据集和Jacquard Dataset上的最新抓取检测算法具有可比性。机器人实验表明,ROI-GD可以帮助机器人在单目标场景和多目标场景中抓取目标,总体成功率分别为92.5%和83.8%。  ———————————————— 版权声明:本文为CSDN博主「Tom Hardy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_29462849/article/details/104505732 
  • [技术干货] 三维重建算法综述|传统+深度学习【转】
    00 前言 01 基于传统多视图几何的三维重建算法 1.1 主动式 (1)结构光 (2)TOF 激光飞行时间法 (3)三角测距法 1.2 被动式 (1)单目视觉 (2)双目/多目视觉 1.3 基于消费级RGB-D相机 02 基于深度学习的三维重建算法 2.1 在传统三维重建算法中引入深度学习方法进行改进 2.2 深度学习重建算法和传统三维重建算法进行融合,优势互补 2.3 模仿动物视觉,直接利用深度学习算法进行三维重建 (1)基于体素 (2)基于点云 (3)基于网格 03 总结 04 参考文献  00 前言 目前,三维重建技术已在游戏、电影、测绘、定位、导航、自动驾驶、VR/AR、工业制造以及消费品领域等方面得到了广泛的应用。方法同样也层出不穷,我们将这些方法依据原理分为两类:  基于传统多视图几何的三维重建算法 基于深度学习的三维重建算法 总地来说,尽管目前传统的三维重建算法依旧占据研究的主要部分,但是越来越多的研究者开始关注于用CNN探索三维重建,或者说,两者之间的交叉与融合。  有人问,在三维重建中引入深度学习方法有什么意义?我将意义概括为三部分:  为传统重建算法性能优化提供新的思路  一项名为 Code SLAM1 的工作,这项研究获得了CVPR 2018年的best paper提名奖,研究利用神经网络框架,并结合图像几何信息实现了单目相机的稠密SLAM。主要贡献在于使用了深度学习方法从单张图像中用神经网络提取出若干个基函数来表示场景的深度,这些基函数表示可以极大简化传统几何方法中的优化问题。显然,深度学习方法的引入可以给传统方法的性能提升提供新的思路,而以前,这部分工作大多由机器学习方法来做。  将深度学习重建算法和传统三维重建算法进行融合,优势互补  业界对算法的鲁棒性要求比较高,因此多传感器、乃至多种算法的融合以提升算法鲁棒性是个必然趋势,而深度学习在一些场景中具有天然优势,比如不可见部分的建模,传统算法就很难凭借“经验”来估计物体的深度。  模仿动物视觉,直接利用深度学习算法进行三维重建  动物跟人类直接基于大脑而非严格的几何计算来进行物体的三维重建,那么直接基于深度学习的方法在原理上也是可行的。特别需要注意的是,在一些研究中,有些方法直接基于单张图像(非单目,单目指利用单个摄像头)进行三维重建。理论上讲,单张图像已经丢失了物体的三维信息,因此在原理上即不能恢复深度信息,但是人类又能凭借经验大致估计物体的距离,因而也具有一定的“合理性”。  两者形成了各自的理论和体系,但未来三维重建领域研究一定是传统优化方法与深度学习的结合。目前,这方面研究仍处于起步阶段,还有许多问题亟待解决。下面的综述主要侧重于深度学习方法,但也仅列出重要文献,更详细的综述将会在公众后续的文章中介绍。  01 基于传统多视图几何的三维重建算法 传统的三维重建算法按传感器是否主动向物体照射光源可以分为 主动式 和 被动式 两种方法。这些年,也有不少研究直接基于消费级的 RGB-D 相机进行三维重建,如基于微软的 Kinect V1 产品,同样取得了不错的效果。基于传统多视图几何的三维重建算法概括如下:  主动式,指通过传感器主动地向物体照射信号,然后依靠解析返回的信号来获得物体的三维信息,常见的有:  结构光 TOF 激光飞行时间 三角测距法 被动式,直接依靠周围环境光源来获取RGB图像,通过依据多视图几何原理对图像进行解析,从而获取物体的三维信息。常见的依据原理可以分为:  单目视觉 双目/多目视觉 基于消费级RGB-D相机,相机可以基于主动式、被动式不同原理,优点在于基于这些设备的算法更具备实用性。  这些方法它们各自有着各自的优点和缺点,同样有各自所适用的应用范围。下面为想要入门基于深度学习进行三维重建领域的同学简要介绍这些方法,如需要深入了解,请仔细阅读相关文献,SfM和多视图几何等经典算法作为入门三维重建领域的基础永远都不会过时。  1.1 主动式 (1)结构光  结构光法依靠投影仪将编码的结构光投射到被拍摄物体上,然后由摄像头进行拍摄。由于被拍摄物体上的不同部分相对于相机的距离精度和方向不同,结构光编码的图案的大小和形状也会发生改变。这种变化可以被摄像头捕获,然后通过运算单元将其换算成深度信息,进而获取物体的三维轮廓信息。这种方法缺点是容易受环境光干扰,因此室外体验差。另外,随检测距离增加,其精度也会变差。目前,一些研究通过增大功率、改变编码方式等形式解决这些问题,取得了一定的效果。  (2)TOF 激光飞行时间法  TOF 飞行时间法依靠通过向目标连续发送光脉冲,然后依据传感器接收到返回光的时间或相位差来计算距离目标的距离。但显然这种方式足够的精度需要极为精确的时间测量模块,因此成本相对较高。好处是这种方法测量距离比较远,受环境光干扰比较小。目前这方面研究旨在降低计时器良品率及成本,相应的算法性能也在提升。  (3)三角测距法  三角测距法,即依据三角测距原理,不同于前两者需要较为精密的传感器,三角测距法整体成本较低,并且在近距离的时候精度较高,因而广泛应用于民用和商用产品中,如扫地机器人中。但三角测距的测量误差与距离有关,随着测量距离越来越大,测量误差也越来越大,这是由三角测量的原理导致的,不可避免。  1.2 被动式 被动式方面依靠多视图几何原理基于视差进行计算,我们简要叙述一下这些方法。  (1)单目视觉  单目视觉只使用单一摄像头作为采集设备,具有低成本、易部署等优点。其依靠一段时间内获得的连续图像的视差来重建三维环境。但其存在固有的问题:单张图像可能对应无数真实物理世界场景(病态),因此使用单目视觉方法从图像中估计深度进而实现三维重建的难度较大。依据原理,可以分类为:  目前这种算法广泛应用于手机等移动设备中,常见的算法有SfM ,REMODE 和SVO 等。  (2)双目/多目视觉  双目视觉主要利用左右相机得到的两幅校正图像找到左右图片的匹配点,然后根据几何原理恢复出环境的三维信息。但该方法难点在于左右相机图片的匹配,匹配地不精确都会影响最后算法成像的效果。多目视觉采用三个或三个以上摄像机来提高匹配的精度,缺点也很明显,需要消耗更多的时间,实时性也更差。  这两种方法理论上都可较精确恢复深度信息,但实际上受拍摄条件的影响,其精度往往无法得到保证。常见的有SGM 和SGBM 算法等,其中自动驾驶数据集KITTI中,排名前五十的算法几乎有一半都是对SGM 的改进。  1.3 基于消费级RGB-D相机 近年来,也有不少研究直接基于消费级的RGB-D相机进行三维重建,如在微软的Kinect V1、V2产品上,取得了不错的效果。最早,由帝国理工大学的Newcombe等人于2011年提出的Kinect Fusion 开启了RGB相机实时三维重建的序幕。此后有 Dynamic Fusion 和Bundle Fusion 等算法。  02 基于深度学习的三维重建算法 我们将基于深度学习的三维重建算法简要地分为三部分,更详细的文献综述将会在后续的公众号的系列文章中做介绍:  在传统三维重建算法中引入深度学习方法进行改进 深度学习重建算法和传统三维重建算法进行融合,优势互补 模仿动物视觉,直接利用深度学习算法进行三维重建 2.1 在传统三维重建算法中引入深度学习方法进行改进 因为CNN在图像的特征匹配上有着巨大优势,所以这方面的研究有很多,比如:  DeepVO,其基于深度递归卷积神经网络(RCNN)直接从一系列原始RGB图像(视频)中推断出姿态,而不采用传统视觉里程计中的任何模块,改进了三维重建中的视觉里程计这一环。  BA-Net ,其将 SfM 算法中的一环集束调整(Bundle Adjustment,BA)优化算法作为神经网络的一层,以便训练出更好的基函数生成网络,从而简化重建中的后端优化过程。  Code SLAM ,如之前所提,其通过神经网络提取出若干个基函数来表示场景的深度,这些基函数可以简化传统几何方法的优化问题。  2.2 深度学习重建算法和传统三维重建算法进行融合,优势互补 CNN-SLAM13将CNN预测的致密深度图和单目SLAM的结果进行融合,在单目SLAM接近失败的图像位置如低纹理区域,其融合方案给予更多权重于深度方案,提高了重建的效果。  2.3 模仿动物视觉,直接利用深度学习算法进行三维重建 我们知道,三维重建领域主要的数据格式有四种:  深度图(depth map),2D图片,每个像素记录从视点到物体的距离,以灰度图表示,越近越黑;  体素(voxel),体积像素概念,类似于2D之于像素定义;  点云(point cloud),每个点逗含有三维坐标,乃至色彩、反射强度信息;  网格(mesh),即多边形网格,容易计算。  因而,依据处理的数据形式不同我们将研究简要分为三部分:1)基于体素;2)基于点云;3)基于网格。而基于深度图的三维重建算法暂时还没有,因为它更多的是用来在2D图像中可视化具体的三维信息而非处理数据。  (1)基于体素  体素,作为最简单的形式,通过将2D卷积扩展到3D进行最简单的三维重建:  Depth Map Prediction from a Single Image using a Multi-Scale Deep Network, 2014 该方法是用深度学习做三维重建的开山之作,基于体素形式,其直接用单张图像使用神经网络直接恢复深度图方法,将网络分为全局粗估计和局部精估计,并用一个尺度不变的损失函数进行回归。  3D-R2N2: A unified approach for single and multi-view 3d object reconstruction, 2016 Christopher等人基于体素形式提出的3D-R2N2模型使用Encoder-3DLSTM-Decoder的网络结构建立2D图形到3D体素模型的映射,完成了基于体素的单视图/多视图三维重建(多视图的输入会被当做一个序列输入到LSTM中,并输出多个结果)。  但这种基于体素的方法存在一个问题,提升精度即需要提升分辨率,而分辨率的增加将大幅增加计算耗时(3D卷积,立次方的计算量)。  (2)基于点云  相较而言,点云是一种更为简单,统一的结构,更容易学习,并且点云在几何变换和变形时更容易操作,因为其连接性不需要更新。但需要注意的是,点云中的点缺少连接性,因而会缺乏物体表面信息,而直观的感受就是重建后的表面不平整。  A Point Set Generation Network for 3D Object Reconstruction From a Single Image, 2017。该方法是用点云做三维重建的开山之作,最大贡献在于解决了训练点云网络时候的损失问题,因为相同的几何形状可能在相同的近似程度上可以用不同的点云表示,如何用恰当的损失函数来进行衡量一直是基于深度学习用点云进行三维重建方法的难题。  Point-Based Multi-View Stereo Network, 2019。该方法通过对场景的点云进行处理,融合三维深度和二维纹理信息,提高了点云的重建精度。  (3)基于网格  我们知道之前的方法的缺点:  基于体素,计算量大,并且分辨率和精度难平衡 基于点云,点云的点之间缺少连接性,重建后物体表面不光滑 相较而言,网格的表示方法具有轻量、形状细节丰富的特点,重要是相邻点之间有连接关系。因而研究者基于网格来做三维重建。我们知道,网格是由顶点,边,面来描述3D物体的,这正好对应于图卷积神经网络的 M=(V,E,F) 所对应。  Pixel2Mesh ,用三角网格来做单张RGB图像的三维重建,相应的算法流程如下: (1)对于任意的输入图像都初始化一个椭球体作为初始三维形状。 (2)然后网络分为两部分: 一部分用全卷积神经网络来提取输入图像的特征;另一部分用图卷积网络来表示三维网格结构。 (3)对三维网格不断进行变形,最终输出物体的形状。 模型通过四种损失函数来约束形状,取得了很好的效果。贡献在于用端到端的神经网络实现了从单张彩色图直接生成用网格表示的物体三维信息。  03 总结 传统的三维重建算法可以分为:  这些方法各自有各自优点和使用范围,简要概括一下:  而基于深度学习的三维重建算法研究主要有三种:  在传统三维重建算法中引入深度学习方法进行改进 深度学习重建算法和传统三维重建算法进行融合,优势互补 模仿动物视觉,直接利用深度学习算法进行三维重建:基于体素 ,基于点云,基于网格 才疏学浅,做了简单的关于用深度学习做三维重建的叙述,更详细的综述将会在后续公众号的文章中给出。  ——————————————— 版权声明:本文为CSDN博主「Tom Hardy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_29462849/article/details/104442128 
  • [其他] 物体检测的前沿算法——目标检测与实例分割 
    前言物体检测是计算机视觉领域的一个重要任务,旨在从图像中准确识别并定位不同类别的物体。随着深度学习技术的飞速发展,目标检测与实例分割成为物体检测领域的前沿算法。本文将深入介绍目标检测与实例分割的原理和常见算法,以及它们在实际应用中的重要意义。 一、目标检测与实例分割的基本原理 目标检测是指在图像中找到并定位一个或多个感兴趣的物体,同时判断物体的类别。实例分割则更进一步,要求在像素级别对图像中的每个物体进行分割,实现对不同物体的精确分割与定位。 二、传统目标检测算法 1. Haar特征与级联分类器:经典的目标检测算法之一,通过Haar-like特征和级联分类器进行物体的检测,然而其性能相对较弱,适用于一些简单场景。 2. HOG+SVM:采用梯度方向直方图(HOG)特征结合支持向量机(SVM)进行目标检测,效果相对较好,但对于复杂场景仍存在一定的限制。  三、深度学习目标检测算法 1. R-CNN系列算法:包括R-CNN、Fast R-CNN、Faster R-CNN,这些算法通过候选框提取、特征提取和分类回归网络来实现目标检测。Faster R-CNN引入了Region Proposal Network(RPN)来加速候选框的提取,取得了较好的检测性能。 2. YOLO(You Only Look Once):采用单个神经网络同时预测候选框的位置和类别,实现实时目标检测。YOLO的速度非常快,适用于实时应用,但在小物体上性能稍逊于Faster R-CNN。  四、实例分割算法 1. Mask R-CNN:基于Faster R-CNN的框架,通过增加分割分支来实现物体实例的像素级分割。Mask R-CNN在目标检测和实例分割任务上均表现出色,成为实例分割领域的代表算法。 2. FCN(Fully Convolutional Network):不同于传统的基于区域的方法,FCN采用全卷积神经网络进行像素级别的语义分割,是实例分割算法的重要起源之一。  五、物体检测算法的应用领域 1. 自动驾驶:物体检测算法在自动驾驶系统中用于识别交通标志、行人、车辆等,实现智能驾驶与交通安全。 2. 工业自动化:应用于生产线上的物体检测,可以实现产品质量检测、零部件装配等自动化工作。 3. 智能安防:用于视频监控系统中的物体检测,可以识别异常行为、盗窃等安全事件。 结语: 目标检测与实例分割作为计算机视觉领域的研究热点,近年来取得了巨大的进步。随着深度学习技术的不断演进,我们相信这些算法在未来会进一步提升,为各行业带来更多智能化的应用。 
总条数:49 到第
上滑加载中