Освоить процесс извлечения данных и построения моделей mmdetection3d с нуля.

  • Эта графическая статья начинается с представления файла конфигурации, постепенно строит новый файл конфигурации и последовательно строит связанные модели. Наконец, в ней используется фрагмент данных облака точек для краткого прохождения процесса обработки.
  • По поводу установки mmdetection3d обратитесь к официальной документации по установке — документации MMDetection3D 1.0.0rc4.

1. Прочтите файл конфигурации.

1.1 Состав файла конфигурации mmdetection3d

Официальная документация: Учебное пособие 1. Изучение файлов конфигурации — документация MMDetection3D 1.0.0rc4.

В mmdetection3d основная идея заключается в реализации индивидуальной модели путем наследования конфигурации по умолчанию.Конечно, вы также можете записать всю конфигурацию модели в файл и использовать ее по мере необходимости.

Файл конфигурации хранится в каталоге mmdetection3d/config.Каталог **_base_ — это базовая конфигурация, которая поставляется с mmdetection3d, то есть исходная конфигурация.Судя по составу каталога _base_**, mmdetection3d делит файлы конфигурации на четыре типа, а именно: набор данных (набор данных), модель (модель), стратегия обучения (расписание) и настройки времени выполнения по умолчанию (время выполнения по умолчанию)

Следующее основано на части содержимого файла конфигурации и объясняет, как его читать.

# configs/centerpoint/centerpoint_01voxel_second_secfpn_4x8_cyclic_20e_nus.py
_base_ = [
    '../_base_/datasets/nus-3d.py',
    '../_base_/models/centerpoint_01voxel_second_secfpn_nus.py', # 继承了这个模型的基础文件
    '../_base_/schedules/cyclic_20e.py', '../_base_/default_runtime.py'
]
model = dict(
    pts_voxel_layer=dict(point_cloud_range=point_cloud_range),
    pts_bbox_head=dict(bbox_coder=dict(pc_range=point_cloud_range[:2])),
    # model training and testing settings
    train_cfg=dict(pts=dict(point_cloud_range=point_cloud_range)),
    test_cfg=dict(pts=dict(pc_range=point_cloud_range[:2])))

Видно, что в файле centerpoint_01voxel_ Second_secfpn_4x8_cycl_20e_nus.py часть модели имеет только небольшой раздел содержимого. Это связано с тем, что centerpoint_01voxel_ Second_secfpn_nus.py унаследован, и только некоторые определенные поля изменяются или добавляются на основе унаследованного файла.

Для удобства объяснения приведем упрощенную версию файла конфигурации.

# configs/_base_/models/centerpoint_01voxel_second_secfpn_nus.py
model = dict(
    type='CenterPoint',
    pts_voxel_layer=dict( 
        max_num_points=10, voxel_size=voxel_size, max_voxels=(90000, 120000)),
    pts_voxel_encoder=dict(type='HardSimpleVFE', num_features=5),
    pts_middle_encoder=dict(),
    pts_backbone=dict(),
    pts_neck=dict(),
    pts_bbox_head=dict(),
    # model training and testing settings
    train_cfg=dict(),
    test_cfg=dict())

Чтобы увидеть, как реализована конкретная сеть, мы сначала начинаем с начала модели.Согласно файлу конфигурации, первым полем является тип.В приведенном выше примере используется CenterPoint.Нам нужно добавить его в mmdetection3d/mmdet3d /models/detectors/ __ init__.py / модели/детекторы/centerpoint.py

Вставьте сюда описание изображения

Вставьте сюда описание изображения

Дальше идет фраза:python pts_voxel_layer=dict( max_num_points=10, voxel_size=voxel_size, max_voxels=(90000, 120000)),

Соответствующее поле инициализации pts_voxel_layer в методе __init__ находим в mmdetection3d/mmdet3d/models/detectors/centerpoint.py.

Вставьте сюда описание изображения

