跨模態(tài)Transformer:面向快速魯棒的3D目標(biāo)檢測
本文經(jīng)自動駕駛之心公眾號授權(quán)轉(zhuǎn)載,轉(zhuǎn)載請聯(lián)系出處。
目前,在自動駕駛的車輛中已經(jīng)配備了多種信息采集傳感器,如激光雷達(dá)、毫米波雷達(dá)以及相機(jī)傳感器。目前來看,多種傳感器融合在自動駕駛的感知任務(wù)中顯示出了巨大的發(fā)展前景。比如:相機(jī)采集到的2D圖像信息捕獲了豐富的語義特征,激光雷達(dá)采集到的點(diǎn)云數(shù)據(jù)可以為感知模型提供物體的準(zhǔn)確位置信息和幾何信息。通過將不同種傳感器獲取到的信息充分利用起來可以減少自動駕駛感知過程中的不確定性因素的發(fā)生,同時使感知模型具有更好的檢測魯棒性。
今天介紹的是一篇來自曠視的自動駕駛感知論文,并且中稿了今年的ICCV2023 視覺頂會,該文章的主要特點(diǎn)是類似PETR這類End-to-End的BEV感知算法(不再需要利用NMS后處理操作過濾感知結(jié)果中的冗余框),同時又額外使用了激光雷達(dá)的點(diǎn)云信息來提高模型的感知性能,是一篇非常不錯的自動駕駛感知方向的論文,文章的鏈接和官方開源倉庫鏈接如下:
- 論文鏈接:https://arxiv.org/pdf/2301.01283.pdf
- 代碼鏈接:https://github.com/junjie18/CMT
CMT算法模型整體結(jié)構(gòu)
接下來先整體介紹一下CMT感知模型的網(wǎng)絡(luò)結(jié)構(gòu),如下圖所示:
通過整個算法框圖可以看出,整個算法模型主要包括三個部分
- 激光雷達(dá)主干網(wǎng)絡(luò)+相機(jī)主干網(wǎng)絡(luò)(Image Backbone + Lidar Backbone):用于獲取點(diǎn)云和環(huán)視圖像的特征得到Point Cloud Token**(PC Tokens)以及Image Token(Im Tokens)**
- 位置編碼的生成:針對不同傳感器采集到的數(shù)據(jù)信息,Im Tokens生成對應(yīng)的坐標(biāo)位置編碼Im PE,PC Tokens生成對應(yīng)的坐標(biāo)位置編碼PC PE,同時Object Queries也生成對應(yīng)的坐標(biāo)位置編碼Query Embedding
- Transformer Decoder+FFN網(wǎng)絡(luò):輸入為Object Queries + Query Embedding 以及完成位置編碼的Im Tokens和PC Tokens進(jìn)行交叉注意力的計(jì)算,利用FFN生成最終的3D Boxes + 類別預(yù)測
在介紹完網(wǎng)絡(luò)整體結(jié)構(gòu)之后,接下來就詳細(xì)介紹一下上述提到的三個子部分
激光雷達(dá)主干網(wǎng)絡(luò)+相機(jī)主干網(wǎng)絡(luò)(Image Backbone + Lidar Backbone)
- 激光雷達(dá)主干網(wǎng)絡(luò)
通常采用的激光雷達(dá)主干網(wǎng)絡(luò)提取點(diǎn)云數(shù)據(jù)特征包括以下五個部分
- 點(diǎn)云信息體素化
- 體素特征編碼
- 3D Backbone(常用VoxelResBackBone8x網(wǎng)絡(luò))對體素特征編碼后的結(jié)果進(jìn)行3D特征的提取
- 將3D Backbone提取到特征的Z軸進(jìn)行壓縮,得到BEV空間下的特征
- 利用2D Backbone對投影到BEV空間的特征做進(jìn)一步的特征擬合
- 由于2D Backbone輸出的特征圖的通道數(shù)與Image輸出的通道數(shù)不一致,用了一個卷積層進(jìn)行通道數(shù)的對齊(針對本文模型而言,做了一個通道數(shù)量的對齊,但并不屬于原有點(diǎn)云信息提取的范疇)
- 相機(jī)主干網(wǎng)絡(luò)
一般采用的相機(jī)主干網(wǎng)絡(luò)提取2D圖像特征包括以下兩個部分: 輸入:2D Backbone輸出的降采樣16倍和32倍的特征圖
輸出:將下采樣16倍和32倍的圖像特征進(jìn)行融合,獲取降采樣16倍的特征圖
Tensor([bs * N, 1024, H / 16, W / 16])
Tensor([bs * N,2048,H / 16,W / 16])
Tensor([bs * N,256,H / 16,W / 16])
輸入:采用ResNet-50網(wǎng)絡(luò)提取環(huán)視圖像特征
輸出:輸出下采樣16倍和32倍的圖像特征
輸入張量:
Tensor([bs * N,3,H,W])
輸出張量:
Tensor([bs * N,1024,H / 16,W / 16])
輸出張量:``Tensor([bs * N,2048,H / 32,W / 32])`
2D Backbone提取圖像特征
Neck(CEFPN)
位置編碼的生成
根據(jù)上面的介紹可知,位置編碼的生成主要包括三個部分,分別是Image Position Embedding,Point Cloud Position Embedding以及Query Embedding;接下來分別介紹一下他們的生成過程。
- Image Position Embedding(Im PE)
Image Position Embedding的生成過程與PETR中圖像位置編碼的生成邏輯是一樣的(具體可以參考PETR論文原文,這里不做過多的闡述),可以總結(jié)為以下四個步驟:
- 在圖像坐標(biāo)系下生成3D圖像視錐點(diǎn)云
- 3D圖像視錐點(diǎn)云利用相機(jī)內(nèi)參矩陣變換到相機(jī)坐標(biāo)系下得到3D相機(jī)坐標(biāo)點(diǎn)
- 相機(jī)坐標(biāo)系下的3D點(diǎn)利用cam2ego坐標(biāo)變換矩陣轉(zhuǎn)換到BEV坐標(biāo)系下
- 將轉(zhuǎn)換后的BEV 3D 坐標(biāo)利用MLP層進(jìn)行位置編碼得到最終的圖像位置編碼
- Point Cloud Position Embedding(PC PE)
Point Cloud Position Embedding的生成過程可以分為以下兩個步驟 在BEV空間的網(wǎng)格坐標(biāo)點(diǎn)利用
pos2embed()
函數(shù)將二維的橫縱坐標(biāo)點(diǎn)變換到高維的特征空間# 點(diǎn)云位置編碼`bev_pos_embeds`的生成 bev_pos_embeds = self.bev_embedding(pos2embed(self.coords_bev.to(device), num_pos_feats=self.hidden_dim)) def coords_bev(self): x_size, y_size = (grid_size[0] // downsample_scale,grid_size[1] // downsample_scale) meshgrid = [[0, y_size - 1, y_size], [0, x_size - 1, x_size]] batch_y, batch_x = torch.meshgrid(*[torch.linspace(it[0], it[1], it[2]) for it in meshgrid]) batch_x = (batch_x + 0.5) / x_size batch_y = (batch_y + 0.5) / y_size coord_base = torch.cat([batch_x[None], batch_y[None]], dim=0) # 生成BEV網(wǎng)格. coord_base = coord_base.view(2, -1).transpose(1, 0) return coord_base # shape: (x_size * y_size, 2) def pos2embed(pos, num_pos_feats=256, temperature=10000): scale = 2 * math.pi pos = pos * scale dim_t = torch.arange(num_pos_feats, dtype=torch.float32, device=pos.device) dim_t = temperature ** (2 * (dim_t // 2) / num_pos_feats) pos_x = pos[..., 0, None] / dim_t pos_y = pos[..., 1, None] / dim_t pos_x = torch.stack((pos_x[..., 0::2].sin(), pos_x[..., 1::2].cos()), dim=-1).flatten(-2) pos_y = torch.stack((pos_y[..., 0::2].sin(), pos_y[..., 1::2].cos()), dim=-1).flatten(-2) posemb = torch.cat((pos_y, pos_x), dim=-1) return posemb # 將二維的x,y坐標(biāo)編碼成512維的高維向量
利用一個MLP網(wǎng)絡(luò)進(jìn)行空間轉(zhuǎn)換,保證通道數(shù)量的對齊
Query Embedding
為了讓Object Queries、Image Token以及Lidar Token之間計(jì)算相似性更加的準(zhǔn)確,論文中的Query Embedding會利用Lidar和Camera生成位置編碼的邏輯來生成;具體而言Query Embedding = Image Position Embedding(同下面的rv_query_embeds) + Point Cloud Position Embedding(同下面的bev_query_embeds)。
bev_query_embeds生成邏輯
由于論文中的Object Query原本就是在BEV空間進(jìn)行初始化的,所以直接復(fù)用Point Cloud Position Embedding生成邏輯中的位置編碼和bev_embedding()函數(shù)即可,對應(yīng)關(guān)鍵代碼如下:
def _bev_query_embed(self, ref_points, img_metas): bev_embeds = self.bev_embedding(pos2embed(ref_points, num_pos_feats=self.hidden_dim)) return bev_embeds # (bs, Num, 256)
rv_query_embeds生成邏輯
上面剛剛提到,Object Query是在BEV坐標(biāo)系下初始的點(diǎn),所以論文中為了可以遵循Image Position Embedding的生成過程,就需要先將BEV坐標(biāo)系下的3D空間點(diǎn)投影到圖像坐標(biāo)系下,然后再利用之前生成Image Position Embedding的處理邏輯,保證生成過程的邏輯相同,核心代碼如下:
def _rv_query_embed(self, ref_points, img_metas): pad_h, pad_w = pad_shape # 由歸一化坐標(biāo)點(diǎn)映射回正常的roi range下的3D坐標(biāo)點(diǎn) ref_points = ref_points * (pc_range[3:] - pc_range[:3]) + pc_range[:3] points = torch.cat([ref_points, ref_points.shape[:-1]], dim=-1) points = bda_mat.inverse().matmul(points) points = points.unsqueeze(1) points = sensor2ego_mats.inverse().matmul(points) points =intrin_mats.matmul(points) proj_points_clone = points.clone() # 選擇有效的投影點(diǎn) z_mask = proj_points_clone[..., 2:3, :].detach() > 0 proj_points_clone[..., :3, :] = points[..., :3, :] / ( points[..., 2:3, :].detach() + z_mask * 1e-6 - (~z_mask) * 1e-6 ) proj_points_clone = ida_mats.matmul(proj_points_clone) proj_points_clone = proj_points_clone.squeeze(-1) mask = ( (proj_points_clone[..., 0] < pad_w) & (proj_points_clone[..., 0] >= 0) & (proj_points_clone[..., 1] < pad_h) & (proj_points_clone[..., 1] >= 0) ) mask &= z_mask.view(*mask.shape) coords_d = ( 1 + torch.arange(depth_num).float() * (pc_range[4] - 1) / depth_num) projback_points = (ida_mats.inverse().matmul(proj_points_clone)) projback_points = torch.einsum("bvnc, d -> bvndc", projback_points, coords_d) projback_points = torch.cat( [projback_points[..., :3], projback_points.shape[:-1]], dim=-1) projback_points = (sensor2ego_mats.matmul(intrin_mats).matmul(projback_points)) projback_points = (bda_mat@ projback_points) projback_points = (projback_points[..., :3] - pc_range[:3]) / (pc_range[3:] - self.pc_range[:3]) rv_embeds = self.rv_embedding(projback_points) rv_embeds = (rv_embeds * mask).sum(dim=1) return rv_embeds
通過上述的變換,即完成了BEV空間坐標(biāo)系下的點(diǎn)先投影到圖像坐標(biāo)系,再利用之前生成Image Position Embedding的處理邏輯生成rv_query_embeds的過程。
最后Query Embedding = rv_query_embeds + bev_query_embeds
Transformer Decoder+FFN網(wǎng)絡(luò)
- Transformer Decoder
這里與Transformer中的Decoder計(jì)算邏輯是完全一樣的,但在輸入數(shù)據(jù)上有點(diǎn)不同
- 第一點(diǎn)是Memory:這里的Memory是Image Token和Lidar Token進(jìn)行Concat后的結(jié)果(可以理解為兩種模態(tài)的融
- 第二點(diǎn)是位置編碼:這里的位置編碼是rv_query_embeds和bev_query_embeds進(jìn)行concat的結(jié)果,query_embed是rv_query_embeds + bev_query_embeds;
- FFN網(wǎng)絡(luò)
這個FFN網(wǎng)絡(luò)的作用與PETR中的作用是完全相同的,具體的輸出結(jié)果可以看PETR原文,這里就不做過多的贅述了。
論文實(shí)驗(yàn)結(jié)果
首先先放出來CMT和其他自動駕駛感知算法的比較實(shí)驗(yàn),論文作者分別在nuScenes的test和val集上進(jìn)行了比較,實(shí)驗(yàn)結(jié)果如下
- 各個感知算法在nuScenes的test set上的感知結(jié)果對比
表格中的Modality代表輸入到感知算法中的傳感器類別,C代表相機(jī)傳感器,模型只喂入相機(jī)數(shù)據(jù)。L代表激光雷達(dá)傳感器,模型只喂入點(diǎn)云數(shù)據(jù)。LC代表激光雷達(dá)和相機(jī)傳感器,模型輸入的是多模態(tài)的數(shù)據(jù)。通過實(shí)驗(yàn)結(jié)果可以看出,CMT-C模型的性能要高于BEVDet和DETR3D。CMT-L模型的性能要高于CenterPoint和UVTR這類純激光雷達(dá)的感知算法模型。而當(dāng)CMT采用激光雷達(dá)的點(diǎn)云數(shù)據(jù)和相機(jī)數(shù)據(jù)后超越了現(xiàn)有的所有單模態(tài)方法,得到了SOTA的結(jié)果。
- 模型在nuScenes的val set上的感知結(jié)果對比
通過實(shí)驗(yàn)結(jié)果可以看出,CMT-L的感知模型的性能超越了FUTR3D和UVTR。當(dāng)同時采用激光雷達(dá)的點(diǎn)云數(shù)據(jù)和相機(jī)數(shù)據(jù)后,CMT較大幅度超越了現(xiàn)有的采用多模態(tài)的感知算法,像FUTR3D、UVTR、TransFusion、BEVFusion等多模態(tài)算法,取得了在val set上的SOTA結(jié)果。
接下來是CMT創(chuàng)新點(diǎn)的消融實(shí)驗(yàn)部分
首先(a)是做了是否采用位置編碼的消融實(shí)驗(yàn),通過結(jié)果可以看出當(dāng)同時采用圖像和激光雷達(dá)的位置編碼后,NDS和mAP指標(biāo)實(shí)現(xiàn)了最好的效果。(c)和(f)部分的消融實(shí)驗(yàn)主要是對點(diǎn)云主干網(wǎng)絡(luò)的主干網(wǎng)絡(luò)類型和體素大小進(jìn)行了不同的嘗試。(d)和(e)部分的消融實(shí)驗(yàn)主要是對相機(jī)主干網(wǎng)絡(luò)的類型和輸入分辨率的大小進(jìn)行了不同的嘗試。這部分只是做了粗略的概括,如果想要看更多詳細(xì)消融實(shí)驗(yàn)的話,大家可以看下論文原文。
最后放一張CMT的感知結(jié)果在nuScenes數(shù)據(jù)集上可視化結(jié)果的展示,通過實(shí)驗(yàn)結(jié)果可以看出,CMT還是有較好的感知結(jié)果的。
總結(jié)
目前將各個模態(tài)融合在一起去提升模型的感知性能已經(jīng)是一個比較火熱的研究方向(畢竟自動駕駛汽車上配備了多種傳感器),同時CMT又是一個完全End-to-End的感知算法(不需要額外的后處理步驟)并在nuScenes數(shù)據(jù)集上有著SOTA的精度,本文就是對這篇文章進(jìn)行了較為細(xì)致的介紹,希望對大家有所幫助。
原文鏈接:https://mp.weixin.qq.com/s/Fx7dkv8f2ibkfO66-5hEXA