class_docstr: The :class:`~poutyne.ModelBundle` class provides a straightforward experimentation tool for efficient and entirely
  customizable finetuning of the whole neural network training procedure with PyTorch. The
  :class:`~poutyne.ModelBundle` object takes care of the training and testing processes while also managing to keep
  traces of all pertinent information via the automatic logging option.
  
  Use ``ModelBundle.from_*`` methods to instanciate a :class:`~poutyne.ModelBundle`.
class_docstr_tok: ["The",":","class",":","`","~poutyne.ModelBundle","`","class","provides","a","straightforward","experimentation","tool","for","efficient","and","entirely","customizable","finetuning","of","the","whole","neural","network","training","procedure","with","PyTorch",".","The",":","class",":","`","~poutyne.ModelBundle","`","object","takes","care","of","the","training","and","testing","processes","while","also","managing","to","keep","traces","of","all","pertinent","information","via","the","automatic","logging","option",".","Use","``","ModelBundle.from_","*","``","methods","to","instanciate","a",":","class",":","`","~poutyne.ModelBundle","`","."]
docstr: Instanciate a :class:`~poutyne.ModelBundle` from a :class:`~poutyne.Model` instance.
  
  Args:
      directory (str): Path to the model bundle's working directory. Will be used for automatic logging.
      model (poutyne.Model): A Model instance..
      logging (bool): Whether or not to log the model bundle's progress. If true, various logging
          callbacks will be inserted to output training and testing stats as well as to save model checkpoints,
          for example, automatically. See :func:`~ModelBundle.train()` and :func:`~ModelBundle.test()` for more
          details. (Default value = True)
      monitoring (bool): Whether or not to monitor the training. If True will track the best epoch.
          If False, ``monitor_metric`` and ``monitor_mode`` are not used, and when testing, the last epoch is used
          to test the model instead of the best epoch.
          (Default value = True)
      monitor_metric (str, optional): Which metric to consider for best model performance calculation. Should be
          in the format '{metric_name}' or 'val_{metric_name}' (i.e. 'val_loss'). If None, will follow the value
          suggested by ``task`` or default to 'val_loss'. If ``monitoring`` is set to False, will be ignore.
  
          .. warning:: If you do not plan on using a validation set, you must set the monitor metric to another
              value.
      monitor_mode (str, optional): Which mode, either 'min' or 'max', should be used when considering the
          ``monitor_metric`` value. If None, will follow the value suggested by ``task`` or default to 'min'.
          If ``monitoring`` is set to False, will be ignore.
  
  Examples:
      Using a PyTorch DataLoader, on classification task with SGD optimizer::
  
          import torch
          from torch.utils.data import DataLoader, TensorDataset
          from poutyne import Model, ModelBundle
  
          num_features = 20
          num_classes = 5
  
          # Our training dataset with 800 samples.
          num_train_samples = 800
          train_x = torch.rand(num_train_samples, num_features)
          train_y = torch.randint(num_classes, (num_train_samples, ), dtype=torch.long)
          train_dataset = TensorDataset(train_x, train_y)
          train_generator = DataLoader(train_dataset, batch_size=32)
  
          # Our validation dataset with 200 samples.
          num_valid_samples = 200
          valid_x = torch.rand(num_valid_samples, num_features)
          valid_y = torch.randint(num_classes, (num_valid_samples, ), dtype=torch.long)
          valid_dataset = TensorDataset(valid_x, valid_y)
          valid_generator = DataLoader(valid_dataset, batch_size=32)
  
          # Our network
          pytorch_network = torch.nn.Linear(num_features, num_train_samples)
  
          model = Model(pytorch_network, 'sgd', 'crossentropy', batch_metrics=['accuracy'])
  
          # Initialization of our experimentation and network training
          exp = ModelBundle.from_model('./simple_example', model)
          exp.train(train_generator, valid_generator, epochs=5)
  
  The above code will yield an output similar to the below lines. Note the automatic checkpoint saving
  in the model bundle directory when the monitored metric improved.
  
  .. code-block:: none
  
          Epoch 1/5 0.09s Step 25/25: loss: 6.351375, acc: 1.375000, val_loss: 6.236106, val_acc: 5.000000
          Epoch 1: val_acc improved from -inf to 5.00000, saving file to ./simple_example/checkpoint_epoch_1.ckpt
          Epoch 2/5 0.10s Step 25/25: loss: 6.054254, acc: 14.000000, val_loss: 5.944495, val_acc: 19.500000
          Epoch 2: val_acc improved from 5.00000 to 19.50000, saving file to ./simple_example/checkpoint_epoch_2.ckpt
          Epoch 3/5 0.09s Step 25/25: loss: 5.759377, acc: 22.875000, val_loss: 5.655412, val_acc: 21.000000
          Epoch 3: val_acc improved from 19.50000 to 21.00000, saving file to ./simple_example/checkpoint_epoch_3.ckpt
          ...
  
  Training can now easily be resumed from the best checkpoint::
  
          exp.train(train_generator, valid_generator, epochs=10)
  
  .. code-block:: none
  
          Restoring model from ./simple_example/checkpoint_epoch_3.ckpt
          Loading weights from ./simple_example/checkpoint.ckpt and starting at epoch 6.
          Loading optimizer state from ./simple_example/checkpoint.optim and starting at epoch 6.
          Epoch 6/10 0.16s Step 25/25: loss: 4.897135, acc: 22.875000, val_loss: 4.813141, val_acc: 20.500000
          Epoch 7/10 0.10s Step 25/25: loss: 4.621514, acc: 22.625000, val_loss: 4.545359, val_acc: 20.500000
          Epoch 8/10 0.24s Step 25/25: loss: 4.354721, acc: 23.625000, val_loss: 4.287117, val_acc: 20.500000
          ...
  
  Testing is also very intuitive::
  
          exp.test(test_generator)
  
  .. code-block:: none
  
          Restoring model from ./simple_example/checkpoint_epoch_9.ckpt
          Found best checkpoint at epoch: 9
          lr: 0.01, loss: 4.09892, acc: 23.625, val_loss: 4.04057, val_acc: 21.5
          On best model: test_loss: 4.06664, test_acc: 17.5
  
  
  Finally, all the pertinent metrics specified to the ModelBundle at each epoch are stored in a specific logging
  file, found here at './simple_example/log.tsv'.
  
  .. code-block:: none
  
          epoch   time                lr      loss                    acc     val_loss            val_acc
          1           0.0721172170015052  0.01    6.351375141143799       1.375   6.23610631942749        5.0
          2           0.0298177790245972  0.01    6.054253826141357       14.000  5.94449516296386        19.5
          3           0.0637106419890187  0.01    5.759376544952392       22.875  5.65541223526001        21.0
          ...
