class_docstr: Implements the Model-Agnostic Meta-Learning algorithm for low data learning.
  
  The algorithm is described in Finn et al., "Model-Agnostic Meta-Learning for Fast
  Adaptation of Deep Networks" (https://arxiv.org/abs/1703.03400).  It is used for
  training models that can perform a variety of tasks, depending on what data they
  are trained on.  It assumes you have training data for many tasks, but only a small
  amount for each one.  It performs "meta-learning" by looping over tasks and trying
  to minimize the loss on each one *after* one or a few steps of gradient descent.
  That is, it does not try to create a model that can directly solve the tasks, but
  rather tries to create a model that is very easy to train.
  
  To use this class, create a subclass of MetaLearner that encapsulates the model
  and data for your learning problem.  Pass it to a MAML object and call fit().
  You can then use train_on_current_task() to fine tune the model for a particular
  task.
  Example
  --------
  >>> import deepchem as dc
  >>> import numpy as np
  >>> import torch
  >>> import torch.nn.functional as F
  >>> from deepchem.metalearning.torch_maml import MetaLearner, MAML
  >>> class SineLearner(MetaLearner):
  ...     def __init__(self):
  ...         self.batch_size = 10
  ...         self.w1 = torch.nn.Parameter(torch.tensor(np.random.normal(size=[1, 40], scale=1.0),requires_grad=True))
  ...         self.w2 = torch.nn.Parameter(torch.tensor(np.random.normal(size=[40, 40], scale=np.sqrt(1 / 40)),requires_grad=True))
  ...         self.w3 = torch.nn.Parameter(torch.tensor(np.random.normal(size=[40, 1], scale=np.sqrt(1 / 40)),requires_grad=True))
  ...         self.b1 = torch.nn.Parameter(torch.tensor(np.zeros(40)),requires_grad=True)
  ...         self.b2 = torch.nn.Parameter(torch.tensor(np.zeros(40)),requires_grad=True)
  ...         self.b3 = torch.nn.Parameter(torch.tensor(np.zeros(1)),requires_grad=True)
  ...     def compute_model(self, inputs, variables, training):
  ...         x, y = inputs
  ...         w1, w2, w3, b1, b2, b3 = variables
  ...         dense1 = F.relu(torch.matmul(x, w1) + b1)
  ...         dense2 = F.relu(torch.matmul(dense1, w2) + b2)
  ...         output = torch.matmul(dense2, w3) + b3
  ...         loss = torch.mean(torch.square(output - y))
  ...         return loss, [output]
  ...     @property
  ...     def variables(self):
  ...         return [self.w1, self.w2, self.w3, self.b1, self.b2, self.b3]
  ...     def select_task(self):
  ...         self.amplitude = 5.0 * np.random.random()
  ...         self.phase = np.pi * np.random.random()
  ...     def get_batch(self):
  ...         x = torch.tensor(np.random.uniform(-5.0, 5.0, (self.batch_size, 1)))
  ...         return [x, torch.tensor(self.amplitude * np.sin(x + self.phase))]
  ...     def parameters(self):
  ...         for key, value in self.__dict__.items():
  ...             if isinstance(value, torch.nn.Parameter):
  ...                 yield value
  >>> learner = SineLearner()
  >>> optimizer = dc.models.optimizers.Adam(learning_rate=5e-3)
  >>> maml = MAML(learner,meta_batch_size=4,optimizer=optimizer)
  >>> maml.fit(9000)
  
  To test it out on a new task and see how it works
  
  >>> learner.select_task()
  >>> maml.restore()
  >>> batch = learner.get_batch()
  >>> loss, outputs = maml.predict_on_batch(batch)
  >>> maml.train_on_current_task()
  >>> loss, outputs = maml.predict_on_batch(batch)
