MMCV核心组件知识整理

MMCV学习——基础篇1(配置&注册机制) MMCV学习  博主最近在学习mmcv这个基础库,所以写一个博客记录一下。一来是作为学习笔记,方便日后查阅,二来是和大家分享交流一下我得学习心得。mmcv是由OpenMMLab开源的一个计算机视觉的基础库,支持了OpenMMLab众多开源的优秀仓库(比如,MMDetection、MMSegmentation、MMSelfSup等等)。合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。mmcv在OpenMMLab构建的整个生态体系之中有着举足轻重的地位,下面就请大家和博主一起揭开学习这个基础库的序 阅读详情

3.1 MMCV整体概述

提供了上层框架需要的 hook 机制以及可以直接使用的 runner

MMCV 提供了非常多的高性能 cuda 算子及其 python 接口

3.2 FileHandler

可参考https://zhuanlan.zhihu.com/p/336097883

fileio中的核心组件,设计文件读写。

mmcv提供了底层逻辑的读写handler,目前支持的有.json/.yaml/.yml/.pickle/.pkl文件

# 具体用法
import mmcv

# load data from a file
data = mmcv.load('test.json')
data = mmcv.load('test.yaml')
data = mmcv.load('test.pkl')

mmcv.dump(data, 'out.pkl')

mmcv支持自定义拓展的文件格式(即需要的文件格式不在上述列表),链接中给了.npy的例子。

3.3 FileClient

其作用是对外提供统一的文件内容获取 API,主要用于训练过程中数据的后端读取,通过用户选择默认或者自定义不同的 FileClient 后端,可以轻松实现文件缓存、文件加速读取等等功能。

https://zhuanlan.zhihu.com/p/339190576

FileClinet用法示例,其实际调用在 mmseg/datasets/pipelines/loading.py/LoadImageFromFile 类中

class LoadImageFromFile(object): # 加载图片到内存中
    """Load an image from file.

    Required keys are "img_prefix" and "img_info" (a dict that must contain the
    key "filename"). Added or updated keys are "filename", "img", "img_shape",
    "ori_shape" (same as `img_shape`), "pad_shape" (same as `img_shape`),
    "scale_factor" (1.0) and "img_norm_cfg" (means=0 and stds=1).

    Args:
        to_float32 (bool): Whether to convert the loaded image to a float32
            numpy array. If set to False, the loaded image is an uint8 array.
            Defaults to False.
        color_type (str): The flag argument for :func:`mmcv.imfrombytes`.
            Defaults to 'color'.
        file_client_args (dict): Arguments to instantiate a FileClient.
            See :class:`mmcv.fileio.FileClient` for details.
            Defaults to ``dict(backend='disk')``.
        imdecode_backend (str): Backend for :func:`mmcv.imdecode`. Default:
            'cv2'
    """

    def __init__(self,
                 to_float32=False,
                 color_type='color',
                 file_client_args=dict(backend='disk'),
                 imdecode_backend='cv2'):
        self.to_float32 = to_float32
        self.color_type = color_type
        # 默认是disk后端
        self.file_client_args = file_client_args.copy()
        self.file_client = None
        self.imdecode_backend = imdecode_backend

    def __call__(self, results):
        """Call functions to load image and get image meta information.

        Args:
            results (dict): Result dict from :obj:`mmseg.CustomDataset`.

        Returns:
            dict: The dict contains loaded image and meta information.
        """

        if self.file_client is None:
            self.file_client = mmcv.FileClient(**self.file_client_args)

        if results.get('img_prefix') is not None:
            filename = osp.join(results['img_prefix'],
                                results['img_info']['filename'])
        else:
            filename = results['img_info']['filename']
        # 读取图片字节内容
        img_bytes = self.file_client.get(filename)
        # 对字节内容进行解码
        img = mmcv.imfrombytes(
            img_bytes, flag=self.color_type, backend=self.imdecode_backend)
        if self.to_float32:
            img = img.astype(np.float32)

        results['filename'] = filename
        results['ori_filename'] = results['img_info']['filename']
        results['img'] = img
        results['img_shape'] = img.shape
        results['ori_shape'] = img.shape
        # Set initial values for default meta_keys
        results['pad_shape'] = img.shape
        results['scale_factor'] = 1.0
        num_channels = 1 if len(img.shape) < 3 else img.shape[2]
        results['img_norm_cfg'] = dict(
            mean=np.zeros(num_channels, dtype=np.float32),
            std=np.ones(num_channels, dtype=np.float32),
            to_rgb=False)
        return results

    def __repr__(self):
        repr_str = self.__class__.__name__
        repr_str += f'(to_float32={self.to_float32},'
        repr_str += f"color_type='{self.color_type}',"
        repr_str += f"imdecode_backend='{self.imdecode_backend}')"
        return repr_str

