搜尋
首頁科技週邊人工智慧實戰部署:動態時序網路用於端到端偵測和追蹤

本文經自動駕駛之心公眾號授權轉載,轉載請聯絡來源。

相信除了少數自研晶片的大廠,絕大多數自動駕駛公司都會使用英偉達NVIDIA晶片,那就離不開TensorRT. TensorRT是在NVIDIA各種GPU硬體平台下運行的一個C 推理框架。我們利用Pytorch、TF或其他框架訓練好的模型,可以先轉化為onnx格式,再轉化為TensorRT的格式,然後利用TensorRT推理引擎去運行我們這個模型,從而提升這個模型在英偉達GPU上運行的速度。

一般來說,onnx和TensorRT僅支援相對比較固定的模型(包括各級的輸入輸出格式固定,單分支等),最多支援最外層動態輸入(導出onnx可以透過設定dynamic_axes參數確定允許動態變化的維度).但活躍在感知算法前沿的小伙伴們都會知道,目前一個重要發展趨勢就是端到端(End-2-End),可能涵蓋了目標檢測,目標跟踪,軌跡預測,決策規劃等全部自動駕駛環節,而且必定是前後幀緊密相關的時序模型.實現了目標檢測和目標跟踪端到端的MUTR3D模型可以作為一個典型例子(模型介紹可參考:)

#在MOTR/MUTR3D中,我們將詳細解釋Label Assignment機制的理論和實例,以實現真正的端到端多目標追蹤。請點擊連結閱讀更多:https://zhuanlan.zhihu.com/p/609123786

這種模型的轉換為TensorRT格式並實現精度對齊,甚至fp16的精度對齊,可能會面臨一系列的動態元素,例如多個if-else分支、子網路輸入形狀的動態變化以及其他需要動態處理的操作和算子等

實戰部署:動態時序網路用於端到端偵測和追蹤##圖片

#MUTR3D架構因為整個過程涉及多個細節,情況各不一樣,縱觀全網的參考資料,甚至google搜索,也很難找到即插即用的方案,只能通過不斷拆分和實驗來逐個解決.透過部落客一個多月的艱苦探索實踐(之前對TensorRT的經驗不多,沒有摸清它的脾氣),動了不少腦筋,也踩了不少坑,最後終於成功轉換並實現fp32/ fp16精度對齊,且時延相比單純的目標偵測增加非常小。想在此做一個簡單的整理,並為大家提供參考(沒錯,一直寫綜述,終於寫實踐了!)

1.數據格式問題

首先是MUTR3D的數據格式比較特殊,都是採用實例形式,這是因為每個query綁定的信息比較多,都打包成實例更容易一對一的訪問.但對於部署而言,輸入輸出只能是tensor,所以首先要對實例資料進行拆解,變成多個tensor變數.並且由於當前幀的query和其他變數是在模型中生成,所以只要輸入前序幀保留的query和其他變數即可,在模型中對二者進行拼接.

2.padding解決輸入動態shape的問題

對於輸入的前序幀query和其他變量,有一個重要問題是shape是不確定的。這是因為MUTR3D僅保留前序幀中曾經檢出過目標的query。這個問題還是比較容易解決的,最簡單的方法就是padding,也就是padding到一個固定大小。對於query可以用全0做padding,數量具體多少合適,可以依照自己的數據做實驗確定。太少容易漏掉目標,太多比較浪費空間。雖然onnx的dynamic_axes參數可以實現動態輸入,但因為涉及後續transformer計算的size,應該是有問題的。我沒有嘗試,讀者可以試驗一下

3.padding對於主transformer中self-attention模組的影響

如果不使用特殊算子,經過填充後就可以成功轉換為ONNX和TensorRT。實際上肯定會遇到這種情況,但不在本篇討論的範圍內。例如,在MUTR3D中,當在幀間移動參考點時,使用torch.linalg.inv算子來求偽逆矩陣是不支援的。如果遇到不支援的算子,只能嘗試替換,如果不行,就只能在模型外部使用,有經驗的人還可以自己寫算子。但由於這一步驟可以放在模型的預處理和後處理中,我選擇將其移到模型外部,編寫自己的算子會更困難