class_docstr_tok: ["Implements","the","Model-Agnostic","Meta-Learning","algorithm","for","low","data","learning",".","The","algorithm","is","described","in","Finn","et","al.",",","``","Model-Agnostic","Meta-Learning","for","Fast","Adaptation","of","Deep","Networks","''","(","https",":","\/\/arxiv.org\/abs\/1703.03400",")",".","It","is","used","for","training","models","that","can","perform","a","variety","of","tasks",",","depending","on","what","data","they","are","trained","on",".","It","assumes","you","have","training","data","for","many","tasks",",","but","only","a","small","amount","for","each","one",".","It","performs","``","meta-learning","''","by","looping","over","tasks","and","trying","to","minimize","the","loss","on","each","one","*","after","*","one","or","a","few","steps","of","gradient","descent",".","That","is",",","it","does","not","try","to","create","a","model","that","can","directly","solve","the","tasks",",","but","rather","tries","to","create","a","model","that","is","very","easy","to","train",".","To","use","this","class",",","create","a","subclass","of","MetaLearner","that","encapsulates","the","model","and","data","for","your","learning","problem",".","Pass","it","to","a","MAML","object","and","call","fit","(",")",".","You","can","then","use","train_on_current_task","(",")","to","fine","tune","the","model","for","a","particular","task",".","Example","--","--","--","--",">",">",">","import","deepchem","as","dc",">",">",">","import","numpy","as","np",">",">",">","import","torch",">",">",">","import","torch.nn.functional","as","F",">",">",">","from","deepchem.metalearning.torch_maml","import","MetaLearner",",","MAML",">",">",">","class","SineLearner","(","MetaLearner",")",":","...","def","__init__","(","self",")",":","...","self.batch_size","=","10","...","self.w1","=","torch.nn.Parameter","(","torch.tensor","(","np.random.normal","(","size=","[","1",",","40","]",",","scale=1.0",")",",","requires_grad=True",")",")","...","self.w2","=","torch.nn.Parameter","(","torch.tensor","(","np.random.normal","(","size=","[","40",",","40","]",",","scale=np.sqrt","(","1","\/","40",")",")",",","requires_grad=True",")",")","...","self.w3","=","torch.nn.Parameter","(","torch.tensor","(","np.random.normal","(","size=","[","40",",","1","]",",","scale=np.sqrt","(","1","\/","40",")",")",",","requires_grad=True",")",")","...","self.b1","=","torch.nn.Parameter","(","torch.tensor","(","np.zeros","(","40",")",")",",","requires_grad=True",")","...","self.b2","=","torch.nn.Parameter","(","torch.tensor","(","np.zeros","(","40",")",")",",","requires_grad=True",")","...","self.b3","=","torch.nn.Parameter","(","torch.tensor","(","np.zeros","(","1",")",")",",","requires_grad=True",")","...","def","compute_model","(","self",",","inputs",",","variables",",","training",")",":","...","x",",","y","=","inputs","...","w1",",","w2",",","w3",",","b1",",","b2",",","b3","=","variables","...","dense1","=","F.relu","(","torch.matmul","(","x",",","w1",")","+","b1",")","...","dense2","=","F.relu","(","torch.matmul","(","dense1",",","w2",")","+","b2",")","...","output","=","torch.matmul","(","dense2",",","w3",")","+","b3","...","loss","=","torch.mean","(","torch.square","(","output","-","y",")",")","...","return","loss",",","[","output","]","...","@","property","...","def","variables","(","self",")",":","...","return","[","self.w1",",","self.w2",",","self.w3",",","self.b1",",","self.b2",",","self.b3","]","...","def","select_task","(","self",")",":","...","self.amplitude","=","5.0","*","np.random.random","(",")","...","self.phase","=","np.pi","*","np.random.random","(",")","...","def","get_batch","(","self",")",":","...","x","=","torch.tensor","(","np.random.uniform","(","-5.0",",","5.0",",","(","self.batch_size",",","1",")",")",")","...","return","[","x",",","torch.tensor","(","self.amplitude","*","np.sin","(","x","+","self.phase",")",")","]","...","def","parameters","(","self",")",":","...","for","key",",","value","in","self.__dict__.items","(",")",":","...","if","isinstance","(","value",",","torch.nn.Parameter",")",":","...","yield","value",">",">",">","learner","=","SineLearner","(",")",">",">",">","optimizer","=","dc.models.optimizers.Adam","(","learning_rate=5e-3",")",">",">",">","maml","=","MAML","(","learner",",","meta_batch_size=4",",","optimizer=optimizer",")",">",">",">","maml.fit","(","9000",")","To","test","it","out","on","a","new","task","and","see","how","it","works",">",">",">","learner.select_task","(",")",">",">",">","maml.restore","(",")",">",">",">","batch","=","learner.get_batch","(",")",">",">",">","loss",",","outputs","=","maml.predict_on_batch","(","batch",")",">",">",">","maml.train_on_current_task","(",")",">",">",">","loss",",","outputs","=","maml.predict_on_batch","(","batch",")"]
docstr: Save a checkpoint to disk.
  
  Usually you do not need to call this method, since fit() saves checkpoints
  automatically.  If you have disabled automatic checkpointing during fitting,
  this can be called to manually write checkpoints.
  
  Parameters
  ----------
  max_checkpoints_to_keep: int
      the maximum number of checkpoints to keep.  Older checkpoints are discarded.
  model_dir: str, default None
      Model directory to save checkpoint to. If None, revert to self.model_dir
