Skip to content

Commit eeff844

Browse files
ValerianReyclaude
andauthored
feat(aggregation): Make Aggregator and Weighting subclasses public (#670)
* Export `WeightedAggregator`, `GramianWeightedAggregator`, `MatrixWeighting`, and `GramianWeighting` from `torchjd.aggregation` (added to `__all__` and documented in `index.rst`) * Update all aggregator and weighting docstrings to reference the most specific public base class (e.g. `GramianWeightedAggregator` instead of `Aggregator`, `GramianWeighting` instead of `Weighting`) * Update internal imports that used the private `_aggregator_bases` path to use the public `torchjd.aggregation` path * Make the combine method protected * Add changelog entry Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 59795e2 commit eeff844

23 files changed

Lines changed: 85 additions & 61 deletions

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ changelog does not include internal changes that do not affect the user.
1010

1111
### Added
1212

13+
- Made `WeightedAggregator`, `GramianWeightedAggregator`, `MatrixWeighting`, and `GramianWeighting`
14+
public. These abstract base classes are now importable from `torchjd.aggregation` and documented.
1315
- Added getters and setters for the constructor parameters of all aggregators and weightings, so
1416
that they can be changed after initialization. This includes: `pref_vector`,
1517
`norm_eps` and `reg_eps` in `UPGrad`, `UPGradWeighting`, `DualProj` and `DualProjWeighting`;

docs/source/docs/aggregation/index.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,21 @@ Abstract base classes
1010
.. autoclass:: torchjd.aggregation.Aggregator
1111
:members: __call__
1212

13+
.. autoclass:: torchjd.aggregation.WeightedAggregator
14+
:members: __call__
15+
16+
.. autoclass:: torchjd.aggregation.GramianWeightedAggregator
17+
:members: __call__
18+
1319
.. autoclass:: torchjd.aggregation.Weighting
1420
:members: __call__
1521

22+
.. autoclass:: torchjd.aggregation.MatrixWeighting
23+
:members: __call__
24+
25+
.. autoclass:: torchjd.aggregation.GramianWeighting
26+
:members: __call__
27+
1628
.. autoclass:: torchjd.aggregation.GeneralizedWeighting
1729
:members: __call__
1830

src/torchjd/aggregation/__init__.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
r"""
22
When doing Jacobian descent, the Jacobian matrix has to be aggregated into a vector to store in the
33
``.grad`` fields of the model parameters. The
4-
:class:`~torchjd.aggregation._aggregator_bases.Aggregator` is responsible for these aggregations.
4+
:class:`~torchjd.aggregation.Aggregator` is responsible for these aggregations.
55
66
When using the :doc:`autogram <../autogram/index>` engine, we rather need to extract a vector
77
of weights from the Gramian of the Jacobian. The
8-
:class:`~torchjd.aggregation._weighting_bases.Weighting` is responsible for this.
8+
:class:`~torchjd.aggregation.Weighting` is responsible for this.
99
1010
.. note::
1111
Most aggregators rely on computing the Gramian of the Jacobian, extracting a vector of weights
12-
from this Gramian using a :class:`~torchjd.aggregation._weighting_bases.Weighting`, and then
13-
combining the rows of the Jacobian using these weights. For all of them, we provide both the
14-
:class:`~torchjd.aggregation._aggregator_bases.Aggregator` interface (to be used in autojac) and
15-
the :class:`~torchjd.aggregation._weighting_bases.Weighting` interface (to be used in autogram).
16-
For the rest, we only provide the :class:`~torchjd.aggregation._aggregator_bases.Aggregator`
12+
from this Gramian using a :class:`~torchjd.aggregation.GramianWeighting`, and then combining the
13+
rows of the Jacobian using these weights. For all of them, we provide both the
14+
:class:`~torchjd.aggregation.Aggregator` interface (to be used in autojac) and the
15+
:class:`~torchjd.aggregation.Weighting` interface (to be used in autogram).
16+
For the rest, we only provide the :class:`~torchjd.aggregation.Aggregator`
1717
interface -- they are not compatible with autogram.
1818
19-
:class:`Aggregators <torchjd.aggregation._aggregator_bases.Aggregator>` and :class:`Weightings
20-
<torchjd.aggregation._weighting_bases.Weighting>` are callables that take a Jacobian matrix or a
19+
:class:`Aggregators <torchjd.aggregation.Aggregator>` and
20+
:class:`Weightings <torchjd.aggregation.Weighting>` are callables that take a Jacobian matrix or a
2121
Gramian matrix as inputs, respectively. The following example shows how to use UPGrad to either
2222
aggregate a Jacobian (of shape ``[m, n]``, where ``m`` is the number of objectives and ``n`` is the
2323
number of parameters), or obtain the weights from the Gramian of the Jacobian (of shape ``[m, m]``).
@@ -39,10 +39,10 @@
3939
When dealing with a more general tensor of objectives, of shape ``[m_1, ..., m_k]`` (i.e. not
4040
necessarily a simple vector), the Jacobian will be of shape ``[m_1, ..., m_k, n]``, and its Gramian
4141
will be called a `generalized Gramian`, of shape ``[m_1, ..., m_k, m_k, ..., m_1]``. One can use a
42-
:class:`GeneralizedWeighting<torchjd.aggregation._weighting_bases.GeneralizedWeighting>` to extract
42+
:class:`GeneralizedWeighting<torchjd.aggregation.GeneralizedWeighting>` to extract
4343
a tensor of weights (of shape ``[m_1, ..., m_k]``) from such a generalized Gramian. The simplest
44-
:class:`GeneralizedWeighting<torchjd.aggregation._weighting_bases.GeneralizedWeighting>` is
45-
:class:`Flattening<torchjd.aggregation._flattening.Flattening>`: it simply "flattens" the
44+
:class:`GeneralizedWeighting<torchjd.aggregation.GeneralizedWeighting>` is
45+
:class:`Flattening<torchjd.aggregation.Flattening>`: it simply "flattens" the
4646
generalized Gramian into a square Gramian matrix (of shape ``[m_1 * ... * m_k, m_1 * ... * m_k]``),
4747
applies a normal weighting to it to obtain a vector of weights, and returns the reshaped tensor of
4848
weights.
@@ -59,7 +59,7 @@
5959
[0.1667, 0.1667, 0.1667]])
6060
"""
6161

62-
from ._aggregator_bases import Aggregator
62+
from ._aggregator_bases import Aggregator, GramianWeightedAggregator, WeightedAggregator
6363
from ._aligned_mtl import AlignedMTL, AlignedMTLWeighting
6464
from ._config import ConFIG
6565
from ._constant import Constant, ConstantWeighting
@@ -80,7 +80,7 @@
8080
from ._utils.check_dependencies import (
8181
OptionalDepsNotInstalledError as _OptionalDepsNotInstalledError,
8282
)
83-
from ._weighting_bases import GeneralizedWeighting, Weighting
83+
from ._weighting_bases import GeneralizedWeighting, GramianWeighting, MatrixWeighting, Weighting
8484

8585
__all__ = [
8686
"Aggregator",
@@ -96,10 +96,13 @@
9696
"GradDrop",
9797
"GradVac",
9898
"GradVacWeighting",
99+
"GramianWeightedAggregator",
100+
"GramianWeighting",
99101
"IMTLG",
100102
"IMTLGWeighting",
101103
"Krum",
102104
"KrumWeighting",
105+
"MatrixWeighting",
103106
"Mean",
104107
"MeanWeighting",
105108
"MGDA",
@@ -114,6 +117,7 @@
114117
"TrimmedMean",
115118
"UPGrad",
116119
"UPGradWeighting",
120+
"WeightedAggregator",
117121
"Weighting",
118122
]
119123

src/torchjd/aggregation/_aggregator_bases.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from abc import ABC, abstractmethod
2+
from typing import cast
23

34
from torch import Tensor, nn
45

5-
from torchjd._linalg import Matrix, PSDMatrix, compute_gramian, is_matrix
6+
from torchjd._linalg import Matrix, compute_gramian, is_matrix
67

7-
from ._weighting_bases import Weighting
8+
from ._weighting_bases import GramianWeighting, MatrixWeighting
89

910

1011
class Aggregator(nn.Module, ABC):
@@ -46,18 +47,18 @@ def __str__(self) -> str:
4647

4748
class WeightedAggregator(Aggregator):
4849
"""
49-
Aggregator that combines the rows of the input jacobian matrix with weights given by applying a
50-
Weighting to it.
50+
Aggregator that combines the rows of the input Jacobian matrix with weights given by applying a
51+
:class:`~torchjd.aggregation.MatrixWeighting` to it.
5152
5253
:param weighting: The object responsible for extracting the vector of weights from the matrix.
5354
"""
5455

55-
def __init__(self, weighting: Weighting[Matrix]) -> None:
56+
def __init__(self, weighting: MatrixWeighting) -> None:
5657
super().__init__()
5758
self.weighting = weighting
5859

5960
@staticmethod
60-
def combine(matrix: Matrix, weights: Tensor) -> Tensor:
61+
def _combine(matrix: Matrix, weights: Tensor) -> Tensor:
6162
"""
6263
Aggregates a matrix by making a linear combination of its rows, using the provided vector of
6364
weights.
@@ -68,19 +69,19 @@ def combine(matrix: Matrix, weights: Tensor) -> Tensor:
6869

6970
def forward(self, matrix: Matrix, /) -> Tensor:
7071
weights = self.weighting(matrix)
71-
vector = self.combine(matrix, weights)
72+
vector = self._combine(matrix, weights)
7273
return vector
7374

7475

7576
class GramianWeightedAggregator(WeightedAggregator):
7677
"""
77-
WeightedAggregator that computes the gramian of the input jacobian matrix before applying a
78-
Weighting to it.
78+
:class:`~torchjd.aggregation.WeightedAggregator` that computes the gramian of the input
79+
Jacobian matrix before applying a :class:`~torchjd.aggregation.GramianWeighting` to it.
7980
8081
:param gramian_weighting: The object responsible for extracting the vector of weights from the
8182
gramian.
8283
"""
8384

84-
def __init__(self, gramian_weighting: Weighting[PSDMatrix]) -> None:
85-
super().__init__(gramian_weighting << compute_gramian)
85+
def __init__(self, gramian_weighting: GramianWeighting) -> None:
86+
super().__init__(cast(MatrixWeighting, gramian_weighting << compute_gramian))
8687
self.gramian_weighting = gramian_weighting

src/torchjd/aggregation/_aligned_mtl.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
class AlignedMTLWeighting(GramianWeighting):
2121
r"""
22-
:class:`~torchjd.aggregation._weighting_bases.Weighting` giving the weights of
22+
:class:`~torchjd.aggregation.GramianWeighting` giving the weights of
2323
:class:`~torchjd.aggregation.AlignedMTL`.
2424
2525
:param pref_vector: The preference vector to use. If not provided, defaults to
@@ -89,7 +89,7 @@ def _compute_balance_transformation(
8989

9090
class AlignedMTL(GramianWeightedAggregator):
9191
r"""
92-
:class:`~torchjd.aggregation._aggregator_bases.Aggregator` as defined in Algorithm 1 of
92+
:class:`~torchjd.aggregation.GramianWeightedAggregator` as defined in Algorithm 1 of
9393
`Independent Component Alignment for Multi-Task Learning
9494
<https://openaccess.thecvf.com/content/CVPR2023/papers/Senushkin_Independent_Component_Alignment_for_Multi-Task_Learning_CVPR_2023_paper.pdf>`_.
9595

src/torchjd/aggregation/_cagrad.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
class CAGradWeighting(GramianWeighting):
2222
"""
23-
:class:`~torchjd.aggregation._weighting_bases.Weighting` giving the weights of
23+
:class:`~torchjd.aggregation.GramianWeighting` giving the weights of
2424
:class:`~torchjd.aggregation.CAGrad`.
2525
2626
:param c: The scale of the radius of the ball constraint.
@@ -94,7 +94,7 @@ def norm_eps(self, value: float) -> None:
9494

9595
class CAGrad(GramianWeightedAggregator):
9696
"""
97-
:class:`~torchjd.aggregation._aggregator_bases.Aggregator` as defined in Algorithm 1 of
97+
:class:`~torchjd.aggregation.GramianWeightedAggregator` as defined in Algorithm 1 of
9898
`Conflict-Averse Gradient Descent for Multi-task Learning
9999
<https://arxiv.org/pdf/2110.14048.pdf>`_.
100100

src/torchjd/aggregation/_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
class ConFIG(Aggregator):
1717
"""
18-
:class:`~torchjd.aggregation._aggregator_bases.Aggregator` as defined in Equation 2 of `ConFIG:
18+
:class:`~torchjd.aggregation.Aggregator` as defined in Equation 2 of `ConFIG:
1919
Towards Conflict-free Training of Physics Informed Neural Networks
2020
<https://arxiv.org/pdf/2408.11104>`_.
2121

src/torchjd/aggregation/_constant.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
class ConstantWeighting(MatrixWeighting):
99
"""
10-
:class:`~torchjd.aggregation._weighting_bases.Weighting` that returns constant, pre-determined
10+
:class:`~torchjd.aggregation.MatrixWeighting` that returns constant, pre-determined
1111
weights.
1212
1313
:param weights: The weights to return at each call.
@@ -37,7 +37,7 @@ def _check_matrix_shape(self, matrix: Tensor) -> None:
3737

3838
class Constant(WeightedAggregator):
3939
"""
40-
:class:`~torchjd.aggregation._aggregator_bases.Aggregator` that makes a linear combination of
40+
:class:`~torchjd.aggregation.WeightedAggregator` that makes a linear combination of
4141
the rows of the provided matrix, with constant, pre-determined weights.
4242
4343
:param weights: The weights associated to the rows of the input matrices.

src/torchjd/aggregation/_dualproj.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
class DualProjWeighting(GramianWeighting):
1414
r"""
15-
:class:`~torchjd.aggregation._weighting_bases.Weighting` giving the weights of
15+
:class:`~torchjd.aggregation.GramianWeighting` giving the weights of
1616
:class:`~torchjd.aggregation.DualProj`.
1717
1818
:param pref_vector: The preference vector to use. If not provided, defaults to
@@ -78,7 +78,7 @@ def reg_eps(self, value: float) -> None:
7878

7979
class DualProj(GramianWeightedAggregator):
8080
r"""
81-
:class:`~torchjd.aggregation._aggregator_bases.Aggregator` that averages the rows of the input
81+
:class:`~torchjd.aggregation.GramianWeightedAggregator` that averages the rows of the input
8282
matrix, and projects the result onto the dual cone of the rows of the matrix. This corresponds
8383
to the solution to Equation 11 of `Gradient Episodic Memory for Continual Learning
8484
<https://proceedings.neurips.cc/paper/2017/file/f87522788a2be2d171666752f97ddebb-Paper.pdf>`_.

src/torchjd/aggregation/_graddrop.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def _identity(P: Tensor) -> Tensor:
1515

1616
class GradDrop(Aggregator):
1717
"""
18-
:class:`~torchjd.aggregation._aggregator_bases.Aggregator` that applies the gradient combination
18+
:class:`~torchjd.aggregation.Aggregator` that applies the gradient combination
1919
steps from GradDrop, as defined in lines 10 to 15 of Algorithm 1 of `Just Pick a Sign:
2020
Optimizing Deep Multitask Models with Gradient Sign Dropout
2121
<https://arxiv.org/pdf/2010.06808.pdf>`_.

0 commit comments

Comments
 (0)