class_docstr: Implementation of a Basic Iterative Pruner.
  Any iterative pruning technique can be extended from this by implementing the `prune_model` method.
  
  :param model: Model that needs to be pruned
  :type model: torch.nn.Module
  :param train_loader: Dataloader for training
  :type train_loader: torch.utils.data.DataLoader
  :param test_loader: Dataloader for validation/testing
  :type test_loader: torch.utils.data.DataLoader
  :param loss_fn: Loss function to be used for training
  :type loss_fn: torch.nn.Module
  :param device: Device used for implementation ("cpu" by default)
  :type device: torch.device
class_docstr_tok: ["Implementation","of","a","Basic","Iterative","Pruner",".","Any","iterative","pruning","technique","can","be","extended","from","this","by","implementing","the","`","prune_model","`","method",".",":","param","model",":","Model","that","needs","to","be","pruned",":","type","model",":","torch.nn.Module",":","param","train_loader",":","Dataloader","for","training",":","type","train_loader",":","torch.utils.data.DataLoader",":","param","test_loader",":","Dataloader","for","validation\/testing",":","type","test_loader",":","torch.utils.data.DataLoader",":","param","loss_fn",":","Loss","function","to","be","used","for","training",":","type","loss_fn",":","torch.nn.Module",":","param","device",":","Device","used","for","implementation","(","``","cpu","''","by","default",")",":","type","device",":","torch.device"]
docstr: Function used for finetuning the model after it is pruned
  
  :param epochs: Number of training epochs
  :type epochs: int
  :param save_model: True if the model needs to be saved
  :type save_model: bool
  :param save_model_path: Path where the model needs to be saved (only used if save_model = True).
  :type save_model_path: str
docstr_tok: ["Function","used","for","finetuning","the","model","after","it","is","pruned",":","param","epochs",":","Number","of","training","epochs",":","type","epochs",":","int",":","param","save_model",":","True","if","the","model","needs","to","be","saved",":","type","save_model",":","bool",":","param","save_model_path",":","Path","where","the","model","needs","to","be","saved","(","only","used","if","save_model","=","True",")",".",":","type","save_model_path",":","str"]
code: def finetune_model(
      self, epochs, save_model=False, save_model_path="model.pt"
  ):
      """
      Function used for finetuning the model after it is pruned
  
      :param epochs: Number of training epochs
      :type epochs: int
      :param save_model: True if the model needs to be saved
      :type save_model: bool
      :param save_model_path: Path where the model needs to be saved (only used if save_model = True).
      :type save_model_path: str
      """
  
      best_acc = 0.0
      best_model_weights = copy.deepcopy(self.model.state_dict())
      loss_arr = []
      accs = []
  
      for ep in range(epochs):
          epoch_loss, epoch_acc = self.train_model()
          test_loss, test_acc = self.evaluate_model()
          if test_acc > best_acc:
              best_acc = epoch_acc
              best_model_weights = copy.deepcopy(
                  self.model.state_dict()
              )
  
          loss_arr.append(epoch_loss)
          print(
              f"Epoch: {ep+1}, Training Loss: {epoch_loss}, Training Accuracy: {epoch_acc}"
          )
          print(
              f"Epoch: {ep+1}, Test Loss: {test_loss}, Test Accuracy: {test_acc}"
          )
  
      self.model.load_state_dict(best_model_weights)
      if save_model:
          torch.save(self.model.state_dict(), save_model_path)
  
file_path: KD_Lib/KD_Lib/Pruning/common/iterative_base_class.py
imports: import copy
  import numpy
  import torch
  import torch.nn
label_desc: Use image node_id 4 for calling the BaseIterativePruner obj's underlying member method code with example usage: obj.finetune_model(epochs, save_model, save_model_path) without return types