Но здесь мы обнаружили, что это поле здесь не используется. Это связано с тем, что класс CenterPoint наследует класс MVXTwoStageDetector . Мы следовали подсказкам и посмотрели на класс MVXTwoStageDetector . Мы обнаружили, что этот класс использует поле pts_voxel_layer и описывает процесс использования. Voxelization(**pts_voxel_layer)Это инкапсулированная функция вокселизации, которая возвращает набор параметров, которые могут представлять вокселы. Здесь нас не волнует конкретная реализация. Кроме того, как видно из рисунка выше, все поля метода init соответствуют полям в файле конфигурации.Другими словами, мы можем следовать подсказкам класса centerpoint, чтобы найти конкретную реализацию всех конфигураций.

Вставьте сюда описание изображения

На этом анализ первой строки завершен, а затем идет предложение.Метод pts_voxel_encoder=dict(type='HardSimpleVFE', num_features=5)анализа тот же, что и выше.

1.2. Используйте базовый файл конфигурации для создания собственного файла конфигурации.

В этой части мы наследуем базовый файл конфигурации и создаем простой файл конфигурации для последующего использования.

  1. Сначала мы создаем папку в каталоге configs для сохранения наших собственных файлов конфигурации и создаем новый файл my_config.py.

  2. Во вновь созданном файле конфигурации напишите следующее содержимое

    _base_ = [
        '../_base_/datasets/nus-3d-mini.py', # 这里我继承了基础文件中的nus-3d.py构建了一个mini版本,主要就是修改了一下数据集路径
        '../_base_/schedules/schedule_2x.py',
        '../_base_/default_runtime.py',
    ]
    voxel_size = [0.1, 0.1, 0.1]
    norm_cfg = None
    DOUBLE_FLIP = False
    # 为了简单演示,这里只实现了体素构造层和编码层
    model = dict(
        type="MY_MODEL",
        voxel_layer=dict(
            max_num_points=32,
            point_cloud_range=[0, -39.68, -3, 69.12, 39.68, 1],
            voxel_size=voxel_size,
            max_voxels=(16000, 40000)),
        voxel_encoder=dict(
            type='VoxelFeatureExtractorV3',
            num_input_features=4
        ),
        train_cfg=dict(),
        test_cfg=dict())
    data = dict(
        samples_per_gpu=1,
        workers_per_gpu=4
    )
    

1.3 Построение сети на основе файлов конфигурации

