<jupyter_start><jupyter_text>Run this only once to extract the image files.- Use the below code when you have the zip and you want to extract it.```    import zipfile as zp    zipExtract = zp.ZipFile('./dataSample.zip','r')    zipExtract.extractall('./')    zipExtract.close()```<jupyter_code>#Import Required Libraries

%matplotlib inline
import torch
import torchvision
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torchvision import  datasets,models, transforms

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

import os
# Define the data directories - Replace them with your train,test and validation dataset.
data_directory = 'dataset2-master/images/'
train_dir = data_directory + 'TRAIN/'
valid_dir = data_directory + 'TEST/'
test_dir = data_directory + 'TEST_SIMPLE/'

train_transforms = transforms.Compose([transforms.Resize(size=(224,224)),
                                        transforms.ToTensor(),
                                       transforms.Normalize([0.5,0.5,0.5], 
                                                            [0.5,0.5,0.5])])
testval_transforms = transforms.Compose([transforms.Resize(size=(224,224)),
                                      transforms.ToTensor(),
                                      transforms.Normalize([0.5,0.5,0.5], 
                                                            [0.5,0.5,0.5])])

image_trainset = datasets.ImageFolder(train_dir, transform=train_transforms)
image_testset = datasets.ImageFolder(test_dir, transform=testval_transforms)
image_valset = datasets.ImageFolder(valid_dir, transform=testval_transforms)

image_trainloader = torch.utils.data.DataLoader(image_trainset, batch_size=20, shuffle=True)
image_testloader = torch.utils.data.DataLoader(image_testset, batch_size=20, shuffle=True)
image_valloader = torch.utils.data.DataLoader(image_valset, batch_size=20, shuffle=True)
classes = ['EOSINOPHIL','LYMPHOCYTE','MONOCYTE','NEUTROPHIL']
def imshow(image, predicted=None, ax=None, title=None):
    if ax is None:
        fig, ax = plt.subplots()
    
    # PyTorch tensors assume the color channel is the first dimension
    # but matplotlib assumes is the third dimension
    image = image.numpy().transpose((1, 2, 0))
    
    # Undo preprocessing
    mean = np.array([0.5, 0.5, 0.5])
    std = np.array([0.5, 0.5, 0.5])
    image = std * image + mean
    
    # Image needs to be clipped between 0 and 1 or it looks like noise when displayed
    image = np.clip(image, 0, 1)
    
    ax.imshow(image)
    
    return ax
dataiter = iter(image_testloader)
images, labels = next(dataiter)
images = images # convert images to numpy for display

imshow(images[0])
#checking the first element in the labels batch
labels
image_trainset.class_to_idx
(image_trainset.classes)[labels[0]]
# check if CUDA is available
train_on_gpu = torch.cuda.is_available()

if not train_on_gpu:
    print('CUDA is not available.  Training on CPU ...')
else:
    print('CUDA is available!  Training on GPU ...')
torch.cuda.get_device_name(0)
class NeuralNet(nn.Module):
    def __init__(self):
        super(NeuralNet, self).__init__()
        self.conv1 = nn.Conv2d(
            in_channels=3, out_channels=16, kernel_size=3, stride=1, padding=1)
        self.conv2 = nn.Conv2d(16, 32, 3, padding=1)
        self.conv3 = nn.Conv2d(32, 64, 3, padding=1)
        self.pool = nn.MaxPool2d(2, 2)
        self.fc1 = nn.Linear(64 * 28 * 28, 784)
        self.fc2 = nn.Linear(784, 196)
        self.fc3 = nn.Linear(196, 4)
        self.dropout = nn.Dropout(0.25)
        self.softmax = nn.LogSoftmax(dim=1)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = self.pool(F.relu(self.conv3(x)))
        x = x.view(-1, 64 * 28 * 28)
        x = self.dropout(x)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        x = self.softmax(x)
        return x

model = NeuralNet()
print(model)


