Spaces:
Paused
Paused
| from typing import Iterable | |
| import torch | |
| from torch import Tensor | |
| from chemprop.data import BatchMolGraph | |
| from chemprop.nn import MulticomponentMessagePassing, Aggregation, Predictor | |
| from chemprop.models.model import MPNN | |
| from chemprop.nn.metrics import Metric | |
| from chemprop.nn.transforms import ScaleTransform | |
| class MulticomponentMPNN(MPNN): | |
| def __init__( | |
| self, | |
| message_passing: MulticomponentMessagePassing, | |
| agg: Aggregation, | |
| predictor: Predictor, | |
| batch_norm: bool = True, | |
| metrics: Iterable[Metric] | None = None, | |
| warmup_epochs: int = 2, | |
| init_lr: float = 1e-4, | |
| max_lr: float = 1e-3, | |
| final_lr: float = 1e-4, | |
| X_d_transform: ScaleTransform | None = None, | |
| ): | |
| super().__init__( | |
| message_passing, | |
| agg, | |
| predictor, | |
| batch_norm, | |
| metrics, | |
| warmup_epochs, | |
| init_lr, | |
| max_lr, | |
| final_lr, | |
| X_d_transform, | |
| ) | |
| self.message_passing: MulticomponentMessagePassing | |
| def fingerprint( | |
| self, | |
| bmgs: Iterable[BatchMolGraph], | |
| V_ds: Iterable[Tensor | None], | |
| X_d: Tensor | None = None, | |
| ) -> Tensor: | |
| H_vs: list[Tensor] = self.message_passing(bmgs, V_ds) | |
| Hs = [self.agg(H_v, bmg.batch) for H_v, bmg in zip(H_vs, bmgs)] | |
| H = torch.cat(Hs, 1) | |
| H = self.bn(H) | |
| return H if X_d is None else torch.cat((H, self.X_d_transform(X_d)), 1) | |
| def load_submodules(cls, checkpoint_path, **kwargs): | |
| hparams = torch.load(checkpoint_path)["hyper_parameters"] | |
| hparams["message_passing"]["blocks"] = [ | |
| block_hparams.pop("cls")(**block_hparams) | |
| for block_hparams in hparams["message_passing"]["blocks"] | |
| ] | |
| kwargs |= { | |
| key: hparams[key].pop("cls")(**hparams[key]) | |
| for key in ("message_passing", "agg", "predictor") | |
| if key not in kwargs | |
| } | |
| return kwargs | |
| def load_from_file(cls, model_path, map_location=None, strict=True) -> MPNN: | |
| d = torch.load(model_path, map_location=map_location) | |
| try: | |
| hparams = d["hyper_parameters"] | |
| state_dict = d["state_dict"] | |
| except KeyError: | |
| raise KeyError(f"Could not find hyper parameters and/or state dict in {model_path}. ") | |
| for key in ["message_passing", "agg", "predictor"]: | |
| hparam_kwargs = hparams[key] | |
| if key == "message_passing": | |
| hparam_kwargs["blocks"] = [ | |
| block_hparams.pop("cls")(**block_hparams) | |
| for block_hparams in hparam_kwargs["blocks"] | |
| ] | |
| hparam_cls = hparam_kwargs.pop("cls") | |
| hparams[key] = hparam_cls(**hparam_kwargs) | |
| model = cls(**hparams) | |
| model.load_state_dict(state_dict, strict=strict) | |
| return model | |