扩展开发示例提供了img文件和annotations 文件不在同一个地方的例子。

3.4 Config

Config 主要是提供各种格式的配置文件解析功能,包括 py、json、ymal 和 yml,是一个非常基础常用类

https://zhuanlan.zhihu.com/p/346203167

3.4.1 Config用法汇总

3.4.1.1 通过 dict 生成 config

mmseg/configs目录下的很多文件是用这个方法定义的

cfg = Config(dict(a=1, b=dict(b1=[0, 1])))

# 可以通过 .属性方式访问,比较方便
cfg.b.b1 # [0, 1]
3.4.1.2 通过 配置文件 生成 config

该功能最为常用,配置文件可以是 py、yaml、yml 和 json 格式。

cfg = Config.fromfile('tests/data/config/a.py')

cfg.filename
cfg.item4 # 'test'
cfg # 打印 config path,和字典内容...
3.4.1.3 自动替换预定义变量

假设h.py文件里面存储的内容是:

cfg_dict = dict(
        item1='{{fileBasename}}',
        item2='{{fileDirname}}',
        item3='abc_{{fileBasenameNoExtension }}')

则可以通过参数 use_predefined_variables 实现自动替换预定义变量功能

# cfg_file 文件名是 h.py
cfg = Config.fromfile(cfg_file, use_predefined_variables=True)
print(cfg.pretty_text)

# 输出
item1 = 'h.py'
item2 = 'config 文件路径'
item3 = 'abc_h'

该参数主要用途是自动替换 Config 类中已经预定义好的变量模板为真实值,在某些场合有用,目前支持 4 个变量:fileDirname、fileBasename、fileBasenameNoExtension 和 fileExtname,预定义变量参考自 VS Code

如果 use_predefined_variables=False( 默认为 True ),则不会进行任何替换。

3.4.1.4 导入自定义模块

Config.fromfile 函数除了有 filename 和 use_predefined_variables 参数外,还有 import_custom_modules,默认是 True,即当 cfg中存在 custom_imports 键时候会对里面的内容进行自动导入,其输入格式要么是 str 要么是 list[str],表示待导入的模块路径,一个典型用法是:

在mmseg/datasets目录下新建greenscreen.py时,需要在__init__里面加入

from .greenscreen import GreenScreenDataset

但是上述做法在某些场景下会比较麻烦。例如该模块处于非常深的层级,那么就需要逐层修改 __init__.py,有了本参数,便可以采用如下做法:

# .py 文件里面存储如下内容
custom_imports = dict(
    imports=['mmdet.models.backbones.mobilenet'],
    allow_failed_imports=False)

# 自动导入 mmdet.models.backbones.mobilenet
Config.fromfile(cfg_file, import_custom_modules=True)
3.4.1.5 合并多个配置文件

(1) 从 base 文件中合并 Config 支持基于单个 base 配置文件,然后合并其余配置,最终得到一个汇总配置,该功能在各大上层框架中使用非常频繁,可以极大的增加配置复用性。一个典型用法是:

# base.py 内容

item1 = [1, 2]
item2 = {'a': 0}
item3 = True
item4 = 'test'

# d.py 内容
_base_ = './base.py'
item1 = [2, 3]
item2 = {'a': 1}
item3 = False
item4 = 'test_base'

# 用法
cfg = Config.fromfile('d.py')

# 输出
item1 = [2, 3]
item2 = dict(a=1)
item3 = False
item4 = 'test_base'