docstr_tok: ["Save","a","checkpoint","to","disk",".","Usually","you","do","not","need","to","call","this","method",",","since","fit","(",")","saves","checkpoints","automatically",".","If","you","have","disabled","automatic","checkpointing","during","fitting",",","this","can","be","called","to","manually","write","checkpoints",".","Parameters","--","--","--","--","--","max_checkpoints_to_keep",":","int","the","maximum","number","of","checkpoints","to","keep",".","Older","checkpoints","are","discarded",".","model_dir",":","str",",","default","None","Model","directory","to","save","checkpoint","to",".","If","None",",","revert","to","self.model_dir"]
code: def save_checkpoint(
      self,
      max_checkpoints_to_keep: int = 5,
      model_dir: Optional[str] = None,
  ) -> None:
      """Save a checkpoint to disk.
  
      Usually you do not need to call this method, since fit() saves checkpoints
      automatically.  If you have disabled automatic checkpointing during fitting,
      this can be called to manually write checkpoints.
  
      Parameters
      ----------
      max_checkpoints_to_keep: int
          the maximum number of checkpoints to keep.  Older checkpoints are discarded.
      model_dir: str, default None
          Model directory to save checkpoint to. If None, revert to self.model_dir
      """
      if model_dir is None:
          model_dir = self.model_dir
      if not os.path.exists(model_dir):
          os.makedirs(model_dir)
  
      # Save the checkpoint to a file.
  
      data: Dict[str, Any] = {
          "model_state_dict": self.learner.__dict__,
          "learning_rate": self.learning_rate,
          "optimizer_state_dict": self._pytorch_optimizer.state_dict(),
          "task_optimizer_state_dict": self._pytorch_task_optimizer.state_dict(),
          "global_step": self._global_step,
      }
      temp_file: str = os.path.join(model_dir, "temp_checkpoint.pt")
      torch.save(data, temp_file)
  
      # Rename and delete older files.
  
      paths: List[str] = [
          os.path.join(model_dir, "checkpoint%d.pt" % (i + 1))
          for i in range(max_checkpoints_to_keep)
      ]
      if os.path.exists(paths[-1]):
          os.remove(paths[-1])
      for i in reversed(range(max_checkpoints_to_keep - 1)):
          if os.path.exists(paths[i]):
              os.rename(paths[i], paths[i + 1])
      os.rename(temp_file, paths[0])
  
file_path: deepchem/deepchem/metalearning/torch_maml.py
imports: import os
  import shutil
  import tempfile
  import time
  from deepchem.models.optimizers import Optimizer, Adam, GradientDescent, LearningRateSchedule
  from typing import Any, Dict, List, Optional, Tuple, Sequence, Union
  from deepchem.utils.typing import OneOrMany
label_desc: Use image node_id 7 for calling the MAML obj's underlying member method code with example usage: obj.save_checkpoint(max_checkpoints_to_keep, model_dir) without return types