class_docstr: Task for image classification.
  
  Attributes:
      model:
          1. Model name
          2. Model name on Backprop's image-classification endpoint
          3. Model object that implements the image-classification task
      local (optional): Run locally. Defaults to False
      api_key (optional): Backprop API key for non-local inference
      device (optional): Device to run inference on. Defaults to "cuda" if available.
class_docstr_tok: ["Task","for","image","classification",".","Attributes",":","model",":","1",".","Model","name","2",".","Model","name","on","Backprop","'s","image-classification","endpoint","3",".","Model","object","that","implements","the","image-classification","task","local","(","optional",")",":","Run","locally",".","Defaults","to","False","api_key","(","optional",")",":","Backprop","API","key","for","non-local","inference","device","(","optional",")",":","Device","to","run","inference","on",".","Defaults","to","``","cuda","''","if","available","."]
docstr: Finetunes a model for image classification.
  
  Args:
      params: Dictionary of model inputs. Contains 'images' and 'labels' keys, with values as lists of images/labels.
      validation_split: Float between 0 and 1 that determines what percentage of the data to use for validation.
      variant: Determines whether to do single or multi-label classification: "single_label" (default) or "multi_label"
      epochs: Integer specifying how many training iterations to run.
      batch_size: Batch size when training. Leave as None to automatically determine batch size.
      optimal_batch_size: Optimal batch size for the model being trained -- defaults to model settings.
      early_stopping_epochs: Integer determining how many epochs will run before stopping without an improvement in validation loss.
      train_dataloader: Dataloader for providing training data when finetuning. Defaults to inbuilt dataloder.
      val_dataloader: Dataloader for providing validation data when finetuning. Defaults to inbuilt dataloader.
      step: Function determining how to call model for a training step. Defaults to step defined in this task class.
      configure_optimizers: Function that sets up the optimizer for training. Defaults to optimizer defined in this task class.
  
  Examples::
  
      import backprop
  
      ic = backprop.ImageClassification()
  
      # Prep training images/labels. Labels are automatically used to set up model with number of classes for classification.
      images = ["images/beagle/photo.jpg", "images/dachsund/photo.jpg", "images/malamute/photo.jpg"]
      labels = ["beagle", "dachsund", "malamute"]
      params = {"images": images, "labels": labels}
  
      # Finetune
      ic.finetune(params, variant="single_label")
