garmentiq.classification.predict
Single-image garment classification.
1"""Single-image garment classification.""" 2import torch 3import torch.nn as nn 4import torch.nn.functional as F 5from PIL import Image 6from torchvision import transforms 7from typing import Type, List, Union 8from garmentiq.utils.device import resolve_device, empty_cache 9 10 11def predict( 12 model: Type[nn.Module], 13 image_path: str, 14 classes: List[str], 15 resize_dim=(120, 184), 16 normalize_mean=[0.8047, 0.7808, 0.7769], 17 normalize_std=[0.2957, 0.3077, 0.3081], 18 device: Union[str, torch.device] = "cpu", 19 verbose=False, 20): 21 """ 22 Loads a trained PyTorch model and makes a prediction on a single image. 23 24 This function processes a single image from disk, applies resizing and normalization, 25 feeds it through a loaded model, and returns the predicted class along with the 26 class probabilities. The model is expected to output logits over a fixed number of classes. 27 28 The model and the preprocessed image tensor are placed on `device`, so the same value should 29 be passed here as was used when loading the model. Any accelerator memory cached during 30 inference is released before returning. 31 32 Args: 33 model (Type[nn.Module]): The loaded PyTorch model instance ready for inference. 34 image_path (str): Path to the input image file (.jpg, .jpeg, .png). 35 classes (List[str]): List of class names corresponding to model outputs. Will be sorted internally. 36 resize_dim (tuple[int, int]): Tuple indicating the dimensions to resize the image to. Default is (120, 184). 37 normalize_mean (list[float]): List of mean values for normalization. Default is [0.8047, 0.7808, 0.7769]. 38 normalize_std (list[float]): List of standard deviation values for normalization. Default is [0.2957, 0.3077, 0.3081]. 39 device (Union[str, torch.device], optional): The device to run inference on, e.g. `"cpu"`, 40 `"cuda"`, `"cuda:0"`, or `"mps"`. Hardware 41 acceleration is opt-in; pass it explicitly to 42 use a GPU or Apple Silicon. Defaults to `"cpu"`. 43 verbose (bool): If True, prints the predicted label and class probabilities. 44 45 Raises: 46 ValueError: If the image file does not have a supported extension (.jpg, .jpeg, .png), 47 or if the requested `device` is invalid or unavailable on this machine. 48 FileNotFoundError: If the model checkpoint file is not found or cannot be loaded. 49 50 Returns: 51 tuple[str, List[float]]: A tuple containing: 52 - predicted label (str): The class label with the highest predicted probability. 53 - prob_list (List[float]): The list of class probabilities in the same order as the sorted class list. 54 """ 55 device = resolve_device(device) 56 57 # Validate image extension 58 if not any( 59 image_path.lower().endswith(ext) for ext in [".jpg", ".jpeg", ".png", ".JPG"] 60 ): 61 raise ValueError("Image file must end with .jpg, .jpeg, .png, or .JPG") 62 63 # Sort the classes list to have a consistent order 64 sorted_classes = sorted(classes) 65 66 # Define the preprocessing transformation. 67 transform = transforms.Compose( 68 [ 69 transforms.Resize(resize_dim), 70 transforms.ToTensor(), 71 transforms.Normalize(mean=normalize_mean, std=normalize_std), 72 ] 73 ) 74 75 # Load and preprocess the image 76 image = Image.open(image_path).convert("RGB") 77 model = model.to(device) 78 image_tensor = transform(image).unsqueeze(0).to(device) # add batch dimension 79 80 # Forward pass 81 with torch.no_grad(): 82 outputs = model(image_tensor) 83 # Compute probabilities using softmax 84 probabilities = ( 85 F.softmax(outputs, dim=1).cpu().numpy()[0] 86 ) # shape: (num_classes,) 87 88 # Determine the predicted index and label 89 pred_index = int(probabilities.argmax()) 90 pred_label = sorted_classes[pred_index] 91 92 # Optionally, you might want to return probabilities as a list of floats: 93 prob_list = probabilities.tolist() 94 95 if verbose: 96 print(f"Prediction: {pred_label}") 97 print(f"Probabilities: {prob_list}") 98 99 del image_tensor, outputs 100 empty_cache(device) 101 102 return pred_label, prob_list
12def predict( 13 model: Type[nn.Module], 14 image_path: str, 15 classes: List[str], 16 resize_dim=(120, 184), 17 normalize_mean=[0.8047, 0.7808, 0.7769], 18 normalize_std=[0.2957, 0.3077, 0.3081], 19 device: Union[str, torch.device] = "cpu", 20 verbose=False, 21): 22 """ 23 Loads a trained PyTorch model and makes a prediction on a single image. 24 25 This function processes a single image from disk, applies resizing and normalization, 26 feeds it through a loaded model, and returns the predicted class along with the 27 class probabilities. The model is expected to output logits over a fixed number of classes. 28 29 The model and the preprocessed image tensor are placed on `device`, so the same value should 30 be passed here as was used when loading the model. Any accelerator memory cached during 31 inference is released before returning. 32 33 Args: 34 model (Type[nn.Module]): The loaded PyTorch model instance ready for inference. 35 image_path (str): Path to the input image file (.jpg, .jpeg, .png). 36 classes (List[str]): List of class names corresponding to model outputs. Will be sorted internally. 37 resize_dim (tuple[int, int]): Tuple indicating the dimensions to resize the image to. Default is (120, 184). 38 normalize_mean (list[float]): List of mean values for normalization. Default is [0.8047, 0.7808, 0.7769]. 39 normalize_std (list[float]): List of standard deviation values for normalization. Default is [0.2957, 0.3077, 0.3081]. 40 device (Union[str, torch.device], optional): The device to run inference on, e.g. `"cpu"`, 41 `"cuda"`, `"cuda:0"`, or `"mps"`. Hardware 42 acceleration is opt-in; pass it explicitly to 43 use a GPU or Apple Silicon. Defaults to `"cpu"`. 44 verbose (bool): If True, prints the predicted label and class probabilities. 45 46 Raises: 47 ValueError: If the image file does not have a supported extension (.jpg, .jpeg, .png), 48 or if the requested `device` is invalid or unavailable on this machine. 49 FileNotFoundError: If the model checkpoint file is not found or cannot be loaded. 50 51 Returns: 52 tuple[str, List[float]]: A tuple containing: 53 - predicted label (str): The class label with the highest predicted probability. 54 - prob_list (List[float]): The list of class probabilities in the same order as the sorted class list. 55 """ 56 device = resolve_device(device) 57 58 # Validate image extension 59 if not any( 60 image_path.lower().endswith(ext) for ext in [".jpg", ".jpeg", ".png", ".JPG"] 61 ): 62 raise ValueError("Image file must end with .jpg, .jpeg, .png, or .JPG") 63 64 # Sort the classes list to have a consistent order 65 sorted_classes = sorted(classes) 66 67 # Define the preprocessing transformation. 68 transform = transforms.Compose( 69 [ 70 transforms.Resize(resize_dim), 71 transforms.ToTensor(), 72 transforms.Normalize(mean=normalize_mean, std=normalize_std), 73 ] 74 ) 75 76 # Load and preprocess the image 77 image = Image.open(image_path).convert("RGB") 78 model = model.to(device) 79 image_tensor = transform(image).unsqueeze(0).to(device) # add batch dimension 80 81 # Forward pass 82 with torch.no_grad(): 83 outputs = model(image_tensor) 84 # Compute probabilities using softmax 85 probabilities = ( 86 F.softmax(outputs, dim=1).cpu().numpy()[0] 87 ) # shape: (num_classes,) 88 89 # Determine the predicted index and label 90 pred_index = int(probabilities.argmax()) 91 pred_label = sorted_classes[pred_index] 92 93 # Optionally, you might want to return probabilities as a list of floats: 94 prob_list = probabilities.tolist() 95 96 if verbose: 97 print(f"Prediction: {pred_label}") 98 print(f"Probabilities: {prob_list}") 99 100 del image_tensor, outputs 101 empty_cache(device) 102 103 return pred_label, prob_list
Loads a trained PyTorch model and makes a prediction on a single image.
This function processes a single image from disk, applies resizing and normalization, feeds it through a loaded model, and returns the predicted class along with the class probabilities. The model is expected to output logits over a fixed number of classes.
The model and the preprocessed image tensor are placed on device, so the same value should
be passed here as was used when loading the model. Any accelerator memory cached during
inference is released before returning.
Arguments:
- model (Type[nn.Module]): The loaded PyTorch model instance ready for inference.
- image_path (str): Path to the input image file (.jpg, .jpeg, .png).
- classes (List[str]): List of class names corresponding to model outputs. Will be sorted internally.
- resize_dim (tuple[int, int]): Tuple indicating the dimensions to resize the image to. Default is (120, 184).
- normalize_mean (list[float]): List of mean values for normalization. Default is [0.8047, 0.7808, 0.7769].
- normalize_std (list[float]): List of standard deviation values for normalization. Default is [0.2957, 0.3077, 0.3081].
- device (Union[str, torch.device], optional): The device to run inference on, e.g.
"cpu","cuda","cuda:0", or"mps". Hardware acceleration is opt-in; pass it explicitly to use a GPU or Apple Silicon. Defaults to"cpu". - verbose (bool): If True, prints the predicted label and class probabilities.
Raises:
- ValueError: If the image file does not have a supported extension (.jpg, .jpeg, .png),
or if the requested
deviceis invalid or unavailable on this machine. - FileNotFoundError: If the model checkpoint file is not found or cannot be loaded.
Returns:
tuple[str, List[float]]: A tuple containing: - predicted label (str): The class label with the highest predicted probability. - prob_list (List[float]): The list of class probabilities in the same order as the sorted class list.