r"""Clips gradient norm of an iterable of parameters. The norm is computed over all gradients together, as if they were concatenated into a single vector. Gradients are modified in-place. Args: tensors: an iterable of Tensors or a single Tensor that will have gradients normalize
(
tensors: Union[Tensor, Iterable[Tensor]], max_norm: float, ord: float = 2.0,
)
| 10 | |
| 11 | |
| 12 | def clip_grad_norm( |
| 13 | tensors: Union[Tensor, Iterable[Tensor]], max_norm: float, ord: float = 2.0, |
| 14 | ): |
| 15 | r"""Clips gradient norm of an iterable of parameters. |
| 16 | The norm is computed over all gradients together, as if they were |
| 17 | concatenated into a single vector. Gradients are modified in-place. |
| 18 | |
| 19 | Args: |
| 20 | tensors: an iterable of Tensors or a single Tensor that will have gradients normalized. |
| 21 | max_norm: max norm of the gradients. |
| 22 | ord: type of the used p-norm. Can be ``'inf'`` for infinity norm. Default: 2.0 |
| 23 | |
| 24 | Returns: |
| 25 | Return type: Tensor of an iterable of Tensors. Total norm of the parameter gradients (viewed as a single vector). |
| 26 | |
| 27 | Examples: |
| 28 | >>> import megengine.optimizer as optim |
| 29 | >>> net = Net() # doctest: +SKIP |
| 30 | >>> original_norm = optim.clip_grad_norm(net.parameters(), max_norm=1.0, ord=2) # doctest: +SKIP |
| 31 | """ |
| 32 | push_scope("clip_grad_norm") |
| 33 | if isinstance(tensors, Tensor): |
| 34 | tensors = [tensors] |
| 35 | tensors = [t for t in tensors if t.grad is not None] |
| 36 | if len(tensors) == 0: |
| 37 | pop_scope("clip_grad_norm") |
| 38 | return Tensor(0.0) |
| 39 | norm_ = [norm(t.grad.flatten(), ord=ord) for t in tensors] |
| 40 | if len(norm_) > 1: |
| 41 | norm_ = norm(concat(norm_), ord=ord) |
| 42 | else: |
| 43 | norm_ = norm_[0] |
| 44 | scale = max_norm / (norm_ + 1e-6) |
| 45 | scale = minimum(scale, 1) |
| 46 | for tensor in tensors: |
| 47 | tensor.grad._reset(tensor.grad * scale) |
| 48 | pop_scope("clip_grad_norm") |
| 49 | return norm_ |
| 50 | |
| 51 | |
| 52 | def clip_grad_value( |