docstr_tok: ["Finetunes","a","model","for","image","classification",".","Args",":","params",":","Dictionary","of","model","inputs",".","Contains","'images","'","and","'labels","'","keys",",","with","values","as","lists","of","images\/labels",".","validation_split",":","Float","between","0","and","1","that","determines","what","percentage","of","the","data","to","use","for","validation",".","variant",":","Determines","whether","to","do","single","or","multi-label","classification",":","``","single_label","''","(","default",")","or","``","multi_label","''","epochs",":","Integer","specifying","how","many","training","iterations","to","run",".","batch_size",":","Batch","size","when","training",".","Leave","as","None","to","automatically","determine","batch","size",".","optimal_batch_size",":","Optimal","batch","size","for","the","model","being","trained","--","defaults","to","model","settings",".","early_stopping_epochs",":","Integer","determining","how","many","epochs","will","run","before","stopping","without","an","improvement","in","validation","loss",".","train_dataloader",":","Dataloader","for","providing","training","data","when","finetuning",".","Defaults","to","inbuilt","dataloder",".","val_dataloader",":","Dataloader","for","providing","validation","data","when","finetuning",".","Defaults","to","inbuilt","dataloader",".","step",":","Function","determining","how","to","call","model","for","a","training","step",".","Defaults","to","step","defined","in","this","task","class",".","configure_optimizers",":","Function","that","sets","up","the","optimizer","for","training",".","Defaults","to","optimizer","defined","in","this","task","class",".","Examples",":",":","import","backprop","ic","=","backprop.ImageClassification","(",")","#","Prep","training","images\/labels",".","Labels","are","automatically","used","to","set","up","model","with","number","of","classes","for","classification",".","images","=","[","``","images\/beagle\/photo.jpg","''",",","``","images\/dachsund\/photo.jpg","''",",","``","images\/malamute\/photo.jpg","''","]","labels","=","[","``","beagle","''",",","``","dachsund","''",",","``","malamute","''","]","params","=","{","``","images","''",":","images",",","``","labels","''",":","labels","}","#","Finetune","ic.finetune","(","params",",","variant=","''","single_label","''",")"]
code: def finetune(
      self,
      params,
      validation_split: Union[
          float, Tuple[List[int], List[int]]
      ] = 0.15,
      variant: str = "single_label",
      epochs: int = 20,
      batch_size: int = None,
      optimal_batch_size: int = None,
      early_stopping_epochs: int = 1,
      train_dataloader=None,
      val_dataloader=None,
      step=None,
      configure_optimizers=None,
  ):
      """
      Finetunes a model for image classification.
  
      Args:
          params: Dictionary of model inputs. Contains 'images' and 'labels' keys, with values as lists of images/labels.
          validation_split: Float between 0 and 1 that determines what percentage of the data to use for validation.
          variant: Determines whether to do single or multi-label classification: "single_label" (default) or "multi_label"
          epochs: Integer specifying how many training iterations to run.
          batch_size: Batch size when training. Leave as None to automatically determine batch size.
          optimal_batch_size: Optimal batch size for the model being trained -- defaults to model settings.
          early_stopping_epochs: Integer determining how many epochs will run before stopping without an improvement in validation loss.
          train_dataloader: Dataloader for providing training data when finetuning. Defaults to inbuilt dataloder.
          val_dataloader: Dataloader for providing validation data when finetuning. Defaults to inbuilt dataloader.
          step: Function determining how to call model for a training step. Defaults to step defined in this task class.
          configure_optimizers: Function that sets up the optimizer for training. Defaults to optimizer defined in this task class.
  
      Examples::
  
          import backprop
  
          ic = backprop.ImageClassification()
  
          # Prep training images/labels. Labels are automatically used to set up model with number of classes for classification.
          images = ["images/beagle/photo.jpg", "images/dachsund/photo.jpg", "images/malamute/photo.jpg"]
          labels = ["beagle", "dachsund", "malamute"]
          params = {"images": images, "labels": labels}
  
          # Finetune
          ic.finetune(params, variant="single_label")
      """
      optimal_batch_size = optimal_batch_size or getattr(
          self.model, "optimal_batch_size", 128
      )
  
      configure_optimizers = (
          configure_optimizers
          or self.model.configure_optimizers
          or self.configure_optimizers
      )
  
      images = params["images"]
      labels = params["labels"]
  
      assert len(images) == len(labels), "The input lists must match"
  
      if variant == "single_label":
          step = step or self.step_single_label
  
          labels_set = set(labels)
          labels_dict = {k: v for k, v in enumerate(labels_set)}
  
          if hasattr(self.model, "pre_finetuning"):
              self.model.pre_finetuning(
                  labels=labels_dict, num_classes=len(labels_set)
              )
  
          dataset = SingleLabelImageClassificationDataset(
              images, labels, self.model.process_batch
          )
  
          self.criterion = nn.CrossEntropyLoss()
      elif variant == "multi_label":
          step = step or self.step_multi_label
  
          all_labels = set(np.concatenate(labels).flat)
  
          labels_dict = {i: label for i, label in enumerate(all_labels)}
  
          if hasattr(self.model, "pre_finetuning"):
              self.model.pre_finetuning(
                  labels=labels_dict, num_classes=len(all_labels)
              )
  
          dataset = MultiLabelImageClassificationDataset(
              images, labels, self.model.process_batch
          )
  
          # Sigmoid and BCE
          self.criterion = nn.BCEWithLogitsLoss()
      else:
          raise ValueError(f"Unsupported variant '{variant}'")
  
      super().finetune(
          dataset=dataset,
          validation_split=validation_split,
          epochs=epochs,
          batch_size=batch_size,
          optimal_batch_size=optimal_batch_size,
          early_stopping_epochs=early_stopping_epochs,
          train_dataloader=train_dataloader,
          val_dataloader=val_dataloader,
          step=step,
          configure_optimizers=configure_optimizers,
      )
  
imports: from typing import List, Tuple, Union
  from ..models import BaseModel
  from backprop.models import AutoModel
  from backprop.utils.datasets import SingleLabelImageClassificationDataset, MultiLabelImageClassificationDataset
  from .base import Task
  from PIL import Image
  from torch import nn
  import torch
  import numpy
  import base64
  import requests
  from io import BytesIO
  from backprop.utils.helpers import img_to_base64, path_to_img
label_desc: Use image node_id 7 for calling the ImageClassification obj's underlying member method code with example usage: obj.finetune(params, validation_split, variant, epochs, batch_size, optimal_batch_size, early_stopping_epochs, train_dataloader, val_dataloader, step, configure_optimizers) without return types