utils.md 4.84 KB
Newer Older
Kai Chen's avatar
Kai Chen committed
1
2
3
4
5
## Utils

### Config

`Config` class is used for manipulating config and config files. It supports
Kai Chen's avatar
Kai Chen committed
6
loading configs from multiple file formats including **python**, **json** and **yaml**.
Kai Chen's avatar
Kai Chen committed
7
8
9
10
11
12
It provides dict-like apis to get and set values.

Here is an example of the config file `test.py`.

```python
a = 1
13
b = dict(b1=[0, 1, 2], b2=None)
Kai Chen's avatar
Kai Chen committed
14
15
16
17
18
19
20
c = (1, 2)
d = 'string'
```

To load and use configs

```python
21
22
23
24
25
26
27
28
>>> cfg = Config.fromfile('test.py')
>>> print(cfg)
>>> dict(a=1,
...      b=dict(b1=[0, 1, 2], b2=None),
...      c=(1, 2),
...      d='string')
```

29
30
31
32
33
34
35
36
37
38
39
40
For all format configs, some predefined variables are supported. It will convert the variable in `{{ var }}` with its real value.

Currently, it supports four predefined variables:

`{{ fileDirname }}` - the current opened file's dirname, e.g. /home/your-username/your-project/folder

`{{ fileBasename }}` - the current opened file's basename, e.g. file.ext

`{{ fileBasenameNoExtension }}` - the current opened file's basename with no file extension, e.g. file

`{{ fileExtname }}` - the current opened file's extension, e.g. .ext

Kai Chen's avatar
Kai Chen committed
41
These variable names are referred from [VS Code](https://code.visualstudio.com/docs/editor/variables-reference).
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

Here is one examples of config with predefined variables.

`config_a.py`

```python
a = 1
b = './work_dir/{{ fileBasenameNoExtension }}'
c = '{{ fileExtname }}'
```

```python
>>> cfg = Config.fromfile('./config_a.py')
>>> print(cfg)
>>> dict(a=1,
...      b='./work_dir/config_a',
...      c='.py')
```

61
62
63
64
65
66
67
68
69
70
71
For all format configs, inheritance is supported. To reuse fields in other config files,
specify `_base_='./config_a.py'` or a list of configs `_base_=['./config_a.py', './config_b.py']`.
Here are 4 examples of config inheritance.

`config_a.py`

```python
a = 1
b = dict(b1=[0, 1, 2], b2=None)
```

lizz's avatar
lizz committed
72
#### Inherit from base config without overlapped keys
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

`config_b.py`

```python
_base_ = './config_a.py'
c = (1, 2)
d = 'string'
```

```python
>>> cfg = Config.fromfile('./config_b.py')
>>> print(cfg)
>>> dict(a=1,
...      b=dict(b1=[0, 1, 2], b2=None),
...      c=(1, 2),
...      d='string')
```

New fields in `config_b.py` are combined with old fields in `config_a.py`

lizz's avatar
lizz committed
93
#### Inherit from base config with overlapped keys
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

`config_c.py`

```python
_base_ = './config_a.py'
b = dict(b2=1)
c = (1, 2)
```

```python
>>> cfg = Config.fromfile('./config_c.py')
>>> print(cfg)
>>> dict(a=1,
...      b=dict(b1=[0, 1, 2], b2=1),
...      c=(1, 2))
```

`b.b2=None` in `config_a` is replaced with `b.b2=1` in `config_c.py`.

Kai Chen's avatar
Kai Chen committed
113
#### Inherit from base config with ignored fields
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

`config_d.py`

```python
_base_ = './config_a.py'
b = dict(_delete_=True, b2=None, b3=0.1)
c = (1, 2)
```

```python
>>> cfg = Config.fromfile('./config_d.py')
>>> print(cfg)
>>> dict(a=1,
...      b=dict(b2=None, b3=0.1),
...      c=(1, 2))
```

You may also set `_delete_=True` to ignore some fields in base configs. All old keys `b1, b2, b3` in `b` are replaced with new keys `b2, b3`.

Kai Chen's avatar
Kai Chen committed
133
#### Inherit from multiple base configs (the base configs should not contain the same keys)
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

`config_e.py`

```python
c = (1, 2)
d = 'string'
```

`config_f.py`

```python
_base_ = ['./config_a.py', './config_e.py']
```

```python
>>> cfg = Config.fromfile('./config_f.py')
>>> print(cfg)
>>> dict(a=1,
...      b=dict(b1=[0, 1, 2], b2=None),
...      c=(1, 2),
...      d='string')
Kai Chen's avatar
Kai Chen committed
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
```

### ProgressBar

If you want to apply a method to a list of items and track the progress, `track_progress`
is a good choice. It will display a progress bar to tell the progress and ETA.

```python
import mmcv

def func(item):
    # do something
    pass

tasks = [item_1, item_2, ..., item_n]

mmcv.track_progress(func, tasks)
```

The output is like the following.
![progress](_static/progress.gif)

There is another method `track_parallel_progress`, which wraps multiprocessing and
progress visualization.

```python
mmcv.track_parallel_progress(func, tasks, 8)  # 8 workers
```

![progress](_static/parallel_progress.gif)

ZwwWayne's avatar
ZwwWayne committed
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
If you want to iterate or enumerate a list of items and track the progress, `track_iter_progress`
is a good choice. It will display a progress bar to tell the progress and ETA.

```python
import mmcv

tasks = [item_1, item_2, ..., item_n]

for task in mmcv.track_iter_progress(tasks):
    # do something like print
    print(task)

for i, task in enumerate(mmcv.track_iter_progress(tasks)):
    # do something like print
    print(i)
    print(task)
```

Kai Chen's avatar
Kai Chen committed
204
205
### Timer

lizz's avatar
lizz committed
206
It is convenient to compute the runtime of a code block with `Timer`.
Kai Chen's avatar
Kai Chen committed
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

```python
import time

with mmcv.Timer():
    # simulate some code block
    time.sleep(1)
```

or try with `since_start()` and `since_last_check()`. This former can
return the runtime since the timer starts and the latter will return the time
since the last time checked.

```python
timer = mmcv.Timer()
# code block 1 here
print(timer.since_start())
# code block 2 here
print(timer.since_last_check())
print(timer.since_start())
```