成功轉換並不意味著一切順利,答案往往是否定的。我們會發現精度差距非常大。這是因為模型有很多模組,讓我們先說第一個原因。在Transformer的自註意力階段,會進行多個查詢之間的資訊互動。然而,原始模型只保留了曾經檢測到目標的查詢(模型中稱為活躍查詢),應該只有這些查詢與當前幀的查詢進行交互。而現在,由於填充了許多無效的查詢,如果所有查詢一起交互,勢必會影響結果

解決這個問題受了DN-DETR[1]的啟發,那就是使用attention_mask,在nn.MultiheadAttention中對應'attn_mask'參數,作用就是屏蔽掉不需要進行信息交互的query,最初是因為在NLP中每個句子長度不一致而設定的,正好符合我現在的需求,只是需要注意True代表需要屏蔽的query,False代表有效query.

實戰部署:動態時序網路用於端到端偵測和追蹤圖片

attention mask示意圖因為計算attention_mask邏輯稍微有點複雜,很多操作轉換TensorRT可能出現新問題,所以也應該在模型外計算好之後作為一個輸入變量輸入模型,再傳遞給transformer.以下是示例代碼:

data['attn_masks'] = attn_masks_init.clone().to(device)data['attn_masks'][active_prev_num:max_num, :] = Truedata['attn_masks'][:, active_prev_num:max_num] = True[1]DN-DETR: Accelerate DETR Training by Introducing Query DeNoising

4.padding對於QIM的影響

QIM是MUTR3D中對transformer輸出的query進行的後處理模組,主要分三步,第一步是篩選active query,即在在當前幀中檢測出目標的query,依據是obj_idxs是否>=0(在訓練階段還包括隨機drop query,和隨機加入fp query,推理階段不涉及),第二步是update query,即針對第一步中篩選的query做一個更新,包括query 輸出值的self-attention,ffn,和與query輸入值的shortcut連接,第三步是將更新的query與重新生成的初始query拼接,作為下一幀的輸入.可見第二步中仍然存在我們在第3點中提到的問題,即self-attention不做全部query之間的交互,而是只進行active query之間的信息交互.所以在這裡又要使用attention mask.

雖然QIM模組是可選的,但實驗表明對模型精度的提升是有幫助的.如果要使用QIM的話,這個attention mask必須在模型裡計算,因為模型外部無法得知當前幀的檢測結果.由於tensorRT的語法限制,很多操作要么會轉換不成功,要么不會得到想要的結果,經過多次實驗,結論是直接用索引切片賦值(類似於​​第3點的示例程式碼)操作一般不支援,最好用矩陣計算的方式,但涉及計算必須將attention mask的bool類型轉為float類型,最後attention mask需要轉回bool類型才能使用.以下是實例代碼:

obj_mask = (obj_idxs >= 0).float()attn_mask = torch.matmul(obj_mask.unsqueeze(-1), obj_mask.unsqueeze(0)).bool()attn_mask = ~attn_mask

5.padding對於輸出結果的影響

進行完以上四點,我們基本上可以保證模型轉換tensorRT的邏輯沒有問題,但輸出結果經過多次驗證後某些幀仍然存在問題一度讓我很不解.但一幀幀從數據上分析,就會發現竟然在某些幀padding的query雖然沒有參與transformer計算,卻可以得到一個較高的score,進而得到錯誤的結果.這種情況在資料量大的情況下確實是可能的,因為padding的query只是初始值是0,reference points也是[0,0],與其他隨機初始化的query進行了同樣的操作.但由於畢竟是padding的query ,我們並不打算使用他們的結果,所以必須要進行過濾.

如何過濾填充查詢的結果呢?填充查詢的標誌只有它們的索引位置,其他資訊都沒有特異性。而索引資訊實際上記錄在第3點使用的注意力遮罩中,這個注意力掩碼是從模型外部傳入的。這個遮罩是二維的,我們可以使用其中的一維(任一行或任一列),將填入的track_score直接置為0。請記住仍然要注意第4步的注意事項,即盡量使用矩陣計算來代替索引切片賦值,並且計算必須轉換為float類型。以下是程式碼範例:

mask = (~attention_mask[-1]).float()track_scores = track_scores * mask

6.如何動態更新track_id

除了模型主體,其實還有非常關鍵的一步,就是動態更新track_id,這也是模型能做到端到端的一個重要因素.但在原模型中更新track_id的方式是一個相對複雜的循環判斷, 即高於score thresh且是新目標的,賦一個新的obj_idx, 低於filter score thresh且是老目標的,對應的disappear time 1,如果disappear time超過miss_tolerance, 對應的obj idx置為-1,即丟棄這個目標.

我們知道tensorRT是不支援if-else多分支語句的(好吧,我一開始不知道),這是個頭痛的問題.如果將更新track_id也放到模型外部,不僅影響了模型端到端的架構,而且也會導致無法使用QIM,因為QIM篩選query的依據是更新後的track_id.所以絞盡腦汁也要把更新track_id放到模型裡面去.

再次發揮聰明才智(快用完了),if-else語句也不是不能代替的,比如使用mask並行操作.例如將條件轉換為mask(例如tensor[mask] = 0).這裡面值得慶幸的是雖然第4,第5點提到tensorRT不支援索引切片賦值操作,但是卻支援bool索引賦值,猜測可能因為切片操作隱性改變了tensor的shape吧.但經過多次實驗,也不是所有情況下的bool索引賦值都支持的,出現了以下幾種頭疼的情況:

需要重新写的内容是:赋值的值必须是一个,不能是多个。例如,当我更新新出现的目标时,我不会统一赋值为某个ID,而是需要为每个目标赋予连续递增的ID。我想到的解决办法是先统一赋值为一个比较大且不可能出现的数字,比如1000,以避免与之前的ID重复,然后在后续处理中将1000替换为唯一且连续递增的数字。(我真是个天才)

如果要进行递增操作(+=1),只能使用简单的掩码,即不能涉及复杂的逻辑计算。例如,对disappear_time的更新,本来需要同时判断obj_idx >= 0且track_scores = 0这个条件。虽然看似不合理,但经过分析发现,即使将obj_idx=-1的非目标的disappear_time递增,因为后续这些目标并不会被选入,所以对整体逻辑影响不大

综上,最后的动态更新track_id示例代码如下,在后处理环节要记得替换obj_idx为1000的数值.:

def update_trackid(self, track_scores, disappear_time, obj_idxs):disappear_time[track_scores >= 0.4] = 0obj_idxs[(obj_idxs == -1) & (track_scores >= 0.4)] = 1000disappear_time[track_scores  5] = -1

至此模型部分的处理就全部结束了,是不是比较崩溃,但是没办法,部署端到端模型肯定比一般模型要复杂很多.模型最后会输出固定shape的结果,还需要在后处理阶段根据obj_idx是否>0判断需要保留到下一帧的query,再根据track_scores是否>filter score thresh判断当前最终的输出结果.总体来看,需要在模型外进行的操作只有三步:帧间移动reference_points,对输入query进行padding,对输出结果进行过滤和转换格式,基本上实现了端到端的目标检测+目标跟踪.

需要重新写的内容是:以上六点的操作顺序需要说明一下。我在这里按照问题分类来写,实际上可能的顺序是1->2->3->5->6->4,因为第五点和第六点是使用QIM的前提,它们之间也存在依赖关系。另外一个问题是我没有使用memory bank,即时序融合的模块,因为经过实验发现这个模块的提升效果并不明显,而且对于端到端跟踪机制来说,已经天然地使用了时序融合(因为直接将前序帧的查询信息带到下一帧),所以时序融合并不是非常必要

