openpoints 0.1.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.
- openpoints/__init__.py +3 -0
- openpoints/cpp/__init__.py +6 -0
- openpoints/cpp/chamfer_dist/__init__.py +110 -0
- openpoints/cpp/chamfer_dist/setup.py +19 -0
- openpoints/cpp/chamfer_dist/test.py +34 -0
- openpoints/cpp/emd/__init__.py +3 -0
- openpoints/cpp/emd/emd.py +88 -0
- openpoints/cpp/emd/setup.py +27 -0
- openpoints/cpp/emd/test_emd_loss.py +45 -0
- openpoints/cpp/pointnet2_batch/__init__.py +24 -0
- openpoints/cpp/pointnet2_batch/setup.py +23 -0
- openpoints/cpp/pointops/__init__.py +0 -0
- openpoints/cpp/pointops/functions/__init__.py +0 -0
- openpoints/cpp/pointops/functions/pointops.py +314 -0
- openpoints/cpp/pointops/setup.py +37 -0
- openpoints/cpp/pointops/src/__init__.py +0 -0
- openpoints/dataset/__init__.py +10 -0
- openpoints/dataset/atom3d/__init__.py +1 -0
- openpoints/dataset/atom3d/psr.py +38 -0
- openpoints/dataset/build.py +98 -0
- openpoints/dataset/data_util.py +192 -0
- openpoints/dataset/datalist.py +67 -0
- openpoints/dataset/dataset_base.py +96 -0
- openpoints/dataset/graph_dataset/__init__.py +3 -0
- openpoints/dataset/graph_dataset/graph_dataset.py +93 -0
- openpoints/dataset/graph_dataset/stack_with_pad.py +91 -0
- openpoints/dataset/graph_dataset/structural_dataset.py +73 -0
- openpoints/dataset/graph_dataset/svd_encodings_dataset.py +110 -0
- openpoints/dataset/grid_sample.py +21 -0
- openpoints/dataset/matterport3d/__init__.py +1 -0
- openpoints/dataset/matterport3d/category_mapping.tsv +1660 -0
- openpoints/dataset/matterport3d/matterport3d.py +210 -0
- openpoints/dataset/matterport3d/matterport3d_dataprocessing.py +105 -0
- openpoints/dataset/modelnet/__init__.py +3 -0
- openpoints/dataset/modelnet/modelnet40_normal_resampled_loader.py +124 -0
- openpoints/dataset/modelnet/modelnet40_ply_2048_loader.py +160 -0
- openpoints/dataset/molhiv/__init__.py +1 -0
- openpoints/dataset/molhiv/data.py +59 -0
- openpoints/dataset/molpcba/__init__.py +1 -0
- openpoints/dataset/molpcba/data.py +59 -0
- openpoints/dataset/parsers/__init__.py +1 -0
- openpoints/dataset/parsers/class_map.py +19 -0
- openpoints/dataset/parsers/constants.py +1 -0
- openpoints/dataset/parsers/parser.py +17 -0
- openpoints/dataset/parsers/parser_factory.py +29 -0
- openpoints/dataset/parsers/parser_image_folder.py +69 -0
- openpoints/dataset/parsers/parser_image_in_tar.py +222 -0
- openpoints/dataset/parsers/parser_image_tar.py +72 -0
- openpoints/dataset/parsers/parser_tfds.py +297 -0
- openpoints/dataset/pcqm4m/__init__.py +1 -0
- openpoints/dataset/pcqm4m/data.py +62 -0
- openpoints/dataset/pcqm4mv2/__init__.py +1 -0
- openpoints/dataset/pcqm4mv2/data.py +87 -0
- openpoints/dataset/s3dis/__init__.py +2 -0
- openpoints/dataset/s3dis/s3dis.py +156 -0
- openpoints/dataset/s3dis/s3dis_block.py +96 -0
- openpoints/dataset/s3dis/s3dis_sphere.py +349 -0
- openpoints/dataset/scannetv2/__init__.py +1 -0
- openpoints/dataset/scannetv2/scannet.py +176 -0
- openpoints/dataset/scanobjectnn/__init__.py +3 -0
- openpoints/dataset/scanobjectnn/scanobjectnn.py +110 -0
- openpoints/dataset/semantic_kitti/__init__.py +1 -0
- openpoints/dataset/semantic_kitti/helper_tool.py +286 -0
- openpoints/dataset/semantic_kitti/label_mapping.yaml +211 -0
- openpoints/dataset/semantic_kitti/semantickitti.py +229 -0
- openpoints/dataset/semantic_kitti/utils/meta/anno_paths.txt +272 -0
- openpoints/dataset/semantic_kitti/utils/meta/class_names.txt +13 -0
- openpoints/dataset/semantic_kitti/utils/semantic-kitti.yaml +211 -0
- openpoints/dataset/shapenet/__init__.py +1 -0
- openpoints/dataset/shapenet/shapenet55.py +76 -0
- openpoints/dataset/shapenet/shapenetpart.py +121 -0
- openpoints/dataset/shapenetpart/__init__.py +1 -0
- openpoints/dataset/shapenetpart/shapenet55.py +75 -0
- openpoints/dataset/shapenetpart/shapenetpart.py +388 -0
- openpoints/dataset/vis2d.py +17 -0
- openpoints/dataset/vis3d.py +153 -0
- openpoints/loss/__init__.py +3 -0
- openpoints/loss/build.py +281 -0
- openpoints/loss/cross_entropy.py +38 -0
- openpoints/loss/distill_loss.py +76 -0
- openpoints/models/__init__.py +10 -0
- openpoints/models/backbone/Stratified_transformer.py +558 -0
- openpoints/models/backbone/__init__.py +11 -0
- openpoints/models/backbone/baafnet.py +527 -0
- openpoints/models/backbone/ball_dgcnn.py +123 -0
- openpoints/models/backbone/curvenet.py +793 -0
- openpoints/models/backbone/debug_invvit.py +114 -0
- openpoints/models/backbone/deepgcn.py +143 -0
- openpoints/models/backbone/dgcnn.py +119 -0
- openpoints/models/backbone/graphvit3d.py +134 -0
- openpoints/models/backbone/grouppointnet.py +100 -0
- openpoints/models/backbone/pct.py +163 -0
- openpoints/models/backbone/pointmlp.py +417 -0
- openpoints/models/backbone/pointnet.py +199 -0
- openpoints/models/backbone/pointnetv2.py +511 -0
- openpoints/models/backbone/pointnext.py +663 -0
- openpoints/models/backbone/pointnextPyG.py +555 -0
- openpoints/models/backbone/pointtransformer.py +293 -0
- openpoints/models/backbone/pointvector.py +853 -0
- openpoints/models/backbone/pointvit.py +392 -0
- openpoints/models/backbone/pointvit_inv.py +942 -0
- openpoints/models/backbone/pointvit_inv_old.py +784 -0
- openpoints/models/backbone/randlenet.py +318 -0
- openpoints/models/backbone/resnet.py +342 -0
- openpoints/models/backbone/simpleview.py +153 -0
- openpoints/models/backbone/simpleview_util.py +292 -0
- openpoints/models/build.py +13 -0
- openpoints/models/classification/__init__.py +5 -0
- openpoints/models/classification/cls_base.py +136 -0
- openpoints/models/classification/point_bert.py +154 -0
- openpoints/models/layers/__init__.py +14 -0
- openpoints/models/layers/activation.py +57 -0
- openpoints/models/layers/attention.py +103 -0
- openpoints/models/layers/conv.py +167 -0
- openpoints/models/layers/drop.py +164 -0
- openpoints/models/layers/graph_conv.py +122 -0
- openpoints/models/layers/group.py +415 -0
- openpoints/models/layers/group_embed.py +286 -0
- openpoints/models/layers/helpers.py +43 -0
- openpoints/models/layers/kmeans.py +119 -0
- openpoints/models/layers/knn.py +110 -0
- openpoints/models/layers/local_aggregation.py +286 -0
- openpoints/models/layers/mlp.py +129 -0
- openpoints/models/layers/norm.py +106 -0
- openpoints/models/layers/padding.py +56 -0
- openpoints/models/layers/patch_embed.py +37 -0
- openpoints/models/layers/registry.py +168 -0
- openpoints/models/layers/subsample.py +185 -0
- openpoints/models/layers/upsampling.py +106 -0
- openpoints/models/layers/weight_init.py +89 -0
- openpoints/models/reconstruction/__init__.py +8 -0
- openpoints/models/reconstruction/base_recontruct.py +216 -0
- openpoints/models/reconstruction/maskedpoint.py +116 -0
- openpoints/models/reconstruction/maskedpointgroup.py +168 -0
- openpoints/models/reconstruction/maskedpointvit.py +253 -0
- openpoints/models/reconstruction/nodeshuffle.py +11 -0
- openpoints/models/registry.py +149 -0
- openpoints/models/segmentation/__init__.py +6 -0
- openpoints/models/segmentation/base_seg.py +278 -0
- openpoints/models/segmentation/vit_seg.py +126 -0
- openpoints/optim/__init__.py +15 -0
- openpoints/optim/adabelief.py +201 -0
- openpoints/optim/adafactor.py +167 -0
- openpoints/optim/adahessian.py +156 -0
- openpoints/optim/adamp.py +105 -0
- openpoints/optim/adamw.py +122 -0
- openpoints/optim/lamb.py +192 -0
- openpoints/optim/lars.py +135 -0
- openpoints/optim/lookahead.py +61 -0
- openpoints/optim/madgrad.py +184 -0
- openpoints/optim/nadam.py +92 -0
- openpoints/optim/nvnovograd.py +120 -0
- openpoints/optim/optim_factory.py +306 -0
- openpoints/optim/radam.py +89 -0
- openpoints/optim/rmsprop_tf.py +139 -0
- openpoints/optim/sgdp.py +70 -0
- openpoints/scheduler/__init__.py +8 -0
- openpoints/scheduler/cosine_lr.py +124 -0
- openpoints/scheduler/multistep_lr.py +65 -0
- openpoints/scheduler/plateau_lr.py +113 -0
- openpoints/scheduler/poly_lr.py +116 -0
- openpoints/scheduler/scheduler.py +110 -0
- openpoints/scheduler/scheduler_factory.py +118 -0
- openpoints/scheduler/step_lr.py +65 -0
- openpoints/scheduler/tanh_lr.py +117 -0
- openpoints/transforms/__init__.py +7 -0
- openpoints/transforms/point_transform_cpu.py +332 -0
- openpoints/transforms/point_transformer_gpu.py +764 -0
- openpoints/transforms/transforms_factory.py +60 -0
- openpoints/utils/__init__.py +8 -0
- openpoints/utils/ckpt_util.py +438 -0
- openpoints/utils/config.py +113 -0
- openpoints/utils/dist_utils.py +54 -0
- openpoints/utils/logger.py +170 -0
- openpoints/utils/metrics.py +311 -0
- openpoints/utils/random.py +16 -0
- openpoints/utils/registry.py +294 -0
- openpoints/utils/str2bool.py +11 -0
- openpoints/utils/wandb.py +88 -0
- openpoints-0.1.0.dist-info/METADATA +150 -0
- openpoints-0.1.0.dist-info/RECORD +184 -0
- openpoints-0.1.0.dist-info/WHEEL +5 -0
- openpoints-0.1.0.dist-info/licenses/LICENSE +21 -0
- openpoints-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
""" Adafactor Optimizer
|
|
2
|
+
|
|
3
|
+
Lifted from https://github.com/pytorch/fairseq/blob/master/fairseq/optim/adafactor.py
|
|
4
|
+
|
|
5
|
+
Original header/copyright below.
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
# Copyright (c) Facebook, Inc. and its affiliates.
|
|
9
|
+
#
|
|
10
|
+
# This source code is licensed under the MIT license found in the
|
|
11
|
+
# LICENSE file in the root directory of this source tree.
|
|
12
|
+
import torch
|
|
13
|
+
import math
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Adafactor(torch.optim.Optimizer):
|
|
17
|
+
"""Implements Adafactor algorithm.
|
|
18
|
+
This implementation is based on: `Adafactor: Adaptive Learning Rates with Sublinear Memory Cost`
|
|
19
|
+
(see https://arxiv.org/abs/1804.04235)
|
|
20
|
+
|
|
21
|
+
Note that this optimizer internally adjusts the learning rate depending on the
|
|
22
|
+
*scale_parameter*, *relative_step* and *warmup_init* options.
|
|
23
|
+
|
|
24
|
+
To use a manual (external) learning rate schedule you should set `scale_parameter=False` and
|
|
25
|
+
`relative_step=False`.
|
|
26
|
+
|
|
27
|
+
Arguments:
|
|
28
|
+
params (iterable): iterable of parameters to optimize or dicts defining parameter groups
|
|
29
|
+
lr (float, optional): external learning rate (default: None)
|
|
30
|
+
eps (tuple[float, float]): regularization constants for square gradient
|
|
31
|
+
and parameter scale respectively (default: (1e-30, 1e-3))
|
|
32
|
+
clip_threshold (float): threshold of root mean square of final gradient update (default: 1.0)
|
|
33
|
+
decay_rate (float): coefficient used to compute running averages of square gradient (default: -0.8)
|
|
34
|
+
beta1 (float): coefficient used for computing running averages of gradient (default: None)
|
|
35
|
+
weight_decay (float, optional): weight decay (L2 penalty) (default: 0)
|
|
36
|
+
scale_parameter (bool): if True, learning rate is scaled by root mean square of parameter (default: True)
|
|
37
|
+
warmup_init (bool): time-dependent learning rate computation depends on
|
|
38
|
+
whether warm-up initialization is being used (default: False)
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(self, params, lr=None, eps=1e-30, eps_scale=1e-3, clip_threshold=1.0,
|
|
42
|
+
decay_rate=-0.8, betas=None, weight_decay=0.0, scale_parameter=True, warmup_init=False):
|
|
43
|
+
relative_step = not lr
|
|
44
|
+
if warmup_init and not relative_step:
|
|
45
|
+
raise ValueError('warmup_init requires relative_step=True')
|
|
46
|
+
|
|
47
|
+
beta1 = None if betas is None else betas[0] # make it compat with standard betas arg
|
|
48
|
+
defaults = dict(lr=lr, eps=eps, eps_scale=eps_scale, clip_threshold=clip_threshold, decay_rate=decay_rate,
|
|
49
|
+
beta1=beta1, weight_decay=weight_decay, scale_parameter=scale_parameter,
|
|
50
|
+
relative_step=relative_step, warmup_init=warmup_init)
|
|
51
|
+
super(Adafactor, self).__init__(params, defaults)
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def _get_lr(param_group, param_state):
|
|
55
|
+
if param_group['relative_step']:
|
|
56
|
+
min_step = 1e-6 * param_state['step'] if param_group['warmup_init'] else 1e-2
|
|
57
|
+
lr_t = min(min_step, 1.0 / math.sqrt(param_state['step']))
|
|
58
|
+
param_scale = 1.0
|
|
59
|
+
if param_group['scale_parameter']:
|
|
60
|
+
param_scale = max(param_group['eps_scale'], param_state['RMS'])
|
|
61
|
+
param_group['lr'] = lr_t * param_scale
|
|
62
|
+
return param_group['lr']
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def _get_options(param_group, param_shape):
|
|
66
|
+
factored = len(param_shape) >= 2
|
|
67
|
+
use_first_moment = param_group['beta1'] is not None
|
|
68
|
+
return factored, use_first_moment
|
|
69
|
+
|
|
70
|
+
@staticmethod
|
|
71
|
+
def _rms(tensor):
|
|
72
|
+
return tensor.norm(2) / (tensor.numel() ** 0.5)
|
|
73
|
+
|
|
74
|
+
def _approx_sq_grad(self, exp_avg_sq_row, exp_avg_sq_col):
|
|
75
|
+
r_factor = (exp_avg_sq_row / exp_avg_sq_row.mean(dim=-1, keepdim=True)).rsqrt_().unsqueeze(-1)
|
|
76
|
+
c_factor = exp_avg_sq_col.unsqueeze(-2).rsqrt()
|
|
77
|
+
return torch.mul(r_factor, c_factor)
|
|
78
|
+
|
|
79
|
+
@torch.no_grad()
|
|
80
|
+
def step(self, closure=None):
|
|
81
|
+
"""Performs a single optimization step.
|
|
82
|
+
Arguments:
|
|
83
|
+
closure (callable, optional): A closure that reevaluates the model and returns the loss.
|
|
84
|
+
"""
|
|
85
|
+
loss = None
|
|
86
|
+
if closure is not None:
|
|
87
|
+
with torch.enable_grad():
|
|
88
|
+
loss = closure()
|
|
89
|
+
|
|
90
|
+
for group in self.param_groups:
|
|
91
|
+
for p in group['params']:
|
|
92
|
+
if p.grad is None:
|
|
93
|
+
continue
|
|
94
|
+
grad = p.grad
|
|
95
|
+
if grad.dtype in {torch.float16, torch.bfloat16}:
|
|
96
|
+
grad = grad.float()
|
|
97
|
+
if grad.is_sparse:
|
|
98
|
+
raise RuntimeError('Adafactor does not support sparse gradients.')
|
|
99
|
+
|
|
100
|
+
state = self.state[p]
|
|
101
|
+
|
|
102
|
+
factored, use_first_moment = self._get_options(group, grad.shape)
|
|
103
|
+
# State Initialization
|
|
104
|
+
if len(state) == 0:
|
|
105
|
+
state['step'] = 0
|
|
106
|
+
|
|
107
|
+
if use_first_moment:
|
|
108
|
+
# Exponential moving average of gradient values
|
|
109
|
+
state['exp_avg'] = torch.zeros_like(grad)
|
|
110
|
+
if factored:
|
|
111
|
+
state['exp_avg_sq_row'] = torch.zeros(grad.shape[:-1]).to(grad)
|
|
112
|
+
state['exp_avg_sq_col'] = torch.zeros(grad.shape[:-2] + grad.shape[-1:]).to(grad)
|
|
113
|
+
else:
|
|
114
|
+
state['exp_avg_sq'] = torch.zeros_like(grad)
|
|
115
|
+
|
|
116
|
+
state['RMS'] = 0
|
|
117
|
+
else:
|
|
118
|
+
if use_first_moment:
|
|
119
|
+
state['exp_avg'] = state['exp_avg'].to(grad)
|
|
120
|
+
if factored:
|
|
121
|
+
state['exp_avg_sq_row'] = state['exp_avg_sq_row'].to(grad)
|
|
122
|
+
state['exp_avg_sq_col'] = state['exp_avg_sq_col'].to(grad)
|
|
123
|
+
else:
|
|
124
|
+
state['exp_avg_sq'] = state['exp_avg_sq'].to(grad)
|
|
125
|
+
|
|
126
|
+
p_fp32 = p
|
|
127
|
+
if p.dtype in {torch.float16, torch.bfloat16}:
|
|
128
|
+
p_fp32 = p_fp32.float()
|
|
129
|
+
|
|
130
|
+
state['step'] += 1
|
|
131
|
+
state['RMS'] = self._rms(p_fp32)
|
|
132
|
+
lr_t = self._get_lr(group, state)
|
|
133
|
+
|
|
134
|
+
beta2t = 1.0 - math.pow(state['step'], group['decay_rate'])
|
|
135
|
+
update = grad ** 2 + group['eps']
|
|
136
|
+
if factored:
|
|
137
|
+
exp_avg_sq_row = state['exp_avg_sq_row']
|
|
138
|
+
exp_avg_sq_col = state['exp_avg_sq_col']
|
|
139
|
+
|
|
140
|
+
exp_avg_sq_row.mul_(beta2t).add_(update.mean(dim=-1), alpha=1.0 - beta2t)
|
|
141
|
+
exp_avg_sq_col.mul_(beta2t).add_(update.mean(dim=-2), alpha=1.0 - beta2t)
|
|
142
|
+
|
|
143
|
+
# Approximation of exponential moving average of square of gradient
|
|
144
|
+
update = self._approx_sq_grad(exp_avg_sq_row, exp_avg_sq_col)
|
|
145
|
+
update.mul_(grad)
|
|
146
|
+
else:
|
|
147
|
+
exp_avg_sq = state['exp_avg_sq']
|
|
148
|
+
|
|
149
|
+
exp_avg_sq.mul_(beta2t).add_(update, alpha=1.0 - beta2t)
|
|
150
|
+
update = exp_avg_sq.rsqrt().mul_(grad)
|
|
151
|
+
|
|
152
|
+
update.div_((self._rms(update) / group['clip_threshold']).clamp_(min=1.0))
|
|
153
|
+
update.mul_(lr_t)
|
|
154
|
+
|
|
155
|
+
if use_first_moment:
|
|
156
|
+
exp_avg = state['exp_avg']
|
|
157
|
+
exp_avg.mul_(group['beta1']).add_(update, alpha=1 - group['beta1'])
|
|
158
|
+
update = exp_avg
|
|
159
|
+
|
|
160
|
+
if group['weight_decay'] != 0:
|
|
161
|
+
p_fp32.add_(p_fp32, alpha=-group['weight_decay'] * lr_t)
|
|
162
|
+
|
|
163
|
+
p_fp32.add_(-update)
|
|
164
|
+
if p.dtype in {torch.float16, torch.bfloat16}:
|
|
165
|
+
p.copy_(p_fp32)
|
|
166
|
+
|
|
167
|
+
return loss
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
""" AdaHessian Optimizer
|
|
2
|
+
|
|
3
|
+
Lifted from https://github.com/davda54/ada-hessian/blob/master/ada_hessian.py
|
|
4
|
+
Originally licensed MIT, Copyright 2020, David Samuel
|
|
5
|
+
"""
|
|
6
|
+
import torch
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Adahessian(torch.optim.Optimizer):
|
|
10
|
+
"""
|
|
11
|
+
Implements the AdaHessian algorithm from "ADAHESSIAN: An Adaptive Second OrderOptimizer for Machine Learning"
|
|
12
|
+
|
|
13
|
+
Arguments:
|
|
14
|
+
params (iterable): iterable of parameters to optimize or dicts defining parameter groups
|
|
15
|
+
lr (float, optional): learning rate (default: 0.1)
|
|
16
|
+
betas ((float, float), optional): coefficients used for computing running averages of gradient and the
|
|
17
|
+
squared hessian trace (default: (0.9, 0.999))
|
|
18
|
+
eps (float, optional): term added to the denominator to improve numerical stability (default: 1e-8)
|
|
19
|
+
weight_decay (float, optional): weight decay (L2 penalty) (default: 0.0)
|
|
20
|
+
hessian_power (float, optional): exponent of the hessian trace (default: 1.0)
|
|
21
|
+
update_each (int, optional): compute the hessian trace approximation only after *this* number of steps
|
|
22
|
+
(to save time) (default: 1)
|
|
23
|
+
n_samples (int, optional): how many times to sample `z` for the approximation of the hessian trace (default: 1)
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, params, lr=0.1, betas=(0.9, 0.999), eps=1e-8, weight_decay=0.0,
|
|
27
|
+
hessian_power=1.0, update_each=1, n_samples=1, avg_conv_kernel=False):
|
|
28
|
+
if not 0.0 <= lr:
|
|
29
|
+
raise ValueError(f"Invalid learning rate: {lr}")
|
|
30
|
+
if not 0.0 <= eps:
|
|
31
|
+
raise ValueError(f"Invalid epsilon value: {eps}")
|
|
32
|
+
if not 0.0 <= betas[0] < 1.0:
|
|
33
|
+
raise ValueError(f"Invalid beta parameter at index 0: {betas[0]}")
|
|
34
|
+
if not 0.0 <= betas[1] < 1.0:
|
|
35
|
+
raise ValueError(f"Invalid beta parameter at index 1: {betas[1]}")
|
|
36
|
+
if not 0.0 <= hessian_power <= 1.0:
|
|
37
|
+
raise ValueError(f"Invalid Hessian power value: {hessian_power}")
|
|
38
|
+
|
|
39
|
+
self.n_samples = n_samples
|
|
40
|
+
self.update_each = update_each
|
|
41
|
+
self.avg_conv_kernel = avg_conv_kernel
|
|
42
|
+
|
|
43
|
+
# use a separate generator that deterministically generates the same `z`s across all GPUs in case of distributed training
|
|
44
|
+
self.seed = 2147483647
|
|
45
|
+
self.generator = torch.Generator().manual_seed(self.seed)
|
|
46
|
+
|
|
47
|
+
defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay, hessian_power=hessian_power)
|
|
48
|
+
super(Adahessian, self).__init__(params, defaults)
|
|
49
|
+
|
|
50
|
+
for p in self.get_params():
|
|
51
|
+
p.hess = 0.0
|
|
52
|
+
self.state[p]["hessian step"] = 0
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def is_second_order(self):
|
|
56
|
+
return True
|
|
57
|
+
|
|
58
|
+
def get_params(self):
|
|
59
|
+
"""
|
|
60
|
+
Gets all parameters in all param_groups with gradients
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
return (p for group in self.param_groups for p in group['params'] if p.requires_grad)
|
|
64
|
+
|
|
65
|
+
def zero_hessian(self):
|
|
66
|
+
"""
|
|
67
|
+
Zeros out the accumalated hessian traces.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
for p in self.get_params():
|
|
71
|
+
if not isinstance(p.hess, float) and self.state[p]["hessian step"] % self.update_each == 0:
|
|
72
|
+
p.hess.zero_()
|
|
73
|
+
|
|
74
|
+
@torch.no_grad()
|
|
75
|
+
def set_hessian(self):
|
|
76
|
+
"""
|
|
77
|
+
Computes the Hutchinson approximation of the hessian trace and accumulates it for each trainable parameter.
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
params = []
|
|
81
|
+
for p in filter(lambda p: p.grad is not None, self.get_params()):
|
|
82
|
+
if self.state[p]["hessian step"] % self.update_each == 0: # compute the trace only each `update_each` step
|
|
83
|
+
params.append(p)
|
|
84
|
+
self.state[p]["hessian step"] += 1
|
|
85
|
+
|
|
86
|
+
if len(params) == 0:
|
|
87
|
+
return
|
|
88
|
+
|
|
89
|
+
if self.generator.device != params[0].device: # hackish way of casting the generator to the right device
|
|
90
|
+
self.generator = torch.Generator(params[0].device).manual_seed(self.seed)
|
|
91
|
+
|
|
92
|
+
grads = [p.grad for p in params]
|
|
93
|
+
|
|
94
|
+
for i in range(self.n_samples):
|
|
95
|
+
# Rademacher distribution {-1.0, 1.0}
|
|
96
|
+
zs = [torch.randint(0, 2, p.size(), generator=self.generator, device=p.device) * 2.0 - 1.0 for p in params]
|
|
97
|
+
h_zs = torch.autograd.grad(
|
|
98
|
+
grads, params, grad_outputs=zs, only_inputs=True, retain_graph=i < self.n_samples - 1)
|
|
99
|
+
for h_z, z, p in zip(h_zs, zs, params):
|
|
100
|
+
p.hess += h_z * z / self.n_samples # approximate the expected values of z*(H@z)
|
|
101
|
+
|
|
102
|
+
@torch.no_grad()
|
|
103
|
+
def step(self, closure=None):
|
|
104
|
+
"""
|
|
105
|
+
Performs a single optimization step.
|
|
106
|
+
Arguments:
|
|
107
|
+
closure (callable, optional) -- a closure that reevaluates the model and returns the loss (default: None)
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
loss = None
|
|
111
|
+
if closure is not None:
|
|
112
|
+
loss = closure()
|
|
113
|
+
|
|
114
|
+
self.zero_hessian()
|
|
115
|
+
self.set_hessian()
|
|
116
|
+
|
|
117
|
+
for group in self.param_groups:
|
|
118
|
+
for p in group['params']:
|
|
119
|
+
if p.grad is None or p.hess is None:
|
|
120
|
+
continue
|
|
121
|
+
|
|
122
|
+
if self.avg_conv_kernel and p.dim() == 4:
|
|
123
|
+
p.hess = torch.abs(p.hess).mean(dim=[2, 3], keepdim=True).expand_as(p.hess).clone()
|
|
124
|
+
|
|
125
|
+
# Perform correct stepweight decay as in AdamW
|
|
126
|
+
p.mul_(1 - group['lr'] * group['weight_decay'])
|
|
127
|
+
|
|
128
|
+
state = self.state[p]
|
|
129
|
+
|
|
130
|
+
# State initialization
|
|
131
|
+
if len(state) == 1:
|
|
132
|
+
state['step'] = 0
|
|
133
|
+
# Exponential moving average of gradient values
|
|
134
|
+
state['exp_avg'] = torch.zeros_like(p)
|
|
135
|
+
# Exponential moving average of Hessian diagonal square values
|
|
136
|
+
state['exp_hessian_diag_sq'] = torch.zeros_like(p)
|
|
137
|
+
|
|
138
|
+
exp_avg, exp_hessian_diag_sq = state['exp_avg'], state['exp_hessian_diag_sq']
|
|
139
|
+
beta1, beta2 = group['betas']
|
|
140
|
+
state['step'] += 1
|
|
141
|
+
|
|
142
|
+
# Decay the first and second moment running average coefficient
|
|
143
|
+
exp_avg.mul_(beta1).add_(p.grad, alpha=1 - beta1)
|
|
144
|
+
exp_hessian_diag_sq.mul_(beta2).addcmul_(p.hess, p.hess, value=1 - beta2)
|
|
145
|
+
|
|
146
|
+
bias_correction1 = 1 - beta1 ** state['step']
|
|
147
|
+
bias_correction2 = 1 - beta2 ** state['step']
|
|
148
|
+
|
|
149
|
+
k = group['hessian_power']
|
|
150
|
+
denom = (exp_hessian_diag_sq / bias_correction2).pow_(k / 2).add_(group['eps'])
|
|
151
|
+
|
|
152
|
+
# make update
|
|
153
|
+
step_size = group['lr'] / bias_correction1
|
|
154
|
+
p.addcdiv_(exp_avg, denom, value=-step_size)
|
|
155
|
+
|
|
156
|
+
return loss
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AdamP Optimizer Implementation copied from https://github.com/clovaai/AdamP/blob/master/adamp/adamp.py
|
|
3
|
+
|
|
4
|
+
Paper: `Slowing Down the Weight Norm Increase in Momentum-based Optimizers` - https://arxiv.org/abs/2006.08217
|
|
5
|
+
Code: https://github.com/clovaai/AdamP
|
|
6
|
+
|
|
7
|
+
Copyright (c) 2020-present NAVER Corp.
|
|
8
|
+
MIT license
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import torch
|
|
12
|
+
import torch.nn.functional as F
|
|
13
|
+
from torch.optim.optimizer import Optimizer
|
|
14
|
+
import math
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _channel_view(x) -> torch.Tensor:
|
|
18
|
+
return x.reshape(x.size(0), -1)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _layer_view(x) -> torch.Tensor:
|
|
22
|
+
return x.reshape(1, -1)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def projection(p, grad, perturb, delta: float, wd_ratio: float, eps: float):
|
|
26
|
+
wd = 1.
|
|
27
|
+
expand_size = (-1,) + (1,) * (len(p.shape) - 1)
|
|
28
|
+
for view_func in [_channel_view, _layer_view]:
|
|
29
|
+
param_view = view_func(p)
|
|
30
|
+
grad_view = view_func(grad)
|
|
31
|
+
cosine_sim = F.cosine_similarity(grad_view, param_view, dim=1, eps=eps).abs_()
|
|
32
|
+
|
|
33
|
+
# FIXME this is a problem for PyTorch XLA
|
|
34
|
+
if cosine_sim.max() < delta / math.sqrt(param_view.size(1)):
|
|
35
|
+
p_n = p / param_view.norm(p=2, dim=1).add_(eps).reshape(expand_size)
|
|
36
|
+
perturb -= p_n * view_func(p_n * perturb).sum(dim=1).reshape(expand_size)
|
|
37
|
+
wd = wd_ratio
|
|
38
|
+
return perturb, wd
|
|
39
|
+
|
|
40
|
+
return perturb, wd
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class AdamP(Optimizer):
|
|
44
|
+
def __init__(self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8,
|
|
45
|
+
weight_decay=0, delta=0.1, wd_ratio=0.1, nesterov=False):
|
|
46
|
+
defaults = dict(
|
|
47
|
+
lr=lr, betas=betas, eps=eps, weight_decay=weight_decay,
|
|
48
|
+
delta=delta, wd_ratio=wd_ratio, nesterov=nesterov)
|
|
49
|
+
super(AdamP, self).__init__(params, defaults)
|
|
50
|
+
|
|
51
|
+
@torch.no_grad()
|
|
52
|
+
def step(self, closure=None):
|
|
53
|
+
loss = None
|
|
54
|
+
if closure is not None:
|
|
55
|
+
with torch.enable_grad():
|
|
56
|
+
loss = closure()
|
|
57
|
+
|
|
58
|
+
for group in self.param_groups:
|
|
59
|
+
for p in group['params']:
|
|
60
|
+
if p.grad is None:
|
|
61
|
+
continue
|
|
62
|
+
|
|
63
|
+
grad = p.grad
|
|
64
|
+
beta1, beta2 = group['betas']
|
|
65
|
+
nesterov = group['nesterov']
|
|
66
|
+
|
|
67
|
+
state = self.state[p]
|
|
68
|
+
|
|
69
|
+
# State initialization
|
|
70
|
+
if len(state) == 0:
|
|
71
|
+
state['step'] = 0
|
|
72
|
+
state['exp_avg'] = torch.zeros_like(p)
|
|
73
|
+
state['exp_avg_sq'] = torch.zeros_like(p)
|
|
74
|
+
|
|
75
|
+
# Adam
|
|
76
|
+
exp_avg, exp_avg_sq = state['exp_avg'], state['exp_avg_sq']
|
|
77
|
+
|
|
78
|
+
state['step'] += 1
|
|
79
|
+
bias_correction1 = 1 - beta1 ** state['step']
|
|
80
|
+
bias_correction2 = 1 - beta2 ** state['step']
|
|
81
|
+
|
|
82
|
+
exp_avg.mul_(beta1).add_(grad, alpha=1 - beta1)
|
|
83
|
+
exp_avg_sq.mul_(beta2).addcmul_(grad, grad, value=1 - beta2)
|
|
84
|
+
|
|
85
|
+
denom = (exp_avg_sq.sqrt() / math.sqrt(bias_correction2)).add_(group['eps'])
|
|
86
|
+
step_size = group['lr'] / bias_correction1
|
|
87
|
+
|
|
88
|
+
if nesterov:
|
|
89
|
+
perturb = (beta1 * exp_avg + (1 - beta1) * grad) / denom
|
|
90
|
+
else:
|
|
91
|
+
perturb = exp_avg / denom
|
|
92
|
+
|
|
93
|
+
# Projection
|
|
94
|
+
wd_ratio = 1.
|
|
95
|
+
if len(p.shape) > 1:
|
|
96
|
+
perturb, wd_ratio = projection(p, grad, perturb, group['delta'], group['wd_ratio'], group['eps'])
|
|
97
|
+
|
|
98
|
+
# Weight decay
|
|
99
|
+
if group['weight_decay'] > 0:
|
|
100
|
+
p.mul_(1. - group['lr'] * group['weight_decay'] * wd_ratio)
|
|
101
|
+
|
|
102
|
+
# Step
|
|
103
|
+
p.add_(perturb, alpha=-step_size)
|
|
104
|
+
|
|
105
|
+
return loss
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
""" AdamW Optimizer
|
|
2
|
+
Impl copied from PyTorch master
|
|
3
|
+
|
|
4
|
+
NOTE: Builtin optim.AdamW is used by the factory, this impl only serves as a Python based reference, will be removed
|
|
5
|
+
someday
|
|
6
|
+
"""
|
|
7
|
+
import math
|
|
8
|
+
import torch
|
|
9
|
+
from torch.optim.optimizer import Optimizer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AdamW(Optimizer):
|
|
13
|
+
r"""Implements AdamW algorithm.
|
|
14
|
+
|
|
15
|
+
The original Adam algorithm was proposed in `Adam: A Method for Stochastic Optimization`_.
|
|
16
|
+
The AdamW variant was proposed in `Decoupled Weight Decay Regularization`_.
|
|
17
|
+
|
|
18
|
+
Arguments:
|
|
19
|
+
params (iterable): iterable of parameters to optimize or dicts defining
|
|
20
|
+
parameter groups
|
|
21
|
+
lr (float, optional): learning rate (default: 1e-3)
|
|
22
|
+
betas (Tuple[float, float], optional): coefficients used for computing
|
|
23
|
+
running averages of gradient and its square (default: (0.9, 0.999))
|
|
24
|
+
eps (float, optional): term added to the denominator to improve
|
|
25
|
+
numerical stability (default: 1e-8)
|
|
26
|
+
weight_decay (float, optional): weight decay coefficient (default: 1e-2)
|
|
27
|
+
amsgrad (boolean, optional): whether to use the AMSGrad variant of this
|
|
28
|
+
algorithm from the paper `On the Convergence of Adam and Beyond`_
|
|
29
|
+
(default: False)
|
|
30
|
+
|
|
31
|
+
.. _Adam\: A Method for Stochastic Optimization:
|
|
32
|
+
https://arxiv.org/abs/1412.6980
|
|
33
|
+
.. _Decoupled Weight Decay Regularization:
|
|
34
|
+
https://arxiv.org/abs/1711.05101
|
|
35
|
+
.. _On the Convergence of Adam and Beyond:
|
|
36
|
+
https://openreview.net/forum?id=ryQu7f-RZ
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8,
|
|
40
|
+
weight_decay=1e-2, amsgrad=False):
|
|
41
|
+
if not 0.0 <= lr:
|
|
42
|
+
raise ValueError("Invalid learning rate: {}".format(lr))
|
|
43
|
+
if not 0.0 <= eps:
|
|
44
|
+
raise ValueError("Invalid epsilon value: {}".format(eps))
|
|
45
|
+
if not 0.0 <= betas[0] < 1.0:
|
|
46
|
+
raise ValueError("Invalid beta parameter at index 0: {}".format(betas[0]))
|
|
47
|
+
if not 0.0 <= betas[1] < 1.0:
|
|
48
|
+
raise ValueError("Invalid beta parameter at index 1: {}".format(betas[1]))
|
|
49
|
+
defaults = dict(lr=lr, betas=betas, eps=eps,
|
|
50
|
+
weight_decay=weight_decay, amsgrad=amsgrad)
|
|
51
|
+
super(AdamW, self).__init__(params, defaults)
|
|
52
|
+
|
|
53
|
+
def __setstate__(self, state):
|
|
54
|
+
super(AdamW, self).__setstate__(state)
|
|
55
|
+
for group in self.param_groups:
|
|
56
|
+
group.setdefault('amsgrad', False)
|
|
57
|
+
|
|
58
|
+
@torch.no_grad()
|
|
59
|
+
def step(self, closure=None):
|
|
60
|
+
"""Performs a single optimization step.
|
|
61
|
+
|
|
62
|
+
Arguments:
|
|
63
|
+
closure (callable, optional): A closure that reevaluates the model
|
|
64
|
+
and returns the loss.
|
|
65
|
+
"""
|
|
66
|
+
loss = None
|
|
67
|
+
if closure is not None:
|
|
68
|
+
with torch.enable_grad():
|
|
69
|
+
loss = closure()
|
|
70
|
+
|
|
71
|
+
for group in self.param_groups:
|
|
72
|
+
for p in group['params']:
|
|
73
|
+
if p.grad is None:
|
|
74
|
+
continue
|
|
75
|
+
|
|
76
|
+
# Perform stepweight decay
|
|
77
|
+
p.data.mul_(1 - group['lr'] * group['weight_decay'])
|
|
78
|
+
|
|
79
|
+
# Perform optimization step
|
|
80
|
+
grad = p.grad
|
|
81
|
+
if grad.is_sparse:
|
|
82
|
+
raise RuntimeError('Adam does not support sparse gradients, please consider SparseAdam instead')
|
|
83
|
+
amsgrad = group['amsgrad']
|
|
84
|
+
|
|
85
|
+
state = self.state[p]
|
|
86
|
+
|
|
87
|
+
# State initialization
|
|
88
|
+
if len(state) == 0:
|
|
89
|
+
state['step'] = 0
|
|
90
|
+
# Exponential moving average of gradient values
|
|
91
|
+
state['exp_avg'] = torch.zeros_like(p)
|
|
92
|
+
# Exponential moving average of squared gradient values
|
|
93
|
+
state['exp_avg_sq'] = torch.zeros_like(p)
|
|
94
|
+
if amsgrad:
|
|
95
|
+
# Maintains max of all exp. moving avg. of sq. grad. values
|
|
96
|
+
state['max_exp_avg_sq'] = torch.zeros_like(p)
|
|
97
|
+
|
|
98
|
+
exp_avg, exp_avg_sq = state['exp_avg'], state['exp_avg_sq']
|
|
99
|
+
if amsgrad:
|
|
100
|
+
max_exp_avg_sq = state['max_exp_avg_sq']
|
|
101
|
+
beta1, beta2 = group['betas']
|
|
102
|
+
|
|
103
|
+
state['step'] += 1
|
|
104
|
+
bias_correction1 = 1 - beta1 ** state['step']
|
|
105
|
+
bias_correction2 = 1 - beta2 ** state['step']
|
|
106
|
+
|
|
107
|
+
# Decay the first and second moment running average coefficient
|
|
108
|
+
exp_avg.mul_(beta1).add_(grad, alpha=1 - beta1)
|
|
109
|
+
exp_avg_sq.mul_(beta2).addcmul_(grad, grad, value=1 - beta2)
|
|
110
|
+
if amsgrad:
|
|
111
|
+
# Maintains the maximum of all 2nd moment running avg. till now
|
|
112
|
+
torch.max(max_exp_avg_sq, exp_avg_sq, out=max_exp_avg_sq)
|
|
113
|
+
# Use the max. for normalizing running avg. of gradient
|
|
114
|
+
denom = (max_exp_avg_sq.sqrt() / math.sqrt(bias_correction2)).add_(group['eps'])
|
|
115
|
+
else:
|
|
116
|
+
denom = (exp_avg_sq.sqrt() / math.sqrt(bias_correction2)).add_(group['eps'])
|
|
117
|
+
|
|
118
|
+
step_size = group['lr'] / bias_correction1
|
|
119
|
+
|
|
120
|
+
p.addcdiv_(exp_avg, denom, value=-step_size)
|
|
121
|
+
|
|
122
|
+
return loss
|