Следующее, что нужно сделать, это начать строить сеть на основе части модели в нашем файле конфигурации.Конкретные шаги заключаются в следующем:

  • Создайте файл py в каталоге mmdet3d/models/detectors с именем my_model.py.

  • Создайте класс.Имя класса должно соответствовать типу в файле конфигурации.Конечно, вы также можете заменить его на import... as... при регистрации :

    from ..builder import DETECTORS # 引入构造器
    
    @DETECTORS.register_module() # 注册,这一句必须要有
    class MY_MODEL():
        def __init__(self):
            pass
    
  • Зарегистрируйтесь в mmdet3d/models/Detectors/_ init _.py :

    Вставьте сюда описание изображения

  • В этом примере для простоты понимания мы не будем наследовать какие-либо файлы, а напишем только метод инициализации.

  • Следующее, что нужно сделать, — это определить соответствующие параметры в методе init и предоставить соответствующую реализацию.

    from mmcv.ops import Voxelization # 引入mmcv中的体素化方法
    from .. import builder	# 引入构造器
    from ..builder import DETECTORS
    
    @DETECTORS.register_module()
    class my_model():
        def __init__(self, voxel_layer, voxel_encoder, train_cfg, test_cfg):
            self.voxel_layer = Voxelization(**voxel_layer) # 这一层是mmcv自带的,在3.4中会再介绍一下
            self.voxel_encoder = builder.build_voxel_encoder(voxel_encoder) # 这里表示这个层是需要我们自己构造的
    
    
  • Следующим шагом будет реализация нашего слоя voxel_encoder. Мы можем создать новый файл в каталоге mmdet3d/models/voxel_encoders или записать его непосредственно в существующий файл. Здесь я написал его под файлом voxel_encoder.py.

    @VOXEL_ENCODERS.register_module() # 注册为体素编码层
    class VoxelFeatureExtractorV3(nn.Module):
        def __init__(
                self, num_input_features=4, norm_cfg=None, name="VoxelFeatureExtractorV3"
        ):
            super(VoxelFeatureExtractorV3, self).__init__()
            self.name = name
            self.num_input_features = num_input_features
    
        def forward(self, features, num_voxels, coors=None):
            """
            	features: 输入的体素
            	num_voxels: 体素数目
            """
            points_mean = features[:, :, : self.num_input_features].sum(
                dim=1, keepdim=False
            ) / num_voxels.type_as(features).view(-1, 1)
    
            return points_mean.contiguous()
    
  • Следующим шагом будет добавление написанного VoxelFeatureExtractorV3 в файл mmdet3d/models/voxel_encoders/__init__.pyvoxel_encoder=dict(type='VoxelFeatureExtractorV3', num_input_features=4) . Таким образом, мы сможем использовать его для вызова нашего модуля кодирования вокселей в файле конфигурации.
    Вставьте сюда описание изображения

  • На этом всё о построении сети на основе модельной части конфигурационного файла, если будет время, добавлю подробнее.

2. Постройте модель

В этой части мы используем блокнот Jupyter для постепенного разложения сбора данных и демонстрации процесса обработки данных в построенной нами сети.

2.1 Чтение файла конфигурации

В реальном процессе обучения все параметры импортируются в соответствии с путем к файлу конфигурации через входящие параметры.Соответствующий код находится в Tools/train.py. Для простоты здесь мы напрямую используем путь для чтения файла конфигурации.

# 读取配置文件
from mmcv import Config

config_file = "/home/wistful/work/mmdetection3d/configs/my_config/my_config.py"
cfg = Config.fromfile(config_file)
print("cfg type:",type(cfg))
print("cfg.model type:",type(cfg.model))
cfg.model  # 打印模型部分

изображение-20230301104254130

Видно, что структура напечатанной модели такая же, как и в нашем файле конфигурации. Среди них здесь не представлены типы данных cfg, cfg.model и т. д.

2.2 Чтение данных

# 取数据
from mmdet3d.datasets import build_dataset

datasets = [build_dataset(cfg.data.train)]

print("datastes type:", type(datasets))
print("datastes[0] type", type(datasets[0]))
print("datastes[0][0] type", type(datasets[0][0]))

datasets[0][0].keys()

Вставьте сюда описание изображения

Здесь я больше не буду объяснять соответствующий контент, вам нужно только понимать, что наборы данных — это список длиной 1, наборы данных[0] — это тип набора данных нусцен, наборы данных[0][i] — это все содержимое нусцен. набор данных, каждый элемент Содержит четыре части: «img_metas», «points», «gt_bboxes_3d», «gt_labels_3d».

Фактически, во время реального процесса обучения или тестирования итератор data_loader также необходим, чтобы облегчить нам чтение данных в нескольких потоках , а также реализовать пакетное и случайное чтение и т. д. mmdet уже помог нам это реализовать. Здесь нам нужно только If для моделирования процесса необходим фрагмент данных, data_loader не будет создан.

2.3 Построение модели

# 构建模型
from mmdet3d.models import build_model
model = build_model(
    cfg.model,
    train_cfg=cfg.get('train_cfg'),
    test_cfg=cfg.get('test_cfg')
)
model

Вставьте сюда описание изображения dsda

3. Запуск процесса

3.1 voxel_layer: облако точек -> воксель

# 示例文件配置中,第一步是voxel_layer层,将点云编码为体素