docstr_tok: ["Instanciate","a",":","class",":","`","~poutyne.ModelBundle","`","from","a",":","class",":","`","~poutyne.Model","`","instance",".","Args",":","directory","(","str",")",":","Path","to","the","model","bundle","'s","working","directory",".","Will","be","used","for","automatic","logging",".","model","(","poutyne.Model",")",":","A","Model","instance","..","logging","(","bool",")",":","Whether","or","not","to","log","the","model","bundle","'s","progress",".","If","true",",","various","logging","callbacks","will","be","inserted","to","output","training","and","testing","stats","as","well","as","to","save","model","checkpoints",",","for","example",",","automatically",".","See",":","func",":","`","~ModelBundle.train","(",")","`","and",":","func",":","`","~ModelBundle.test","(",")","`","for","more","details",".","(","Default","value","=","True",")","monitoring","(","bool",")",":","Whether","or","not","to","monitor","the","training",".","If","True","will","track","the","best","epoch",".","If","False",",","``","monitor_metric","``","and","``","monitor_mode","``","are","not","used",",","and","when","testing",",","the","last","epoch","is","used","to","test","the","model","instead","of","the","best","epoch",".","(","Default","value","=","True",")","monitor_metric","(","str",",","optional",")",":","Which","metric","to","consider","for","best","model","performance","calculation",".","Should","be","in","the","format","'","{","metric_name","}","'","or","'val_","{","metric_name","}","'","(","i.e",".","'val_loss","'",")",".","If","None",",","will","follow","the","value","suggested","by","``","task","``","or","default","to","'val_loss","'",".","If","``","monitoring","``","is","set","to","False",",","will","be","ignore",".","..","warning",":",":","If","you","do","not","plan","on","using","a","validation","set",",","you","must","set","the","monitor","metric","to","another","value",".","monitor_mode","(","str",",","optional",")",":","Which","mode",",","either","'min","'","or","'max","'",",","should","be","used","when","considering","the","``","monitor_metric","``","value",".","If","None",",","will","follow","the","value","suggested","by","``","task","``","or","default","to","'min","'",".","If","``","monitoring","``","is","set","to","False",",","will","be","ignore",".","Examples",":","Using","a","PyTorch","DataLoader",",","on","classification","task","with","SGD","optimizer",":",":","import","torch","from","torch.utils.data","import","DataLoader",",","TensorDataset","from","poutyne","import","Model",",","ModelBundle","num_features","=","20","num_classes","=","5","#","Our","training","dataset","with","800","samples",".","num_train_samples","=","800","train_x","=","torch.rand","(","num_train_samples",",","num_features",")","train_y","=","torch.randint","(","num_classes",",","(","num_train_samples",",",")",",","dtype=torch.long",")","train_dataset","=","TensorDataset","(","train_x",",","train_y",")","train_generator","=","DataLoader","(","train_dataset",",","batch_size=32",")","#","Our","validation","dataset","with","200","samples",".","num_valid_samples","=","200","valid_x","=","torch.rand","(","num_valid_samples",",","num_features",")","valid_y","=","torch.randint","(","num_classes",",","(","num_valid_samples",",",")",",","dtype=torch.long",")","valid_dataset","=","TensorDataset","(","valid_x",",","valid_y",")","valid_generator","=","DataLoader","(","valid_dataset",",","batch_size=32",")","#","Our","network","pytorch_network","=","torch.nn.Linear","(","num_features",",","num_train_samples",")","model","=","Model","(","pytorch_network",",","'sgd","'",",","'crossentropy","'",",","batch_metrics=","[","'accuracy","'","]",")","#","Initialization","of","our","experimentation","and","network","training","exp","=","ModelBundle.from_model","(","'.\/simple_example","'",",","model",")","exp.train","(","train_generator",",","valid_generator",",","epochs=5",")","The","above","code","will","yield","an","output","similar","to","the","below","lines",".","Note","the","automatic","checkpoint","saving","in","the","model","bundle","directory","when","the","monitored","metric","improved",".","..","code-block",":",":","none","Epoch","1\/5","0.09s","Step","25\/25",":","loss",":","6.351375",",","acc",":","1.375000",",","val_loss",":","6.236106",",","val_acc",":","5.000000","Epoch","1",":","val_acc","improved","from","-inf","to","5.00000",",","saving","file","to",".\/simple_example\/checkpoint_epoch_1.ckpt","Epoch","2\/5","0.10s","Step","25\/25",":","loss",":","6.054254",",","acc",":","14.000000",",","val_loss",":","5.944495",",","val_acc",":","19.500000","Epoch","2",":","val_acc","improved","from","5.00000","to","19.50000",",","saving","file","to",".\/simple_example\/checkpoint_epoch_2.ckpt","Epoch","3\/5","0.09s","Step","25\/25",":","loss",":","5.759377",",","acc",":","22.875000",",","val_loss",":","5.655412",",","val_acc",":","21.000000","Epoch","3",":","val_acc","improved","from","19.50000","to","21.00000",",","saving","file","to",".\/simple_example\/checkpoint_epoch_3.ckpt","...","Training","can","now","easily","be","resumed","from","the","best","checkpoint",":",":","exp.train","(","train_generator",",","valid_generator",",","epochs=10",")","..","code-block",":",":","none","Restoring","model","from",".\/simple_example\/checkpoint_epoch_3.ckpt","Loading","weights","from",".\/simple_example\/checkpoint.ckpt","and","starting","at","epoch","6",".","Loading","optimizer","state","from",".\/simple_example\/checkpoint.optim","and","starting","at","epoch","6",".","Epoch","6\/10","0.16s","Step","25\/25",":","loss",":","4.897135",",","acc",":","22.875000",",","val_loss",":","4.813141",",","val_acc",":","20.500000","Epoch","7\/10","0.10s","Step","25\/25",":","loss",":","4.621514",",","acc",":","22.625000",",","val_loss",":","4.545359",",","val_acc",":","20.500000","Epoch","8\/10","0.24s","Step","25\/25",":","loss",":","4.354721",",","acc",":","23.625000",",","val_loss",":","4.287117",",","val_acc",":","20.500000","...","Testing","is","also","very","intuitive",":",":","exp.test","(","test_generator",")","..","code-block",":",":","none","Restoring","model","from",".\/simple_example\/checkpoint_epoch_9.ckpt","Found","best","checkpoint","at","epoch",":","9","lr",":","0.01",",","loss",":","4.09892",",","acc",":","23.625",",","val_loss",":","4.04057",",","val_acc",":","21.5","On","best","model",":","test_loss",":","4.06664",",","test_acc",":","17.5","Finally",",","all","the","pertinent","metrics","specified","to","the","ModelBundle","at","each","epoch","are","stored","in","a","specific","logging","file",",","found","here","at","'.\/simple_example\/log.tsv","'",".","..","code-block",":",":","none","epoch","time","lr","loss","acc","val_loss","val_acc","1","0.0721172170015052","0.01","6.351375141143799","1.375","6.23610631942749","5.0","2","0.0298177790245972","0.01","6.054253826141357","14.000","5.94449516296386","19.5","3","0.0637106419890187","0.01","5.759376544952392","22.875","5.65541223526001","21.0","..."]
code: def from_model(
      cls,
      directory: str,
      model: Model,
      *,
      logging: bool = True,
      monitoring: bool = True,
      monitor_metric: Union[str, None] = None,
      monitor_mode: Union[str, None] = None,
  ):
      # pylint: disable=line-too-long
      """
      Instanciate a :class:`~poutyne.ModelBundle` from a :class:`~poutyne.Model` instance.
  
      Args:
          directory (str): Path to the model bundle's working directory. Will be used for automatic logging.
          model (poutyne.Model): A Model instance..
          logging (bool): Whether or not to log the model bundle's progress. If true, various logging
              callbacks will be inserted to output training and testing stats as well as to save model checkpoints,
              for example, automatically. See :func:`~ModelBundle.train()` and :func:`~ModelBundle.test()` for more
              details. (Default value = True)
          monitoring (bool): Whether or not to monitor the training. If True will track the best epoch.
              If False, ``monitor_metric`` and ``monitor_mode`` are not used, and when testing, the last epoch is used
              to test the model instead of the best epoch.
              (Default value = True)
          monitor_metric (str, optional): Which metric to consider for best model performance calculation. Should be
              in the format '{metric_name}' or 'val_{metric_name}' (i.e. 'val_loss'). If None, will follow the value
              suggested by ``task`` or default to 'val_loss'. If ``monitoring`` is set to False, will be ignore.
  
              .. warning:: If you do not plan on using a validation set, you must set the monitor metric to another
                  value.
          monitor_mode (str, optional): Which mode, either 'min' or 'max', should be used when considering the
              ``monitor_metric`` value. If None, will follow the value suggested by ``task`` or default to 'min'.
              If ``monitoring`` is set to False, will be ignore.
  
      Examples:
          Using a PyTorch DataLoader, on classification task with SGD optimizer::
  
              import torch
              from torch.utils.data import DataLoader, TensorDataset
              from poutyne import Model, ModelBundle
  
              num_features = 20
              num_classes = 5
  
              # Our training dataset with 800 samples.
              num_train_samples = 800
              train_x = torch.rand(num_train_samples, num_features)
              train_y = torch.randint(num_classes, (num_train_samples, ), dtype=torch.long)
              train_dataset = TensorDataset(train_x, train_y)
              train_generator = DataLoader(train_dataset, batch_size=32)
  
              # Our validation dataset with 200 samples.
              num_valid_samples = 200
              valid_x = torch.rand(num_valid_samples, num_features)
              valid_y = torch.randint(num_classes, (num_valid_samples, ), dtype=torch.long)
              valid_dataset = TensorDataset(valid_x, valid_y)
              valid_generator = DataLoader(valid_dataset, batch_size=32)
  
              # Our network
              pytorch_network = torch.nn.Linear(num_features, num_train_samples)
  
              model = Model(pytorch_network, 'sgd', 'crossentropy', batch_metrics=['accuracy'])
  
              # Initialization of our experimentation and network training
              exp = ModelBundle.from_model('./simple_example', model)
              exp.train(train_generator, valid_generator, epochs=5)
  
      The above code will yield an output similar to the below lines. Note the automatic checkpoint saving
      in the model bundle directory when the monitored metric improved.
  
      .. code-block:: none
  
              Epoch 1/5 0.09s Step 25/25: loss: 6.351375, acc: 1.375000, val_loss: 6.236106, val_acc: 5.000000
              Epoch 1: val_acc improved from -inf to 5.00000, saving file to ./simple_example/checkpoint_epoch_1.ckpt
              Epoch 2/5 0.10s Step 25/25: loss: 6.054254, acc: 14.000000, val_loss: 5.944495, val_acc: 19.500000
              Epoch 2: val_acc improved from 5.00000 to 19.50000, saving file to ./simple_example/checkpoint_epoch_2.ckpt
              Epoch 3/5 0.09s Step 25/25: loss: 5.759377, acc: 22.875000, val_loss: 5.655412, val_acc: 21.000000
              Epoch 3: val_acc improved from 19.50000 to 21.00000, saving file to ./simple_example/checkpoint_epoch_3.ckpt
              ...
  
      Training can now easily be resumed from the best checkpoint::
  
              exp.train(train_generator, valid_generator, epochs=10)
  
      .. code-block:: none
  
              Restoring model from ./simple_example/checkpoint_epoch_3.ckpt
              Loading weights from ./simple_example/checkpoint.ckpt and starting at epoch 6.
              Loading optimizer state from ./simple_example/checkpoint.optim and starting at epoch 6.
              Epoch 6/10 0.16s Step 25/25: loss: 4.897135, acc: 22.875000, val_loss: 4.813141, val_acc: 20.500000
              Epoch 7/10 0.10s Step 25/25: loss: 4.621514, acc: 22.625000, val_loss: 4.545359, val_acc: 20.500000
              Epoch 8/10 0.24s Step 25/25: loss: 4.354721, acc: 23.625000, val_loss: 4.287117, val_acc: 20.500000
              ...
  
      Testing is also very intuitive::
  
              exp.test(test_generator)
  
      .. code-block:: none
  
              Restoring model from ./simple_example/checkpoint_epoch_9.ckpt
              Found best checkpoint at epoch: 9
              lr: 0.01, loss: 4.09892, acc: 23.625, val_loss: 4.04057, val_acc: 21.5
              On best model: test_loss: 4.06664, test_acc: 17.5
  
  
      Finally, all the pertinent metrics specified to the ModelBundle at each epoch are stored in a specific logging
      file, found here at './simple_example/log.tsv'.
  
      .. code-block:: none
  
              epoch	time	            lr	    loss	            acc	    val_loss	        val_acc
              1	    0.0721172170015052	0.01	6.351375141143799	1.375	6.23610631942749	5.0
              2	    0.0298177790245972	0.01	6.054253826141357	14.000	5.94449516296386	19.5
              3	    0.0637106419890187	0.01	5.759376544952392	22.875	5.65541223526001	21.0
              ...
      """
      (
          monitoring,
          monitor_metric,
          monitor_mode,
      ) = cls._get_monitoring_config(
          monitoring, monitor_metric, monitor_mode
      )
  
      return ModelBundle(
          directory,
          model,
          logging=logging,
          monitoring=monitoring,
          monitor_metric=monitor_metric,
          monitor_mode=monitor_mode,
          _is_direct=False,
      )
  
imports: import os
  import warnings
  from typing import Any, Callable, Dict, List, Tuple, Union
  import torch
  from poutyne.framework.callbacks import AtomicCSVLogger, BestModelRestore, LRSchedulerCheckpoint, ModelCheckpoint, OptimizerCheckpoint, PeriodicSaveLambda, RandomStatesCheckpoint, TensorBoardLogger
  from poutyne.framework.model import Model
  from poutyne.plotting import plot_history
  from poutyne.utils import load_random_states, set_seeds
label_desc: Use image node_id 3 for calling the ModelBundle obj's underlying member method code with example usage: obj.from_model(cls, directory, model) and returns: ModelBundle