Spaces:
Build error
Build error
# -*- coding: utf-8 -*- | |
"""Good.ipynb | |
Automatically generated by Colaboratory. | |
Original file is located at | |
https://colab.research.google.com/drive/1AkM6wLyspo4q2ScK_pIkTAFDV-Q-JCgh | |
""" | |
!pip install torchinfo | |
files.upload() | |
from google.colab import files | |
import matplotlib.pyplot as plt | |
import torch | |
import torchvision | |
from torch import nn | |
from torchvision import transforms | |
from Helperfunction import set_seeds | |
device = "cuda" if torch.cuda.is_available() else "cpu" | |
device | |
# Commented out IPython magic to ensure Python compatibility. | |
# %%writefile predict.py | |
# | |
# #predict | |
# | |
# | |
# """ | |
# Utility functions to make predictions. | |
# | |
# Main reference for code creation: https://www.learnpytorch.io/06_pytorch_transfer_learning/#6-make-predictions-on-images-from-the-test-set | |
# """ | |
# import torch | |
# import torchvision | |
# from torchvision import transforms | |
# import matplotlib.pyplot as plt | |
# | |
# from typing import List, Tuple | |
# | |
# from PIL import Image | |
# | |
# # Set device | |
# device = "cuda" if torch.cuda.is_available() else "cpu" | |
# | |
# # Predict on a target image with a target model | |
# # Function created in: https://www.learnpytorch.io/06_pytorch_transfer_learning/#6-make-predictions-on-images-from-the-test-set | |
# def pred_and_plot_image( | |
# model: torch.nn.Module, | |
# class_names: List[str], | |
# image_path: str, | |
# image_size: Tuple[int, int] = (224, 224), | |
# transform: torchvision.transforms = None, | |
# device: torch.device = device, | |
# ): | |
# """Predicts on a target image with a target model. | |
# | |
# Args: | |
# model (torch.nn.Module): A trained (or untrained) PyTorch model to predict on an image. | |
# class_names (List[str]): A list of target classes to map predictions to. | |
# image_path (str): Filepath to target image to predict on. | |
# image_size (Tuple[int, int], optional): Size to transform target image to. Defaults to (224, 224). | |
# transform (torchvision.transforms, optional): Transform to perform on image. Defaults to None which uses ImageNet normalization. | |
# device (torch.device, optional): Target device to perform prediction on. Defaults to device. | |
# """ | |
# | |
# # Open image | |
# img = Image.open(image_path) | |
# | |
# # Create transformation for image (if one doesn't exist) | |
# if transform is not None: | |
# image_transform = transform | |
# else: | |
# image_transform = transforms.Compose( | |
# [ | |
# transforms.Resize(image_size), | |
# transforms.ToTensor(), | |
# transforms.Normalize( | |
# mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225] | |
# ), | |
# ] | |
# ) | |
# | |
# ### Predict on image ### | |
# | |
# # Make sure the model is on the target device | |
# model.to(device) | |
# | |
# # Turn on model evaluation mode and inference mode | |
# model.eval() | |
# with torch.inference_mode(): | |
# # Transform and add an extra dimension to image (model requires samples in [batch_size, color_channels, height, width]) | |
# transformed_image = image_transform(img).unsqueeze(dim=0) | |
# | |
# # Make a prediction on image with an extra dimension and send it to the target device | |
# target_image_pred = model(transformed_image.to(device)) | |
# | |
# # Convert logits -> prediction probabilities (using torch.softmax() for multi-class classification) | |
# target_image_pred_probs = torch.softmax(target_image_pred, dim=1) | |
# | |
# # Convert prediction probabilities -> prediction labels | |
# target_image_pred_label = torch.argmax(target_image_pred_probs, dim=1) | |
# | |
# # Plot image with predicted label and probability | |
# plt.figure() | |
# plt.imshow(img) | |
# plt.title( | |
# f"Pred: {class_names[target_image_pred_label]} | Prob: {target_image_pred_probs.max():.3f}" | |
# ) | |
# plt.axis(False) | |
# | |
from google.colab import drive | |
drive.mount('/content/drive') | |
# Commented out IPython magic to ensure Python compatibility. | |
# %%writefile model_builder.py | |
# | |
# #model_builder | |
# | |
# """ | |
# Contains PyTorch model code to instantiate a TinyVGG model. | |
# """ | |
# import torch | |
# from torch import nn | |
# | |
# class TinyVGG(nn.Module): | |
# """Creates the TinyVGG architecture. | |
# | |
# Replicates the TinyVGG architecture from the CNN explainer website in PyTorch. | |
# See the original architecture here: https://poloclub.github.io/cnn-explainer/ | |
# | |
# Args: | |
# input_shape: An integer indicating number of input channels. | |
# hidden_units: An integer indicating number of hidden units between layers. | |
# output_shape: An integer indicating number of output units. | |
# """ | |
# def __init__(self, input_shape: int, hidden_units: int, output_shape: int) -> None: | |
# super().__init__() | |
# self.conv_block_1 = nn.Sequential( | |
# nn.Conv2d(in_channels=input_shape, | |
# out_channels=hidden_units, | |
# kernel_size=3, | |
# stride=1, | |
# padding=0), | |
# nn.ReLU(), | |
# nn.Conv2d(in_channels=hidden_units, | |
# out_channels=hidden_units, | |
# kernel_size=3, | |
# stride=1, | |
# padding=0), | |
# nn.ReLU(), | |
# nn.MaxPool2d(kernel_size=2, | |
# stride=2) | |
# ) | |
# self.conv_block_2 = nn.Sequential( | |
# nn.Conv2d(hidden_units, hidden_units, kernel_size=3, padding=0), | |
# nn.ReLU(), | |
# nn.Conv2d(hidden_units, hidden_units, kernel_size=3, padding=0), | |
# nn.ReLU(), | |
# nn.MaxPool2d(2) | |
# ) | |
# self.classifier = nn.Sequential( | |
# nn.Flatten(), | |
# # Where did this in_features shape come from? | |
# # It's because each layer of our network compresses and changes the shape of our inputs data. | |
# nn.Linear(in_features=hidden_units*13*13, | |
# out_features=output_shape) | |
# ) | |
# | |
# def forward(self, x: torch.Tensor): | |
# x = self.conv_block_1(x) | |
# x = self.conv_block_2(x) | |
# x = self.classifier(x) | |
# return x | |
# # return self.classifier(self.block_2(self.block_1(x))) # <- leverage the benefits of operator fusion | |
# Commented out IPython magic to ensure Python compatibility. | |
# %%writefile utils.py | |
# | |
# #utils.py | |
# | |
# """ | |
# Contains various utility functions for PyTorch model training and saving. | |
# """ | |
# import torch | |
# from pathlib import Path | |
# | |
# def save_model(model: torch.nn.Module, | |
# target_dir: str, | |
# model_name: str): | |
# """Saves a PyTorch model to a target directory. | |
# | |
# Args: | |
# model: A target PyTorch model to save. | |
# target_dir: A directory for saving the model to. | |
# model_name: A filename for the saved model. Should include | |
# either ".pth" or ".pt" as the file extension. | |
# | |
# Example usage: | |
# save_model(model=model_0, | |
# target_dir="models", | |
# model_name="05_going_modular_tingvgg_model.pth") | |
# """ | |
# # Create target directory | |
# target_dir_path = Path(target_dir) | |
# target_dir_path.mkdir(parents=True, | |
# exist_ok=True) | |
# | |
# # Create model save path | |
# assert model_name.endswith(".pth") or model_name.endswith(".pt"), "model_name should end with '.pt' or '.pth'" | |
# model_save_path = target_dir_path / model_name | |
# | |
# # Save the model state_dict() | |
# print(f"[INFO] Saving model to: {model_save_path}") | |
# torch.save(obj=model.state_dict(), | |
# f=model_save_path) | |
# Commented out IPython magic to ensure Python compatibility. | |
# %%writefile engine.py | |
# #engine.py | |
# | |
# """ | |
# Contains functions for training and testing a PyTorch model. | |
# """ | |
# import torch | |
# | |
# from tqdm.auto import tqdm | |
# from typing import Dict, List, Tuple | |
# | |
# def train_step(model: torch.nn.Module, | |
# dataloader: torch.utils.data.DataLoader, | |
# loss_fn: torch.nn.Module, | |
# optimizer: torch.optim.Optimizer, | |
# device: torch.device) -> Tuple[float, float]: | |
# """Trains a PyTorch model for a single epoch. | |
# | |
# Turns a target PyTorch model to training mode and then | |
# runs through all of the required training steps (forward | |
# pass, loss calculation, optimizer step). | |
# | |
# Args: | |
# model: A PyTorch model to be trained. | |
# dataloader: A DataLoader instance for the model to be trained on. | |
# loss_fn: A PyTorch loss function to minimize. | |
# optimizer: A PyTorch optimizer to help minimize the loss function. | |
# device: A target device to compute on (e.g. "cuda" or "cpu"). | |
# | |
# Returns: | |
# A tuple of training loss and training accuracy metrics. | |
# In the form (train_loss, train_accuracy). For example: | |
# | |
# (0.1112, 0.8743) | |
# """ | |
# # Put model in train mode | |
# model.train() | |
# | |
# # Setup train loss and train accuracy values | |
# train_loss, train_acc = 0, 0 | |
# | |
# # Loop through data loader data batches | |
# for batch, (X, y) in enumerate(dataloader): | |
# # Send data to target device | |
# X, y = X.to(device), y.to(device) | |
# | |
# # 1. Forward pass | |
# y_pred = model(X) | |
# | |
# # 2. Calculate and accumulate loss | |
# loss = loss_fn(y_pred, y) | |
# train_loss += loss.item() | |
# | |
# # 3. Optimizer zero grad | |
# optimizer.zero_grad() | |
# | |
# # 4. Loss backward | |
# loss.backward() | |
# | |
# # 5. Optimizer step | |
# optimizer.step() | |
# | |
# # Calculate and accumulate accuracy metric across all batches | |
# y_pred_class = torch.argmax(torch.softmax(y_pred, dim=1), dim=1) | |
# train_acc += (y_pred_class == y).sum().item()/len(y_pred) | |
# | |
# # Adjust metrics to get average loss and accuracy per batch | |
# train_loss = train_loss / len(dataloader) | |
# train_acc = train_acc / len(dataloader) | |
# return train_loss, train_acc | |
# | |
# def test_step(model: torch.nn.Module, | |
# dataloader: torch.utils.data.DataLoader, | |
# loss_fn: torch.nn.Module, | |
# device: torch.device) -> Tuple[float, float]: | |
# """Tests a PyTorch model for a single epoch. | |
# | |
# Turns a target PyTorch model to "eval" mode and then performs | |
# a forward pass on a testing dataset. | |
# | |
# Args: | |
# model: A PyTorch model to be tested. | |
# dataloader: A DataLoader instance for the model to be tested on. | |
# loss_fn: A PyTorch loss function to calculate loss on the test data. | |
# device: A target device to compute on (e.g. "cuda" or "cpu"). | |
# | |
# Returns: | |
# A tuple of testing loss and testing accuracy metrics. | |
# In the form (test_loss, test_accuracy). For example: | |
# | |
# (0.0223, 0.8985) | |
# """ | |
# # Put model in eval mode | |
# model.eval() | |
# | |
# # Setup test loss and test accuracy values | |
# test_loss, test_acc = 0, 0 | |
# | |
# # Turn on inference context manager | |
# with torch.inference_mode(): | |
# # Loop through DataLoader batches | |
# for batch, (X, y) in enumerate(dataloader): | |
# # Send data to target device | |
# X, y = X.to(device), y.to(device) | |
# | |
# # 1. Forward pass | |
# test_pred_logits = model(X) | |
# | |
# # 2. Calculate and accumulate loss | |
# loss = loss_fn(test_pred_logits, y) | |
# test_loss += loss.item() | |
# | |
# # Calculate and accumulate accuracy | |
# test_pred_labels = test_pred_logits.argmax(dim=1) | |
# test_acc += ((test_pred_labels == y).sum().item()/len(test_pred_labels)) | |
# | |
# # Adjust metrics to get average loss and accuracy per batch | |
# test_loss = test_loss / len(dataloader) | |
# test_acc = test_acc / len(dataloader) | |
# return test_loss, test_acc | |
# | |
# def train(model: torch.nn.Module, | |
# train_dataloader: torch.utils.data.DataLoader, | |
# test_dataloader: torch.utils.data.DataLoader, | |
# optimizer: torch.optim.Optimizer, | |
# loss_fn: torch.nn.Module, | |
# epochs: int, | |
# device: torch.device) -> Dict[str, List]: | |
# """Trains and tests a PyTorch model. | |
# | |
# Passes a target PyTorch models through train_step() and test_step() | |
# functions for a number of epochs, training and testing the model | |
# in the same epoch loop. | |
# | |
# Calculates, prints and stores evaluation metrics throughout. | |
# | |
# Args: | |
# model: A PyTorch model to be trained and tested. | |
# train_dataloader: A DataLoader instance for the model to be trained on. | |
# test_dataloader: A DataLoader instance for the model to be tested on. | |
# optimizer: A PyTorch optimizer to help minimize the loss function. | |
# loss_fn: A PyTorch loss function to calculate loss on both datasets. | |
# epochs: An integer indicating how many epochs to train for. | |
# device: A target device to compute on (e.g. "cuda" or "cpu"). | |
# | |
# Returns: | |
# A dictionary of training and testing loss as well as training and | |
# testing accuracy metrics. Each metric has a value in a list for | |
# each epoch. | |
# In the form: {train_loss: [...], | |
# train_acc: [...], | |
# test_loss: [...], | |
# test_acc: [...]} | |
# For example if training for epochs=2: | |
# {train_loss: [2.0616, 1.0537], | |
# train_acc: [0.3945, 0.3945], | |
# test_loss: [1.2641, 1.5706], | |
# test_acc: [0.3400, 0.2973]} | |
# """ | |
# # Create empty results dictionary | |
# results = {"train_loss": [], | |
# "train_acc": [], | |
# "test_loss": [], | |
# "test_acc": [] | |
# } | |
# | |
# # Make sure model on target device | |
# model.to(device) | |
# | |
# # Loop through training and testing steps for a number of epochs | |
# for epoch in tqdm(range(epochs)): | |
# train_loss, train_acc = train_step(model=model, | |
# dataloader=train_dataloader, | |
# loss_fn=loss_fn, | |
# optimizer=optimizer, | |
# device=device) | |
# test_loss, test_acc = test_step(model=model, | |
# dataloader=test_dataloader, | |
# loss_fn=loss_fn, | |
# device=device) | |
# | |
# # Print out what's happening | |
# print( | |
# f"Epoch: {epoch+1} | " | |
# f"train_loss: {train_loss:.4f} | " | |
# f"train_acc: {train_acc:.4f} | " | |
# f"test_loss: {test_loss:.4f} | " | |
# f"test_acc: {test_acc:.4f}" | |
# ) | |
# | |
# # Update results dictionary | |
# results["train_loss"].append(train_loss) | |
# results["train_acc"].append(train_acc) | |
# results["test_loss"].append(test_loss) | |
# results["test_acc"].append(test_acc) | |
# | |
# # Return the filled results at the end of the epochs | |
# return results | |
# Commented out IPython magic to ensure Python compatibility. | |
# %%writefile data_setup.py | |
# #data_setup.py | |
# """ | |
# Contains functionality for creating PyTorch DataLoaders for | |
# image classification data. | |
# """ | |
# import os | |
# | |
# from torchvision import datasets, transforms | |
# from torch.utils.data import DataLoader | |
# | |
# NUM_WORKERS = os.cpu_count() | |
# | |
# def create_dataloaders( | |
# train_dir: str, | |
# test_dir: str, | |
# transform: transforms.Compose, | |
# batch_size: int, | |
# num_workers: int=NUM_WORKERS | |
# ): | |
# """Creates training and testing DataLoaders. | |
# | |
# Takes in a training directory and testing directory path and turns | |
# them into PyTorch Datasets and then into PyTorch DataLoaders. | |
# | |
# Args: | |
# train_dir: Path to training directory. | |
# test_dir: Path to testing directory. | |
# transform: torchvision transforms to perform on training and testing data. | |
# batch_size: Number of samples per batch in each of the DataLoaders. | |
# num_workers: An integer for number of workers per DataLoader. | |
# | |
# Returns: | |
# A tuple of (train_dataloader, test_dataloader, class_names). | |
# Where class_names is a list of the target classes. | |
# Example usage: | |
# train_dataloader, test_dataloader, class_names = \ | |
# = create_dataloaders(train_dir=path/to/train_dir, | |
# test_dir=path/to/test_dir, | |
# transform=some_transform, | |
# batch_size=32, | |
# num_workers=4) | |
# """ | |
# # Use ImageFolder to create dataset(s) | |
# train_data = datasets.ImageFolder(train_dir, transform=transform) | |
# test_data = datasets.ImageFolder(test_dir, transform=transform) | |
# | |
# # Get class names | |
# class_names = train_data.classes | |
# | |
# # Turn images into data loaders | |
# train_dataloader = DataLoader( | |
# train_data, | |
# batch_size=batch_size, | |
# shuffle=True, | |
# num_workers=num_workers, | |
# pin_memory=True, | |
# ) | |
# test_dataloader = DataLoader( | |
# test_data, | |
# batch_size=batch_size, | |
# shuffle=False, | |
# num_workers=num_workers, | |
# pin_memory=True, | |
# ) | |
# | |
# return train_dataloader, test_dataloader, class_names | |
# Commented out IPython magic to ensure Python compatibility. | |
# %%writefile train.py | |
# #train.py only in this cell | |
# | |
# """ | |
# Trains a PyTorch image classification model using device-agnostic code. | |
# """ | |
# | |
# import os | |
# import torch | |
# #import data_setup, engine, model_builder, utils | |
# | |
# from torchvision import transforms | |
# | |
# # Setup hyperparameters | |
# NUM_EPOCHS = 5 | |
# BATCH_SIZE = 32 | |
# HIDDEN_UNITS = 10 | |
# LEARNING_RATE = 0.001 | |
# | |
# # Setup directories | |
# train_dir = "data/pizza_steak_sushi/train" | |
# test_dir = "data/pizza_steak_sushi/test" | |
# | |
# # Setup target device | |
# device = "cuda" if torch.cuda.is_available() else "cpu" | |
# | |
# # Create transforms | |
# data_transform = transforms.Compose([ | |
# transforms.Resize((64, 64)), | |
# transforms.ToTensor() | |
# ]) | |
# | |
# # Create DataLoaders with help from data_setup.py | |
# train_dataloader, test_dataloader, class_names = data_setup.create_dataloaders( | |
# train_dir=train_dir, | |
# test_dir=test_dir, | |
# transform=data_transform, | |
# batch_size=BATCH_SIZE | |
# ) | |
# | |
# # Create model with help from model_builder.py | |
# model = model_builder.TinyVGG( | |
# input_shape=3, | |
# hidden_units=HIDDEN_UNITS, | |
# output_shape=len(class_names) | |
# ).to(device) | |
# | |
# # Set loss and optimizer | |
# loss_fn = torch.nn.CrossEntropyLoss() | |
# optimizer = torch.optim.Adam(model.parameters(), | |
# lr=LEARNING_RATE) | |
# | |
# # Start training with help from engine.py | |
# engine.train(model=model, | |
# train_dataloader=train_dataloader, | |
# test_dataloader=test_dataloader, | |
# loss_fn=loss_fn, | |
# optimizer=optimizer, | |
# epochs=NUM_EPOCHS, | |
# device=device) | |
# | |
# # Save the model with help from utils.py | |
# utils.save_model(model=model, | |
# target_dir="models", | |
# model_name="05_going_modular_script_mode_tinyvgg_model.pth") | |
# | |
# | |
# | |
# | |
!python /content/data_setup.py/train.py --batch_size 64 --learning_rate 0.001 --num_epochs 25 | |
# 1. Get pretrained weights for ViT-Base | |
pretrained_vit_weights = torchvision.models.ViT_B_16_Weights.DEFAULT | |
# 2. Setup a ViT model instance with pretrained weights | |
pretrained_vit = torchvision.models.vit_b_16(weights=pretrained_vit_weights).to(device) | |
# 3. Freeze the base parameters | |
for parameter in pretrained_vit.parameters(): | |
parameter.requires_grad = False | |
# 4. Change the classifier head | |
class_names = ['Bad_tire','Good_tire'] | |
set_seeds() | |
pretrained_vit.heads = nn.Linear(in_features=768, out_features=len(class_names)).to(device) | |
# pretrained_vit # uncomment for model output | |
from torchinfo import summary | |
# Print a summary using torchinfo (uncomment for actual output) | |
summary(model=pretrained_vit, | |
input_size=(32, 3, 224, 224), # (batch_size, color_channels, height, width) | |
#col_names=["input_size"], # uncomment for smaller output | |
col_names=["input_size", "output_size", "num_params", "trainable"], | |
col_width=20, | |
row_settings=["var_names"] | |
) | |
# Setup directory paths to train and test images | |
train_dir = '/content/drive/MyDrive/Test/test' | |
test_dir = '/content/drive/MyDrive/Train/train' | |
# Get automatic transforms from pretrained ViT weights | |
pretrained_vit_transforms = pretrained_vit_weights.transforms() | |
print(pretrained_vit_transforms) | |
import os | |
from torchvision import datasets, transforms | |
from torch.utils.data import DataLoader | |
NUM_WORKERS = os.cpu_count() | |
def create_dataloaders( | |
train_dir: str, | |
test_dir: str, | |
transform: transforms.Compose, | |
batch_size: int, | |
num_workers: int=NUM_WORKERS | |
): | |
# Use ImageFolder to create dataset(s) | |
train_data = datasets.ImageFolder(train_dir, transform=transform) | |
test_data = datasets.ImageFolder(test_dir, transform=transform) | |
# Get class names | |
class_names = train_data.classes | |
# Turn images into data loaders | |
train_dataloader = DataLoader( | |
train_data, | |
batch_size=batch_size, | |
shuffle=True, | |
num_workers=num_workers, | |
pin_memory=True, | |
) | |
test_dataloader = DataLoader( | |
test_data, | |
batch_size=batch_size, | |
shuffle=False, | |
num_workers=num_workers, | |
pin_memory=True, | |
) | |
return train_dataloader, test_dataloader, class_names | |
# Setup dataloaders | |
train_dataloader_pretrained, test_dataloader_pretrained, class_names = create_dataloaders( | |
train_dir=train_dir, | |
test_dir=test_dir, | |
transform=pretrained_vit_transforms, | |
batch_size=32) # Could increase if we had more samples, such as here: https://arxiv.org/abs/2205.01580 (there are other improvements there too...) | |
#import data_setup.py | |
!python train.py --batch_size 64 --learning_rate 0.001 --num_epochs 25 | |
import engine | |
# Create optimizer and loss function | |
optimizer = torch.optim.Adam(params=pretrained_vit.parameters(), | |
lr=1e-3) | |
loss_fn = torch.nn.CrossEntropyLoss() | |
# Train the classifier head of the pretrained ViT feature extractor model | |
set_seeds() | |
pretrained_vit_results = engine.train(model=pretrained_vit, | |
train_dataloader=train_dataloader_pretrained, | |
test_dataloader=test_dataloader_pretrained, | |
optimizer=optimizer, | |
loss_fn=loss_fn, | |
epochs=10, | |
device=device) | |
# Commented out IPython magic to ensure Python compatibility. | |
# %%writefile helper_functions.py | |
# | |
# # helper_functions.py | |
# | |
# """ | |
# A series of helper functions used throughout the course. | |
# | |
# If a function gets defined once and could be used over and over, it'll go in here. | |
# """ | |
# import torch | |
# import matplotlib.pyplot as plt | |
# import numpy as np | |
# | |
# from torch import nn | |
# import os | |
# import zipfile | |
# from pathlib import Path | |
# import requests | |
# import os | |
# | |
# | |
# | |
# # Plot linear data or training and test and predictions (optional) | |
# def plot_predictions( | |
# train_data, train_labels, test_data, test_labels, predictions=None | |
# ): | |
# """ | |
# Plots linear training data and test data and compares predictions. | |
# """ | |
# plt.figure(figsize=(10, 7)) | |
# | |
# # Plot training data in blue | |
# plt.scatter(train_data, train_labels, c="b", s=4, label="Training data") | |
# | |
# # Plot test data in green | |
# plt.scatter(test_data, test_labels, c="g", s=4, label="Testing data") | |
# | |
# if predictions is not None: | |
# # Plot the predictions in red (predictions were made on the test data) | |
# plt.scatter(test_data, predictions, c="r", s=4, label="Predictions") | |
# | |
# # Show the legend | |
# plt.legend(prop={"size": 14}) | |
# | |
# | |
# # Calculate accuracy (a classification metric) | |
# def accuracy_fn(y_true, y_pred): | |
# """Calculates accuracy between truth labels and predictions. | |
# | |
# Args: | |
# y_true (torch.Tensor): Truth labels for predictions. | |
# y_pred (torch.Tensor): Predictions to be compared to predictions. | |
# | |
# Returns: | |
# [torch.float]: Accuracy value between y_true and y_pred, e.g. 78.45 | |
# """ | |
# correct = torch.eq(y_true, y_pred).sum().item() | |
# acc = (correct / len(y_pred)) * 100 | |
# return acc | |
# | |
# | |
# def print_train_time(start, end, device=None): | |
# """Prints difference between start and end time. | |
# | |
# Args: | |
# start (float): Start time of computation (preferred in timeit format). | |
# end (float): End time of computation. | |
# device ([type], optional): Device that compute is running on. Defaults to None. | |
# | |
# Returns: | |
# float: time between start and end in seconds (higher is longer). | |
# """ | |
# total_time = end - start | |
# print(f"\nTrain time on {device}: {total_time:.3f} seconds") | |
# return total_time | |
# | |
# | |
# # Plot loss curves of a model | |
# def plot_loss_curves(results): | |
# """Plots training curves of a results dictionary. | |
# | |
# Args: | |
# results (dict): dictionary containing list of values, e.g. | |
# {"train_loss": [...], | |
# "train_acc": [...], | |
# "test_loss": [...], | |
# "test_acc": [...]} | |
# """ | |
# loss = results["train_loss"] | |
# test_loss = results["test_loss"] | |
# | |
# accuracy = results["train_acc"] | |
# test_accuracy = results["test_acc"] | |
# | |
# epochs = range(len(results["train_loss"])) | |
# | |
# plt.figure(figsize=(15, 7)) | |
# | |
# # Plot loss | |
# plt.subplot(1, 2, 1) | |
# plt.plot(epochs, loss, label="train_loss") | |
# plt.plot(epochs, test_loss, label="test_loss") | |
# plt.title("Loss") | |
# plt.xlabel("Epochs") | |
# plt.legend() | |
# | |
# # Plot accuracy | |
# plt.subplot(1, 2, 2) | |
# plt.plot(epochs, accuracy, label="train_accuracy") | |
# plt.plot(epochs, test_accuracy, label="test_accuracy") | |
# plt.title("Accuracy") | |
# plt.xlabel("Epochs") | |
# plt.legend() | |
# | |
# | |
# # Pred and plot image function from notebook 04 | |
# # See creation: https://www.learnpytorch.io/04_pytorch_custom_datasets/#113-putting-custom-image-prediction-together-building-a-function | |
# from typing import List | |
# import torchvision | |
# | |
# | |
# def pred_and_plot_image( | |
# model: torch.nn.Module, | |
# image_path: str, | |
# class_names: List[str] = None, | |
# transform=None, | |
# device: torch.device = "cuda" if torch.cuda.is_available() else "cpu", | |
# ): | |
# """Makes a prediction on a target image with a trained model and plots the image. | |
# | |
# Args: | |
# model (torch.nn.Module): trained PyTorch image classification model. | |
# image_path (str): filepath to target image. | |
# class_names (List[str], optional): different class names for target image. Defaults to None. | |
# transform (_type_, optional): transform of target image. Defaults to None. | |
# device (torch.device, optional): target device to compute on. Defaults to "cuda" if torch.cuda.is_available() else "cpu". | |
# | |
# Returns: | |
# Matplotlib plot of target image and model prediction as title. | |
# | |
# Example usage: | |
# pred_and_plot_image(model=model, | |
# image="some_image.jpeg", | |
# class_names=["class_1", "class_2", "class_3"], | |
# transform=torchvision.transforms.ToTensor(), | |
# device=device) | |
# """ | |
# | |
# # 1. Load in image and convert the tensor values to float32 | |
# target_image = torchvision.io.read_image(str(image_path)).type(torch.float32) | |
# | |
# # 2. Divide the image pixel values by 255 to get them between [0, 1] | |
# target_image = target_image / 255.0 | |
# | |
# # 3. Transform if necessary | |
# if transform: | |
# target_image = transform(target_image) | |
# | |
# # 4. Make sure the model is on the target device | |
# model.to(device) | |
# | |
# # 5. Turn on model evaluation mode and inference mode | |
# model.eval() | |
# with torch.inference_mode(): | |
# # Add an extra dimension to the image | |
# target_image = target_image.unsqueeze(dim=0) | |
# | |
# # Make a prediction on image with an extra dimension and send it to the target device | |
# target_image_pred = model(target_image.to(device)) | |
# | |
# # 6. Convert logits -> prediction probabilities (using torch.softmax() for multi-class classification) | |
# target_image_pred_probs = torch.softmax(target_image_pred, dim=1) | |
# | |
# # 7. Convert prediction probabilities -> prediction labels | |
# target_image_pred_label = torch.argmax(target_image_pred_probs, dim=1) | |
# | |
# # 8. Plot the image alongside the prediction and prediction probability | |
# plt.imshow( | |
# target_image.squeeze().permute(1, 2, 0) | |
# ) # make sure it's the right size for matplotlib | |
# if class_names: | |
# title = f"Pred: {class_names[target_image_pred_label.cpu()]} | Prob: {target_image_pred_probs.max().cpu():.3f}" | |
# else: | |
# title = f"Pred: {target_image_pred_label} | Prob: {target_image_pred_probs.max().cpu():.3f}" | |
# plt.title(title) | |
# plt.axis(False) | |
# | |
# def set_seeds(seed: int=42): | |
# """Sets random sets for torch operations. | |
# | |
# Args: | |
# seed (int, optional): Random seed to set. Defaults to 42. | |
# """ | |
# # Set the seed for general torch operations | |
# torch.manual_seed(seed) | |
# # Set the seed for CUDA torch operations (ones that happen on the GPU) | |
# torch.cuda.manual_seed(seed) | |
# | |
# Plot the loss curves | |
from helper_functions import plot_loss_curves | |
plot_loss_curves(pretrained_vit_results) | |
import requests | |
# Import function to make predictions on images and plot them | |
from predict import pred_and_plot_image | |
# Setup custom image path | |
custom_image_path = "/content/drive/MyDrive/validation/Bad_Tire (3).jpg" | |
# Predict on custom image | |
pred_and_plot_image(model=pretrained_vit, | |
image_path=custom_image_path, | |
class_names=class_names) | |
# Import function to make predictions on images and plot them | |
from predict import pred_and_plot_image | |
# Setup custom image path | |
custom_image_path = "/content/drive/MyDrive/validation/Good_Tire (4).jpg" | |
# Predict on custom image | |
pred_and_plot_image(model=pretrained_vit, | |
image_path=custom_image_path, | |
class_names=class_names) |