(2) 从多个 base 文件中合并 Config 同时也支持多个 base 文件合并得到最终配置,用户只需要在非 base 配置文件中将类似 _base_ = './base.py'改成 _base_ = ['./base.py',...] 即可。如配置configs/unet/deeplabv3_unet_s5_d16_256x256_40k_greenscreen.py时

_base_ = [
    '../_base_/models/deeplabv3_unet_s5-d16.py', '../_base_/datasets/greenscreen.py',
    '../_base_/default_runtime.py', '../_base_/schedules/schedule_40k.py'
]
model = dict(test_cfg=dict(crop_size=(256, 256), stride=(170, 170)))
evaluation = dict(metric='mDice')

需要特别强调的是:

  • base 文件的 key 是不允许改的,必须是 _base_ ,否则程序不知道哪个字段才是 base
  • 多个 base 以 list 方式并行构建模式下,不允许多个 base 文件中有相同字段,程序会报 Duplicate Key Error,因为此时不知道以哪个配置为主

(3) 合并字典到配置 通过 cfg.merge_from_dict 函数接口可以实现对字典内容进行合并,典型用法如下:

cfg_file = osp.join(data_path, 'config/a.py')
cfg = Config.fromfile(cfg_file)
input_options = {'item2.a': 1, 'item2.b': 0.1, 'item3': False}
cfg.merge_from_dict(input_options)

# 原始 a.py 内容为:
item1 = [1, 2]
item2 = {'a': 0}
item3 = True
item4 = 'test'

# 进行合并后, cfg 内容
item1 = [1, 2]
item2 = dict(a=1, b=0.1)
item3 = False
item4 = 'test'

(4) allow_list_keys 模式合并 假设某个配置文件中内容为:

item = [dict(a=0), dict(b=0, c=0)]

可以通过如下方式修改 list 内容:

input_options = {'item.0.a': 1, 'item.1.b': 1}
cfg.merge_from_dict(input_options, allow_list_keys=True)

# 输出
item = [dict(a=1), dict(b=1, c=0)]

如果 input_options 内部索引越界或者 allow_list_keys=False (默认是 True),则会报错。

(5) 允许删掉特定内容 该功能也比较常用,思考如下场景:在 RetinaNet 算法中,其采用的 bbox 回归 loss 配置如下:

loss_bbox=dict(type='L1Loss', loss_weight=1.0,其他参数)

上述配置是在 base 文件中,但是在 FASF 算法中采用的是 IOULoss,现在要做的事情是在 FASF 配置中自动覆盖掉 base 配置中的 L1Loss,可以采用如下做法:

loss_bbox=dict(
    _delete_=True,
    type='IoULoss',
    eps=1e-6,
    loss_weight=1.0,
    reduction='none')

如果没有 _delete_=True 参数,则两个配置会自动合并,L1Loss 中的其他参数始终会保留,无法删除,这肯定是不正确的( IoULoss 中不需要 L1Loss 的初始化参数),现在通过引入 _delete_ 保留字则可以实现忽略 base 相关配置,直接采用新配置文件字段功能。

3.4.1.6 pretty_text 和 dump

pretty_text 函数可以将字典内容按照 PEP8 格式打印,输出结构清晰,非常好看,如下所示:

# 直接打印字典内容
print(cfg._cfg_dict)
# 输出
{'item1': [1, 2], 'item2': {'a': 1, 'b': 0.1}, 'item3': False, 'item4': 'test'}

# pretty 打印字典内容
print(cfg.pretty_text)
# 输出
item1 = [1, 2]
item2 = dict(a=1, b=0.1)
item3 = False
item4 = 'test'

上述功能是解决第三方库 yapf 实现。而 dump 功能就是将 cfg 内容保存,当想查看实验配置是否正确、查看实验记录以及复现以前实验结果时候非常有用。

3.4.2 Config源码解析

见 https://zhuanlan.zhihu.com/p/346203167

3.5 Registry

Registry 用于提供全局类注册器功能

3.5.1 Registry 功能和用法

https://zhuanlan.zhihu.com/p/355271993

Registry 类可以提供一种完全相似的对外装饰函数来管理构建不同的组件,例如 backbones、head 和 necks 等等,Registry 类内部其实维护的是一个全局 key-value 对。通过 Registry 类,用户可以通过字符串方式实例化任何想要的模块。

例如在 Faster R-CNN 的 backbone 模块实例化时,可以采用如下配置:

backbone=dict(
    type='ResNet', # 待实例化的类名
    depth=50, # 后面的都是对于的类初始化参数
    num_stages=4,
    out_indices=(0, 1, 2, 3),
    frozen_stages=1,
    norm_cfg=dict(type='BN', requires_grad=True),
    norm_eval=True,
    style='pytorch'),

(1) 最简实现

# 方便起见,此处并未使用类方式构建,而是直接采用全局变量

_module_dict = dict()

# 定义装饰器函数
def register_module(name):
    def _register(cls):
        _module_dict[name] = cls
        return cls

    return _register

# 装饰器用法
@register_module('one_class')
class OneTest(object):
    pass

@register_module('two_class')
class TwoTest(object):
    pass

进行简单测试:

if __name__ == '__main__':
    # 通过注册类名实现自动实例化功能
    one_test = _module_dict['one_class']()
    print(one_test)

# 输出
<__main__.OneTest object at 0x7f1d7c5acee0>

可以发现只要将所定义的简单装饰器函数作用到类名上,然后内部采用 _module_dict 保存信息即可

(2) 实现无需传入参数,自动根据类名初始化类

_module_dict = dict()

def register_module(module_name=None):
    def _register(cls):
        name = module_name
        # 如果 module_name 没有给,则自动获取
        if module_name is None:
            name = cls.__name__
        _module_dict[name] = cls
        return cls

    return _register

@register_module('one_class')
class OneTest(object):
    pass

@register_module()
class TwoTest(object):
    pass

进行简单测试:

if __name__ == '__main__':
    one_test = _module_dict['one_class']
    # 方便起见,此处仅仅打印了类对象,而没有实例化。如果要实例化,只需要 one_test() 即可
    print(one_test)
    two_test = _module_dict['TwoTest']
    print(two_test)

# 输出
<class '__main__.OneTest '>
<class '__main__.TwoTest'>

(3) 实现重名注册强制报错功能

def register_module(module_name=None):
    def _register(cls):
        name = module_name
        if module_name is None:
            name = cls.__name__

        # 如果重名注册,则强制报错
        if name in _module_dict:
            raise KeyError(f'{module_name} is already registered '
                           f'in {name}')
        _module_dict[name] = cls
        return cls

    return _register

新增一个 force 参数即可

def register_module(module_name=None,force=False):
    def _register(cls):
        name = module_name
        if module_name is None:
            name = cls.__name__

        # 如果重名注册,则强制报错
        if not force and name in _module_dict:
            raise KeyError(f'{module_name} is already registered '
                           f'in {name}')
        _module_dict[name] = cls
        return cls

    return _register

测试:

@register_module('one_class')
class OneTest(object):
    pass

@register_module('one_class',True)
class TwoTest(object):
    pass

if __name__ == '__main__':
    one_test = _module_dict['one_class']
    print(one_test)

# 输出
<class '__main__.TwoTest'>

(5) 实现直接注册类功能

实现直接注册类的功能,只需要 _module_dict['name'] = module_class 即可。

3.5.2 Registry 类实现

class Registry:
    def __init__(self, name):
        # 可实现注册类细分功能
        self._name = name 
        # 内部核心内容,维护所有的已经注册好的 class
        self._module_dict = dict()

    def _register_module(self, module_class, module_name=None, force=False):
        if not inspect.isclass(module_class):
            raise TypeError('module must be a class, '
                            f'but got {type(module_class)}')

        if module_name is None:
            module_name = module_class.__name__
        if not force and module_name in self._module_dict:
            raise KeyError(f'{module_name} is already registered '
                           f'in {self.name}')
        # 最核心代码
        self._module_dict[module_name] = module_class

    # 装饰器函数
    def register_module(self, name=None, force=False, module=None):
        if module is not None:
            # 如果已经是 module,那就知道 增加到字典中即可
            self._register_module(
                module_class=module, module_name=name, force=force)
            return module

        # 最标准用法
        # use it as a decorator: @x.register_module()
        def _register(cls):
            self._register_module(
                module_class=cls, module_name=name, force=force)
            return cls
        return _register

