中文字幕 另类精品,亚洲欧美一区二区蜜桃,日本在线精品视频免费,孩交精品乱子片免费

<sup id="3hn2b"></sup>

    1. <sub id="3hn2b"><ol id="3hn2b"></ol></sub><legend id="3hn2b"></legend>

      1. <xmp id="3hn2b"></xmp>

      2. "); //-->

        博客專欄

        EEPW首頁 > 博客 > 地平線 LiDAR-Camera 融合多任務(wù) BEVFusion 參考算法-V1.0

        地平線 LiDAR-Camera 融合多任務(wù) BEVFusion 參考算法-V1.0

        發(fā)布人:地平線開發(fā)者 時間:2025-02-08 來源:工程師 發(fā)布文章

        該示例為參考算法,僅作為在 征程 6 上模型部署的設(shè)計參考,非量產(chǎn)算法。

        1.簡介

        激光雷達(dá)天然地具有深度信息,攝像頭可以提供豐富的語義信息,它們是車載視覺感知系統(tǒng)中兩個最關(guān)鍵的傳感器。但是,如果激光雷達(dá)或者攝像頭發(fā)生故障,則整個感知框架不能做出任何預(yù)測,這在根本上限制了實際自動駕駛場景的部署能力。目前主流的感知架構(gòu)選擇在特征層面進(jìn)行多傳感器融合,即中融合,其中比較有代表性的路線就是 BEV 范式。BEVFusion 就是典型的中融合方法,其存在兩個獨立流,將來自相機(jī)和 LiDAR 的原始輸入編碼為同一個 BEV 空間。由于是通用的融合框架,相機(jī)流和 LiDAR 流的方法都可以自由選擇,在 nuScenes 數(shù)據(jù)集表現(xiàn)出了很強(qiáng)的泛化能力。本文將介紹 BEVFusion 在地平線 J6E/M 平臺上的優(yōu)化部署。


        2.性能精度指標(biāo)

        模型參數(shù):

        模型數(shù)據(jù)集Input shapeLiDAR StreamCamera StreamBEV HeadOcc Head

        BEVFusionNuscenes圖像輸入:6x3x512x960點云輸入:1x5x20x40000CenterPointBEVFormerBEVFormerDetDecoderBevformerOccDetDecoder

        性能精度表現(xiàn):

        浮點**精度** NDS量化精度 NDSJ6E

        Latency/msFPS

        0.64280.6352135.6430.95


        3.公版模型介紹


        BEVFusion 主要由相機(jī)流、激光雷達(dá)流、動態(tài)融合模塊和檢測頭組成,下面將逐一進(jìn)行介紹。


        3.1 相機(jī)流

        相機(jī)流將多視角圖像轉(zhuǎn)到 BEV 空間,由圖像編碼器、視覺投影模塊、BEV 編碼器組成。


        3.1.1 圖像**編碼器**


        圖像編碼器旨在將輸入圖像編碼為語義信息豐富的深度特征,它由用于基本特征提取的 2D backbone Dual-Swin-Tiny 和用于多尺度特征提取的 FPN 組成,并采用了一個簡單的功能自適應(yīng)模塊 ADP 來完善上采樣功能,如下圖所示:



        3.1.2 視覺投影模塊


        視覺投影模塊采用 LSS 將圖像特征轉(zhuǎn)換為 3D 自車坐標(biāo),將圖像視圖作為輸入,并通過分類方式密集地預(yù)測深度。

        然后,根據(jù)相機(jī)外參和預(yù)測的圖像深度,獲取偽體素。

        3.1.3 BEV 編碼模塊

        BEV 編碼模塊采用空間到通道(S2C)操作將 4D 偽體素特征編碼到 3D BEV 空間,從而保留語義信息并降低成本。然后又使用四個 3 × 3 卷積層縮小通道維度,并提取高級語義信息。


        3.2 LiDAR 流

        LiDAR 流將激光雷達(dá)點轉(zhuǎn)換為 BEV 空間,BEVFusion 采用 3 種流行的方法,PointPillars、CenterPoint 和 TransFusion 作為激光雷達(dá)流,從而展示模型框架的優(yōu)秀泛化能力。


        3.3 動態(tài)融合模塊

        動態(tài)融合模塊的作用是將 concat 后的相機(jī)、 LiDAR 的 BEV 特進(jìn)行有效融合。受 Squeeze-and-Excitation 機(jī)制的啟發(fā), BEVFusion 應(yīng)用一個簡單的通道注意力模塊來選擇重要的融合特征,網(wǎng)絡(luò)結(jié)構(gòu)圖如下所示:



        4.地平線部署優(yōu)化

        地平線參考算法使用流程請參考附錄《TCJ6007-J6 參考算法使用指南》;對應(yīng)高效模型設(shè)計建議請參考附錄《J6 算法平臺模型設(shè)計建議


        4.1 優(yōu)化點總結(jié)

        整體情況:

        BEVFusion 參考算法采用 BEVFormer 和 centerpoint 分別生成視覺和 LiDAR BEV 特征,然后使用 SE 模型融合 BEV 特征,最后將 BEV 特征解碼。

        暫時無法在飛書文檔外展示此內(nèi)容

        改動點:

        相機(jī)流使用了地平線深度優(yōu)化后的 bevformer 參考算法,并將其轉(zhuǎn)換到 LiDAR 坐標(biāo)系,其相對于公版的優(yōu)化如下:

        使用地平線深度優(yōu)化后的高效 backbone HENet 提取圖像特征;

        將 attention 層的 mean 替換為 conv 計算,使性能上獲得提升;

        公版模型中,在 Encoder 的空間融合模塊,會根據(jù) bev_mask 計算有效的 query 和 reference_points,輸出 queries_rebatch 和 reference_points_rebatch,作用為減少交互的數(shù)據(jù)量,提升模型運(yùn)行性能。對于稀疏的 query 做 crossattn 后再將 query 放回到 bev_feature 中。;

        修復(fù)了公版模型中時序融合的 bug,并獲得了精度上的提升,同時通過對關(guān)鍵層做 int16 的量化精度配置以保障 1%以內(nèi)的量化精度損失。

        LiDAR 流采用了地平線深度優(yōu)化后的 centerpoint 參考算法,其相對于公版的優(yōu)化如下:

        前處理部分的輸入為 5 維點云并做歸一化處理,對量化訓(xùn)練更加友好;

        PillarFeatutreNet 中的 PFNLayer 使用 Conv2d + BatchNorm2d + ReLU,替換原有的 Linear + BatchNorm1d + ReLU,使該結(jié)構(gòu)可在 BPU 上高效支持,實現(xiàn)了性能提升;

        PillarFeatutreNet 中的 PFNLayer 使用 MaxPool2d,替換公版的 torch.max,便于性能的提升;

        Scatter 過程使用 horizon_plugin_pytorch 優(yōu)化實現(xiàn)的 point_pillars_scatter,便于模型推理優(yōu)化,邏輯與 torch 公版相同;

        對于耗時嚴(yán)重的 OP,采用 H、W 維度轉(zhuǎn)換的方式,將較大維數(shù)放到 W 維度,比如 1x5x40000x20 轉(zhuǎn)換為 1x5x20x40000;

        相對于公版,增加了 OCC 任務(wù)頭,實現(xiàn)了 LiDAR+Camera+OCC 動靜態(tài)二網(wǎng)合一;


        4.2 性能優(yōu)化4.2.1 相機(jī)流

        公版 BEVFusion 使用流行的 Lift-Splat-Shoot(LSS)并適度調(diào)整以提高性能。參考算法直接采用了地平線深度優(yōu)化后的 BEVFormer 參考算法作為相機(jī)流網(wǎng)絡(luò),bev 網(wǎng)格的尺寸配置為 128 x128。

        改動點 1:

        backbone 由公版的 Dual-Swin-Tiny 替換為地平線的高效 backbone HENet,不僅在精度上可與 ResNet50 相媲美,而且在性能上有顯著優(yōu)勢。

        HENet 是針對 征程 6 平臺專門設(shè)計的高效 backbone,其采用了純 CNN 架構(gòu),總體可分為四個 stage,每個 stage 會進(jìn)行 2 倍下采樣。以下為總體的結(jié)構(gòu)配置:

        depth = [4, 3, 8, 6]
        block_cls = ["GroupDWCB", "GroupDWCB", "AltDWCB", "DWCB"]
        width = [64, 128, 192, 384]
        attention_block_num = [0,0,0,0]
        mlp_ratios, mlp_ratio_attn = [2, 2, 2, 3], 2
        act_layer = ["nn.GELU", "nn.GELU", "nn.GELU", "nn.GELU""]
        use_layer_scale = [True,True,True,True]
        final_expand_channel, feature_mix_channel = 0,1024
        down_cls = ["S2DDown", "S2DDown", "S2DDown", "None"71


        模型相關(guān)細(xì)節(jié)可以參考【地平線高效 backbone: HENet】

        代碼路徑:/usr/local/lib/python3.10/dist-packages/hat/models/backbones/henet.py

        改動點 2:

        bevformer 中的Temporal Self-Attention通過引入時序信息與當(dāng)前時刻的 BEV Query 進(jìn)行融合,提高 BEV Query 的建模能力,Temporal Self-Attention中最關(guān)鍵的結(jié)構(gòu)為MultiScaleDeformableAttention

        經(jīng)評估,該模塊中的 mean 對性能影響較大,參考算法中將其替換為固定 weight 的 conv 計算,從而獲取性能上的提升,相關(guān)代碼:


        class HorizonTemporalSelfAttention(MultiScaleDeformableAttentionBase):
           """The basic structure of HorizonTemporalSelfAttention.
           Args:
               embed_dims: The embedding dimension of Attention.
               num_heads: Parallel attention heads.
               num_levels: The num of featuremap.
               num_points: The num points for each head sample.
               grid_align_num: The align num for grid, align the grid shape of \
                   gridsample operator to \
                   [bs * numhead, -1, grid_align_num * numpoints, 2].
               num_bev_queue: The num queue for temporal fusion.
               reduce_align_num: The align num for reduce mean, align the shape to \
                   [bs, num_bev_queue * reduce_align_num, -1, num_query].
               dropout: Probability of an element to be zeroed.
               feats_size: The Size of featmaps.
           """
           def
        __init__
        (
               self,
               embed_dims: int = 256,
               num_heads: int = 8,
               num_levels: int = 4,
               num_points: int = 4,
               grid_align_num: int = 8,
               num_bev_queue: int = 2,
               reduce_align_num: int = 1,
               dropout: float = 0.1,
               feats_size: Sequence[Sequence[int]] = ((128, 128),),
           ) -> None:
               super().
        __init__
        (
                   embed_dims=embed_dims,
                   num_heads=num_heads,
                   num_levels=num_levels,
                   num_points=num_points,
                   grid_align_num=grid_align_num,
                   feats_size=feats_size,
               )
               self.dropout = nn.Dropout(dropout)
               self.num_bev_queue = num_bev_queue
               self.reduce_align_num = reduce_align_num
               ...
               #將mean計算替換為conv計算
               self.query_reduce_mean = nn.Conv2d(
                   self.num_bev_queue * self.reduce_align_num,
                   self.reduce_align_num,
                   1,
                   bias=False,
               )
               



        代碼路徑:/usr/local/lib/python3.10/dist-packages/hat/models/task_modules/bevformer/attention.py

        改動點 3:

        Spatial Cross-Attention利用 Temporal Self-Attention 模塊輸出的 bev_query, 對主干網(wǎng)絡(luò)和 Neck 網(wǎng)絡(luò)提取到的多尺度環(huán)視圖像特征進(jìn)行查詢,生成 BEV 空間下的BEV Embedding特征。公版的 BEVFormer 中采用 bevmask 來減少 camera 的 query 點數(shù)的優(yōu)化,但是由于涉及到 BPU 不支持的動態(tài) shape,并且涉及到運(yùn)行效率較低的 gather/scatter 操作(當(dāng)前 gather 算子已經(jīng)支持 BPU 加速)。進(jìn)一步分析發(fā)現(xiàn):

        從 bev voxel 的角度來看,中心點到 multi camera 的映射是稀疏的;

        從 bev pillar 的角度來看,通常每個 pillar 只會映射到 1-2 個 camera;

        基于以上分析以及實驗結(jié)果,參考算法在設(shè)置了virtual_bev_h、virtual_bev_w、max_numcam_overlap這 3 個參數(shù)對稀疏率進(jìn)行配置,這 3 個參數(shù)的具體含義是:

        virtual_bev_h:虛擬 bev 的高度,用于計算將稀疏點集恢復(fù)為密集 bev 的網(wǎng)格,參考算法中配置為 64;

        virtual_bev_w:虛擬 bev 的寬度,用于計算將稀疏點集恢復(fù)為密集 bev 的網(wǎng)格,參考算法中配置為 80;

        max_numcam_overlap:每個 bev pillar 映射到的最多 camera 數(shù)量,參考算法中配置為 2;

            view_transformer=dict(
               type="SingleBevFormerViewTransformer",
               bev_h=bev_h_,
               bev_w=bev_w_,
               pc_range=point_cloud_range,
               num_points_in_pillar=2,
               embed_dims=
        _dim_
        ,
               queue_length=1,
               in_indices=(-1,),
               single_bev=True,
               use_lidar2img=use_lidar2img,
               max_camoverlap_num=max_camoverlap_num, #2
               virtual_bev_h=64,
               virtual_bev_w=80,
               positional_encoding=dict(
                   type="LearnedPositionalEncoding",
                   num_feats=
        _pos_dim_
        ,
                   row_num_embed=bev_h_,
                   col_num_embed=bev_w_,
               ),

        代碼路徑:samples/ai_toolchain/horizon_model_train_sample/scripts/configs/lidar_bevfusion/bevfusion_pointpillar_henet_multisensor_multitask_nuscenes.py


        4.2.2 LiDAR 流

        公版 BEVFusion 采用了當(dāng)前流行的 3 種激光點云檢測模型 PointPillars , CenterPoint 和 TransFusion 作為 LiDAR 流來展示框架的通用性。BEVFusion 參考算法復(fù)用了經(jīng)過深度優(yōu)化的 centerpoint 參考算法,其相對于公版主要做了以下性能優(yōu)化,下面將逐一介紹。

        改動點 1:

        為了應(yīng)用 2D 卷積架構(gòu),PillarFeatutreNet 將點云(P,N,5)轉(zhuǎn)換為 2D 偽圖像,整體步驟如下圖所示:


        公版模型中 PillarFeatutreNet 中的部分算子在 BPU 運(yùn)行效率比較低,所以參考算法對其做了替換:

        PillarFeatutreNet 中的 PFNLayer 使用 BPU 上運(yùn)行比較高效的 Conv2d + BathNorm2d + ReLU 算子,替換了公版的 Linear + BatchNorm1d + ReLU 結(jié)構(gòu),實現(xiàn)了性能的提升;

        PillarFeatutreNet 中的 PFNLayer 使用 MaxPool2d,替換原有的 torch.max,便于性能的提升,對應(yīng)代碼:

        class PFNLayer(nn.Module):
           def
        __init__
        (
               self,
               in_channels: int,
               out_channels: int,
               bn_kwargs: dict = None,
               last_layer: bool = False,
               use_conv: bool = True,
               pool_size: Tuple[int, int] = (1, 1),
               hw_reverse: bool = False,
           ):
               """Pillar Feature Net Layer.
               This layer is used to convert point cloud into pseudo-image.
               Can stack multiple to form Pillar Feature Net.
               The original PointPillars paper uses only a single PFNLayer.
               Args:
                   in_channels (int): number of input channels.
                   out_channels (int): number of output channels.
                   bn_kwrags (dict): batch normalization arguments. Defaults to None.
                   last_layer (bool, optional): if True, there is no concatenation of
                       layers. Defaults to False.
               """
               ...
               if not self.use_conv:
                   ...
               else:
                   #使用Conv2d + BathNorm2d + ReLU,
                   #替換了公版的 Linear + BatchNorm1d + ReLU
                   self.linear = nn.Conv2d(
                       in_channels, self.units, kernel_size=1, bias=False
                   )
                   self.norm = nn.BatchNorm2d(self.units, **bn_kwargs)
                   self.relu = nn.ReLU(inplace=True)
                   #使用 MaxPool2d,替換torch.max
                   self.max_pool = nn.MaxPool2d(
                       kernel_size=pool_size, stride=pool_size
                   )

        代碼路徑:/usr/local/lib/python3.10/dist-packages/hat/models/task_modules/lidar/pillar_encoder.py

        改動點 2:

        如上圖所示,Scatter 是實現(xiàn)偽圖像轉(zhuǎn)換的重要一個步驟,參考算法使用horizon_plugin_pytorch實現(xiàn)的point_pillars_scatter,便于模型推理優(yōu)化,邏輯與公版相同。對應(yīng)代碼:



        from horizon_plugin_pytorch.nn.functional import point_pillars_scatter
        class PointPillarScatter(nn.Module):
           ...
           def forward(
               ...
               ):
                #input_shape=(coors_range[3:] - coors_range[:3]) / voxel_size
                self.nx = input_shape[0]

                self.ny = input_shape[1]
                if self.use_horizon_pillar_scatter: #對應(yīng)改動4
                    if len(voxel_features.shape) == 4:
                        P, C = voxel_features.size(2), voxel_features.size(3)
                        voxel_features = voxel_features.reshape(P, C)
                    out_shape = (batch_size, self.nchannels, self.ny, self.nx)
                    #(P, C)-->(batch,C,H,W)
                    batch_canvas = point_pillars_scatter(
                        voxel_features, coords, out_shape
                    )
                else:
                    ...
                return batch_canvas  


        其中,核心函數(shù)point_pillars_scatter是在horizon_plugin_pytorch中實現(xiàn)的。

        代碼路徑: /usr/local/lib/python3.10/dist-packages/hat/models/task_modules/lidar/pillar_encoder.py


        4.2.3 動態(tài)融合模塊

        相對于公版的動態(tài)融合模塊(參考 3.3 節(jié)),參考算法在 concat 后新增了 1 個 conv1x1,有助于性能的提升,相關(guān)代碼如下:

        class BevFuseModule(nn.Module):
           """BevFuseModule fuses features using convolutions and SE block.
           Args:
               input_c: The number of input channels.
               fuse_c: The number of channels after fusion.
           """
           def
        __init__
        (self, input_c: int, fuse_c: int):
               super().
        __init__
        ()
               self.reduce_conv = ConvModule2d(
                   input_c,
                   fuse_c,
                   kernel_size=1,
                   stride=1,
                   padding=0,
                   norm_layer=nn.BatchNorm2d(fuse_c, eps=1e-3, momentum=0.01),
                   act_layer=nn.ReLU(inplace=False),
               ...
           def forward(self, x: torch.Tensor):
               #增加了 conv1x1
               x = self.reduce_conv(x)
               x = self.conv2(x)
               pts_feats = self.seblock(x)
               return pts_feats


        代碼路徑: /usr/local/lib/python3.10/dist-packages/hat/models/task_modules/lidar_fusion/fusion_module.py


        4.3 浮點精度優(yōu)化4.3.1 旋轉(zhuǎn)增強(qiáng)

        在模型訓(xùn)練時,參考算法對 bev 進(jìn)行旋轉(zhuǎn)增強(qiáng),相關(guān)代碼如下:

        train_dataset = dict(
           type="NuscenesBevSequenceDataset",
           data_path=os.path.join(data_rootdir, "train_lmdb"),
           ...
           transforms=[
               dict(type="MultiViewsImgResize", size=input_size),
               dict(type="MultiViewsImgFlip"),
               dict(type="MultiViewsImgRotate", rot=(-5.4, 5.4)),
               dict(type="BevBBoxRotation", rotation_3d_range=(-0.3925, 0.3925)),
               dict(type="MultiViewsPhotoMetricDistortion"),
               dict(
                   type="MultiViewsImgTransformWrapper",
                   transforms=[
                       dict(type="PILToTensor"),
                       dict(type="BgrToYuv444", rgb_input=True),
                       dict(type="Normalize", mean=128, std=128),
                   ],
               ),
           ],
        )


        代碼路徑:

        horizon_model_train_sample/scripts/configs/lidar_bevfusion/bevfusion_pointpillar_henet_multisensor_multitask_nuscenes.py
        /usr/local/lib/python3.10/dist-packages/hat/data/transforms/multi_views.py


        4.3.2 加載預(yù)訓(xùn)練模型

        為了提升浮點模型的精度,浮點訓(xùn)練時相機(jī)流和 LiDAR 流分別加載了預(yù)訓(xùn)練模型,然后再共同訓(xùn)練,對應(yīng)代碼如下:

        float_trainer = dict(
            type="distributed_data_parallel_trainer",
            model=model,
            data_loader=data_loader,
            model_convert_pipeline=dict(
                type="ModelConvertPipeline",
                converters=[
                    dict(
                        type="LoadCheckpoint",
                        #加載相機(jī)流的預(yù)訓(xùn)練模型
                        checkpoint_path=os.path.join(
                            camera_ckpt_dir, "float-checkpoint-last.pth.tar"
                        ),
                        allow_miss=True,
                        ignore_extra=True,
                        verbose=True,
                    ),
                    dict(
                        type="LoadCheckpoint",
                        #加載LiDAR流的預(yù)訓(xùn)練模型
                        checkpoint_path=os.path.join(
                            lidar_ckpt_dir, "float-checkpoint-last.pth.tar"
                        ),
                       ...
            ),

        代碼路徑:

        horizon_model_train_sample/scripts/configs/lidar_bevfusion/bevfusion_pointpillar_henet_multisensor_multitask_nuscenes.py


        4.4 量化精度優(yōu)化4.4.1 全 int8+部分算子配置為 int16

        BEVFusion 參考算法采用的量化策略為全 int8+部分敏感算子通過 set_qconfig 配置為 int16,其中敏感算子的集中分布在 bevformer 部分,如下為 bevformer 中將MultiScaleDeformableAttention中對量化敏感的算子和 Tensor 配置為 int16 的示例代碼:


        class MultiScaleDeformableAttentionBase(nn.Module):
            """The basic class for MultiScaleDeformableAttention.
            Args:
                embed_dims: The embedding dimension of Attention.
                num_heads: Parallel attention heads.
                num_levels: The num of featuremap.
                num_points: The num points for each head sample.
                grid_align_num: The align num for grid, align the grid shape of \
                    gridsample operator to \
                    [bs * numhead, -1, grid_align_num * numpoints, 2].
                feats_size: The Size of featmaps.
            """
            def 
        __init__
        (
                self,
                embed_dims: int = 256,
                num_heads: int = 8,
                num_levels: int = 4,
                num_points: int = 4,
                grid_align_num: int = 8,
                feats_size: Sequence[Sequence[int]] = ((128, 128),),
            ) -> None:
                super().
        __init__
        ()
                ...
            def set_qconfig(self) -> None:
                """Set the quantization configuration."""
                from hat.utils import qconfig_manager
                int16_module = [
                    self.sampling_offsets,
                    self.quant_shape,
                    self.norm_offset,
                    self.add_offset,
                    self.add1,
                    self.mul1,
                ]
                for m in int16_module:
                    m.qconfig = qconfig_manager.get_qconfig(
                        activation_qat_qkwargs={"dtype": qint16},
                        activation_calibration_qkwargs={
                            "dtype": qint16,
                        },
                        activation_calibration_observer="mix",
                    )

        代碼路徑:

        /usr/local/lib/python3.10/dist-packages/hat/models/task_modules/bevformer/attention.py


        4.5 其它優(yōu)化4.5.1 增加 Occ 任務(wù)頭

        除了公版 BEVFusion 就存在的 3D 檢測頭外,參考算法增加了 Occ 任務(wù)頭做占用預(yù)測,和 3D 檢測頭共用特征部分,從而極大地節(jié)省了計算資源。Occ 任務(wù)頭復(fù)用了 FlashOcc 中的 head 進(jìn)行設(shè)計,通過通道轉(zhuǎn)高度模塊將 BEV 特征沿通道維度執(zhí)行簡單的重塑操作。相關(guān)代碼如下:

            def forward(self, img_feats: Tensor):
                """Forward mould.
                Args:
                    img_feats: (B, C, Dy, Dx)
                Returns:
                    occ_pred:tensor
                """
                occ_pred = self.final_conv(img_feats)
                if self.use_upsample is True:
                    occ_pred = F.interpolate(
                        occ_pred, size=(200, 200), mode="bilinear", align_corners=False
                    )
                # (B, C, Dy, Dx) --> (B, Dx, Dy, C)
                occ_pred = occ_pred.permute(0, 3, 2, 1)
                bs, Dx, Dy = occ_pred.shape[:3]
                if self.use_predicter:
                    #通道轉(zhuǎn)高度操作
                    # (B, Dx, Dy, C) --> (B, Dx, Dy, 2
        *C) --> (B, Dx, Dy, Dz*
        n_cls)
                    occ_pred = self.predicter(occ_pred)
                    occ_pred = occ_pred.view(bs, Dx, Dy, self.Dz, self.num_classes)
                return occ_pred

        代碼路徑:

        /usr/local/lib/python3.10/dist-packages/hat/models/task_modules/flashocc/bev_occ_head.py

        Occ label 坐標(biāo)轉(zhuǎn)換

        由于 Occ label 是在 ego 坐標(biāo)系中標(biāo)注的,所以需要將其統(tǒng)一到 Lidar 坐標(biāo)系,相關(guān)代碼如下:

        class NuscenesBevDataset(NuscenesDataset):
           ...
            def 
        __getitem__
        (self, item):
                aug_cfg = None
                if isinstance(item, dict):
                    idx = item["idx"]
                    aug_cfg = item["aug"]
                else:
                    idx = item
                sample = self._decode(self.pack_file, self.samples[idx])
                sample = NuscenesSample(sample)
                data = self.sampler(sample)
                if aug_cfg:
                    data["scenes_aug"] = aug_cfg
                if self.transforms is not None:
                    data = self.transforms(data)
                if self.with_lidar_occ:
                    #將Occ label由ego坐標(biāo)系轉(zhuǎn)到lidar坐標(biāo)系
                    data["gt_occ_info"] = sample._get_lidar_occ(data["lidar2global"])
                return data

        代碼路徑:

        /usr/local/lib/python3.10/dist-packages/hat/data/datasets/nuscenes_dataset.py

        Bev 特征裁剪

        bev 的空間范圍為[51.2,51.2],grid 尺寸為 128x128;而 occ 的空間范圍為[40,40],grid 尺寸為 128x128。為了將 bev 空間范圍對齊到 Occ,occ_head中根據(jù)比例將 128x128 的 bev feature 從中心裁剪出 100x100 的 roi,從而滿足 40/51.2=100/128。相關(guān)代碼如下:


        occ_head = dict(
            type="BevformerOccDetDecoder",
            use_mask=True,
            lidar_input=lidar_input,
            camera_input=camera_input,
            num_classes=num_classes_occ,
            #使用RoiResize做bev feature的裁剪
            roi_resizer=dict(
                type="RoiResize",
                in_strides=[1],
                roi_resize_cfgs=[
                    dict(
                        in_stride=1,
                        roi_box=(14, 14, 114, 114),
                    )
                ],
            ),

        代碼路徑:

        horizon_model_train_sample/scripts/configs/lidar_bevfusion/bevfusion_pointpillar_henet_multisensor_multitask_nuscenes.py


        5.總結(jié)與建議5.1 訓(xùn)練建議

        建議在浮點訓(xùn)練時分別加載 Lidar 流和相機(jī)流的預(yù)訓(xùn)練模型,然后再訓(xùn)練整個網(wǎng)絡(luò);

        建議選擇合適的 bev grid size,實驗中發(fā)現(xiàn) bev grid size 配置為 128x128 時的精度比 50x50 要高;

        對于多任務(wù)模型,建議在量化訓(xùn)練適當(dāng)增加 epoch,即量化訓(xùn)練不一定要嚴(yán)格按照浮點訓(xùn)練的 1/10 epoch 來訓(xùn)練;

        浮點訓(xùn)練時采用CosineAnnealingLrUpdater策略,量化訓(xùn)練時采用StepDecayLrUpdater策略,對于此模型來說,采用StepDecayLrUpdater策略對量化訓(xùn)練精度更友好;


        5.2 部署建議

        建議在模型架構(gòu)設(shè)計之初就考慮采用地平線深度優(yōu)化后的 backbone 或者網(wǎng)絡(luò)作為 base model;

        在注意力機(jī)制中存在一些 add、sum 等 ElementWise 操作,對于導(dǎo)致性能瓶頸的可以考慮 conv 替換,對于造成量化風(fēng)險的可以根據(jù)敏感度分析結(jié)果合理選擇更高的量化精度,以確保注意力機(jī)制的部署;

        建議在選擇 bev size 時考慮性能影響。征程 6 相比于 征程 5 帶寬增大,但仍需注意 bev size 過大導(dǎo)致訪存時間過長對性能的影響,建議考慮實際部署情況選擇合適的 bev size;

        若出現(xiàn)性能問題可以通過優(yōu)化 backbone 或者減少層數(shù)或者點數(shù)的方式來提升性能,但要注意以上操作可能會導(dǎo)致精度損失,請優(yōu)先考慮對點數(shù)的減少等對精度的影響較小性能收益最高的操作;


        附錄

        論文:BEVFusion

        公版模型代碼:https://github.com/ADLab-AutoDrive/BEVFusion

        參考算法使用指南:J6 參考算法使用指南


        *博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。




        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