class_docstr: ModularTorchModel is a subclass of TorchModel that allows for components to be
  pretrained and then combined into a final model. It is designed to be subclassed
  for specific models and is not intended to be used directly. There are 3 main differences
  between ModularTorchModel and TorchModel:
  
  - The build_components() method is used to define the components of the model.
  - The components are combined into a final model with the build_model() method.
  - The loss function is defined with the loss_func method. This may access the
    components to compute the loss using intermediate values from the network, rather
    than just the full forward pass output.
  
  Here is an example of how to use ModularTorchModel to pretrain a linear layer, load
  it into another network and then finetune that network:
  
  >>> import numpy as np
  >>> import deepchem as dc
  >>> import torch
  >>> n_samples = 6
  >>> n_feat = 3
  >>> n_hidden = 2
  >>> n_tasks = 6
  >>> pt_tasks = 3
  >>> X = np.random.rand(n_samples, n_feat)
  >>> y_pretrain = np.zeros((n_samples, pt_tasks)).astype(np.float32)
  >>> dataset_pt = dc.data.NumpyDataset(X, y_pretrain)
  >>> y_finetune = np.zeros((n_samples, n_tasks)).astype(np.float32)
  >>> dataset_ft = dc.data.NumpyDataset(X, y_finetune)
  >>> components = {'linear': torch.nn.Linear(n_feat, n_hidden),
  ... 'activation': torch.nn.ReLU(), 'head': torch.nn.Linear(n_hidden, n_tasks)}
  >>> model = torch.nn.Sequential(components['linear'], components['activation'],
  ... components['head'])
  >>> modular_model = dc.models.torch_models.modular.ModularTorchModel(model, components)
  >>> def example_loss_func(inputs, labels, weights):
  ...    return (torch.nn.functional.mse_loss(model(inputs), labels[0]) * weights[0]).mean()
  >>> modular_model.loss_func = example_loss_func
  >>> def example_model_build():
  ...     return torch.nn.Sequential(components['linear'], components['activation'],
  ... components['head'])
  >>> modular_model.build_model = example_model_build
  >>> pretrain_components = {'linear': torch.nn.Linear(n_feat, n_hidden),
  ... 'activation': torch.nn.ReLU(), 'head': torch.nn.Linear(n_hidden, pt_tasks)}
  >>> pretrain_model = torch.nn.Sequential(pretrain_components['linear'],
  ... pretrain_components['activation'], pretrain_components['head'])
  >>> pretrain_modular_model = dc.models.torch_models.modular.ModularTorchModel(pretrain_model,
  ... pretrain_components)
  >>> def example_pt_loss_func(inputs, labels, weights):
  ...     return (torch.nn.functional.mse_loss(pretrain_model(inputs), labels[0]) * weights[0]).mean()
  >>> pretrain_modular_model.loss_func = example_pt_loss_func
  >>> pt_loss = pretrain_modular_model.fit(dataset_pt, nb_epoch=1)
  >>> modular_model.load_from_pretrained(pretrain_modular_model, components=['linear'])
  >>> ft_loss = modular_model.fit(dataset_ft, nb_epoch=1)