# move tensors to GPU if CUDA is available
if train_on_gpu:
    model.cuda()
#Criterion
criterion = nn.CrossEntropyLoss()

#Optimizer
optimizer = optim.SGD(model.parameters(), lr=0.01)

# number of epochs to train the model
n_epochs = 30

valid_loss_min = np.Inf # track change in validation loss

for epoch in range(1, n_epochs+1):

    # keep track of training and validation loss
    train_loss = 0.0
    valid_loss = 0.0

    model.train()
    for data, target in image_trainloader:
        # move tensors to GPU if CUDA is available
        if train_on_gpu:
            data, target = data.cuda(), target.cuda()
        # clear the gradients of all optimized variables
        optimizer.zero_grad()
        # forward pass: compute predicted outputs by passing inputs to the model
        output = model(data)
        # calculate the batch loss
        loss = criterion(output, target)
        # backward pass: compute gradient of the loss with respect to model parameters
        loss.backward()
        # perform a single optimization step (parameter update)
        optimizer.step()
        # update training loss
        train_loss += loss.item()*data.size(0)

    # Validation Stage
    model.eval()
    for data, target in image_valloader:
        # move tensors to GPU if CUDA is available
        if train_on_gpu:
            data, target = data.cuda(), target.cuda()
        # forward pass: compute predicted outputs by passing inputs to the model
        output = model(data)
        # calculate the batch loss
        loss = criterion(output, target)
        # update average validation loss 
        valid_loss += loss.item()*data.size(0)
    
    # calculate average losses
    train_loss = train_loss/len(image_trainloader.dataset)
    valid_loss = valid_loss/len(image_valloader.dataset)
        
    # print training/validation statistics 
    print('Epoch: {} \tTraining Loss: {:.6f} \tValidation Loss: {:.6f}'.format(
        epoch, train_loss, valid_loss))
    
    # save model if validation loss has decreased
    if valid_loss <= valid_loss_min:
        print('Validation loss decreased ({:.4f} --> {:.4f}).  Saving model ...'.format(
        valid_loss_min,
        valid_loss))
        torch.save(model.state_dict(), 'saveCheck3.pt')
        valid_loss_min = valid_loss
model.load_state_dict(torch.load('saveCheck2.pt'))
def process_image(image):
    image_PIL = Image.open(image)
    
    image_modifications = transforms.Compose([
        transforms.Resize(size=(224,224)),
        transforms.ToTensor(),
        transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
    ])
    
    image_tensor = image_modifications(image_PIL) #Applying transforms on the image
    
    return image_tensor

image_proccessed = process_image(test_dir + "/EOSINOPHIL/_0_5239.jpeg")

imshow(image_proccessed)
def predict(image_path, model):
    model.eval()
    image_predict_processed = process_image(image_path)
    processed = image_predict_processed.unsqueeze(0).cuda()
    with torch.no_grad():
        output = model.forward(processed)
    prob = torch.exp(output)
    predict_cpu_value = prob.cpu()
    predicted_type_index = torch.argmax(predict_cpu_value).item()
    predicted = classes[predicted_type_index]
    if predicted in [classes[1],classes[2]]:
        print(predicted,'Mononuclear')
    else:
        print(predicted,'Polynuclear')
    imshow(image_predict_processed,predicted)
    plt.figure()
    plt.bar(classes,predict_cpu_value[0].numpy())
    plt.show()
    
    return predicted
predict('dataset2-master/images/TEST/EOSINOPHIL/_0_1616.jpeg',model)
model<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10962846677132392, 'fraction_numerical': 0.023940345368916798, 'mean_word_length': 2.88268156424581, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '591925', 'license': 'MIT', 'n_tokens_mistral': 2523, 'n_tokens_neox': 2407, 'n_words': 591, 'path': 'Image Classification - P or M.ipynb', 'repo_name': 'yashwanthkorla/Predicting-Polynuclear-or-Mononuclear', 'size': '7644'}