application_vnd.jupyter.stderr_output_1.png
from PIL import Image

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, classification_report, ConfusionMatrixDisplay, confusion_matrix, roc_curve, auc

from sklearn.metrics import confusion_matrix, roc_curve, auc

from torch import nn

from torch.optim import Adam

from torch.utils.data import Dataset, DataLoader

from torchvision import transforms

from tqdm.notebook import tqdm

import matplotlib.pyplot as plt

import os

import pandas as pd

import timm

import torch

import numpy as np
import pandas as pd
import os
import cv2
import matplotlib.pyplot as plt
import torch
from torch import nn
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms
from torch.optim import Adam
import glob
from tqdm.notebook import tqdm
from PIL import Image
import torchvision
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, classification_report, ConfusionMatrixDisplay, confusion_matrix, roc_curve, auc
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

class BreastCancerDataset(Dataset):
    def __init__(self, data_path_file, train=True):
        super(Dataset, self).__init__()
        self.data = pd.read_csv(data_path_file, index_col=0)
        self.global_path = '/kaggle/input/meta-data/Data_image'
        if train:
            self.transform = transforms.Compose([transforms.Grayscale(num_output_channels=3), transforms.Resize(size=(224, 224)), transforms.RandomHorizontalFlip(), transforms.RandomRotation(10), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])
        else:
            self.transform = transforms.Compose([transforms.Grayscale(num_output_channels=3), transforms.Resize(size=(224, 224)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])
    def __len__(self):
        return len(self.data)
    def __getitem__(self, idx):
        row = self.data.iloc[idx]
        label = row['status']
        img_path = os.path.join(self.global_path, row['Path'])
        labels = torch.tensor(label)
        image = Image.open(img_path)
        if self.transform:
            image = self.transform(image)
        return (image, labels)

path_train_fold_0 = '/kaggle/input/data-ddsm-cdd-mias/DDSM/DDSM/DDSM_Fold_4/train_DDSM_fold_3.csv'
path_val_fold_0 = '/kaggle/input/data-ddsm-cdd-mias/DDSM/DDSM/DDSM_Fold_4/valid_DDSM_fold_3.csv'
path_test_DDSM = '/kaggle/input/data-ddsm-cdd-mias/Data_Test/Data_Test/Test_ddsm.csv'

train_dataset = BreastCancerDataset(path_train_fold_0, train=True)
val_dataset = BreastCancerDataset(path_val_fold_0, train=False)
test_dataset_DDSM = BreastCancerDataset(path_test_DDSM, train=False)

batch_size = 64
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=True)
test_loader_DDSM = DataLoader(test_dataset_DDSM, batch_size=batch_size, shuffle=True)

def save_model(epochs, model, optimizer, criterion, pretrained='True'):
    """
    Function to save the trained model to disk.
    """
    torch.save({'epoch': epochs, 'model_state_dict': model.state_dict(), 'optimizer_state_dict': optimizer.state_dict(), 'loss': criterion}, f'/kaggle/working/model_pretrained_{pretrained}_{epochs}.pth')

def save_plots(train_acc, valid_acc, train_loss, valid_loss, pretrained='True'):
    """
    Function to save the loss and accuracy plots to disk.
    """

import timm
model = timm.create_model('hrnet_w18', pretrained=True, num_classes=3)
criterion = nn.CrossEntropyLoss()
optimizer = Adam(model.parameters(), lr=0.001)

list_acc_train, list_acc_val, list_loss_train, list_loss_val = ([], [], [], [])
num_epochs = 100
best_f1 = 0.0
for epoch in tqdm(range(1, num_epochs + 1)):
    model.train()
    train_loss = 0.0
    train_acc = 0.0
    total = 0
    for inputs, labels in tqdm(train_loader):
        optimizer.zero_grad()
        model.to(device)
        inputs, labels = (inputs.to(device), labels.to(device))
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        train_loss += loss.item()
        predicted = torch.max(outputs, 1)[1].to(device)
        total += labels.size(0)
        train_acc += (predicted == labels).sum().item()
    train_acc /= total
    train_loss /= len(train_loader)
    list_loss_train.append(train_loss)
    list_acc_train.append(train_acc)
    model.eval()
    with torch.no_grad():
        val_loss = 0.0
        val_acc = 0.0
        f1_scr = 0.0
        total = 0.0
        label_list, label_pred_list = ([], [])
        for inputs, labels in val_loader:
            inputs, labels = (inputs.to(device), labels.to(device))
            outputs = model(inputs)
            loss = criterion(outputs, labels)
            val_loss += loss.item()
            predicted = torch.max(outputs, 1)[1].to(device)
            total += labels.size(0)
            val_acc += (predicted == labels).sum().item()
            label_list.append(labels)
            label_pred_list.append(predicted)
        val_acc = val_acc / total
        label_list, label_pred_list = (torch.cat(label_list, 0), torch.cat(label_pred_list, 0))
        f1_scr = f1_score(label_list.cpu(), label_pred_list.cpu(), average='macro')
        val_loss /= len(val_loader)
        list_loss_val.append(val_loss)
        list_acc_val.append(val_acc)
    if f1_scr > best_f1:
        best_f1 = f1_scr
        save_model(epoch, model, optimizer, criterion)
history = {'loss_train': list_loss_train, 'acc_train': list_acc_train, 'loss_val': list_loss_val, 'acc_val': list_acc_val}
df_history = pd.DataFrame(history)
df_history.to_csv('/kaggle/working/history.csv')

from sklearn.metrics import confusion_matrix, roc_curve, auc
with torch.no_grad():
    y_true = []
    y_pred = []
    for inputs, labels in tqdm(test_loader_DDSM):
        inputs = inputs.to(device)
        labels = labels.to(device)
        model.to(device)
        outputs = model(inputs)
        predicted = torch.max(outputs, dim=1)[1]
        y_true += labels.tolist()
        y_pred += predicted.tolist()
accuracy = accuracy_score(y_true, y_pred)
precision = precision_score(y_true, y_pred, average='weighted')
recall = recall_score(y_true, y_pred, average='weighted')
f1 = f1_score(y_true, y_pred, average='weighted')
fpr, tpr, thresholds = roc_curve(y_true, y_pred, pos_label=3)
auc_score = auc(fpr, tpr)
print(f'Accuracy: {accuracy:.2f}')
print(f'Precision: {precision:.2f}')
print(f'Recall: {recall:.2f}')
print(f'F1 score: {f1:.2f}')
print(f'AUC score : {f1:.2f}')
cm = confusion_matrix(y_true, y_pred)
cr = classification_report(y_true, y_pred)
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=['normal', 'benign', 'malignant'])
disp.plot()
plt.savefig('confusion_matrix_DDSM.png')
plt.show()