python-wml 3.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of python-wml might be problematic. Click here for more details.
- python_wml-3.0.0.dist-info/LICENSE +23 -0
- python_wml-3.0.0.dist-info/METADATA +51 -0
- python_wml-3.0.0.dist-info/RECORD +164 -0
- python_wml-3.0.0.dist-info/WHEEL +5 -0
- python_wml-3.0.0.dist-info/top_level.txt +1 -0
- wml/__init__.py +0 -0
- wml/basic_data_def/__init__.py +2 -0
- wml/basic_data_def/detection_data_def.py +279 -0
- wml/basic_data_def/io_data_def.py +2 -0
- wml/basic_img_utils.py +816 -0
- wml/img_patch.py +92 -0
- wml/img_utils.py +571 -0
- wml/iotoolkit/__init__.py +17 -0
- wml/iotoolkit/aic_keypoint.py +115 -0
- wml/iotoolkit/baidu_mask_toolkit.py +244 -0
- wml/iotoolkit/base_dataset.py +210 -0
- wml/iotoolkit/bboxes_statistics.py +515 -0
- wml/iotoolkit/build.py +0 -0
- wml/iotoolkit/cityscapes_toolkit.py +183 -0
- wml/iotoolkit/classification_data_statistics.py +25 -0
- wml/iotoolkit/coco_data_fwd.py +225 -0
- wml/iotoolkit/coco_keypoints.py +118 -0
- wml/iotoolkit/coco_keypoints_fmt2.py +103 -0
- wml/iotoolkit/coco_toolkit.py +397 -0
- wml/iotoolkit/coco_wholebody.py +269 -0
- wml/iotoolkit/common.py +108 -0
- wml/iotoolkit/crowd_pose.py +146 -0
- wml/iotoolkit/fast_labelme.py +110 -0
- wml/iotoolkit/image_folder.py +95 -0
- wml/iotoolkit/imgs_cache.py +58 -0
- wml/iotoolkit/imgs_reader_mt.py +73 -0
- wml/iotoolkit/labelme_base.py +102 -0
- wml/iotoolkit/labelme_json_to_img.py +49 -0
- wml/iotoolkit/labelme_toolkit.py +117 -0
- wml/iotoolkit/labelme_toolkit_fwd.py +733 -0
- wml/iotoolkit/labelmemckeypoints_dataset.py +169 -0
- wml/iotoolkit/lspet.py +48 -0
- wml/iotoolkit/mapillary_vistas_toolkit.py +269 -0
- wml/iotoolkit/mat_data.py +90 -0
- wml/iotoolkit/mckeypoints_statistics.py +28 -0
- wml/iotoolkit/mot_datasets.py +62 -0
- wml/iotoolkit/mpii.py +108 -0
- wml/iotoolkit/npmckeypoints_dataset.py +164 -0
- wml/iotoolkit/o365_to_coco.py +136 -0
- wml/iotoolkit/object365_toolkit.py +156 -0
- wml/iotoolkit/object365v2_toolkit.py +71 -0
- wml/iotoolkit/pascal_voc_data.py +51 -0
- wml/iotoolkit/pascal_voc_toolkit.py +194 -0
- wml/iotoolkit/pascal_voc_toolkit_fwd.py +473 -0
- wml/iotoolkit/penn_action.py +57 -0
- wml/iotoolkit/rawframe_dataset.py +129 -0
- wml/iotoolkit/rewrite_pascal_voc.py +28 -0
- wml/iotoolkit/semantic_data.py +49 -0
- wml/iotoolkit/split_file_by_type.py +29 -0
- wml/iotoolkit/sports_mot_datasets.py +78 -0
- wml/iotoolkit/vis_objectdetection_dataset.py +70 -0
- wml/iotoolkit/vis_torch_data.py +39 -0
- wml/iotoolkit/yolo_toolkit.py +38 -0
- wml/object_detection2/__init__.py +4 -0
- wml/object_detection2/basic_visualization.py +37 -0
- wml/object_detection2/bboxes.py +812 -0
- wml/object_detection2/data_process_toolkit.py +146 -0
- wml/object_detection2/keypoints.py +292 -0
- wml/object_detection2/mask.py +120 -0
- wml/object_detection2/metrics/__init__.py +3 -0
- wml/object_detection2/metrics/build.py +15 -0
- wml/object_detection2/metrics/classifier_toolkit.py +440 -0
- wml/object_detection2/metrics/common.py +71 -0
- wml/object_detection2/metrics/mckps_toolkit.py +338 -0
- wml/object_detection2/metrics/toolkit.py +1953 -0
- wml/object_detection2/npod_toolkit.py +361 -0
- wml/object_detection2/odtools.py +243 -0
- wml/object_detection2/standard_names.py +75 -0
- wml/object_detection2/visualization.py +956 -0
- wml/object_detection2/wmath.py +34 -0
- wml/semantic/__init__.py +0 -0
- wml/semantic/basic_toolkit.py +65 -0
- wml/semantic/mask_utils.py +156 -0
- wml/semantic/semantic_test.py +21 -0
- wml/semantic/structures.py +1 -0
- wml/semantic/toolkit.py +105 -0
- wml/semantic/visualization_utils.py +658 -0
- wml/threadtoolkit.py +50 -0
- wml/walgorithm.py +228 -0
- wml/wcollections.py +212 -0
- wml/wfilesystem.py +487 -0
- wml/wml_utils.py +657 -0
- wml/wstructures/__init__.py +4 -0
- wml/wstructures/common.py +9 -0
- wml/wstructures/keypoints_train_toolkit.py +149 -0
- wml/wstructures/kps_structures.py +579 -0
- wml/wstructures/mask_structures.py +1161 -0
- wml/wtorch/__init__.py +8 -0
- wml/wtorch/bboxes.py +104 -0
- wml/wtorch/classes_suppression.py +24 -0
- wml/wtorch/conv_module.py +181 -0
- wml/wtorch/conv_ws.py +144 -0
- wml/wtorch/data/__init__.py +16 -0
- wml/wtorch/data/_utils/__init__.py +45 -0
- wml/wtorch/data/_utils/collate.py +183 -0
- wml/wtorch/data/_utils/fetch.py +47 -0
- wml/wtorch/data/_utils/pin_memory.py +121 -0
- wml/wtorch/data/_utils/signal_handling.py +72 -0
- wml/wtorch/data/_utils/worker.py +227 -0
- wml/wtorch/data/base_data_loader_iter.py +93 -0
- wml/wtorch/data/dataloader.py +501 -0
- wml/wtorch/data/datapipes/__init__.py +1 -0
- wml/wtorch/data/datapipes/iter/__init__.py +12 -0
- wml/wtorch/data/datapipes/iter/batch.py +126 -0
- wml/wtorch/data/datapipes/iter/callable.py +92 -0
- wml/wtorch/data/datapipes/iter/listdirfiles.py +37 -0
- wml/wtorch/data/datapipes/iter/loadfilesfromdisk.py +30 -0
- wml/wtorch/data/datapipes/iter/readfilesfromtar.py +60 -0
- wml/wtorch/data/datapipes/iter/readfilesfromzip.py +63 -0
- wml/wtorch/data/datapipes/iter/sampler.py +94 -0
- wml/wtorch/data/datapipes/utils/__init__.py +0 -0
- wml/wtorch/data/datapipes/utils/common.py +65 -0
- wml/wtorch/data/dataset.py +354 -0
- wml/wtorch/data/datasets/__init__.py +4 -0
- wml/wtorch/data/datasets/common.py +53 -0
- wml/wtorch/data/datasets/listdirfilesdataset.py +36 -0
- wml/wtorch/data/datasets/loadfilesfromdiskdataset.py +30 -0
- wml/wtorch/data/distributed.py +135 -0
- wml/wtorch/data/multi_processing_data_loader_iter.py +866 -0
- wml/wtorch/data/sampler.py +267 -0
- wml/wtorch/data/single_process_data_loader_iter.py +24 -0
- wml/wtorch/data/test_data_loader.py +26 -0
- wml/wtorch/dataset_toolkit.py +67 -0
- wml/wtorch/depthwise_separable_conv_module.py +98 -0
- wml/wtorch/dist.py +591 -0
- wml/wtorch/dropblock/__init__.py +6 -0
- wml/wtorch/dropblock/dropblock.py +228 -0
- wml/wtorch/dropblock/dropout.py +40 -0
- wml/wtorch/dropblock/scheduler.py +48 -0
- wml/wtorch/ema.py +61 -0
- wml/wtorch/fc_module.py +73 -0
- wml/wtorch/functional.py +34 -0
- wml/wtorch/iter_dataset.py +26 -0
- wml/wtorch/loss.py +69 -0
- wml/wtorch/nets/__init__.py +0 -0
- wml/wtorch/nets/ckpt_toolkit.py +219 -0
- wml/wtorch/nets/fpn.py +276 -0
- wml/wtorch/nets/hrnet/__init__.py +0 -0
- wml/wtorch/nets/hrnet/config.py +2 -0
- wml/wtorch/nets/hrnet/hrnet.py +494 -0
- wml/wtorch/nets/misc.py +249 -0
- wml/wtorch/nets/resnet/__init__.py +0 -0
- wml/wtorch/nets/resnet/layers/__init__.py +17 -0
- wml/wtorch/nets/resnet/layers/aspp.py +144 -0
- wml/wtorch/nets/resnet/layers/batch_norm.py +231 -0
- wml/wtorch/nets/resnet/layers/blocks.py +111 -0
- wml/wtorch/nets/resnet/layers/wrappers.py +110 -0
- wml/wtorch/nets/resnet/r50_config.py +38 -0
- wml/wtorch/nets/resnet/resnet.py +691 -0
- wml/wtorch/nets/shape_spec.py +20 -0
- wml/wtorch/nets/simple_fpn.py +101 -0
- wml/wtorch/nms.py +109 -0
- wml/wtorch/nn.py +896 -0
- wml/wtorch/ocr_block.py +193 -0
- wml/wtorch/summary.py +331 -0
- wml/wtorch/train_toolkit.py +603 -0
- wml/wtorch/transformer_blocks.py +266 -0
- wml/wtorch/utils.py +719 -0
- wml/wtorch/wlr_scheduler.py +100 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import torch.nn.functional as F
|
|
3
|
+
from torch import nn
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DropBlock2D(nn.Module):
|
|
7
|
+
r"""Randomly zeroes 2D spatial blocks of the input tensor.
|
|
8
|
+
|
|
9
|
+
As described in the paper
|
|
10
|
+
`DropBlock: A regularization method for convolutional networks`_ ,
|
|
11
|
+
dropping whole blocks of feature map allows to remove semantic
|
|
12
|
+
information as compared to regular dropout.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
drop_prob (float): probability of an element to be dropped.
|
|
16
|
+
block_size (int): size of the block to drop
|
|
17
|
+
|
|
18
|
+
Shape:
|
|
19
|
+
- Input: `(N, C, H, W)`
|
|
20
|
+
- Output: `(N, C, H, W)`
|
|
21
|
+
|
|
22
|
+
.. _DropBlock: A regularization method for convolutional networks:
|
|
23
|
+
https://arxiv.org/abs/1810.12890
|
|
24
|
+
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, drop_prob, block_size):
|
|
28
|
+
super(DropBlock2D, self).__init__()
|
|
29
|
+
|
|
30
|
+
self.drop_prob = drop_prob
|
|
31
|
+
self.block_size = block_size
|
|
32
|
+
self.cur_drop_prob = 0.0
|
|
33
|
+
|
|
34
|
+
def forward(self, x):
|
|
35
|
+
# shape: (bsize, channels, height, width)
|
|
36
|
+
|
|
37
|
+
assert x.dim() == 4, \
|
|
38
|
+
"Expected input with 4 dimensions (bsize, channels, height, width)"
|
|
39
|
+
|
|
40
|
+
if not self.training or self.drop_prob <= 0.:
|
|
41
|
+
self.cur_drop_prob = 0.0
|
|
42
|
+
return x
|
|
43
|
+
else:
|
|
44
|
+
# get gamma value
|
|
45
|
+
gamma = self._compute_gamma(x)
|
|
46
|
+
|
|
47
|
+
# sample mask
|
|
48
|
+
mask = (torch.rand(x.shape[0], *x.shape[2:]) < gamma).to(x.dtype)
|
|
49
|
+
|
|
50
|
+
# place mask on input device
|
|
51
|
+
mask = mask.to(x.device)
|
|
52
|
+
|
|
53
|
+
# compute block mask
|
|
54
|
+
block_mask = self._compute_block_mask(mask)
|
|
55
|
+
|
|
56
|
+
cur_nr = torch.sum(block_mask,dtype=torch.float32)
|
|
57
|
+
if cur_nr < 1:
|
|
58
|
+
print(f"ERROR: DropBlock drop_prob={self.drop_prob}, gamma={gamma}, cur_nr={cur_nr}")
|
|
59
|
+
return x
|
|
60
|
+
|
|
61
|
+
scale = (block_mask.numel()/cur_nr).to(x.dtype)
|
|
62
|
+
|
|
63
|
+
# apply block mask
|
|
64
|
+
out = x * block_mask[:, None, :, :]
|
|
65
|
+
|
|
66
|
+
# scale output
|
|
67
|
+
out = out * scale
|
|
68
|
+
|
|
69
|
+
self.cur_drop_prob = 1.0-cur_nr/block_mask.numel()
|
|
70
|
+
return out
|
|
71
|
+
|
|
72
|
+
def _compute_block_mask(self, mask):
|
|
73
|
+
block_mask = F.max_pool2d(input=mask[:, None, :, :],
|
|
74
|
+
kernel_size=(self.block_size, self.block_size),
|
|
75
|
+
stride=(1, 1),
|
|
76
|
+
padding=self.block_size // 2)
|
|
77
|
+
|
|
78
|
+
if self.block_size % 2 == 0:
|
|
79
|
+
block_mask = block_mask[:, :, :-1, :-1]
|
|
80
|
+
|
|
81
|
+
block_mask = 1 - block_mask.squeeze(1)
|
|
82
|
+
|
|
83
|
+
return block_mask
|
|
84
|
+
|
|
85
|
+
def _compute_gamma(self, x):
|
|
86
|
+
return self.drop_prob / (self.block_size ** 2)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class WDropBlock2D(nn.Module):
|
|
90
|
+
r"""
|
|
91
|
+
与DropBlock2D不同的在于:DropBlock2d会将一个空间位置整个通道都设置为0,或者都设置为1,
|
|
92
|
+
WDropBlock2D会将channel中的各元素单独drop
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
def __init__(self, drop_prob, block_size):
|
|
96
|
+
super().__init__()
|
|
97
|
+
|
|
98
|
+
self.drop_prob = drop_prob
|
|
99
|
+
self.block_size = block_size
|
|
100
|
+
self.cur_drop_prob = 0.0
|
|
101
|
+
|
|
102
|
+
def forward(self, x):
|
|
103
|
+
# shape: (bsize, channels, height, width)
|
|
104
|
+
|
|
105
|
+
assert x.dim() == 4, \
|
|
106
|
+
"Expected input with 4 dimensions (bsize, channels, height, width)"
|
|
107
|
+
|
|
108
|
+
if not self.training or self.drop_prob <= 0.:
|
|
109
|
+
self.cur_drop_prob = 0.0
|
|
110
|
+
return x
|
|
111
|
+
else:
|
|
112
|
+
# get gamma value
|
|
113
|
+
gamma = self._compute_gamma(x)
|
|
114
|
+
|
|
115
|
+
# sample mask
|
|
116
|
+
mask = (torch.rand(*x.shape) < gamma).to(x.dtype)
|
|
117
|
+
|
|
118
|
+
# place mask on input device
|
|
119
|
+
mask = mask.to(x.device)
|
|
120
|
+
|
|
121
|
+
# compute block mask
|
|
122
|
+
block_mask = self._compute_block_mask(mask)
|
|
123
|
+
|
|
124
|
+
cur_nr = torch.sum(block_mask,dtype=torch.float32)
|
|
125
|
+
if cur_nr < 1:
|
|
126
|
+
print(f"ERROR: DropBlock drop_prob={self.drop_prob}, gamma={gamma}, cur_nr={cur_nr}")
|
|
127
|
+
return x
|
|
128
|
+
|
|
129
|
+
scale = (block_mask.numel()/cur_nr).to(x.dtype)
|
|
130
|
+
|
|
131
|
+
# apply block mask
|
|
132
|
+
out = x * block_mask
|
|
133
|
+
|
|
134
|
+
# scale output
|
|
135
|
+
out = out * scale
|
|
136
|
+
|
|
137
|
+
self.cur_drop_prob = 1.0-cur_nr/block_mask.numel()
|
|
138
|
+
return out
|
|
139
|
+
|
|
140
|
+
def _compute_block_mask(self, mask):
|
|
141
|
+
block_mask = F.max_pool2d(input=mask,
|
|
142
|
+
kernel_size=(self.block_size, self.block_size),
|
|
143
|
+
stride=(1, 1),
|
|
144
|
+
padding=self.block_size // 2)
|
|
145
|
+
|
|
146
|
+
if self.block_size % 2 == 0:
|
|
147
|
+
block_mask = block_mask[:, :, :-1, :-1]
|
|
148
|
+
|
|
149
|
+
block_mask = 1 - block_mask
|
|
150
|
+
|
|
151
|
+
return block_mask
|
|
152
|
+
|
|
153
|
+
def _compute_gamma(self, x):
|
|
154
|
+
return self.drop_prob / (self.block_size ** 2)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class DropBlock3D(DropBlock2D):
|
|
158
|
+
r"""Randomly zeroes 3D spatial blocks of the input tensor.
|
|
159
|
+
|
|
160
|
+
An extension to the concept described in the paper
|
|
161
|
+
`DropBlock: A regularization method for convolutional networks`_ ,
|
|
162
|
+
dropping whole blocks of feature map allows to remove semantic
|
|
163
|
+
information as compared to regular dropout.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
drop_prob (float): probability of an element to be dropped.
|
|
167
|
+
block_size (int): size of the block to drop
|
|
168
|
+
|
|
169
|
+
Shape:
|
|
170
|
+
- Input: `(N, C, D, H, W)`
|
|
171
|
+
- Output: `(N, C, D, H, W)`
|
|
172
|
+
|
|
173
|
+
.. _DropBlock: A regularization method for convolutional networks:
|
|
174
|
+
https://arxiv.org/abs/1810.12890
|
|
175
|
+
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
def __init__(self, drop_prob, block_size):
|
|
179
|
+
super(DropBlock3D, self).__init__(drop_prob, block_size)
|
|
180
|
+
|
|
181
|
+
def forward(self, x):
|
|
182
|
+
# shape: (bsize, channels, depth, height, width)
|
|
183
|
+
|
|
184
|
+
assert x.dim() == 5, \
|
|
185
|
+
"Expected input with 5 dimensions (bsize, channels, depth, height, width)"
|
|
186
|
+
|
|
187
|
+
if not self.training or self.drop_prob == 0.:
|
|
188
|
+
return x
|
|
189
|
+
else:
|
|
190
|
+
# get gamma value
|
|
191
|
+
gamma = self._compute_gamma(x)
|
|
192
|
+
|
|
193
|
+
# sample mask
|
|
194
|
+
mask = (torch.rand(x.shape[0], *x.shape[2:]) < gamma).float()
|
|
195
|
+
|
|
196
|
+
# place mask on input device
|
|
197
|
+
mask = mask.to(x.device)
|
|
198
|
+
|
|
199
|
+
# compute block mask
|
|
200
|
+
block_mask = self._compute_block_mask(mask)
|
|
201
|
+
|
|
202
|
+
# apply block mask
|
|
203
|
+
out = x * block_mask[:, None, :, :, :]
|
|
204
|
+
|
|
205
|
+
cur_nr = block_mask.sum()
|
|
206
|
+
if cur_nr < 1:
|
|
207
|
+
print(f"ERROR: DropBlock drop_prob={self.drop_prob}, gamma={gamma}, cur_nr={cur_nr}")
|
|
208
|
+
return x
|
|
209
|
+
# scale output
|
|
210
|
+
out = out * block_mask.numel() / cur_nr
|
|
211
|
+
|
|
212
|
+
return out
|
|
213
|
+
|
|
214
|
+
def _compute_block_mask(self, mask):
|
|
215
|
+
block_mask = F.max_pool3d(input=mask[:, None, :, :, :],
|
|
216
|
+
kernel_size=(self.block_size, self.block_size, self.block_size),
|
|
217
|
+
stride=(1, 1, 1),
|
|
218
|
+
padding=self.block_size // 2)
|
|
219
|
+
|
|
220
|
+
if self.block_size % 2 == 0:
|
|
221
|
+
block_mask = block_mask[:, :, :-1, :-1, :-1]
|
|
222
|
+
|
|
223
|
+
block_mask = 1 - block_mask.squeeze(1)
|
|
224
|
+
|
|
225
|
+
return block_mask
|
|
226
|
+
|
|
227
|
+
def _compute_gamma(self, x):
|
|
228
|
+
return self.drop_prob / (self.block_size ** 3)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import torch.nn.functional as F
|
|
3
|
+
from torch import nn
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class WDropout(nn.Module):
|
|
7
|
+
r"""Randomly zeroes 2D spatial blocks of the input tensor.
|
|
8
|
+
|
|
9
|
+
As described in the paper
|
|
10
|
+
`DropBlock: A regularization method for convolutional networks`_ ,
|
|
11
|
+
dropping whole blocks of feature map allows to remove semantic
|
|
12
|
+
information as compared to regular dropout.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
drop_prob (float): probability of an element to be dropped.
|
|
16
|
+
block_size (int): size of the block to drop
|
|
17
|
+
|
|
18
|
+
Shape:
|
|
19
|
+
- Input: `(N, C, H, W)`
|
|
20
|
+
- Output: `(N, C, H, W)`
|
|
21
|
+
|
|
22
|
+
.. _DropBlock: A regularization method for convolutional networks:
|
|
23
|
+
https://arxiv.org/abs/1810.12890
|
|
24
|
+
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, drop_prob,inplace=False):
|
|
28
|
+
super().__init__()
|
|
29
|
+
|
|
30
|
+
self.drop_prob = drop_prob
|
|
31
|
+
self.inplace = inplace
|
|
32
|
+
self.cur_drop_prob = 0.0
|
|
33
|
+
|
|
34
|
+
def forward(self, x):
|
|
35
|
+
if not self.training or self.drop_prob <= 0.:
|
|
36
|
+
self.cur_drop_prob = 0.0
|
|
37
|
+
return x
|
|
38
|
+
else:
|
|
39
|
+
self.cur_drop_prob = self.drop_prob
|
|
40
|
+
return F.dropout(x, self.drop_prob, self.training, self.inplace)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from torch import nn
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class LinearScheduler(nn.Module):
|
|
6
|
+
'''
|
|
7
|
+
在指定的步数范围内将dropblock的prob设置为相应的值
|
|
8
|
+
如果start_value>0,stop_value>0则设置为对应的插值
|
|
9
|
+
否则设置为dropblock的默认值
|
|
10
|
+
'''
|
|
11
|
+
def __init__(self, dropblock, start_value=-1.0, stop_value=-1.0, begin_step=0,end_step=-1,enable_prob=None):
|
|
12
|
+
super(LinearScheduler, self).__init__()
|
|
13
|
+
self.dropblock = dropblock
|
|
14
|
+
self.i = 0
|
|
15
|
+
if start_value>=0.0 and stop_value>=0.0 and end_step>0:
|
|
16
|
+
nr_steps = end_step-begin_step
|
|
17
|
+
assert nr_steps>0,f"ERROR begin step and end {begin_step} {end_step}"
|
|
18
|
+
self.drop_values = np.linspace(start=start_value, stop=stop_value, num=int(nr_steps))
|
|
19
|
+
self.drop_prob = None
|
|
20
|
+
elif start_value<0 and stop_value<0:
|
|
21
|
+
self.drop_values = None
|
|
22
|
+
self.drop_prob = self.dropblock.drop_prob
|
|
23
|
+
if end_step<0:
|
|
24
|
+
end_step = 1e9
|
|
25
|
+
self.begin_step = begin_step
|
|
26
|
+
self.end_step = end_step
|
|
27
|
+
self.enable_prob = enable_prob
|
|
28
|
+
|
|
29
|
+
def forward(self, x):
|
|
30
|
+
if self.enable_prob is not None and self.enable_prob > 0:
|
|
31
|
+
if np.random.rand() > self.enable_prob:
|
|
32
|
+
self.dropblock.cur_drop_prob = 0.0
|
|
33
|
+
return x
|
|
34
|
+
return self.dropblock(x)
|
|
35
|
+
|
|
36
|
+
def step(self,step=None):
|
|
37
|
+
if step is not None:
|
|
38
|
+
self.i = step
|
|
39
|
+
else:
|
|
40
|
+
self.i += 1
|
|
41
|
+
if self.i>=self.begin_step and self.i<=self.end_step:
|
|
42
|
+
if self.drop_prob is not None:
|
|
43
|
+
self.dropblock.drop_prob = self.drop_prob
|
|
44
|
+
elif self.drop_values is not None and self.i-self.begin_step < len(self.drop_values):
|
|
45
|
+
self.dropblock.drop_prob = self.drop_values[self.i-self.begin_step]
|
|
46
|
+
elif self.drop_prob is not None:
|
|
47
|
+
self.dropblock.drop_prob = 0.0
|
|
48
|
+
|
wml/wtorch/ema.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding:utf-8 -*-
|
|
3
|
+
# Copyright (c) 2014-2021 Megvii Inc. All rights reserved.
|
|
4
|
+
import math
|
|
5
|
+
from copy import deepcopy
|
|
6
|
+
|
|
7
|
+
import torch
|
|
8
|
+
import torch.nn as nn
|
|
9
|
+
|
|
10
|
+
__all__ = ["ModelEMA", "is_parallel"]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def is_parallel(model):
|
|
14
|
+
"""check if model is in parallel mode."""
|
|
15
|
+
parallel_type = (
|
|
16
|
+
nn.parallel.DataParallel,
|
|
17
|
+
nn.parallel.DistributedDataParallel,
|
|
18
|
+
)
|
|
19
|
+
return isinstance(model, parallel_type)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ModelEMA:
|
|
23
|
+
"""
|
|
24
|
+
Model Exponential Moving Average from https://github.com/rwightman/pytorch-image-models
|
|
25
|
+
Keep a moving average of everything in the model state_dict (parameters and buffers).
|
|
26
|
+
This is intended to allow functionality like
|
|
27
|
+
https://www.tensorflow.org/api_docs/python/tf/train/ExponentialMovingAverage
|
|
28
|
+
A smoothed version of the weights is necessary for some training schemes to perform well.
|
|
29
|
+
This class is sensitive where it is initialized in the sequence of model init,
|
|
30
|
+
GPU assignment and distributed training wrappers.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, model, decay=0.9999, updates=0):
|
|
34
|
+
"""
|
|
35
|
+
Args:
|
|
36
|
+
model (nn.Module): model to apply EMA.
|
|
37
|
+
decay (float): ema decay reate.
|
|
38
|
+
updates (int): counter of EMA updates.
|
|
39
|
+
"""
|
|
40
|
+
# Create EMA(FP32)
|
|
41
|
+
self.ema = deepcopy(model.module if is_parallel(model) else model).eval()
|
|
42
|
+
self.updates = updates
|
|
43
|
+
# decay exponential ramp (to help early epochs)
|
|
44
|
+
self.decay = lambda x: decay * (1 - math.exp(-x / 2000))
|
|
45
|
+
for p in self.ema.parameters():
|
|
46
|
+
p.requires_grad_(False)
|
|
47
|
+
|
|
48
|
+
def update(self, model):
|
|
49
|
+
# Update EMA parameters
|
|
50
|
+
#print(f"EMA Update.")
|
|
51
|
+
with torch.no_grad():
|
|
52
|
+
self.updates += 1
|
|
53
|
+
d = self.decay(self.updates) #old persent
|
|
54
|
+
|
|
55
|
+
msd = (
|
|
56
|
+
model.module.state_dict() if is_parallel(model) else model.state_dict()
|
|
57
|
+
) # model state_dict
|
|
58
|
+
for k, v in self.ema.state_dict().items():
|
|
59
|
+
if v.dtype.is_floating_point:
|
|
60
|
+
v *= d
|
|
61
|
+
v += (1.0 - d) * msd[k].detach()
|
wml/wtorch/fc_module.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
import copy
|
|
3
|
+
import torch.nn as nn
|
|
4
|
+
import wml.wtorch.nn as wnn
|
|
5
|
+
from torch.nn.modules.batchnorm import _BatchNorm
|
|
6
|
+
from torch.nn.modules.instancenorm import _InstanceNorm
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FCModule(nn.Module):
|
|
11
|
+
def __init__(self,
|
|
12
|
+
in_channels,
|
|
13
|
+
out_channels,
|
|
14
|
+
bias='auto',
|
|
15
|
+
norm_cfg=None,
|
|
16
|
+
act_cfg=dict(type='ReLU'),
|
|
17
|
+
inplace=True,
|
|
18
|
+
):
|
|
19
|
+
super().__init__()
|
|
20
|
+
norm_cfg = copy.deepcopy(norm_cfg)
|
|
21
|
+
assert norm_cfg is None or isinstance(norm_cfg, dict)
|
|
22
|
+
assert act_cfg is None or isinstance(act_cfg, dict)
|
|
23
|
+
self.norm_cfg = norm_cfg
|
|
24
|
+
self.act_cfg = act_cfg
|
|
25
|
+
|
|
26
|
+
self.with_norm = norm_cfg is not None
|
|
27
|
+
self.with_activation = act_cfg is not None
|
|
28
|
+
# if the conv layer is before a norm layer, bias is unnecessary.
|
|
29
|
+
if bias == 'auto':
|
|
30
|
+
bias = not self.with_norm
|
|
31
|
+
self.with_bias = bias
|
|
32
|
+
|
|
33
|
+
modules = []
|
|
34
|
+
# build convolution layer
|
|
35
|
+
fc = nn.Linear(
|
|
36
|
+
in_channels,
|
|
37
|
+
out_channels,
|
|
38
|
+
bias=bias)
|
|
39
|
+
# export the attributes of self.conv to a higher level for convenience
|
|
40
|
+
self.in_channels = in_channels
|
|
41
|
+
self.out_channels = out_channels
|
|
42
|
+
modules.append(fc)
|
|
43
|
+
|
|
44
|
+
# build normalization layers
|
|
45
|
+
if self.with_norm:
|
|
46
|
+
# norm layer is after conv layer
|
|
47
|
+
norm_type = norm_cfg.pop('type')
|
|
48
|
+
norm = wnn.get_norm1d(norm_type,
|
|
49
|
+
self.out_channels,
|
|
50
|
+
norm_args=norm_cfg)
|
|
51
|
+
if self.with_bias:
|
|
52
|
+
if isinstance(norm, (_BatchNorm, _InstanceNorm)):
|
|
53
|
+
warnings.warn(
|
|
54
|
+
'Unnecessary conv bias before batch/instance norm')
|
|
55
|
+
modules.append(norm)
|
|
56
|
+
|
|
57
|
+
# build activation layer
|
|
58
|
+
if self.with_activation:
|
|
59
|
+
act_cfg_ = act_cfg.copy()
|
|
60
|
+
# nn.Tanh has no 'inplace' argument
|
|
61
|
+
if act_cfg_['type'] not in [
|
|
62
|
+
'Tanh', 'PReLU', 'Sigmoid', 'HSigmoid', 'Swish', 'GELU'
|
|
63
|
+
]:
|
|
64
|
+
act_cfg_.setdefault('inplace', inplace)
|
|
65
|
+
act_type = act_cfg_.pop('type')
|
|
66
|
+
inplace = act_cfg_.pop('inplace')
|
|
67
|
+
activate = wnn.get_activation(act_type,inplace)
|
|
68
|
+
modules.append(activate)
|
|
69
|
+
self.fc = nn.Sequential(*modules)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def forward(self, x):
|
|
73
|
+
return self.fc.forward(x)
|
wml/wtorch/functional.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
|
|
3
|
+
def soft_one_hot(labels,confidence,smooth_cfg,num_classes):
|
|
4
|
+
'''
|
|
5
|
+
labels: any shape in, value in [0,num_classes)
|
|
6
|
+
smooth_cfg:Example:
|
|
7
|
+
{1:[3,4], #标签1向3,4平滑
|
|
8
|
+
3:[1,4],
|
|
9
|
+
5:{2:0.04,3:0.06}, #标签5向2,3平滑,2得到0.04的置信度,3得到0.06的置信度
|
|
10
|
+
}
|
|
11
|
+
'''
|
|
12
|
+
old_shape = labels.shape
|
|
13
|
+
labels = torch.reshape(labels,[-1])
|
|
14
|
+
targets = torch.zeros([labels.shape[0],num_classes],dtype=torch.float32)
|
|
15
|
+
smooth_labels = set(list(smooth_cfg.keys()))
|
|
16
|
+
h_labels = labels.cpu().numpy()
|
|
17
|
+
targets[torch.arange(targets.shape[0]),h_labels] = 1.0
|
|
18
|
+
for i,l in enumerate(h_labels):
|
|
19
|
+
if l in smooth_labels:
|
|
20
|
+
d = smooth_cfg[l]
|
|
21
|
+
if isinstance(d,dict):
|
|
22
|
+
for k,v in d.items():
|
|
23
|
+
targets[i,k] = v
|
|
24
|
+
else:
|
|
25
|
+
smooth_v = (1-confidence)/len(d)
|
|
26
|
+
for k in d:
|
|
27
|
+
targets[i,k] = smooth_v
|
|
28
|
+
targets[i,l] = confidence
|
|
29
|
+
|
|
30
|
+
targets = targets.to(labels.device)
|
|
31
|
+
ret_shape = list(old_shape)+[num_classes]
|
|
32
|
+
targets = torch.reshape(targets,ret_shape)
|
|
33
|
+
|
|
34
|
+
return targets
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import os
|
|
2
|
+
class IterdatasetWrapper:
|
|
3
|
+
def __init__(self,dataset,max_iter=100000):
|
|
4
|
+
self.dataset = dataset
|
|
5
|
+
self.max_iter = max_iter
|
|
6
|
+
self.iter = iter(self.dataset)
|
|
7
|
+
|
|
8
|
+
def __len__(self):
|
|
9
|
+
return self.max_iter
|
|
10
|
+
|
|
11
|
+
def __getitem__(self, item):
|
|
12
|
+
try:
|
|
13
|
+
data = next(self.iter)
|
|
14
|
+
except StopIteration as e:
|
|
15
|
+
self.iter = iter(self.dataset)
|
|
16
|
+
try:
|
|
17
|
+
data = next(self.iter)
|
|
18
|
+
except Exception as e:
|
|
19
|
+
print('ERROR: IterdatasetWrapper:',e)
|
|
20
|
+
raise e
|
|
21
|
+
except Exception as e:
|
|
22
|
+
print('ERROR: IterdatasetWrapper:',e)
|
|
23
|
+
raise e
|
|
24
|
+
return data
|
|
25
|
+
|
|
26
|
+
|
wml/wtorch/loss.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import torch.nn.functional as F
|
|
3
|
+
|
|
4
|
+
def focal_loss_for_heat_map(labels,logits,pos_threshold=0.99,alpha=2,beta=4,sum=True):
|
|
5
|
+
'''
|
|
6
|
+
focal loss for heat map, for example CenterNet2's heat map loss
|
|
7
|
+
'''
|
|
8
|
+
logits = logits.to(torch.float32)
|
|
9
|
+
zeros = torch.zeros_like(labels)
|
|
10
|
+
ones = torch.ones_like(labels)
|
|
11
|
+
num_pos = torch.sum(torch.where(torch.greater_equal(labels, pos_threshold), ones, zeros))
|
|
12
|
+
|
|
13
|
+
probs = F.sigmoid(logits)
|
|
14
|
+
pos_weight = torch.where(torch.greater_equal(labels, pos_threshold), ones - probs, zeros)
|
|
15
|
+
neg_weight = torch.where(torch.less(labels, pos_threshold), probs, zeros)
|
|
16
|
+
'''
|
|
17
|
+
用于保证数值稳定性,log(sigmoid(x)) = log(1/(1+e^-x) = -log(1+e^-x) = x-x-log(1+e^-x) = x-log(e^x +1)
|
|
18
|
+
pos_loss = tf.where(tf.less(logits,0),logits-tf.log(tf.exp(logits)+1),tf.log(probs))
|
|
19
|
+
'''
|
|
20
|
+
pure_pos_loss = -torch.minimum(logits,logits.new_tensor(0,dtype=logits.dtype))+torch.log(1+torch.exp(-torch.abs(logits)))
|
|
21
|
+
pos_loss = pure_pos_loss*torch.pow(pos_weight, alpha)
|
|
22
|
+
if sum:
|
|
23
|
+
pos_loss = torch.sum(pos_loss)
|
|
24
|
+
'''
|
|
25
|
+
用于保证数值稳定性
|
|
26
|
+
'''
|
|
27
|
+
pure_neg_loss = F.relu(logits)+torch.log(1+torch.exp(-torch.abs(logits)))
|
|
28
|
+
neg_loss = torch.pow((1 - labels), beta) * torch.pow(neg_weight, alpha) * pure_neg_loss
|
|
29
|
+
if sum:
|
|
30
|
+
neg_loss = torch.sum(neg_loss)
|
|
31
|
+
loss = (pos_loss + neg_loss) / (num_pos + 1e-4)
|
|
32
|
+
return loss
|
|
33
|
+
|
|
34
|
+
def focal_mse_loss_for_head_map(gt_value,pred_value,alpha=0.25,gamma=2):
|
|
35
|
+
'''
|
|
36
|
+
alpha: pos loss x alpha, neg loss x (1-alpha)
|
|
37
|
+
gamma: loss x loss^gamma
|
|
38
|
+
gt_value: value range [0,1]
|
|
39
|
+
注:
|
|
40
|
+
|
|
41
|
+
'''
|
|
42
|
+
assert gt_value.numel()==pred_value.numel(), f"ERROR: unmatch gt_value's shape {gt_value.shape} and pred_value's shape {pred_value.shape}"
|
|
43
|
+
gt_value = gt_value.float()
|
|
44
|
+
pred_value = pred_value.float()
|
|
45
|
+
loss = torch.square(gt_value-pred_value)
|
|
46
|
+
bin_gt_value = torch.greater(gt_value,0).to(pred_value.dtype)
|
|
47
|
+
total_nr = bin_gt_value.new_tensor(torch.numel(bin_gt_value))
|
|
48
|
+
#neg_scale = torch.sum(bin_gt_value)/total_nr
|
|
49
|
+
#pos_scale = bin_gt_value.new_tensor(1.0)-neg_scale
|
|
50
|
+
num_pos = torch.sum(bin_gt_value)
|
|
51
|
+
num_neg = total_nr-num_pos
|
|
52
|
+
|
|
53
|
+
neg_scale = total_nr/(num_neg*2.0+2e-1)
|
|
54
|
+
pos_scale = total_nr/(num_pos*2.0+2e-1)
|
|
55
|
+
|
|
56
|
+
auto_t = bin_gt_value*pos_scale+(1-bin_gt_value)*neg_scale
|
|
57
|
+
loss = loss*auto_t
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if alpha is not None and alpha>0:
|
|
61
|
+
alpha_t = bin_gt_value*alpha+(1-bin_gt_value)*(1-alpha)
|
|
62
|
+
alpha_t = alpha_t/torch.clip(torch.mean(alpha_t).detach(),min=1e-6)
|
|
63
|
+
loss = loss*alpha_t
|
|
64
|
+
if gamma is not None and gamma>0:
|
|
65
|
+
gamma_t = torch.pow(torch.abs(gt_value-pred_value),gamma)
|
|
66
|
+
gamma_t = gamma_t/torch.clip(torch.mean(gamma_t).detach(),min=1e-6)
|
|
67
|
+
loss = loss*gamma_t
|
|
68
|
+
|
|
69
|
+
return loss
|
|
File without changes
|