voxel_layer = model.voxel_layer
# 取点云数据
points = datasets[0][0].get('points').data
# 将点云数据送入 voxel_layer
voxels_out, coors_out, num_points_per_voxel_out = voxel_layer(points)

В приведенном выше коде voxel_layer(points)выполняется self.voxel_layer = Voxelization(**voxel_layer)ввод и вывод вокселизации. Вы можете посмотреть на это поближе.

Давайте voxel_layer.parametersснова воспользуемся параметрами печати и получим следующий результат:

Вставьте сюда описание изображения

Теперь давайте подумаем о нашем настроенном файле конфигурации и снова поместим его сюда:

voxel_size = [0.1, 0.1, 0.1]
model = dict(
    type="MY_MODEL",
    voxel_layer=dict(
        max_num_points=32,
        point_cloud_range=[0, -39.68, -3, 69.12, 39.68, 1],
        voxel_size=voxel_size,
        max_voxels=(16000, 40000)),
    voxel_encoder=dict(
        type='VoxelFeatureExtractorV3',
        num_input_features=4
    ),
    train_cfg=dict(),
    test_cfg=dict())

Видно, что параметры, переданные слоем voxel_layer, являются содержимым нашего файла конфигурации.Согласно входным и выходным данным Voxelization, упомянутым ранее, мы видим, что в прямой части отсутствует только одна входная точка, то есть точка облако. В блоке кода в начале этого раздела voxels_out, coors_out, num_points_per_voxel_out = voxel_layer(points)облако точек преобразуется в воксельную операцию.Давайте посмотрим на форму до и после вывода:

Вставьте сюда описание изображения

То есть для облака точек в пользовательском диапазоне в соответствии с размером пользовательского вокселя [0,1, 0,1, 0,1] каждый воксел может сохранять до 32 точек. Наконец, 32242 точки преобразуются в 6051 воксел. Каждый воксель содержит Немного по-другому, но записано.

3.2 voxel_encoder: кодирование вокселей

Этот слой в основном кодирует выходные данные предыдущего слоя (voxel_layer).Перейдя к 1.3, мы дали соответствующую реализацию.Реализация здесь относительно проста, то есть нахождение средней точки в каждом вокселе. Давайте теперь вспомним функцию пересылки в реализации:def forward(self, features, num_voxels, coors=None)

Давайте сначала распечатаем параметры этого слоя.

Вставьте сюда описание изображения

Обнаружено, что вывода нет. Это потому, что мы не определили соответствующий метод. Мы добавляем метод в класс VoxelFeatureExtractorV3:

    def __repr__(self):
        s = self.__class__.__name__ + '('
        s += 'num_input_features=' + str(self.num_input_features)
        s += ')'
        return s

При повторном выполнении будет выведен вывод, а параметры будут такими же, как в файле конфигурации. Следующий код передает выходные данные предыдущего слоя на этот слой.

import torch

voxel_encoder = model.voxel_encoder
print(voxel_encoder.parameters)
voxel_encoder_inputs = voxels_out  # 将上一层的输出作为输入
num_voxels = torch.tensor(voxels_out.shape[0])  # 这里只用一条数据作为演示,所以要转一下tensor
voxel_encoder_result = voxel_encoder(voxel_encoder_inputs, num_voxels)
print("voxel_encoder output shape:", voxel_encoder_result.shape)

Вставьте сюда описание изображения

Наш файл конфигурации и сеть обеспечивают определение и реализацию только двух основных уровней. Остальные уровни (шея, магистраль...) аналогичны и выполняются по одному и тому же процессу. Полный процесс также будет включать в себя расчет функции потерь. Обратный обновление и т. д. Этот шаг описан в начале модели и не будет подробно описан в этой статье.

Supongo que te gusta

Origin blog.csdn.net/u014295602/article/details/129283630
Recomendado
Clasificación