Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
MMCV
Commits
fdeee889
"vscode:/vscode.git/clone" did not exist on "849957bc76c315e18e9872a189dd9905b866769a"
Commit
fdeee889
authored
May 25, 2025
by
limm
Browse files
release v1.6.1 of mmcv
parent
df465820
Changes
663
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
719 additions
and
202 deletions
+719
-202
docs/zh_cn/index.rst
docs/zh_cn/index.rst
+0
-0
docs/zh_cn/make.bat
docs/zh_cn/make.bat
+0
-0
docs/zh_cn/mmcv-logo.png
docs/zh_cn/mmcv-logo.png
+0
-0
docs/zh_cn/understand_mmcv/cnn.md
docs/zh_cn/understand_mmcv/cnn.md
+570
-0
docs/zh_cn/understand_mmcv/config.md
docs/zh_cn/understand_mmcv/config.md
+3
-0
docs/zh_cn/understand_mmcv/data_process.md
docs/zh_cn/understand_mmcv/data_process.md
+5
-5
docs/zh_cn/understand_mmcv/io.md
docs/zh_cn/understand_mmcv/io.md
+1
-0
docs/zh_cn/understand_mmcv/ops.md
docs/zh_cn/understand_mmcv/ops.md
+60
-0
docs/zh_cn/understand_mmcv/registry.md
docs/zh_cn/understand_mmcv/registry.md
+37
-10
docs/zh_cn/understand_mmcv/runner.md
docs/zh_cn/understand_mmcv/runner.md
+9
-5
docs/zh_cn/understand_mmcv/utils.md
docs/zh_cn/understand_mmcv/utils.md
+2
-3
docs/zh_cn/understand_mmcv/visualization.md
docs/zh_cn/understand_mmcv/visualization.md
+0
-0
docs_zh_CN/community/pr.md
docs_zh_CN/community/pr.md
+0
-90
docs_zh_CN/faq.md
docs_zh_CN/faq.md
+0
-37
docs_zh_CN/understand_mmcv/ops.md
docs_zh_CN/understand_mmcv/ops.md
+0
-36
examples/train.py
examples/train.py
+1
-1
mmcv/__init__.py
mmcv/__init__.py
+1
-0
mmcv/arraymisc/quantization.py
mmcv/arraymisc/quantization.py
+16
-6
mmcv/cnn/alexnet.py
mmcv/cnn/alexnet.py
+6
-4
mmcv/cnn/bricks/activation.py
mmcv/cnn/bricks/activation.py
+8
-5
No files found.
docs
_
zh_
CN
/index.rst
→
docs
/
zh_
cn
/index.rst
View file @
fdeee889
File moved
docs
_
zh_
CN
/make.bat
→
docs
/
zh_
cn
/make.bat
View file @
fdeee889
File moved
docs
_
zh_
CN
/mmcv-logo.png
→
docs
/
zh_
cn
/mmcv-logo.png
View file @
fdeee889
File moved
docs
_
zh_
CN
/understand_mmcv/cnn.md
→
docs
/
zh_
cn
/understand_mmcv/cnn.md
View file @
fdeee889
...
@@ -259,7 +259,7 @@ conv = ConvModule(
...
@@ -259,7 +259,7 @@ conv = ConvModule(
self
.
cls
=
nn
.
Sequential
(
nn
.
Conv1d
(
3
,
1
,
3
),
nn
.
Linear
(
1
,
2
))
self
.
cls
=
nn
.
Sequential
(
nn
.
Conv1d
(
3
,
1
,
3
),
nn
.
Linear
(
1
,
2
))
# 如果我们想将模型的权重初始化为 1,将偏差初始化为 2
# 如果我们想将模型的权重初始化为 1,将偏差初始化为 2
# 但希望 `
cls
` 中的权重为 3,偏差为 4,则我们可以使用关键字override
# 但希望 `
reg
` 中的权重为 3,偏差为 4,则我们可以使用关键字override
model
=
FooNet
()
model
=
FooNet
()
init_cfg
=
dict
(
type
=
'Constant'
,
layer
=
[
'Conv1d'
,
'Conv2d'
],
val
=
1
,
bias
=
2
,
init_cfg
=
dict
(
type
=
'Constant'
,
layer
=
[
'Conv1d'
,
'Conv2d'
],
val
=
1
,
bias
=
2
,
...
@@ -355,7 +355,7 @@ conv = ConvModule(
...
@@ -355,7 +355,7 @@ conv = ConvModule(
initialize
(
model
,
init_cfg
)
initialize
(
model
,
init_cfg
)
```
```
4.
初始化继承自BaseModule、Sequential、ModuleList的模型
4.
初始化继承自BaseModule、Sequential、ModuleList
、ModuleDict
的模型
`BaseModule`
继承自
`torch.nn.Module`
, 它们之间唯一的不同是
`BaseModule`
实现了
`init_weight`
`BaseModule`
继承自
`torch.nn.Module`
, 它们之间唯一的不同是
`BaseModule`
实现了
`init_weight`
...
@@ -363,9 +363,11 @@ conv = ConvModule(
...
@@ -363,9 +363,11 @@ conv = ConvModule(
`ModuleList`
继承自
`BaseModule`
和
`torch.nn.ModuleList`
`ModuleList`
继承自
`BaseModule`
和
`torch.nn.ModuleList`
`````python
`ModuleDict`
继承自
`BaseModule`
和
`torch.nn.ModuleDict`
```
python
import
torch.nn
as
nn
import
torch.nn
as
nn
from mmcv.runner import BaseModule, Sequential, ModuleList
from
mmcv.runner
import
BaseModule
,
Sequential
,
ModuleList
,
ModuleDict
class
FooConv1d
(
BaseModule
):
class
FooConv1d
(
BaseModule
):
...
@@ -483,7 +485,50 @@ conv = ConvModule(
...
@@ -483,7 +485,50 @@ conv = ConvModule(
# [[2., 2., 2.],
# [[2., 2., 2.],
# [2., 2., 2.],
# [2., 2., 2.],
# [2., 2., 2.]]]], requires_grad=True)
# [2., 2., 2.]]]], requires_grad=True)
`````
# ModuleDict
model1
=
FooConv1d
(
init_cfg1
)
model2
=
FooConv2d
(
init_cfg2
)
modeldict
=
ModuleDict
(
dict
(
model1
=
model1
,
model2
=
model2
))
modeldict
.
init_weights
()
# modeldict['model1'].conv1d.weight
# Parameter containing:
# tensor([[[0., 0., 0., 0.],
# [0., 0., 0., 0.],
# [0., 0., 0., 0.],
# [0., 0., 0., 0.]]], requires_grad=True)
# modeldict['model2'].conv2d.weight
# Parameter containing:
# tensor([[[[2., 2., 2.],
# [2., 2., 2.],
# [2., 2., 2.]],
# ...,
# [[2., 2., 2.],
# [2., 2., 2.],
# [2., 2., 2.]]]], requires_grad=True)
# inner init_cfg has higher priority
model1
=
FooConv1d
(
init_cfg1
)
model2
=
FooConv2d
(
init_cfg2
)
init_cfg
=
dict
(
type
=
'Constant'
,
layer
=
[
'Conv1d'
,
'Conv2d'
],
val
=
4.
,
bias
=
5.
)
modeldict
=
ModuleDict
(
dict
(
model1
=
model1
,
model2
=
model2
),
init_cfg
=
init_cfg
)
modeldict
.
init_weights
()
# modeldict['model1'].conv1d.weight
# Parameter containing:
# tensor([[[0., 0., 0., 0.],
# [0., 0., 0., 0.],
# [0., 0., 0., 0.],
# [0., 0., 0., 0.]]], requires_grad=True)
# modeldict['model2'].conv2d.weight
# Parameter containing:
# tensor([[[[2., 2., 2.],
# [2., 2., 2.],
# [2., 2., 2.]],
# ...,
# [[2., 2., 2.],
# [2., 2., 2.],
# [2., 2., 2.]]]], requires_grad=True)
```
### Model Zoo
### Model Zoo
...
...
docs
_
zh_
CN
/understand_mmcv/config.md
→
docs
/
zh_
cn
/understand_mmcv/config.md
View file @
fdeee889
...
@@ -40,6 +40,7 @@ d = 'string'
...
@@ -40,6 +40,7 @@ d = 'string'
这里是一个带有预定义变量的配置文件的例子。
这里是一个带有预定义变量的配置文件的例子。
`config_a.py`
`config_a.py`
```
python
```
python
a
=
1
a
=
1
b
=
'./work_dir/{{ fileBasenameNoExtension }}'
b
=
'./work_dir/{{ fileBasenameNoExtension }}'
...
@@ -65,6 +66,7 @@ c = '{{ fileExtname }}'
...
@@ -65,6 +66,7 @@ c = '{{ fileExtname }}'
a
=
1
a
=
1
b
=
dict
(
b1
=
[
0
,
1
,
2
],
b2
=
None
)
b
=
dict
(
b1
=
[
0
,
1
,
2
],
b2
=
None
)
```
```
### 不含重复键值对从基类配置文件继承
### 不含重复键值对从基类配置文件继承
`config_b.py`
`config_b.py`
...
@@ -83,6 +85,7 @@ d = 'string'
...
@@ -83,6 +85,7 @@ d = 'string'
...
c
=
(
1
,
2
),
...
c
=
(
1
,
2
),
...
d
=
'string'
)
...
d
=
'string'
)
```
```
在
`config_b.py`
里的新字段与在
`config_a.py`
里的旧字段拼接
在
`config_b.py`
里的新字段与在
`config_a.py`
里的旧字段拼接
### 含重复键值对从基类配置文件继承
### 含重复键值对从基类配置文件继承
...
...
docs
_
zh_
CN
/understand_mmcv/data_process.md
→
docs
/
zh_
cn
/understand_mmcv/data_process.md
View file @
fdeee889
...
@@ -252,9 +252,9 @@ flow = mmcv.flowread('compressed.jpg', quantize=True, concat_axis=1)
...
@@ -252,9 +252,9 @@ flow = mmcv.flowread('compressed.jpg', quantize=True, concat_axis=1)
mmcv
.
flowshow
(
flow
)
mmcv
.
flowshow
(
flow
)
```
```


3
.
流变换
1
.
流变换
```
python
```
python
img1
=
mmcv
.
imread
(
'img1.jpg'
)
img1
=
mmcv
.
imread
(
'img1.jpg'
)
...
@@ -264,12 +264,12 @@ warpped_img2 = mmcv.flow_warp(img1, flow)
...
@@ -264,12 +264,12 @@ warpped_img2 = mmcv.flow_warp(img1, flow)
img1 (左) and img2 (右)
img1 (左) and img2 (右)


光流 (img2 -> img1)
光流 (img2 -> img1)


变换后的图像和真实图像的差异
变换后的图像和真实图像的差异


docs
_
zh_
CN
/understand_mmcv/io.md
→
docs
/
zh_
cn
/understand_mmcv/io.md
View file @
fdeee889
...
@@ -107,6 +107,7 @@ c
...
@@ -107,6 +107,7 @@ c
d
d
e
e
```
```
#### 从硬盘读取
#### 从硬盘读取
使用
`list_from_file`
读取
`a.txt`
使用
`list_from_file`
读取
`a.txt`
...
...
docs/zh_cn/understand_mmcv/ops.md
0 → 100644
View file @
fdeee889
## 算子
MMCV 提供了检测、分割等任务中常用的算子
| Device | CPU | CUDA | MLU | MPS |
| ---------------------------- | --- | ---- | --- | --- |
| ActiveRotatedFilter | √ | √ | | |
| AssignScoreWithK | | √ | | |
| BallQuery | | √ | | |
| BBoxOverlaps | | √ | √ | √ |
| BorderAlign | | √ | | |
| BoxIouRotated | √ | √ | | |
| CARAFE | | √ | | |
| ChamferDistance | | √ | | |
| CrissCrossAttention | | √ | | |
| ContourExpand | √ | | | |
| ConvexIoU | | √ | | |
| CornerPool | | √ | | |
| Correlation | | √ | | |
| Deformable Convolution v1/v2 | √ | √ | | |
| Deformable RoIPool | | √ | | |
| DiffIoURotated | | √ | | |
| DynamicScatter | | √ | | |
| FurthestPointSample | | √ | | |
| FurthestPointSampleWithDist | | √ | | |
| FusedBiasLeakyrelu | | √ | | |
| GatherPoints | | √ | | |
| GroupPoints | | √ | | |
| Iou3d | | √ | | |
| KNN | | √ | | |
| MaskedConv | | √ | | |
| MergeCells | | √ | | |
| MinAreaPolygon | | √ | | |
| ModulatedDeformConv2d | √ | √ | | |
| MultiScaleDeformableAttn | | √ | | |
| NMS | √ | √ | √ | |
| NMSRotated | √ | √ | | |
| PixelGroup | √ | | | |
| PointsInBoxes | √ | √ | | |
| PointsInPolygons | | √ | | |
| PSAMask | √ | √ | √ | |
| RotatedFeatureAlign | √ | √ | | |
| RoIPointPool3d | | √ | | |
| RoIPool | | √ | √ | |
| RoIAlignRotated | √ | √ | √ | |
| RiRoIAlignRotated | | √ | | |
| RoIAlign | √ | √ | √ | |
| RoIAwarePool3d | | √ | | |
| SAConv2d | | √ | | |
| SigmoidFocalLoss | | √ | √ | |
| SoftmaxFocalLoss | | √ | | |
| SoftNMS | | √ | | |
| Sparse Convolution | | √ | | |
| Synchronized BatchNorm | | √ | | |
| ThreeInterpolate | | √ | | |
| ThreeNN | | √ | | |
| TINShift | | √ | √ | |
| UpFirDn2d | | √ | | |
| Voxelization | √ | √ | | |
| PrRoIPool | | √ | | |
docs
_
zh_
CN
/understand_mmcv/registry.md
→
docs
/
zh_
cn
/understand_mmcv/registry.md
View file @
fdeee889
## 注册器
## 注册器
MMCV 使用
[
注册器
](
https://github.com/open-mmlab/mmcv/blob/master/mmcv/utils/registry.py
)
来管理具有相似功能的不同模块, 例如, 检测器中的主干网络、头部、和模型颈部。
MMCV 使用
[
注册器
](
https://github.com/open-mmlab/mmcv/blob/master/mmcv/utils/registry.py
)
来管理具有相似功能的不同模块, 例如, 检测器中的主干网络、头部、和模型颈部。
在 OpenMMLab 家族中的绝大部分开源项目使用注册器去管理数据集和模型的模块,例如
[
MMDetection
](
https://github.com/open-mmlab/mmdetection
)
,
[
MMDetection3D
](
https://github.com/open-mmlab/mmdetection3d
)
,
[
MMClassification
](
https://github.com/open-mmlab/mmclassification
)
,
[
MMEditing
](
https://github.com/open-mmlab/mmediting
)
等。
在 OpenMMLab 家族中的绝大部分开源项目使用注册器去管理数据集和模型的模块,例如
[
MMDetection
](
https://github.com/open-mmlab/mmdetection
)
,
[
MMDetection3D
](
https://github.com/open-mmlab/mmdetection3d
)
,
[
MMClassification
](
https://github.com/open-mmlab/mmclassification
)
,
[
MMEditing
](
https://github.com/open-mmlab/mmediting
)
等。
```
{note}
在 v1.5.1 版本开始支持注册函数的功能。
```
### 什么是注册器
### 什么是注册器
在MMCV中,注册器可以看作类到字符串的映射。
一个注册器中的类通常有相似的接口,但是可以实现不同的算法或支持不同的数据集。
在MMCV中,注册器可以看作类或函数到字符串的映射。
借助注册器,用户可以通过使用相应的字符串查找并实例化该类,并根据他们的需要实例化对应模块。
一个注册器中的类或函数通常有相似的接口,但是可以实现不同的算法或支持不同的数据集。
借助注册器,用户可以通过使用相应的字符串查找类或函数,并根据他们的需要实例化对应模块或调用函数获取结果。
一个典型的案例是,OpenMMLab 中的大部分开源项目的配置系统,这些系统通过配置文件来使用注册器创建钩子、执行器、模型和数据集。
一个典型的案例是,OpenMMLab 中的大部分开源项目的配置系统,这些系统通过配置文件来使用注册器创建钩子、执行器、模型和数据集。
可以在
[
这里
](
https://mmcv.readthedocs.io/en/latest/api.html?highlight=registry#mmcv.utils.Registry
)
找到注册器接口使用文档。
可以在
[
这里
](
https://mmcv.readthedocs.io/en/latest/api.html?highlight=registry#mmcv.utils.Registry
)
找到注册器接口使用文档。
...
@@ -15,7 +21,7 @@ MMCV 使用 [注册器](https://github.com/open-mmlab/mmcv/blob/master/mmcv/util
...
@@ -15,7 +21,7 @@ MMCV 使用 [注册器](https://github.com/open-mmlab/mmcv/blob/master/mmcv/util
2.
创建注册器
2.
创建注册器
3.
使用此注册器来管理模块
3.
使用此注册器来管理模块
`Registry`
(注册器)的参数
`build_func`
(构建函数) 用来自定
以
如何实例化类的实例,默认使用
[
这里
](
https://mmcv.readthedocs.io/en/latest/api.html?highlight=registry#mmcv.utils.build_from_cfg
)
实现的
`build_from_cfg`
。
`Registry`
(注册器)的参数
`build_func`
(构建函数) 用来自定
义
如何实例化类的实例
或如何调用函数获取结果
,默认使用
[
这里
](
https://mmcv.readthedocs.io/en/latest/api.html?highlight=registry#mmcv.utils.build_from_cfg
)
实现的
`build_from_cfg`
。
### 一个简单的例子
### 一个简单的例子
...
@@ -29,9 +35,10 @@ from mmcv.utils import Registry
...
@@ -29,9 +35,10 @@ from mmcv.utils import Registry
CONVERTERS
=
Registry
(
'converter'
)
CONVERTERS
=
Registry
(
'converter'
)
```
```
然后我们在包中可以实现不同的转换器(converter)。例如,在
`converters/converter1.py`
中实现
`Converter1`
。
然后我们在包中可以实现不同的转换器(converter)
,其可以为类或函数
。例如,在
`converters/converter1.py`
中实现
`Converter1`
,在
`converters/converter2.py`
中实现
`converter2`
。
```
python
```
python
# converter1.py
from
.builder
import
CONVERTERS
from
.builder
import
CONVERTERS
# 使用注册器管理模块
# 使用注册器管理模块
...
@@ -41,19 +48,39 @@ class Converter1(object):
...
@@ -41,19 +48,39 @@ class Converter1(object):
self
.
a
=
a
self
.
a
=
a
self
.
b
=
b
self
.
b
=
b
```
```
使用注册器管理模块的关键步骤是,将实现的模块注册到注册表
`CONVERTERS`
中。通过
`@CONVERTERS.register_module()`
装饰所实现的模块,字符串和类之间的映射就可以由
`CONVERTERS`
构建和维护,如下所示:
通过这种方式,就可以通过
`CONVERTERS`
建立字符串与类之间的映射,如下所示:
```
python
# converter2.py
from
.builder
import
CONVERTERS
from
.converter1
import
Converter1
# 使用注册器管理模块
@
CONVERTERS
.
register_module
()
def
converter2
(
a
,
b
)
return
Converter1
(
a
,
b
)
```
使用注册器管理模块的关键步骤是,将实现的模块注册到注册表
`CONVERTERS`
中。通过
`@CONVERTERS.register_module()`
装饰所实现的模块,字符串到类或函数之间的映射就可以由
`CONVERTERS`
构建和维护,如下所示:
通过这种方式,就可以通过
`CONVERTERS`
建立字符串与类或函数之间的映射,如下所示:
```
python
```
python
'Converter1'
->
<
class
'
Converter1
'>
'Converter1'
->
<
class
'
Converter1
'>
'
converter2
' -> <function '
converter2
'>
```
```
{note}
只有模块所在的文件被导入时,注册机制才会被触发,所以您需要在某处导入该文件。更多详情请查看 https://github.com/open-mmlab/mmdetection/issues/5974。
```
```
如果模块被成功注册了,你可以通过配置文件使用这个转换器(converter),如下所示:
如果模块被成功注册了,你可以通过配置文件使用这个转换器(converter),如下所示:
```
python
```
python
converter_cfg
=
dict
(
type
=
'Converter1'
,
a
=
a_value
,
b
=
b_value
)
converter1_cfg
=
dict
(
type
=
'Converter1'
,
a
=
a_value
,
b
=
b_value
)
converter
=
CONVERTERS
.
build
(
converter_cfg
)
converter2_cfg
=
dict
(
type
=
'converter2'
,
a
=
a_value
,
b
=
b_value
)
converter1
=
CONVERTERS
.
build
(
converter1_cfg
)
# returns the calling result
result
=
CONVERTERS
.
build
(
converter2_cfg
)
```
```
### 自定义构建函数
### 自定义构建函数
...
@@ -84,7 +111,7 @@ CONVERTERS = Registry('converter', build_func=build_converter)
...
@@ -84,7 +111,7 @@ CONVERTERS = Registry('converter', build_func=build_converter)
该功能类似于默认的`build_from_cfg`。在大多数情况下,默认就足够了。
该功能类似于默认的`build_from_cfg`。在大多数情况下,默认就足够了。
```
```
`build_model_from_cfg`
也实现了在
`nn.Sequent
a
il`
中构建PyTorch模块,你可以直接使用它们。
`build_model_from_cfg`
也实现了在
`nn.Sequenti
a
l`
中构建PyTorch模块,你可以直接使用它们。
### 注册器层结构
### 注册器层结构
...
...
docs
_
zh_
CN
/understand_mmcv/runner.md
→
docs
/
zh_
cn
/understand_mmcv/runner.md
View file @
fdeee889
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
### EpochBasedRunner
### EpochBasedRunner
顾名思义,
`EpochBasedRunner`
是指以 epoch 为周期的工作流,例如设置 workflow = [('train', 2), ('val', 1)] 表示循环迭代地训练 2 个 epoch,然后验证 1 个 epoch。MMDetection 目标检测框架默认采用的是
`EpochBasedRunner`
。
顾名思义,
`EpochBasedRunner`
是指以 epoch 为周期的工作流,例如设置 workflow =
\
[
('train', 2), ('val', 1)
\
]
表示循环迭代地训练 2 个 epoch,然后验证 1 个 epoch。MMDetection 目标检测框架默认采用的是
`EpochBasedRunner`
。
其抽象逻辑如下所示:
其抽象逻辑如下所示:
...
@@ -25,6 +25,7 @@ while curr_epoch < max_epochs:
...
@@ -25,6 +25,7 @@ while curr_epoch < max_epochs:
for
_
in
range
(
epochs
):
for
_
in
range
(
epochs
):
epoch_runner
(
data_loaders
[
i
],
**
kwargs
)
epoch_runner
(
data_loaders
[
i
],
**
kwargs
)
```
```
目前支持训练和验证两个工作流,以训练函数为例,其抽象逻辑是:
目前支持训练和验证两个工作流,以训练函数为例,其抽象逻辑是:
```
python
```
python
...
@@ -40,7 +41,8 @@ def train(self, data_loader, **kwargs):
...
@@ -40,7 +41,8 @@ def train(self, data_loader, **kwargs):
```
```
### IterBasedRunner
### IterBasedRunner
不同于
`EpochBasedRunner`
,
`IterBasedRunner`
是指以 iter 为周期的工作流,例如设置 workflow = [('train', 2), ('val', 1)] 表示循环迭代的训练 2 个 iter,然后验证 1 个 iter,MMSegmentation 语义分割框架默认采用的是
`EpochBasedRunner`
。
不同于
`EpochBasedRunner`
,
`IterBasedRunner`
是指以 iter 为周期的工作流,例如设置 workflow =
\[
('train', 2), ('val', 1)
\]
表示循环迭代的训练 2 个 iter,然后验证 1 个 iter,MMSegmentation 语义分割框架默认采用的是
`IterBasedRunner`
。
其抽象逻辑如下所示:
其抽象逻辑如下所示:
...
@@ -59,6 +61,7 @@ while curr_iter < max_iters:
...
@@ -59,6 +61,7 @@ while curr_iter < max_iters:
for
_
in
range
(
iters
):
for
_
in
range
(
iters
):
iter_runner
(
iter_loaders
[
i
],
**
kwargs
)
iter_runner
(
iter_loaders
[
i
],
**
kwargs
)
```
```
目前支持训练和验证两个工作流,以验证函数为例,其抽象逻辑是:
目前支持训练和验证两个工作流,以验证函数为例,其抽象逻辑是:
```
python
```
python
...
@@ -75,6 +78,7 @@ def val(self, data_loader, **kwargs):
...
@@ -75,6 +78,7 @@ def val(self, data_loader, **kwargs):
除了上述基础功能外,
`EpochBasedRunner`
和
`IterBasedRunner`
还提供了 resume 、 save_checkpoint 和注册 hook 功能。
除了上述基础功能外,
`EpochBasedRunner`
和
`IterBasedRunner`
还提供了 resume 、 save_checkpoint 和注册 hook 功能。
### 一个简单例子
### 一个简单例子
以最常用的分类任务为例详细说明
`runner`
的使用方法。 开启任何一个训练任务,都需要包括如下步骤:
以最常用的分类任务为例详细说明
`runner`
的使用方法。 开启任何一个训练任务,都需要包括如下步骤:
**(1) dataloader、model 和优化器等类初始化**
**(1) dataloader、model 和优化器等类初始化**
...
@@ -148,8 +152,8 @@ runner.run(data_loaders, cfg.workflow)
...
@@ -148,8 +152,8 @@ runner.run(data_loaders, cfg.workflow)
关于 workflow 设置,以
`EpochBasedRunner`
为例,详情如下:
关于 workflow 设置,以
`EpochBasedRunner`
为例,详情如下:
-
假设只想运行训练工作流,则可以设置 workflow = [('train', 1)],表示只进行迭代训练
-
假设只想运行训练工作流,则可以设置 workflow =
\
[
('train', 1)
\
]
,表示只进行迭代训练
-
假设想运行训练和验证工作流,则可以设置 workflow = [('train', 3), ('val', 1)],表示先训练 3 个 epoch ,然后切换到 val 工作流,运行 1 个 epoch,然后循环,直到训练 epoch 次数达到指定值
-
假设想运行训练和验证工作流,则可以设置 workflow =
\
[
('train', 3), ('val', 1)
\
]
,表示先训练 3 个 epoch ,然后切换到 val 工作流,运行 1 个 epoch,然后循环,直到训练 epoch 次数达到指定值
-
工作流设置还自由定制,例如你可以先验证再训练 workflow = [('val', 1), ('train', 1)]
-
工作流设置还自由定制,例如你可以先验证再训练 workflow =
\
[
('val', 1), ('train', 1)
\
]
上述代码都已经封装到了各个代码库的 train.py 中,用户只需要设置相应的配置即可,上述流程会自动运行。
上述代码都已经封装到了各个代码库的 train.py 中,用户只需要设置相应的配置即可,上述流程会自动运行。
docs
_
zh_
CN
/understand_mmcv/utils.md
→
docs
/
zh_
cn
/understand_mmcv/utils.md
View file @
fdeee889
...
@@ -17,7 +17,7 @@ mmcv.track_progress(func, tasks)
...
@@ -17,7 +17,7 @@ mmcv.track_progress(func, tasks)
```
```
效果如下
效果如下


如果你想可视化多进程任务的进度,你可以使用
`track_parallel_progress`
。
如果你想可视化多进程任务的进度,你可以使用
`track_parallel_progress`
。
...
@@ -25,7 +25,7 @@ mmcv.track_progress(func, tasks)
...
@@ -25,7 +25,7 @@ mmcv.track_progress(func, tasks)
mmcv
.
track_parallel_progress
(
func
,
tasks
,
8
)
# 8 workers
mmcv
.
track_parallel_progress
(
func
,
tasks
,
8
)
# 8 workers
```
```


如果你想要迭代或枚举数据列表并可视化进度,你可以使用
`track_iter_progress`
。
如果你想要迭代或枚举数据列表并可视化进度,你可以使用
`track_iter_progress`
。
...
@@ -58,7 +58,6 @@ with mmcv.Timer():
...
@@ -58,7 +58,6 @@ with mmcv.Timer():
你也可以使用
`since_start()`
和
`since_last_check()`
。前者返回计时器启动后的运行时长,后者返回最近一次查看计时器后的运行时长。
你也可以使用
`since_start()`
和
`since_last_check()`
。前者返回计时器启动后的运行时长,后者返回最近一次查看计时器后的运行时长。
```
python
```
python
timer
=
mmcv
.
Timer
()
timer
=
mmcv
.
Timer
()
# code block 1 here
# code block 1 here
...
...
docs
_
zh_
CN
/understand_mmcv/visualization.md
→
docs
/
zh_
cn
/understand_mmcv/visualization.md
View file @
fdeee889
File moved
docs_zh_CN/community/pr.md
deleted
100644 → 0
View file @
df465820
## 拉取请求
### 什么是拉取请求?
`拉取请求`
(Pull Request),
[
GitHub 官方文档
](
https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests
)
定义如下。
>拉取请求是一种通知机制。你修改了他人的代码,将你的修改通知原来作者,希望他合并你的修改。
### 基本的工作流:
1.
获取最新的代码库
2.
从主分支创建最新的分支进行开发
3.
提交修改
4.
推送你的修改并创建一个
`拉取请求`
5.
讨论、审核代码
6.
将开发分支合并到主分支
### 具体步骤
1.
获取最新的代码库
+
当你第一次提 PR 时
-
复刻 OpenMMLab 原代码库,点击 GitHub 页面右上角的
**Fork**
按钮即可
!
[
avatar
](
../../docs/_static/community/1.png
)
- 克隆复刻的代码库到本地
```bash
git clone git@github.com:XXX/mmcv.git
```
- 添加原代码库为上游代码库
```bash
git remote add upstream git@github.com:open-mmlab/mmcv
```
+ 从第二个 PR 起
- 检出本地代码库的主分支,然后从最新的原代码库的主分支拉取更新
```bash
git checkout master
git pull upstream master
```
2.
从主分支创建一个新的开发分支
```
bash
git checkout
-b
branchname
```
注意:为了保证提交历史清晰可读,我们强烈推荐您先检出主分支 (master),再创建新的分支。
3.
提交你的修改
```
bash
# coding
git add
[
files]
git commit
-m
'messages'
```
4.
推送你的修改到复刻的代码库,并创建一个
`拉取请求`
+
推送当前分支到远端复刻的代码库
```
bash
git push origin branchname
```
+ 创建一个`拉取请求`

+ 修改`拉取请求`信息模板,描述修改原因和修改内容。还可以在 PR 描述中,手动关联到相关的`议题` (issue),(更多细节,请参考[官方文档](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue))。
5.
讨论并评审你的代码
+
创建
`拉取请求`
时,可以关联给相关人员进行评审
!
[
avatar
](
../../docs/_static/community/3.png
)
+ 根据评审人员的意见修改代码,并推送修改
6.
`拉取请求`
合并之后删除该分支
```
bash
git branch
-d
branchname
# delete local branch
git push origin
--delete
branchname
# delete remote branch
```
### PR 规范
1.
使用
[
pre-commit hook
](
https://pre-commit.com
)
,尽量减少代码风格相关问题
2.
一个PR对应一个短期分支
3.
粒度要细,一个PR只做一件事情,避免超大的PR
>- Bad:实现Faster R-CNN
>- Acceptable:给 Faster R-CNN 添加一个 box head
>- Good:给 box head 增加一个参数来支持自定义的 conv 层数
4.
每次 Commit 时需要提供清晰且有意义 commit 信息
5.
提供清晰且有意义的
`拉取请求`
描述
>- 标题写明白任务名称,一般格式:[Prefix] Short description of the pull request (Suffix)
>- prefix: 新增功能 [Feature], 修 bug [Fix], 文档相关 [Docs], 开发中 [WIP] (暂时不会被review)
>- 描述里介绍`拉取请求`的主要修改内容,结果,以及对其他部分的影响, 参考`拉取请求`模板
>- 关联相关的`议题` (issue) 和其他`拉取请求`
docs_zh_CN/faq.md
deleted
100644 → 0
View file @
df465820
## 常见问题
在这里我们列出了用户经常遇到的问题以及对应的解决方法。如果您遇到了其他常见的问题,并且知道可以帮到大家的解决办法,
欢迎随时丰富这个列表。
-
MMCV 和 MMDetection 的兼容性问题;"ConvWS is already registered in conv layer"
请按照上述说明为您的 MMDetection 版本安装正确版本的 MMCV。
-
"No module named 'mmcv.ops'"; "No module named 'mmcv._ext'"
1. 使用 `pip uninstall mmcv` 卸载您环境中的 mmcv
2. 按照上述说明安装 mmcv-full
-
"invalid device function" 或者 "no kernel image is available for execution"
1. 检查 GPU 的 CUDA 计算能力
2. 运行 `python mmdet/utils/collect_env.py` 来检查 PyTorch、torchvision 和 MMCV 是否是针对正确的 GPU 架构构建的
您可能需要去设置 `TORCH_CUDA_ARCH_LIST` 来重新安装 MMCV
兼容性问题的可能会出现在使用旧版的 GPUs,如:colab 上的 Tesla K80 (3.7)
3. 检查运行环境是否和 mmcv/mmdet 编译时的环境相同。例如,您可能使用 CUDA 10.0 编译 mmcv,但在 CUDA 9.0 的环境中运行它
-
"undefined symbol" 或者 "cannot open xxx.so"。
1. 如果符号和 CUDA/C++ 相关(例如:libcudart.so 或者 GLIBCXX),请检查 CUDA/GCC 运行时的版本是否和编译 mmcv 的一致
2. 如果符号和 PyTorch 相关(例如:符号包含 caffe、aten 和 TH),请检查 PyTorch 运行时的版本是否和编译 mmcv 的一致
3. 运行 `python mmdet/utils/collect_env.py` 以检查 PyTorch、torchvision 和 MMCV 构建和运行的环境是否相同
-
"RuntimeError: CUDA error: invalid configuration argument"。
这个错误可能是由于您的 GPU 性能不佳造成的。尝试降低[THREADS_PER_BLOCK](https://github.com/open-mmlab/mmcv/blob/cac22f8cf5a904477e3b5461b1cc36856c2793da/mmcv/ops/csrc/common_cuda_helper.hpp#L10)
的值并重新编译 mmcv。
-
"RuntimeError: nms is not compiled with GPU support"。
这个错误是由于您的 CUDA 环境没有正确安装。
您可以尝试重新安装您的 CUDA 环境,然后删除 mmcv/build 文件夹并重新编译 mmcv。
docs_zh_CN/understand_mmcv/ops.md
deleted
100644 → 0
View file @
df465820
## CUDA 算子
MMCV 提供了检测、分割等任务中常用的 CUDA 算子
-
AssignScoreWithK
-
BallQuery
-
BBoxOverlaps
-
CARAFE
-
CrissCrossAttention
-
ContextBlock
-
CornerPool
-
Deformable Convolution v1/v2
-
Deformable RoIPool
-
DynamicScatter
-
GatherPoints
-
FurthestPointSample
-
FurthestPointSampleWithDist
-
GeneralizedAttention
-
KNN
-
MaskedConv
-
NMS
-
PSAMask
-
RoIPointPool3d
-
RoIPool
-
RoIAlign
-
RoIAwarePool3d
-
SimpleRoIAlign
-
SigmoidFocalLoss
-
SoftmaxFocalLoss
-
SoftNMS
-
Synchronized BatchNorm
-
Voxelization
-
ThreeInterpolate
-
ThreeNN
-
Weight standardization
-
Correlation
examples/train.py
View file @
fdeee889
...
@@ -14,7 +14,7 @@ from mmcv.utils import get_logger
...
@@ -14,7 +14,7 @@ from mmcv.utils import get_logger
class
Model
(
nn
.
Module
):
class
Model
(
nn
.
Module
):
def
__init__
(
self
):
def
__init__
(
self
):
super
(
Model
,
self
).
__init__
()
super
().
__init__
()
self
.
conv1
=
nn
.
Conv2d
(
3
,
6
,
5
)
self
.
conv1
=
nn
.
Conv2d
(
3
,
6
,
5
)
self
.
pool
=
nn
.
MaxPool2d
(
2
,
2
)
self
.
pool
=
nn
.
MaxPool2d
(
2
,
2
)
self
.
conv2
=
nn
.
Conv2d
(
6
,
16
,
5
)
self
.
conv2
=
nn
.
Conv2d
(
6
,
16
,
5
)
...
...
mmcv/__init__.py
View file @
fdeee889
...
@@ -13,3 +13,4 @@ from .visualization import *
...
@@ -13,3 +13,4 @@ from .visualization import *
# - runner
# - runner
# - parallel
# - parallel
# - op
# - op
# - device
mmcv/arraymisc/quantization.py
View file @
fdeee889
# Copyright (c) OpenMMLab. All rights reserved.
# Copyright (c) OpenMMLab. All rights reserved.
from
typing
import
Union
import
numpy
as
np
import
numpy
as
np
def
quantize
(
arr
,
min_val
,
max_val
,
levels
,
dtype
=
np
.
int64
):
def
quantize
(
arr
:
np
.
ndarray
,
min_val
:
Union
[
int
,
float
],
max_val
:
Union
[
int
,
float
],
levels
:
int
,
dtype
=
np
.
int64
)
->
tuple
:
"""Quantize an array of (-inf, inf) to [0, levels-1].
"""Quantize an array of (-inf, inf) to [0, levels-1].
Args:
Args:
arr (ndarray): Input array.
arr (ndarray): Input array.
min_val (
scalar
): Minimum value to be clipped.
min_val (
int or float
): Minimum value to be clipped.
max_val (
scalar
): Maximum value to be clipped.
max_val (
int or float
): Maximum value to be clipped.
levels (int): Quantization levels.
levels (int): Quantization levels.
dtype (np.type): The type of the quantized array.
dtype (np.type): The type of the quantized array.
...
@@ -29,13 +35,17 @@ def quantize(arr, min_val, max_val, levels, dtype=np.int64):
...
@@ -29,13 +35,17 @@ def quantize(arr, min_val, max_val, levels, dtype=np.int64):
return
quantized_arr
return
quantized_arr
def
dequantize
(
arr
,
min_val
,
max_val
,
levels
,
dtype
=
np
.
float64
):
def
dequantize
(
arr
:
np
.
ndarray
,
min_val
:
Union
[
int
,
float
],
max_val
:
Union
[
int
,
float
],
levels
:
int
,
dtype
=
np
.
float64
)
->
tuple
:
"""Dequantize an array.
"""Dequantize an array.
Args:
Args:
arr (ndarray): Input array.
arr (ndarray): Input array.
min_val (
scalar
): Minimum value to be clipped.
min_val (
int or float
): Minimum value to be clipped.
max_val (
scalar
): Maximum value to be clipped.
max_val (
int or float
): Maximum value to be clipped.
levels (int): Quantization levels.
levels (int): Quantization levels.
dtype (np.type): The type of the dequantized array.
dtype (np.type): The type of the dequantized array.
...
...
mmcv/cnn/alexnet.py
View file @
fdeee889
# Copyright (c) OpenMMLab. All rights reserved.
# Copyright (c) OpenMMLab. All rights reserved.
import
logging
import
logging
from
typing
import
Optional
import
torch
import
torch.nn
as
nn
import
torch.nn
as
nn
...
@@ -11,8 +13,8 @@ class AlexNet(nn.Module):
...
@@ -11,8 +13,8 @@ class AlexNet(nn.Module):
num_classes (int): number of classes for classification.
num_classes (int): number of classes for classification.
"""
"""
def
__init__
(
self
,
num_classes
=
-
1
):
def
__init__
(
self
,
num_classes
:
int
=
-
1
):
super
(
AlexNet
,
self
).
__init__
()
super
().
__init__
()
self
.
num_classes
=
num_classes
self
.
num_classes
=
num_classes
self
.
features
=
nn
.
Sequential
(
self
.
features
=
nn
.
Sequential
(
nn
.
Conv2d
(
3
,
64
,
kernel_size
=
11
,
stride
=
4
,
padding
=
2
),
nn
.
Conv2d
(
3
,
64
,
kernel_size
=
11
,
stride
=
4
,
padding
=
2
),
...
@@ -40,7 +42,7 @@ class AlexNet(nn.Module):
...
@@ -40,7 +42,7 @@ class AlexNet(nn.Module):
nn
.
Linear
(
4096
,
num_classes
),
nn
.
Linear
(
4096
,
num_classes
),
)
)
def
init_weights
(
self
,
pretrained
=
None
)
:
def
init_weights
(
self
,
pretrained
:
Optional
[
str
]
=
None
)
->
None
:
if
isinstance
(
pretrained
,
str
):
if
isinstance
(
pretrained
,
str
):
logger
=
logging
.
getLogger
()
logger
=
logging
.
getLogger
()
from
..runner
import
load_checkpoint
from
..runner
import
load_checkpoint
...
@@ -51,7 +53,7 @@ class AlexNet(nn.Module):
...
@@ -51,7 +53,7 @@ class AlexNet(nn.Module):
else
:
else
:
raise
TypeError
(
'pretrained must be a str or None'
)
raise
TypeError
(
'pretrained must be a str or None'
)
def
forward
(
self
,
x
)
:
def
forward
(
self
,
x
:
torch
.
Tensor
)
->
torch
.
Tensor
:
x
=
self
.
features
(
x
)
x
=
self
.
features
(
x
)
if
self
.
num_classes
>
0
:
if
self
.
num_classes
>
0
:
...
...
mmcv/cnn/bricks/activation.py
View file @
fdeee889
# Copyright (c) OpenMMLab. All rights reserved.
# Copyright (c) OpenMMLab. All rights reserved.
from
typing
import
Dict
import
torch
import
torch
import
torch.nn
as
nn
import
torch.nn
as
nn
import
torch.nn.functional
as
F
import
torch.nn.functional
as
F
...
@@ -28,12 +30,12 @@ class Clamp(nn.Module):
...
@@ -28,12 +30,12 @@ class Clamp(nn.Module):
Default to 1.
Default to 1.
"""
"""
def
__init__
(
self
,
min
=-
1.
,
max
=
1.
):
def
__init__
(
self
,
min
:
float
=
-
1.
,
max
:
float
=
1.
):
super
(
Clamp
,
self
).
__init__
()
super
().
__init__
()
self
.
min
=
min
self
.
min
=
min
self
.
max
=
max
self
.
max
=
max
def
forward
(
self
,
x
):
def
forward
(
self
,
x
)
->
torch
.
Tensor
:
"""Forward function.
"""Forward function.
Args:
Args:
...
@@ -67,7 +69,7 @@ class GELU(nn.Module):
...
@@ -67,7 +69,7 @@ class GELU(nn.Module):
>>> output = m(input)
>>> output = m(input)
"""
"""
def
forward
(
self
,
input
)
:
def
forward
(
self
,
input
:
torch
.
Tensor
)
->
torch
.
Tensor
:
return
F
.
gelu
(
input
)
return
F
.
gelu
(
input
)
...
@@ -78,11 +80,12 @@ else:
...
@@ -78,11 +80,12 @@ else:
ACTIVATION_LAYERS
.
register_module
(
module
=
nn
.
GELU
)
ACTIVATION_LAYERS
.
register_module
(
module
=
nn
.
GELU
)
def
build_activation_layer
(
cfg
)
:
def
build_activation_layer
(
cfg
:
Dict
)
->
nn
.
Module
:
"""Build activation layer.
"""Build activation layer.
Args:
Args:
cfg (dict): The activation layer config, which should contain:
cfg (dict): The activation layer config, which should contain:
- type (str): Layer type.
- type (str): Layer type.
- layer args: Args needed to instantiate an activation layer.
- layer args: Args needed to instantiate an activation layer.
...
...
Prev
1
2
3
4
5
6
7
8
9
…
34
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment