<jupyter_start><jupyter_text>Cat Dog Classifier It is a image classification model developed using Transfer Learning from the densenet121 pretrained model.  Imports<jupyter_code>%matplotlib inline
%config InlineBackend.figure_format = 'retina'

import matplotlib.pyplot as plt

import torch
from torch import nn
from torch import optim
import torch.nn.functional as F
from torchvision import datasets, transforms, models<jupyter_output><empty_output><jupyter_text>Pre-processing<jupyter_code># Base data path
data_dir = './data/Cat_Dog_data/Cat_Dog_data' # Add path to your data

# Randomising and normalizing the train data, i.e. using data augmentation for getting a variation of data that is not actually present in the dataset

train_transform = transforms.Compose([
    transforms.RandomRotation(30),
    transforms.RandomResizedCrop(224),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])
])

# Performing basic crop and normalization of the test data, for correct testing

test_transform = transforms.Compose([
    transforms.Resize(255),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])
])

# defining train and test data paths
train_data = datasets.ImageFolder(data_dir + '/train', transform=train_transform)
test_data = datasets.ImageFolder(data_dir + '/test', transform=test_transform)

# Initializing PyTorch loaders for train and test data using a batch size of 64
trainloader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)
testloader = torch.utils.data.DataLoader(test_data, batch_size=64)<jupyter_output><empty_output><jupyter_text>Model<jupyter_code>device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

model = models.densenet121(pretrained=True)

for param in model.parameters():
    param.requires_grad = False

model.classifier = nn.Sequential(
    nn.Linear(1024, 256),
    nn.ReLU(),
    nn.Dropout(0.2),
    nn.Linear(256, 2),
    nn.LogSoftmax(dim=1)
)

criterion = nn.NLLLoss()

optimizer = optim.Adam(model.classifier.parameters(), lr=0.003)

model.to(device);<jupyter_output><empty_output><jupyter_text>Training Loot<jupyter_code>epochs = 1
steps = 0
running_loss = 0
print_every = 5
for epoch in range(epochs):
    for inputs, labels in trainloader:
        steps += 1
        inputs, labels = inputs.to(device), labels.to(device)

        optimizer.zero_grad()

        logps = model.forward(inputs)
        loss = criterion(logps, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()

        if steps % print_every == 0:
            test_loss = 0
            accuracy = 0
            model.eval()
            with torch.no_grad():
                for inputs, labels in testloader:
                    inputs, labels = inputs.to(device), labels.to(device)
                    logps = model.forward(inputs)
                    batch_loss = criterion(logps, labels)
                    test_loss += batch_loss.item()

                    ps = torch.exp(logps)
                    top_p, top_class = ps.topk(1, dim=1)
                    equals = top_class == labels.view(*top_class.shape)
                    accuracy += torch.mean(equals.type(torch.FloatTensor)).item()

            print(f"Epoch {epoch+1}/{epochs}.. "
                  f"Train loss: {running_loss/print_every:.3f}.. "
                  f"Test loss: {test_loss/len(testloader):.3f}.. "
                  f"Test accuracy: {accuracy/len(testloader):.3f}")
            running_loss = 0
            model.train()<jupyter_output><empty_output><jupyter_text>Saving Model<jupyter_code>torch.save(model, "./model.pth")<jupyter_output><empty_output><jupyter_text>Using local image to test real world use caseFeel free to use your own images<jupyter_code>img_path = './cat_test.jpg'
loaded_model = torch.load('./model.pth')
loaded_model.eval()
eval_transforms = transforms.Compose([
    transforms.Resize(255),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])
])
import io
from PIL import Image
def transform_image(image_bytes):
    image = Image.open(io.BytesIO(image_bytes))
    return eval_transforms(image).unsqueeze(0)
with open('img_path', 'rb') as f:
    image_bytes = f.read()
    tensor = transform_image(image_bytes=image_bytes)
    print(tensor)
def get_prediction(image_bytes):
    tensor = transform_image(image_bytes=image_bytes)
    tensor = tensor.to(device)
    outputs = loaded_model.forward(tensor)
    _, y_hat = outputs.max(1)
    return y_hat
with open('./cat_test.jpg', 'rb') as f:
    image_bytes = f.read()
    y_hat = get_prediction(image_bytes)
    class_label = y_hat.to("cpu").numpy()
    print(class_dict[class_label[0]])<jupyter_output><empty_output><jupyter_text>Mapping 0-1 classes to human readable class labels<jupyter_code>class_dict = {0: 'cat', 1: 'dog'}<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1171332142148104, 'fraction_numerical': 0.02799285288862418, 'mean_word_length': 3.6009132420091325, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '362450', 'license': 'MIT', 'n_tokens_mistral': 1739, 'n_tokens_neox': 1620, 'n_words': 349, 'path': 'cat-dog-classifier.ipynb', 'repo_name': 'rajrohanyadav/cat-dog-classifier', 'size': '5037'}