class_docstr_tok: ["ModularTorchModel","is","a","subclass","of","TorchModel","that","allows","for","components","to","be","pretrained","and","then","combined","into","a","final","model",".","It","is","designed","to","be","subclassed","for","specific","models","and","is","not","intended","to","be","used","directly",".","There","are","3","main","differences","between","ModularTorchModel","and","TorchModel",":","-","The","build_components","(",")","method","is","used","to","define","the","components","of","the","model",".","-","The","components","are","combined","into","a","final","model","with","the","build_model","(",")","method",".","-","The","loss","function","is","defined","with","the","loss_func","method",".","This","may","access","the","components","to","compute","the","loss","using","intermediate","values","from","the","network",",","rather","than","just","the","full","forward","pass","output",".","Here","is","an","example","of","how","to","use","ModularTorchModel","to","pretrain","a","linear","layer",",","load","it","into","another","network","and","then","finetune","that","network",":",">",">",">","import","numpy","as","np",">",">",">","import","deepchem","as","dc",">",">",">","import","torch",">",">",">","n_samples","=","6",">",">",">","n_feat","=","3",">",">",">","n_hidden","=","2",">",">",">","n_tasks","=","6",">",">",">","pt_tasks","=","3",">",">",">","X","=","np.random.rand","(","n_samples",",","n_feat",")",">",">",">","y_pretrain","=","np.zeros","(","(","n_samples",",","pt_tasks",")",")",".astype","(","np.float32",")",">",">",">","dataset_pt","=","dc.data.NumpyDataset","(","X",",","y_pretrain",")",">",">",">","y_finetune","=","np.zeros","(","(","n_samples",",","n_tasks",")",")",".astype","(","np.float32",")",">",">",">","dataset_ft","=","dc.data.NumpyDataset","(","X",",","y_finetune",")",">",">",">","components","=","{","'linear","'",":","torch.nn.Linear","(","n_feat",",","n_hidden",")",",","...","'activation","'",":","torch.nn.ReLU","(",")",",","'head","'",":","torch.nn.Linear","(","n_hidden",",","n_tasks",")","}",">",">",">","model","=","torch.nn.Sequential","(","components","[","'linear","'","]",",","components","[","'activation","'","]",",","...","components","[","'head","'","]",")",">",">",">","modular_model","=","dc.models.torch_models.modular.ModularTorchModel","(","model",",","components",")",">",">",">","def","example_loss_func","(","inputs",",","labels",",","weights",")",":","...","return","(","torch.nn.functional.mse_loss","(","model","(","inputs",")",",","labels","[","0","]",")","*","weights","[","0","]",")",".mean","(",")",">",">",">","modular_model.loss_func","=","example_loss_func",">",">",">","def","example_model_build","(",")",":","...","return","torch.nn.Sequential","(","components","[","'linear","'","]",",","components","[","'activation","'","]",",","...","components","[","'head","'","]",")",">",">",">","modular_model.build_model","=","example_model_build",">",">",">","pretrain_components","=","{","'linear","'",":","torch.nn.Linear","(","n_feat",",","n_hidden",")",",","...","'activation","'",":","torch.nn.ReLU","(",")",",","'head","'",":","torch.nn.Linear","(","n_hidden",",","pt_tasks",")","}",">",">",">","pretrain_model","=","torch.nn.Sequential","(","pretrain_components","[","'linear","'","]",",","...","pretrain_components","[","'activation","'","]",",","pretrain_components","[","'head","'","]",")",">",">",">","pretrain_modular_model","=","dc.models.torch_models.modular.ModularTorchModel","(","pretrain_model",",","...","pretrain_components",")",">",">",">","def","example_pt_loss_func","(","inputs",",","labels",",","weights",")",":","...","return","(","torch.nn.functional.mse_loss","(","pretrain_model","(","inputs",")",",","labels","[","0","]",")","*","weights","[","0","]",")",".mean","(",")",">",">",">","pretrain_modular_model.loss_func","=","example_pt_loss_func",">",">",">","pt_loss","=","pretrain_modular_model.fit","(","dataset_pt",",","nb_epoch=1",")",">",">",">","modular_model.load_from_pretrained","(","pretrain_modular_model",",","components=","[","'linear","'","]",")",">",">",">","ft_loss","=","modular_model.fit","(","dataset_ft",",","nb_epoch=1",")"]
docstr: Create a ModularTorchModel.
  
  Parameters
  ----------
  model: nn.Module
      The model to be trained.
  components: dict
      A dictionary of the components of the model. The keys are the names of the
      components and the values are the components themselves.
docstr_tok: ["Create","a","ModularTorchModel",".","Parameters","--","--","--","--","--","model",":","nn.Module","The","model","to","be","trained",".","components",":","dict","A","dictionary","of","the","components","of","the","model",".","The","keys","are","the","names","of","the","components","and","the","values","are","the","components","themselves","."]
code: def __init__(self, model: nn.Module, components: dict, **kwargs):
      """Create a ModularTorchModel.
  
      Parameters
      ----------
      model: nn.Module
          The model to be trained.
      components: dict
          A dictionary of the components of the model. The keys are the names of the
          components and the values are the components themselves.
      """
  
      self.model = model
      self.components = components
      # FIXME self.loss_func is an incorrect argument for TorchModel.loss because
      # it performs more than computing loss
      super().__init__(self.model, self.loss_func, **kwargs)
      self.model.to(self.device)
      self.components = {
          k: v.to(self.device) if isinstance(v, nn.Module) else v
          for k, v in self.components.items()
      }
  
imports: import time
  import logging
  import os
  from collections.abc import Sequence
  from typing import Any, Callable, Iterable, List, Optional, Tuple, Union, Sequence
  import torch
  import torch.nn
  from deepchem.models.torch_models.torch_model import TorchModel
  from deepchem.models.optimizers import LearningRateSchedule
  from deepchem.utils.typing import LossFn, OneOrMany
label_desc: Use image node_id 1 to create a new ModularTorchModel object from inherited base classes: TorchModel with example: obj = ModularTorchModel(model, components)