-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathimtl_g.py
More file actions
55 lines (42 loc) · 1.63 KB
/
imtl_g.py
File metadata and controls
55 lines (42 loc) · 1.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import torch
from torch import Tensor
from .bases import _WeightedAggregator, _Weighting
class IMTLG(_WeightedAggregator):
"""
:class:`~torchjd.aggregation.bases.Aggregator` generalizing the method described in
`Towards Impartial Multi-task Learning <https://discovery.ucl.ac.uk/id/eprint/10120667/>`_.
This generalization, defined formally in `Jacobian Descent For Multi-Objective Optimization
<https://arxiv.org/pdf/2406.16232>`_, supports matrices with some linearly dependant rows.
.. admonition::
Example
Use IMTL-G to aggregate a matrix.
>>> from torch import tensor
>>> from torchjd.aggregation import IMTLG
>>>
>>> A = IMTLG()
>>> J = tensor([[-4., 1., 1.], [6., 1., 1.]])
>>>
>>> A(J)
tensor([0.0767, 1.0000, 1.0000])
"""
def __init__(self):
super().__init__(weighting=_IMTLGWeighting())
class _IMTLGWeighting(_Weighting):
"""
:class:`~torchjd.aggregation.bases._Weighting` that extracts weights as described in the
definition of A_IMTLG of `Jacobian Descent For Multi-Objective Optimization
<https://arxiv.org/pdf/2406.16232>`_.
"""
def forward(self, matrix: Tensor) -> Tensor:
gramian = matrix @ matrix.T
return self._compute_from_gramian(gramian)
@staticmethod
def _compute_from_gramian(gramian: Tensor) -> Tensor:
d = torch.sqrt(torch.diagonal(gramian))
v = torch.linalg.pinv(gramian) @ d
v_sum = v.sum()
if v_sum.abs() < 1e-12:
weights = torch.zeros_like(v)
else:
weights = v / v_sum
return weights