【mmdetection3d】——学习配置文件
教程 1: 學習配置文件
我們在配置文件中支持了繼承和模塊化來方便進行各種實驗。
如果需要檢查配置文件,可以通過運行 python tools/misc/print_config.py /PATH/TO/CONFIG 來查看完整的配置。
你也可以傳入 --options xxx.yyy=zzz 參數來查看更新后的配置。
配置文件結構
在 config/_base_ 文件夾下有 4 個基本組件類型,分別是:數據集 (dataset),模型 (model),訓練策略 (schedule) 和運行時的默認設置 (default runtime)。
通過從上述每個文件夾中選取一個組件進行組合,許多方法如 SECOND、PointPillars、PartA2 和 VoteNet 都能夠很容易地構建出來。
由 _base_ 下的組件組成的配置,被我們稱為 原始配置 (primitive)。
對于同一文件夾下的所有配置,推薦只有一個對應的 原始配置 文件,所有其他的配置文件都應該繼承自這個 原始配置 文件,這樣就能保證配置文件的最大繼承深度為 3。
為了便于理解,我們建議貢獻者繼承現有方法。
例如,如果在 PointPillars 的基礎上做了一些修改,用戶首先可以通過指定 _base_ = ../pointpillars/hv_pointpillars_fpn_sbn-all_4x8_2x_nus-3d.py 來繼承基礎的 PointPillars 結構,然后修改配置文件中的必要參數以完成繼承。
如果你在構建一個與任何現有方法不共享結構的全新方法,可以在 configs 文件夾下創建一個新的例如 xxx_rcnn 文件夾。
更多細節請參考 MMCV 文檔。
配置文件名稱風格
我們遵循以下樣式來命名配置文件,并建議貢獻者遵循相同的風格。
{model}_[model setting]_{backbone}_{neck}_[norm setting]_[misc]_[gpu x batch_per_gpu]_{schedule}_{dataset}{xxx} 是被要求填寫的字段而 [yyy] 是可選的。
- {model}:模型種類,例如 hv_pointpillars (Hard Voxelization PointPillars)、VoteNet 等。
- [model setting]:某些模型的特殊設定。
- {backbone}: 主干網絡種類例如 regnet-400mf、regnet-1.6gf 等。
- {neck}:模型頸部的種類包括 fpn、secfpn 等。
- [norm_setting]:如無特殊聲明,默認使用 bn (Batch Normalization),其他類型可以有 gn (Group Normalization)、sbn (Synchronized Batch Normalization) 等。
gn-head/gn-neck 表示 GN 僅應用于網絡的頭部或頸部,而 gn-all 表示 GN 用于整個模型,例如主干網絡、頸部和頭部。 - [misc]:模型中各式各樣的設置/插件,例如 strong-aug 意味著在訓練過程中使用更強的數據增廣策略。
- [batch_per_gpu x gpu]:每個 GPU 的樣本數和 GPU 數量,默認使用 4x8。
- {schedule}:訓練方案,選項是 1x、2x、20e 等。
1x 和 2x 分別代表訓練 12 和 24 輪。
20e 在級聯模型中使用,表示訓練 20 輪。
對于 1x/2x,初始學習率在第 8/16 和第 11/22 輪衰減 10 倍;對于 20e,初始學習率在第 16 和第 19 輪衰減 10 倍。 - {dataset}:數據集,例如 nus-3d、kitti-3d、lyft-3d、scannet-3d、sunrgbd-3d 等。
當某一數據集存在多種設定時,我們也標記下所使用的類別數量,例如 kitti-3d-3class 和 kitti-3d-car 分別意味著在 KITTI 的所有三類上和單獨車這一類上進行訓練。
棄用的 train_cfg/test_cfg
遵循 MMDetection 的做法,我們在配置文件中棄用 train_cfg 和 test_cfg,請在模型配置中指定它們。
原始的配置結構如下:
遷移后的配置結構如下:
# 推薦的形式 model = dict(type=...,...train_cfg=dict(...),test_cfg=dict(...), )VoteNet 配置文件示例
model = dict(type='VoteNet', # 檢測器的類型,更多細節請參考 mmdet3d.models.detectorsbackbone=dict(type='PointNet2SASSG', # 主干網絡的類型,更多細節請參考 mmdet3d.models.backbonesin_channels=4, # 點云輸入通道數num_points=(2048, 1024, 512, 256), # 每個 SA 模塊采樣的中心點的數量radius=(0.2, 0.4, 0.8, 1.2), # 每個 SA 層的半徑num_samples=(64, 32, 16, 16), # 每個 SA 層聚集的點的數量sa_channels=((64, 64, 128), (128, 128, 256), (128, 128, 256),(128, 128, 256)), # SA 模塊中每個多層感知器的輸出通道數fp_channels=((256, 256), (256, 256)), # FP 模塊中每個多層感知器的輸出通道數norm_cfg=dict(type='BN2d'), # 歸一化層的配置sa_cfg=dict( # 點集抽象 (SA) 模塊的配置type='PointSAModule', # SA 模塊的類型pool_mod='max', # SA 模塊的池化方法 (最大池化或平均池化)use_xyz=True, # 在特征聚合中是否使用 xyz 坐標normalize_xyz=True)), # 在特征聚合中是否使用標準化的 xyz 坐標bbox_head=dict(type='VoteHead', # 檢測框頭的類型,更多細節請參考 mmdet3d.models.dense_headsnum_classes=18, # 分類的類別數量bbox_coder=dict(type='PartialBinBasedBBoxCoder', # 框編碼層的類型,更多細節請參考 mmdet3d.core.bbox.codersnum_sizes=18, # 尺寸聚類的數量num_dir_bins=1, # 編碼方向角的間隔數with_rot=False, # 框是否帶有旋轉角度mean_sizes=[[0.76966727, 0.8116021, 0.92573744],[1.876858, 1.8425595, 1.1931566],[0.61328, 0.6148609, 0.7182701],[1.3955007, 1.5121545, 0.83443564],[0.97949594, 1.0675149, 0.6329687],[0.531663, 0.5955577, 1.7500148],[0.9624706, 0.72462326, 1.1481868],[0.83221924, 1.0490936, 1.6875663],[0.21132214, 0.4206159, 0.5372846],[1.4440073, 1.8970833, 0.26985747],[1.0294262, 1.4040797, 0.87554324],[1.3766412, 0.65521795, 1.6813129],[0.6650819, 0.71111923, 1.298853],[0.41999173, 0.37906948, 1.7513971],[0.59359556, 0.5912492, 0.73919016],[0.50867593, 0.50656086, 0.30136237],[1.1511526, 1.0546296, 0.49706793],[0.47535285, 0.49249494, 0.5802117]]), # 每一類的平均尺寸,其順序與類名順序相同vote_moudule_cfg=dict( # 投票 (vote) 模塊的配置,更多細節請參考 mmdet3d.models.model_utilsin_channels=256, # 投票模塊的輸入通道數vote_per_seed=1, # 對于每個種子點生成的投票數gt_per_seed=3, # 每個種子點的真實標簽個數conv_channels=(256, 256), # 卷積通道數conv_cfg=dict(type='Conv1d'), # 卷積配置norm_cfg=dict(type='BN1d'), # 歸一化層配置norm_feats=True, # 是否標準化特征vote_loss=dict( # 投票分支的損失函數配置type='ChamferDistance', # 投票分支的損失函數類型mode='l1', # 投票分支的損失函數模式reduction='none', # 設置對損失函數輸出的聚合方法loss_dst_weight=10.0)), # 投票分支的目標損失權重vote_aggregation_cfg=dict( # 投票聚合分支的配置type='PointSAModule', # 投票聚合模塊的類型num_point=256, # 投票聚合分支中 SA 模塊的點的數量radius=0.3, # 投票聚合分支中 SA 模塊的半徑num_sample=16, # 投票聚合分支中 SA 模塊的采樣點的數量mlp_channels=[256, 128, 128, 128], # 投票聚合分支中 SA 模塊的多層感知器的通道數use_xyz=True, # 是否使用 xyz 坐標normalize_xyz=True), # 是否使用標準化后的 xyz 坐標feat_channels=(128, 128), # 特征卷積的通道數conv_cfg=dict(type='Conv1d'), # 卷積的配置norm_cfg=dict(type='BN1d'), # 歸一化層的配置objectness_loss=dict( # 物體性 (objectness) 損失函數的配置type='CrossEntropyLoss', # 損失函數類型class_weight=[0.2, 0.8], # 損失函數對每一類的權重reduction='sum', # 設置損失函數輸出的聚合方法loss_weight=5.0), # 損失函數權重center_loss=dict( # 中心 (center) 損失函數的配置type='ChamferDistance', # 損失函數類型mode='l2', # 損失函數模式reduction='sum', # 設置損失函數輸出的聚合方法loss_src_weight=10.0, # 源損失權重loss_dst_weight=10.0), # 目標損失權重dir_class_loss=dict( # 方向分類損失函數的配置type='CrossEntropyLoss', # 損失函數類型reduction='sum', # 設置損失函數輸出的聚合方法loss_weight=1.0), # 損失函數權重dir_res_loss=dict( # 方向殘差 (residual) 損失函數的配置type='SmoothL1Loss', # 損失函數類型reduction='sum', # 設置損失函數輸出的聚合方法loss_weight=10.0), # 損失函數權重size_class_loss=dict( # 尺寸分類損失函數的配置type='CrossEntropyLoss', # 損失函數類型reduction='sum', # 設置損失函數輸出的聚合方法loss_weight=1.0), # 損失函數權重size_res_loss=dict( # 尺寸殘差損失函數的配置type='SmoothL1Loss', # 損失函數類型reduction='sum', # 設置損失函數輸出的聚合方法loss_weight=3.3333333333333335), # 損失函數權重semantic_loss=dict( # 語義損失函數的配置type='CrossEntropyLoss', # 損失函數類型reduction='sum', # 設置損失函數輸出的聚合方法loss_weight=1.0)), # 損失函數權重train_cfg = dict( # VoteNet 訓練的超參數配置pos_distance_thr=0.3, # 距離 >= 0.3 閾值的樣本將被視為正樣本neg_distance_thr=0.6, # 距離 < 0.6 閾值的樣本將被視為負樣本sample_mod='vote'), # 采樣方法的模式test_cfg = dict( # VoteNet 測試的超參數配置sample_mod='seed', # 采樣方法的模式nms_thr=0.25, # NMS 中使用的閾值score_thr=0.8, # 剔除框的閾值per_class_proposal=False)) # 是否使用逐類提議框 (proposal) dataset_type = 'ScanNetDataset' # 數據集類型 data_root = './data/scannet/' # 數據路徑 class_names = ('cabinet', 'bed', 'chair', 'sofa', 'table', 'door', 'window','bookshelf', 'picture', 'counter', 'desk', 'curtain','refrigerator', 'showercurtrain', 'toilet', 'sink', 'bathtub','garbagebin') # 類的名稱 train_pipeline = [ # 訓練流水線,更多細節請參考 mmdet3d.datasets.pipelinesdict(type='LoadPointsFromFile', # 第一個流程,用于讀取點,更多細節請參考 mmdet3d.datasets.pipelines.indoor_loadingshift_height=True, # 是否使用變換高度load_dim=6, # 讀取的點的維度use_dim=[0, 1, 2]), # 使用所讀取點的哪些維度dict(type='LoadAnnotations3D', # 第二個流程,用于讀取標注,更多細節請參考 mmdet3d.datasets.pipelines.indoor_loadingwith_bbox_3d=True, # 是否讀取 3D 框with_label_3d=True, # 是否讀取 3D 框對應的類別標簽with_mask_3d=True, # 是否讀取 3D 實例分割掩碼with_seg_3d=True), # 是否讀取 3D 語義分割掩碼dict(type='PointSegClassMapping', # 選取有效的類別,更多細節請參考 mmdet3d.datasets.pipelines.point_seg_class_mappingvalid_cat_ids=(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 24, 28, 33, 34,36, 39), # 所有有效類別的編號max_cat_id=40), # 輸入語義分割掩碼中可能存在的最大類別編號dict(type='PointSample', # 室內點采樣,更多細節請參考 mmdet3d.datasets.pipelines.indoor_samplenum_points=40000), # 采樣的點的數量dict(type='IndoorFlipData', # 數據增廣流程,隨機翻轉點和 3D 框flip_ratio_yz=0.5, # 沿著 yz 平面被翻轉的概率flip_ratio_xz=0.5), # 沿著 xz 平面被翻轉的概率dict(type='IndoorGlobalRotScale', # 數據增廣流程,旋轉并放縮點和 3D 框,更多細節請參考 mmdet3d.datasets.pipelines.indoor_augmentshift_height=True, # 讀取的點是否有高度這一屬性rot_range=[-0.027777777777777776, 0.027777777777777776], # 旋轉角范圍scale_range=None), # 縮放尺寸范圍dict(type='DefaultFormatBundle3D', # 默認格式打包以收集讀取的所有數據,更多細節請參考 mmdet3d.datasets.pipelines.formatingclass_names=('cabinet', 'bed', 'chair', 'sofa', 'table', 'door','window', 'bookshelf', 'picture', 'counter', 'desk','curtain', 'refrigerator', 'showercurtrain', 'toilet','sink', 'bathtub', 'garbagebin')),dict(type='Collect3D', # 最后一個流程,決定哪些鍵值對應的數據會被輸入給檢測器,更多細節請參考 mmdet3d.datasets.pipelines.formatingkeys=['points', 'gt_bboxes_3d', 'gt_labels_3d', 'pts_semantic_mask','pts_instance_mask']) ] test_pipeline = [ # 測試流水線,更多細節請參考 mmdet3d.datasets.pipelinesdict(type='LoadPointsFromFile', # 第一個流程,用于讀取點,更多細節請參考 mmdet3d.datasets.pipelines.indoor_loadingshift_height=True, # 是否使用變換高度load_dim=6, # 讀取的點的維度use_dim=[0, 1, 2]), # 使用所讀取點的哪些維度dict(type='PointSample', # 室內點采樣,更多細節請參考 mmdet3d.datasets.pipelines.indoor_samplenum_points=40000), # 采樣的點的數量dict(type='DefaultFormatBundle3D', # 默認格式打包以收集讀取的所有數據,更多細節請參考 mmdet3d.datasets.pipelines.formatingclass_names=('cabinet', 'bed', 'chair', 'sofa', 'table', 'door','window', 'bookshelf', 'picture', 'counter', 'desk','curtain', 'refrigerator', 'showercurtrain', 'toilet','sink', 'bathtub', 'garbagebin')),dict(type='Collect3D', # 最后一個流程,決定哪些鍵值對應的數據會被輸入給檢測器,更多細節請參考 mmdet3d.datasets.pipelines.formatingkeys=['points']) ] eval_pipeline = [ # 模型驗證或可視化所使用的流水線,更多細節請參考 mmdet3d.datasets.pipelinesdict(type='LoadPointsFromFile', # 第一個流程,用于讀取點,更多細節請參考 mmdet3d.datasets.pipelines.indoor_loadingshift_height=True, # 是否使用變換高度load_dim=6, # 讀取的點的維度use_dim=[0, 1, 2]), # 使用所讀取點的哪些維度dict(type='DefaultFormatBundle3D', # 默認格式打包以收集讀取的所有數據,更多細節請參考 mmdet3d.datasets.pipelines.formatingclass_names=('cabinet', 'bed', 'chair', 'sofa', 'table', 'door','window', 'bookshelf', 'picture', 'counter', 'desk','curtain', 'refrigerator', 'showercurtrain', 'toilet','sink', 'bathtub', 'garbagebin')),with_label=False),dict(type='Collect3D', # 最后一個流程,決定哪些鍵值對應的數據會被輸入給檢測器,更多細節請參考 mmdet3d.datasets.pipelines.formatingkeys=['points']) ] data = dict(samples_per_gpu=8, # 單張 GPU 上的樣本數workers_per_gpu=4, # 每張 GPU 上用于讀取數據的進程數train=dict( # 訓練數據集配置type='RepeatDataset', # 數據集嵌套,更多細節請參考 https://github.com/open-mmlab/mmdetection/blob/master/mmdet/datasets/dataset_wrappers.pytimes=5, # 重復次數dataset=dict(type='ScanNetDataset', # 數據集類型data_root='./data/scannet/', # 數據路徑ann_file='./data/scannet/scannet_infos_train.pkl', # 數據標注文件的路徑pipeline=[ # 流水線,這里傳入的就是上面創建的訓練流水線變量dict(type='LoadPointsFromFile',shift_height=True,load_dim=6,use_dim=[0, 1, 2]),dict(type='LoadAnnotations3D',with_bbox_3d=True,with_label_3d=True,with_mask_3d=True,with_seg_3d=True),dict(type='PointSegClassMapping',valid_cat_ids=(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 24,28, 33, 34, 36, 39),max_cat_id=40),dict(type='PointSample', num_points=40000),dict(type='IndoorFlipData',flip_ratio_yz=0.5,flip_ratio_xz=0.5),dict(type='IndoorGlobalRotScale',shift_height=True,rot_range=[-0.027777777777777776, 0.027777777777777776],scale_range=None),dict(type='DefaultFormatBundle3D',class_names=('cabinet', 'bed', 'chair', 'sofa', 'table','door', 'window', 'bookshelf', 'picture','counter', 'desk', 'curtain', 'refrigerator','showercurtrain', 'toilet', 'sink', 'bathtub','garbagebin')),dict(type='Collect3D',keys=['points', 'gt_bboxes_3d', 'gt_labels_3d','pts_semantic_mask', 'pts_instance_mask'])],filter_empty_gt=False, # 是否過濾掉空的標簽框classes=('cabinet', 'bed', 'chair', 'sofa', 'table', 'door','window', 'bookshelf', 'picture', 'counter', 'desk','curtain', 'refrigerator', 'showercurtrain', 'toilet','sink', 'bathtub', 'garbagebin'))), # 類別名稱val=dict( # 驗證數據集配置type='ScanNetDataset', # 數據集類型data_root='./data/scannet/', # 數據路徑ann_file='./data/scannet/scannet_infos_val.pkl', # 數據標注文件的路徑pipeline=[ # 流水線,這里傳入的就是上面創建的測試流水線變量dict(type='LoadPointsFromFile',shift_height=True,load_dim=6,use_dim=[0, 1, 2]),dict(type='PointSample', num_points=40000),dict(type='DefaultFormatBundle3D',class_names=('cabinet', 'bed', 'chair', 'sofa', 'table','door', 'window', 'bookshelf', 'picture','counter', 'desk', 'curtain', 'refrigerator','showercurtrain', 'toilet', 'sink', 'bathtub','garbagebin')),dict(type='Collect3D', keys=['points'])],classes=('cabinet', 'bed', 'chair', 'sofa', 'table', 'door', 'window','bookshelf', 'picture', 'counter', 'desk', 'curtain','refrigerator', 'showercurtrain', 'toilet', 'sink', 'bathtub','garbagebin'), # 類別名稱test_mode=True), # 是否開啟測試模式test=dict( # 測試數據集配置type='ScanNetDataset', # 數據集類型data_root='./data/scannet/', # 數據路徑ann_file='./data/scannet/scannet_infos_val.pkl', # 數據標注文件的路徑pipeline=[ # 流水線,這里傳入的就是上面創建的測試流水線變量dict(type='LoadPointsFromFile',shift_height=True,load_dim=6,use_dim=[0, 1, 2]),dict(type='PointSample', num_points=40000),dict(type='DefaultFormatBundle3D',class_names=('cabinet', 'bed', 'chair', 'sofa', 'table','door', 'window', 'bookshelf', 'picture','counter', 'desk', 'curtain', 'refrigerator','showercurtrain', 'toilet', 'sink', 'bathtub','garbagebin')),dict(type='Collect3D', keys=['points'])],classes=('cabinet', 'bed', 'chair', 'sofa', 'table', 'door', 'window','bookshelf', 'picture', 'counter', 'desk', 'curtain','refrigerator', 'showercurtrain', 'toilet', 'sink', 'bathtub','garbagebin'), # 類別名稱test_mode=True)) # 是否開啟測試模式 evaluation = dict(pipeline=[ # 流水線,這里傳入的就是上面創建的驗證流水線變量dict(type='LoadPointsFromFile',coord_type='DEPTH',shift_height=False,load_dim=6,use_dim=[0, 1, 2]),dict(type='DefaultFormatBundle3D',class_names=('cabinet', 'bed', 'chair', 'sofa', 'table', 'door','window', 'bookshelf', 'picture', 'counter', 'desk','curtain', 'refrigerator', 'showercurtrain', 'toilet','sink', 'bathtub', 'garbagebin'),with_label=False),dict(type='Collect3D', keys=['points']) ]) lr = 0.008 # 優化器的學習率 optimizer = dict( # 構建優化器所使用的配置,我們支持所有 PyTorch 中支持的優化器,并且擁有相同的參數名稱type='Adam', # 優化器類型,更多細節請參考 https://github.com/open-mmlab/mmcv/blob/v1.3.7/mmcv/runner/optimizer/default_constructor.py#L12lr=0.008) # 優化器的學習率,用戶可以在 PyTorch 文檔中查看這些參數的詳細使用方法 optimizer_config = dict( # 構建優化器鉤子的配置,更多實現細節可參考 https://github.com/open-mmlab/mmcv/blob/v1.3.7/mmcv/runner/hooks/optimizer.py#L22grad_clip=dict( # 梯度裁剪的配置max_norm=10, # 梯度的最大模長norm_type=2)) # 所使用的 p-范數的類型,可以設置成 'inf' 則指代無窮范數 lr_config = dict( # 學習率策略配置,用于注冊學習率更新的鉤子policy='step', # 學習率調整的策略,支持 CosineAnnealing、Cyclic 等,更多支持的種類請參考 https://github.com/open-mmlab/mmcv/blob/v1.3.7/mmcv/runner/hooks/lr_updater.py#L9warmup=None, # Warmup 策略,同時也支持 `exp` 和 `constant`step=[24, 32]) # 學習率衰減的步數 checkpoint_config = dict( # 設置保存模型權重鉤子的配置,具體實現請參考 https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/checkpoint.pyinterval=1) # 保存模型權重的間隔是 1 輪 log_config = dict( # 用于注冊輸出記錄信息鉤子的配置interval=50, # 輸出記錄信息的間隔hooks=[dict(type='TextLoggerHook'),dict(type='TensorboardLoggerHook')]) # 用于記錄訓練過程的信息記錄機制 runner = dict(type='EpochBasedRunner', max_epochs=36) # 程序運行器,將會運行 `workflow` `max_epochs` 次 dist_params = dict(backend='nccl') # 設置分布式訓練的配置,通訊端口值也可被設置 log_level = 'INFO' # 輸出記錄信息的等級 find_unused_parameters = True # 是否查找模型中未使用的參數 work_dir = None # 當前實驗存儲模型權重和輸出信息的路徑 load_from = None # 從指定路徑讀取一個預訓練的模型權重,這將不會繼續 (resume) 訓練 resume_from = None # 從一個指定路徑讀入模型權重并繼續訓練,這意味著訓練輪數、優化器狀態等都將被讀取 workflow = [('train', 1)] # 要運行的工作流。[('train', 1)] 意味著只有一個名為 'train' 的工作流,它只會被執行一次。這一工作流依據 `max_epochs` 的值將會訓練模型 36 輪。 gpu_ids = range(0, 1) # 所使用的 GPU 編號常問問題 (FAQ)
忽略基礎配置文件里的部分內容
有時,您也許會需要通過設置 _delete_=True 來忽略基礎配置文件里的一些域內容。
請參照 mmcv 來獲得一些簡單的指導。
例如在 MMDetection3D 中,為了改變如下所示 PointPillars FPN 模塊的某些配置:
model = dict(type='MVXFasterRCNN',pts_voxel_layer=dict(...),pts_voxel_encoder=dict(...),pts_middle_encoder=dict(...),pts_backbone=dict(...),pts_neck=dict(type='FPN',norm_cfg=dict(type='naiveSyncBN2d', eps=1e-3, momentum=0.01),act_cfg=dict(type='ReLU'),in_channels=[64, 128, 256],out_channels=256,start_level=0,num_outs=3),pts_bbox_head=dict(...))FPN 和 SECONDFPN 使用不同的關鍵詞來構建。
_base_ = '../_base_/models/hv_pointpillars_fpn_nus.py' model = dict(pts_neck=dict(_delete_=True,type='SECONDFPN',norm_cfg=dict(type='naiveSyncBN2d', eps=1e-3, momentum=0.01),in_channels=[64, 128, 256],upsample_strides=[1, 2, 4],out_channels=[128, 128, 128]),pts_bbox_head=dict(...))_delete_=True 的標識將會使用新的鍵值覆蓋掉 pts_neck 中的所有舊鍵值。
使用配置文件里的中間變量
配置文件里會使用一些中間變量,例如數據集中的 train_pipeline/test_pipeline。
值得注意的是,當修改子配置文件中的中間變量后,用戶還需再次將其傳入相應字段。
例如,我們想在訓練和測試中,對 PointPillars 使用多尺度策略 (multi scale strategy),那么 train_pipeline/test_pipeline 就是我們想要修改的中間變量。
這里,我們首先定義了新的 train_pipeline/test_pipeline,然后將其傳入 data。
總結
以上是生活随笔為你收集整理的【mmdetection3d】——学习配置文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言变量为什么要定义,C语言为什么要规
- 下一篇: c语言float输出分数,c语言同一题目