好了,现在我们可以对比TensorRT的推理结果和PyTorch的推理结果,会发现在FP32精度下可以实现精度对齐,非常棒!但是,如果需要转换为FP16(可以大幅降低部署时延),第一次推理会发现结果完全变成None(再次崩溃)。导致FP16结果为None一般都是因为出现数据溢出,即数值大小超限(FP16最大支持范围是-65504~+65504)。如果你的代码使用了一些特殊的操作,或者你的数据天然数值较大,例如内外参、姿态等数据很可能超限,一般可以通过缩放等方式解决。这里再说一下和我以上6点相关的一个原因:

7.使用attention_mask导致的fp16结果为none的问题

这个问题非常隐蔽,因为问题隐藏在torch.nn.MultiheadAttention源码中,具体在torch.nn.functional.py文件中,有以下几句:


if attn_mask is not None and attn_mask.dtype == torch.bool:new_attn_mask = torch.zeros_like(attn_mask, dtype=q.dtype)new_attn_mask.masked_fill_(attn_mask, float("-inf"))attn_mask = new_attn_mask

可以看到,这一步操作是对attn_mask中值为True的元素用float("-inf")填充,这也是attention mask的原理所在,也就是值为1的位置会被替换成负无穷,这样在后续的softmax操作中,这个位置的输入会被加上负无穷,输出的结果就可以忽略不记,不会对其他位置的输出产生影响.大家也能看出来了,这个float("-inf")是fp32精度,肯定超过fp16支持的范围了,所以导致结果为none.我在这里把它替换为fp16支持的下限,即-65504,转fp16就正常了,虽然说一般不要修改源码,但这个确实没办法.不要问我怎么知道这么隐蔽的问题的,因为不是我一个人想到的.但如果使用attention_mask之前仔细研究了原理,想到也不难.

好的,以下是我在端到端模型部署方面的全部经验分享,我保证这不是标题党。由于我对tensorRT的接触时间不长,所以可能有些描述不准确的地方

實戰部署:動態時序網路用於端到端偵測和追蹤

需要进行改写的内容是:原文链接:https://mp.weixin.qq.com/s/EcmNH2to2vXBsdnNvpo0xw

以上是實戰部署:動態時序網路用於端到端偵測和追蹤的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:51CTO.COM。如有侵權,請聯絡admin@php.cn刪除
SOA中的软件架构设计及软硬件解耦方法论SOA中的软件架构设计及软硬件解耦方法论Apr 08, 2023 pm 11:21 PM

​对于下一代集中式电子电器架构而言,采用central+zonal 中央计算单元与区域控制器布局已经成为各主机厂或者tier1玩家的必争选项,关于中央计算单元的架构方式,有三种方式:分离SOC、硬件隔离、软件虚拟化。集中式中央计算单元将整合自动驾驶,智能座舱和车辆控制三大域的核心业务功能,标准化的区域控制器主要有三个职责:电力分配、数据服务、区域网关。因此,中央计算单元将会集成一个高吞吐量的以太网交换机。随着整车集成化的程度越来越高,越来越多ECU的功能将会慢慢的被吸收到区域控制器当中。而平台化

新视角图像生成:讨论基于NeRF的泛化方法新视角图像生成:讨论基于NeRF的泛化方法Apr 09, 2023 pm 05:31 PM

新视角图像生成(NVS)是计算机视觉的一个应用领域,在1998年SuperBowl的比赛,CMU的RI曾展示过给定多摄像头立体视觉(MVS)的NVS,当时这个技术曾转让给美国一家体育电视台,但最终没有商业化;英国BBC广播公司为此做过研发投入,但是没有真正产品化。在基于图像渲染(IBR)领域,NVS应用有一个分支,即基于深度图像的渲染(DBIR)。另外,在2010年曾很火的3D TV,也是需要从单目视频中得到双目立体,但是由于技术的不成熟,最终没有流行起来。当时基于机器学习的方法已经开始研究,比

多无人机协同3D打印盖房子,研究登上Nature封面多无人机协同3D打印盖房子,研究登上Nature封面Apr 09, 2023 am 11:51 AM

