Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6b8ee39
Create _test_time.py
Jun 10, 2025
cd13eed
removed unnecessary clauses in TestTimeCriterion
Jun 11, 2025
d0ee0a3
added tests for TestTimeNet
Jun 12, 2025
32aec72
Corrected wrong attribute call
Jun 12, 2025
c23e8f2
fixed wrong dataloader in test
Jun 12, 2025
a3c0ced
remade tests, improved TestTimeNet
Jun 12, 2025
28ce3f3
Updated tests
Jun 12, 2025
e81a62e
added softmax_entropy, added foundation of Tent
Jun 13, 2025
4c76ba4
Updated Tent
Jun 16, 2025
aab0c09
added Tent, param freeze
Jun 24, 2025
44b2df9
Merge branch 'main' into mbarneche-tent
mbarneche Jun 24, 2025
616cc29
changed None to all to adapt all params
Jun 24, 2025
26840fd
Merge branch 'mbarneche-tent' of https://github.com/mbarneche/skada i…
Jun 24, 2025
b4c1841
Add shot loss
marionpavaux Jun 24, 2025
8bacda4
Merge branch 'mbarneche-tent' of https://github.com/mbarneche/skada i…
marionpavaux Jun 24, 2025
1f52a1b
Add reference for shot loss
marionpavaux Jun 24, 2025
bc37c6e
Implement SHOT model
FDerrida Jun 24, 2025
5a71c1d
Merge branch 'mbarneche-tent' of github.com:mbarneche/skada into mbar…
FDerrida Jun 24, 2025
6d34ed8
Add estimated labels
marionpavaux Jun 24, 2025
0c0dfae
Merge branch 'mbarneche-tent' of https://github.com/mbarneche/skada i…
marionpavaux Jun 24, 2025
1e501b8
Merge branch 'main' into mbarneche-tent
tgnassou Jun 25, 2025
7b17529
Add example for test time
marionpavaux Jun 25, 2025
62d86db
Add example for test time
marionpavaux Jun 25, 2025
d29d299
Add shot implementation and PseudoLabels class
FDerrida Jun 25, 2025
65c60d3
Merge branch 'mbarneche-tent' of github.com:mbarneche/skada into mbar…
FDerrida Jun 25, 2025
d103ef8
Adapt estimated labels to callbacks
marionpavaux Jun 25, 2025
96717f7
Merge branch 'main' into mbarneche-tent
tgnassou Sep 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions skada/deep/_test_time.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Author : Maxence Barneche
#
# License: BSD-3-Clause

import torch

from skada.deep.base import DomainAwareNet


class TestTimeCriterion(torch.nn.Module):
def __init__(
self,
base_criterion,
adapt_criterion,
reg=1,
reduction="mean",
train_on_target=False,
):
super().__init__()
self.base_criterion = base_criterion
self.adapt_criterion = adapt_criterion
self.reg = reg
self.train_on_target = train_on_target

# Update the reduce parameter for both criteria if specified
if hasattr(self.base_criterion, "reduction"):
self.base_criterion.reduction = reduction

# TODO: implement losses between source and target
# that are sum of the losses of each sample
# if hasattr(self.adapt_criterion, 'reduction'):
# self.adapt_criterion.reduction = reduction

def forward(
self,
y_pred,
y_true,
):
"""
Parameters
----------
y_pred : tuple
This tuple comprises all the different data
needed to compute DA loss:
- y_pred : prediction of the source and target domains
- domain_pred : prediction of domain classifier if given
- features : features of the chosen layer
of source and target domains
- sample_domain : giving the domain of each samples
y_true :
The true labels. Available for source, masked for target.
"""
y_pred, domain_pred, features, _, sample_idx = y_pred

if self.train_on_target:
Comment thread
tgnassou marked this conversation as resolved.
# In finetune mode, we only compute the base loss
return self.base_criterion(y_pred, y_true)
else:
# In adapt mode, we compute the adaptation loss
return self.adapt_criterion(
y_s=y_true,
y_pred=y_pred,
domain_pred=domain_pred,
features=features,
sample_idx=sample_idx,
)


class TestTimeNet(DomainAwareNet):
def __init__(self, module, criterion: "TestTimeCriterion", **kwargs):
super().__init__(module, criterion=criterion, **kwargs)

def fit_prepare(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not fan of fit_prepare but I don't have other chouchou for now

self, X, y=None, sample_domain=None, sample_weight=None, **fit_params
):
X = self._prepare_input(X, y, sample_domain, sample_weight)
X = X.select_source()
temp = self.criterion.train_on_target
self.criterion.train_on_target = False
self.partial_fit(X, None, **fit_params)
self.criterion.train_on_target = temp
return self

def fit_adapt(self, X, sample_domain=None, sample_weight=None, **fit_params):
if sample_domain is None:
sample_domain = -1
X = self._prepare_input(X, None, sample_domain, sample_weight)
X = X.select_target()
temp = self.criterion.train_on_target
self.criterion.train_on_target = True
self.partial_fit(X, None, **fit_params)
self.criterion.train_on_target = temp

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get this temp parameters

return self

def fit(self, X, y=None, sample_domain=None, sample_weight=None, **fit_params):
X = self._prepare_input(X, y, sample_domain, sample_weight)
self.fit_prepare(X, **fit_params)
self.fit_adapt(X, **fit_params)
return self
41 changes: 41 additions & 0 deletions skada/deep/tests/test_test_time.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Author : Maxence Barneche
#
# License: BSD-3-Clause

import pytest

torch = pytest.importorskip("torch")

from torch.utils.data import DataLoader

from skada.datasets import make_shifted_datasets
from skada.deep._test_time import TestTimeCriterion, TestTimeNet
from skada.deep.base import DomainAwareModule
from skada.deep.losses import TestLoss
from skada.deep.modules import ToyModule2D


def test_test_time_criterion():
num_features = 10
module = ToyModule2D(num_features=num_features)
criterion = TestTimeCriterion(torch.nn.CrossEntropyLoss(), TestLoss())

n_samples = 20
dataset = make_shifted_datasets(
n_samples_source=n_samples,
n_samples_target=n_samples,
shift="conditional_shift",
noise=0.1,
random_state=42,
)
X, y, sample_domain = dataset
method = TestTimeNet(
DomainAwareModule(module, "dropout"),
iterator_train=DataLoader,
criterion=criterion,
batch_size=10,
max_epochs=2,
train_split=None,
)

method.fit(X, y, sample_domain)