在 MMCV 中所有的类实例化都是通过 build_from_cfg 函数实现,做的事情非常简单,就是给定 module_name,然后从 self._module_dict 提取即可。

def build_from_cfg(cfg, registry, default_args=None):
    args = cfg.copy()

    if default_args is not None:
        for name, value in default_args.items():
            args.setdefault(name, value)

    obj_type = args.pop('type') # 注册 str 类名
    if is_str(obj_type):
        # 相当于 self._module_dict[obj_type]
        obj_cls = registry.get(obj_type)
        if obj_cls is None:
            raise KeyError(
                f'{obj_type} is not in the {registry.name} registry')

    # 如果已经实例化了,那就直接返回
    elif inspect.isclass(obj_type):
        obj_cls = obj_type
    else:
        raise TypeError(
            f'type must be a str or valid type, but got {type(obj_type)}')

    # 最终初始化对于类,并且返回,就完成了一个类的实例化过程
    return obj_cls(**args)

一个完整的使用例子如下:

CONVERTERS = Registry('converter')

@CONVERTERS.register_module()
class Converter1(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b

converter_cfg = dict(type='Converter1', a=a_value, b=b_value)
converter = build_from_cfg(converter_cfg,CONVERTERS)

3.6 Hook

处理被拦截的函数调用、事件、消息的代码,被称为钩子(hook)

在我们熟知的 pytorch 中某个 tensor 或者 module 都有 register_hook(hook_fn) 函数,通过注册 hook,可以拦截和修改某些中间变量的值。

3.6.1 Hook如何用

在 python 中要实现 hook 机制,非常简单,传入一个函数即可,如下是一个简单的 hook,该 hook 的功能是打印内部变量

def hook(d):
   print(d)

def add(a,b,c,hook_fn=None)
   sum1=a+b
   if hook_fn is not None:
       hook_fn(sum1)
    return sum1+c

# 调用
add(1,2,3,hook)

在 PyTorch 中提供了非常方便的注册机制,用户可以随意插入任何函数来捕获中间过程,下面是一个简单的示例

import torch
from torch import nn
from mmcv.cnn import constant_init

# hook 函数,其三个参数不能修改(参数名随意),本质上是 PyTorch 内部回调函数

# module 本身对象
# input 该 module forward 前输入
# output 该 module forward 后输出
def forward_hook_fn(module, input, output):
    print('weight', module.weight.data)
    print('bias', module.bias.data)
    print('input', input)
    print('output', output)

class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.fc = nn.Linear(3, 1)
        self.fc.register_forward_hook(forward_hook_fn)
        constant_init(self.fc, 1)

    def forward(self, x):
        o = self.fc(x)
        return o

运行输出:

if __name__ == '__main__':
    model = Model()
    x = torch.Tensor([[0.0, 1.0, 2.0]])
    y = model(x)

# 输出
weight:tensor([[1., 1., 1.]])
bias: tensor([0.])
input: (tensor([[0., 1., 2.]]),)
output:tensor([[3.]], grad_fn=<AddmmBackward>)
【mmcv】——CNN 【mmdetection3d】——卷积神经网络 我们为卷积神经网络提供了一些构建模块,包括层构建、模块组件和权重初始化。 网络层的构建 在运行实验时,我们可能需要尝试同属一种类型但不同配置的层,但又不希望每次都修改代码。于是我们提供一些层构建方法,可以从字典构建层,字典可以在配置文件中配置,也可以通过命令行参数指定。 用法 一个简单的例子: cfg = dict(type='Conv3d') layer = build_conv_layer(cfg, in_channels=3, out_channels= 阅读详情

相关推荐

(linux系统下)MMCV及MMClassification教程及安装问题解决

超详细小白一步一步教你安装mmcv及mmclassification以及出现问题的详细解决方案!

weixin_63701570的博客 3794

【零基础保姆级教程】mmcv安装教程

mmcv这个库比较难安装,但在进行深度学习工作的时候却又很难避开,若是没有安装conda环境和CUDA环境的尤其难安装,若大家有遇到mmcv安装上的问题,可按照本文的步骤一步步安装即可解决。

2401_84870184的博客 2万+

OpenMMLab生态中MMCV与MMDet、MMDet3D、MMSeg版本兼容性全解析

本文深入解析OpenMMLab生态中MMCV、MMDetection、MMDetection3D和MMSegmentation等核心框架的版本兼容性问题。针对开发者常遇到的安装冲突,文章提供了从确定MMCV版本到匹配上层框架的实战指南,并分享了一份经验证的兼容性参考矩阵,帮助用户高效解决环境配置难题。

weixin_29061509的博客 335

【mmcv安装使用】

MMLab是香港中文大学深圳研究院的一个计算机视觉和深度学习研究团队,由教授陈嘉杰(Jiajie Chen)领导。该团队成立于2017年,致力于图像识别、目标检测、语义分割、人脸识别等领域的研究。MMLab开发了许多开源的深度学习工具包和算法,如PyTorch中的Detectron2、mmdetection、mmcv等,这些工具包和算法在学术界和工业界都有广泛的应用。MMLab的研究成果在计算机视觉领域享有很高的声誉,团队成员也经常在国际计算机视觉顶级会议上发表论文和做报告。

天风的人工智能博客 6113

别再乱装了!手把手教你搞定MMCV、MMdetection、MMdetection3d的正确安装顺序(附版本对照表)

本文详细解析了MMCV、MMdetection和MMdetection3d的正确安装顺序及版本匹配问题,帮助开发者避免常见的环境配置错误。通过提供版本对照表和实战安装步骤,确保深度学习环境稳定运行,提升开发效率。

weixin_29081163的博客 257

【OpenMMLab】从零到一:手把手解决mmcv-full、mmdet与MMRotate的版本兼容与部署实战

本文详细解析了OpenMMLab生态中mmcv-full、mmdet与MMRotate的版本兼容性问题,提供了从PyTorch、CUDA版本选择到组件安装的完整部署指南。通过实战案例和疑难解答,帮助开发者规避常见陷阱,实现环境快速配置与多版本管理,特别适合计算机视觉领域的研究与工程应用。

weixin_33727510的博客 450

版本匹配指南:PyTorch版本、CUDA 版本和MMCV版本的对应关系

📚版本匹配不再愁!🔍一文解锁PyTorch、CUDA与MMCV的最佳拍档🎉 🚀深度学习领域,版本匹配是关键!本指南为你揭秘PyTorch、CUDA与MMCV的对应关系,让你轻松选择最佳拍档!🌟 🔍我们深入探讨版本匹配的重要性,并提供版本对应关系表,助你快速定位合适版本。📋 🔧同时,分享如何选择合适的MMCV版本,避免实践中的版本匹配问题。🚀 💡总结与展望,期待与你共同进步,掌握版本匹配的艺术!🤝 #PyTorch版本匹配 #CUDA版本匹配 #MMCV版本选择 #深度学习最佳

创作高质量博文,分享知识,共同进步! 8269

Jetson Orin Nano一站式AI开发环境部署实战:从JetPack到MMCV的完整配置与避坑指南

本文详细介绍了在Jetson Orin Nano上部署一站式AI开发环境的完整流程,包括JetPack、CUDA、cuDNN的配置,Miniforge虚拟环境的搭建,以及PyTorch、MMCV等深度学习框架的编译与优化。通过实战经验和避坑指南,帮助开发者高效完成环境部署,提升AI开发效率。

weixin_42525289的博客 114

mmcv解析-tpcv

这个系列旨在围绕着mmcv,解析封装了pytorch训练的一系列代码,不涉及到具体的算子封装这个层面,算子封装要到关注算法时采取关注。

liguandong 1885

从mmcv到mmengine:手把手教你迁移get_dist_info等分布式函数(附完整代码对比)

本文详细解析了从mmcv到mmengine的分布式函数迁移实战,重点介绍了`get_dist_info`等核心函数的新路径和使用方法。通过完整代码对比和常见问题解决方案,帮助开发者高效应对`ModuleNotFoundError`等迁移挑战,充分利用新版分布式训练的性能优化和扩展性增强。

weixin_30905133的博客 420

MMPose与MMDetection环境搭建全攻略:从安装到避坑指南

本文提供MMPose与MMDetection环境搭建的完整教程,涵盖从基础环境配置到核心组件安装的详细步骤,特别针对常见问题提供实用解决方案。通过硬件要求说明、版本匹配技巧和验证方法,帮助开发者高效完成AI开发环境部署,避免常见安装陷阱。

weixin_29061465的博客 223

PyTorch、CUDA与MMCV版本匹配指南:解决深度学习环境部署难题

在深度学习项目开发与部署中,环境配置是首要且关键的一步,其核心在于确保核心组件间的版本兼容性。CUDA作为NVIDIA GPU的并行计算平台,为上层框架提供硬件加速支持;PyTorch等深度学习框架则通过CUDA Runtime API调用GPU资源。若版本不匹配,将直接导致诸如“CUDA error: no kernel image is available”或“undefined symbol”等运行时错误,严重影响开发效率与项目稳定性。尤其在计算机视觉领域,MMCV等基础库因包含大量高性能CUDA算子

weixin_33857679的博客 466

OpenMMLab实战部署:从环境配置到避坑指南

本文详细介绍了OpenMMLab实战部署的全过程,从环境配置到避坑指南,帮助开发者高效搭建计算机视觉开发环境。涵盖硬件检查、Conda环境配置、PyTorch与CUDA版本选择、核心组件安装及子项目特定要求,特别针对国内网络环境提供了镜像加速技巧,确保顺利完成部署。

weixin_29098391的博客 294

MMDetection实战环境搭建:从零到一解决版本依赖与CUDA适配

本文详细介绍了MMDetection实战环境搭建的关键步骤,重点解决版本依赖与CUDA适配问题。通过硬件摸底、Conda虚拟环境配置、PyTorch版本选择和MMCV安装等环节的实战经验,帮助开发者避免常见陷阱,确保环境稳定运行。特别针对项目复现和疑难杂症提供了实用解决方案,是MMDetection用户必备的环境配置指南。

weixin_30689307的博客 444

AI 代码赋能短视频带货:服装及多赛道批量内容生产全流程实操

本文聚焦 AI 技术在短视频带货领域的落地应用,以服装赛道为核心,延伸至花卉绿植、图书、茶具等热门领域,系统拆解 AI 工具在选品、素材处理、视频制作(含动态效果、场景搭建)、运营优化等环节的实操方法。针对从业者普遍面临的 “内容生产低效”“无专业技术难出优质视频”“流量运营踩坑” 等痛点,提供从基础工具使用到高阶视频制作的全流程技术方案,助力相关从业者借助 AI 实现批量、高效的短视频内容产出。

m0_67958922的博客 3081

vue高德地图POI关键字搜索定位

最近在项目中遇到了关于地图的问题,首先为了满足需求从而使用的是JSAPI为2.0版本的。需求是根据关键字搜索定位到该位置。值得注意的是在使用 AMap.Event.addListener时 Event一定要大写的E,不然页面会报错。在地图上定义一个输入框,根据输入的位置进行提示,然后点击后跳转到对应的位置并打点标记。JSAPI主要使用这两个。

YL 2131

OpenMMLab-AI实战营第二期——4-2.MMDetection代码课

MMDetection 支持了各种不同的检测任务,包括目标检测,实例分割,全景分割,以及半监督目标检测。检测是分割的基础,所以它也包含了很多分割任务,和MMSegmentation的区别是:目前,支持的分割任务为语义分割中支持了实例分割和全景分割。超详细!带你轻松掌握 MMSegmentation 整体构建流程语义分割的应用:①自动驾驶;②遥感图像分析;③医学图像分析。所以可以理解为专门为了这三个垂直方向把语义分割方向的模型单独列出来了这个库主要是面向3D的,感觉重点在点云数据上,

啷个哩个啷 2144

手眼标定(EyeToHand)推导

Base为基坐标系(B),工具末端坐标系(T),标定板为Mark坐标系(M),相机坐标系(C)对于每两个姿态都存在上式,组成一个AX=XB的矩阵方程,X为。此时转换成AX=0的问题,单纯用SVD求奇异解便可得到。相机坐标系到Base基坐标系下的转换关系。已知标定板与机械臂末端的相对位置固定不变,,即。带入(2)式求,至此求解出需要的手眼矩阵。在眼在手外的时候,其实是要求解。

stevenreally6的博客 1142

SegNeXt实战指南(一):环境搭建与首个预测任务

本文详细介绍了SegNeXt环境搭建与首个预测任务的实战指南,包括MMSegmentation开发环境的配置、MMCV全家桶的安装与验证,以及如何运行第一个预测任务。通过具体的代码示例和常见问题解决方案,帮助开发者快速掌握SegNeXt的应用技巧,提升图像分割任务的效率。

weixin_33738578的博客 363

基于Keil软件实现OLED显示(江协科技HAL库)

没有HAL库的OLED驱动文件,可以看过来

2401_82728381的博客 1452

软件设计师---钉子户

软件设计师---钉子户

我从不打没有准备的仗! 2万+

PoseC3D实战:如何用pyskl训练自定义动作识别数据集(附环境配置避坑指南)

本文详细介绍了使用pyskl框架训练自定义动作识别数据集的全流程,重点解析了PoseC3D模型的环境配置、数据准备与模型训练中的常见问题与解决方案。通过实战指南,帮助开发者避开版本依赖、数据格式转换等关键陷阱,高效完成从原始视频到可运行模型的完整链路。

4k5l6j7h8的博客 206

8.5华为OD机试真题 新系统 - IPv4 等长子网划分与自动分配系统 (Java/Py/C/C++/Js/Go)

8.5华为OD机试真题 新系统 - IPv4 等长子网划分与自动分配系统 (Java/Py/C/C++/Js/Go)

算法大师! 524

【3D目标检测】三大框架环境搭建实战指南(OpenPCDet、MMdetection3d、Det3d)

本文详细介绍了3D目标检测三大主流框架OpenPCDet、MMdetection3d和Det3d的环境搭建实战指南,包括虚拟环境配置、核心依赖安装、框架编译技巧及常见问题解决方案。针对不同框架特点提供版本匹配建议,帮助开发者快速搭建稳定的开发环境,提升3D目标检测项目开发效率。

weixin_30275415的博客 403

条件DDPM:Diffusion model的第三个巅峰之作

前言:DDPM从2020年诞生,短短一年的时间,模型上有两个巨大的改进,其中一个就是condition的引入,最近大部分DDPM相关的论文都会讨论这一点,有些文章称之为latent variable。和当年GAN的发展类似,CGAN和DCGAN的出现极大程度上促进了GAN的发扬光大,意义重大。本文基于前面几篇文章继续聊一聊: 从VAE到Diffusion Model_沉迷单车的追风少年-优快云博客 为什么diffusion model扩散模型可以称为score-based models?_沉迷单车的.

沉迷单车的追风少年 1万+

SAP Gateway 中事务码 /IWFND/MAINT_SERVICE 的用法介绍

本文系统梳理了SAP Gateway中/IWFND/MAINT_SERVICE事务码的核心功能与运维实践。作为OData服务管理中樞,它支持服务注册激活、ICF节点配置、系统别名绑定、批量处理等关键操作。文章详解了服务目录、ICF节点、系统别名的配置要点,提供了批量激活、缓存清理、性能监控等实用技巧,并针对常见陷阱(如传输配置、删除残留)给出解决方案。通过制造业批量激活、零售业OAuth集成等案例,展示了事务码在企业级应用中的实际价值,为SAP Gateway运维提供了一套完整的治理清单。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 302
上一篇: MM Segmentation 训练自己的数据集
下一篇: SNPE-Benchmark
Thinkobj
博客等级 码龄8年 10粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值