我们经常可以看到蜜蜂、蚂蚁等各种动物忙碌地筑巢。经过自然选择,它们的工作效率高到叹为观止这些动物的分工合作能力已经「传给」了无人机,来自英国帝国理工学院的一项研究向我们展示了未来的方向,就像这样:无人机 3D 打灰:本周三,这一研究成果登上了《自然》封面。论文地址:https://www.nature.com/articles/s41586-022-04988-4为了展示无人机的能力,研究人员使用泡沫和一种特殊的轻质水泥材料,建造了高度从 0.18 米到 2.05 米不等的结构。与预想的原始蓝图

如何让自动驾驶汽车“认得路”如何让自动驾驶汽车“认得路”Apr 09, 2023 pm 01:41 PM

与人类行走一样,自动驾驶汽车想要完成出行过程也需要有独立思考,可以对交通环境进行判断、决策的能力。随着高级辅助驾驶系统技术的提升,驾驶员驾驶汽车的安全性不断提高,驾驶员参与驾驶决策的程度也逐渐降低,自动驾驶离我们越来越近。自动驾驶汽车又称为无人驾驶车,其本质就是高智能机器人,可以仅需要驾驶员辅助或完全不需要驾驶员操作即可完成出行行为的高智能机器人。自动驾驶主要通过感知层、决策层及执行层来实现,作为自动化载具,自动驾驶汽车可以通过加装的雷达(毫米波雷达、激光雷达)、车载摄像头、全球导航卫星系统(G

超逼真渲染!虚幻引擎技术大牛解读全局光照系统Lumen超逼真渲染!虚幻引擎技术大牛解读全局光照系统LumenApr 08, 2023 pm 10:21 PM

实时全局光照(Real-time GI)一直是计算机图形学的圣杯。多年来,业界也提出多种方法来解决这个问题。常用的方法包通过利用某些假设来约束问题域,比如静态几何,粗糙的场景表示或者追踪粗糙探针,以及在两者之间插值照明。在虚幻引擎中,全局光照和反射系统Lumen这一技术便是由Krzysztof Narkowicz和Daniel Wright一起创立的。目标是构建一个与前人不同的方案,能够实现统一照明,以及类似烘烤一样的照明质量。近期,在SIGGRAPH 2022上,Krzysztof Narko

一文聊聊智能驾驶系统与软件升级的关联设计方案一文聊聊智能驾驶系统与软件升级的关联设计方案Apr 11, 2023 pm 07:49 PM

由于智能汽车集中化趋势,导致在网络连接上已经由传统的低带宽Can网络升级转换到高带宽以太网网络为主的升级过程。为了提升车辆升级能力,基于为车主提供持续且优质的体验和服务,需要在现有系统基础(由原始只对车机上传统的 ECU 进行升级,转换到实现以太网增量升级的过程)之上开发一套可兼容现有 OTA 系统的全新 OTA 服务系统,实现对整车软件、固件、服务的 OTA 升级能力,从而最终提升用户的使用体验和服务体验。软件升级触及的两大领域-FOTA/SOTA整车软件升级是通过OTA技术,是对车载娱乐、导

internet的基本结构与技术起源于什么internet的基本结构与技术起源于什么Dec 15, 2020 pm 04:48 PM

internet的基本结构与技术起源于ARPANET。ARPANET是计算机网络技术发展中的一个里程碑,它的研究成果对促进网络技术的发展起到了重要的作用,并未internet的形成奠定了基础。arpanet(阿帕网)为美国国防部高级研究计划署开发的世界上第一个运营的封包交换网络,它是全球互联网的始祖。

综述:自动驾驶的协同感知技术综述:自动驾驶的协同感知技术Apr 08, 2023 pm 03:01 PM

arXiv综述论文“Collaborative Perception for Autonomous Driving: Current Status and Future Trend“,2022年8月23日,上海交大。感知是自主驾驶系统的关键模块之一,然而单车的有限能力造成感知性能提高的瓶颈。为了突破单个感知的限制,提出协同感知,使车辆能够共享信息,感知视线之外和视野以外的环境。本文回顾了很有前途的协同感知技术相关工作,包括基本概念、协同模式以及关键要素和应用。最后,讨论该研究领域的开放挑战和问题

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
2 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
2 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器