@@ -559,25 +559,20 @@ def update_metric_manager(
559559 """
560560 metric_manager .update (preds , target )
561561
562- def train_step (self , input : TorchInputType , target : TorchTargetType ) -> tuple [TrainingLosses , TorchPredType ]:
563- """
564- Given a single batch of input and target data, generate predictions, compute loss, update parameters and
565- optionally update metrics if they exist. (i.e. backprop on a single batch of data).
566- Assumes ``self.model`` is in train mode already.
562+ def _train_step (
563+ self , model : torch .nn .Module , optimizer : Optimizer , input : TorchInputType , target : TorchTargetType
564+ ) -> tuple [TrainingLosses , TorchPredType ]:
565+ """Helper train step.
567566
568- Args:
569- input (TorchInputType): The input to be fed into the model.
570- target (TorchTargetType): The target corresponding to the input.
571-
572- Returns:
573- tuple[TrainingLosses, TorchPredType]: The losses object from the train step along with
574- a dictionary of any predictions produced by the model.
567+ This interface allows for injection of model and optimizer params, which
568+ are useful for personalized FL methods.
575569 """
570+
576571 # Clear gradients from optimizer if they exist
577- self . optimizers [ "global" ] .zero_grad ()
572+ optimizer .zero_grad ()
578573
579574 # Call user defined methods to get predictions and compute loss
580- preds , features = self .predict ( input )
575+ preds , features = self ._predict ( model , input )
581576 target = self .transform_target (target )
582577 losses = self .compute_training_loss (preds , features , target )
583578
@@ -588,6 +583,22 @@ def train_step(self, input: TorchInputType, target: TorchTargetType) -> tuple[Tr
588583
589584 return losses , preds
590585
586+ def train_step (self , input : TorchInputType , target : TorchTargetType ) -> tuple [TrainingLosses , TorchPredType ]:
587+ """
588+ Given a single batch of input and target data, generate predictions, compute loss, update parameters and
589+ optionally update metrics if they exist. (i.e. backprop on a single batch of data).
590+ Assumes ``self.model`` is in train mode already.
591+
592+ Args:
593+ input (TorchInputType): The input to be fed into the model.
594+ target (TorchTargetType): The target corresponding to the input.
595+
596+ Returns:
597+ tuple[TrainingLosses, TorchPredType]: The losses object from the train step along with
598+ a dictionary of any predictions produced by the model.
599+ """
600+ return self ._train_step (self .model , self .optimizers ["global" ], input , target )
601+
591602 def val_step (self , input : TorchInputType , target : TorchTargetType ) -> tuple [EvaluationLosses , TorchPredType ]:
592603 """
593604 Given input and target, compute loss, update loss and metrics. Assumes ``self.model`` is in eval mode already.
@@ -975,34 +986,19 @@ def get_parameter_exchanger(self, config: Config) -> ParameterExchanger:
975986 """
976987 return FullParameterExchanger ()
977988
978- def predict (self , input : TorchInputType ) -> tuple [TorchPredType , TorchFeatureType ]:
979- """
980- Computes the prediction(s), and potentially features, of the model(s) given the input.
981-
982- Args:
983- input (TorchInputType): Inputs to be fed into the model. If input is of type ``dict[str, torch.Tensor]``,
984- it is assumed that the keys of input match the names of the keyword arguments of
985- ``self.model.forward().``
986-
987- Returns:
988- tuple[TorchPredType, TorchFeatureType]: A tuple in which the first element contains a dictionary of
989- predictions indexed by name and the second element contains intermediate activations indexed by name. By
990- passing features, we can compute losses such as the contrastive loss in MOON. All predictions included in
991- dictionary will by default be used to compute metrics separately.
989+ def _predict (self , model : torch .nn .Module , input : TorchInputType ) -> tuple [TorchPredType , TorchFeatureType ]:
990+ """Helper predict method.
992991
993- Raises:
994- TypeError: Occurs when something other than a tensor or dict of tensors is passed in to the model's
995- forward method.
996- ValueError: Occurs when something other than a tensor or dict of tensors is returned by the model
997- forward.
992+ Unlike, predict(), this interface allows for injecting the model param.
998993 """
994+
999995 if isinstance (input , torch .Tensor ):
1000- output = self . model (input )
996+ output = model (input )
1001997 elif isinstance (input , dict ):
1002998 # If input is a dictionary, then we unpack it before computing the forward pass.
1003999 # Note that this assumes the keys of the input match (exactly) the keyword args
10041000 # of self.model.forward().
1005- output = self . model (** input )
1001+ output = model (** input )
10061002 else :
10071003 raise TypeError ("'input' must be of type torch.Tensor or dict[str, torch.Tensor]." )
10081004
@@ -1018,6 +1014,29 @@ def predict(self, input: TorchInputType) -> tuple[TorchPredType, TorchFeatureTyp
10181014 else :
10191015 raise ValueError ("Model forward did not return a tensor, dictionary of tensors, or tuple of tensors" )
10201016
1017+ def predict (self , input : TorchInputType ) -> tuple [TorchPredType , TorchFeatureType ]:
1018+ """
1019+ Computes the prediction(s), and potentially features, of the model(s) given the input.
1020+
1021+ Args:
1022+ input (TorchInputType): Inputs to be fed into the model. If input is of type ``dict[str, torch.Tensor]``,
1023+ it is assumed that the keys of input match the names of the keyword arguments of
1024+ ``self.model.forward().``
1025+
1026+ Returns:
1027+ tuple[TorchPredType, TorchFeatureType]: A tuple in which the first element contains a dictionary of
1028+ predictions indexed by name and the second element contains intermediate activations indexed by name. By
1029+ passing features, we can compute losses such as the contrastive loss in MOON. All predictions included in
1030+ dictionary will by default be used to compute metrics separately.
1031+
1032+ Raises:
1033+ TypeError: Occurs when something other than a tensor or dict of tensors is passed in to the model's
1034+ forward method.
1035+ ValueError: Occurs when something other than a tensor or dict of tensors is returned by the model
1036+ forward.
1037+ """
1038+ return self ._predict (self .model , input )
1039+
10211040 def compute_loss_and_additional_losses (
10221041 self , preds : TorchPredType , features : TorchFeatureType , target : TorchTargetType
10231042 ) -> tuple [torch .Tensor , dict [str , torch .Tensor ] | None ]:
@@ -1280,6 +1299,15 @@ def update_before_epoch(self, epoch: int) -> None:
12801299 """
12811300 pass
12821301
1302+ def _transform_gradients (self , model : torch .nn .Module , losses : TrainingLosses ) -> None :
1303+ """
1304+ Helper transform gradients method.
1305+
1306+ Unlike transform_gradients(), this helper's interface allows for injecting
1307+ model as a param.
1308+ """
1309+ pass
1310+
12831311 def transform_gradients (self , losses : TrainingLosses ) -> None :
12841312 """
12851313 Hook function for model training only called after backwards pass but before optimizer step. Useful for
@@ -1288,7 +1316,7 @@ def transform_gradients(self, losses: TrainingLosses) -> None:
12881316 Args:
12891317 losses (TrainingLosses): The losses object from the train step
12901318 """
1291- pass
1319+ return self . _transform_gradients ( self . model , losses )
12921320
12931321 def _save_client_state (self ) -> None :
12941322 """
0 commit comments