Spaces:
Running
Running
File size: 34,272 Bytes
faf90bc |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"id": "f7c4548e-c6b2-48dc-9df1-58a7c06481d8",
"metadata": {},
"outputs": [],
"source": [
"import torch\n",
"from sklearn.metrics import classification_report, confusion_matrix, accuracy_score\n",
"import seaborn as sns\n",
"import matplotlib.pyplot as plt\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "9bd4822d-3ccd-416d-a03f-a0eda7b2bfaa",
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"# Import custom modules\n",
"from models.resnet_model import MalariaResNet50\n",
"from data_prep import get_dataloaders"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "91ac3fe5-c5d7-497d-9a6d-2903f6b97bf7",
"metadata": {},
"outputs": [],
"source": [
"MODEL_PATH = 'models/malaria_model.pth'"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "1c7e9e80-2986-4979-8450-6821e6e0a3a8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Total Classes: 2\n",
"Train batches: 689, Val batches: 87, Test batches: 87\n",
"Using device: cuda\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/conda/lib/python3.12/site-packages/torchvision/models/_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and may be removed in the future. The current behavior is equivalent to passing `weights=ResNet50_Weights.IMAGENET1K_V1`. You can also use `weights=ResNet50_Weights.DEFAULT` to get the most up-to-date weights.\n",
" warnings.warn(msg)\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model loaded from models/malaria_model.pth\n",
"Running inference on test set...\n",
"\n",
"Test Accuracy: 0.9699\n",
"\n",
"Classification Report:\n",
" precision recall f1-score support\n",
"\n",
" Parasitized 0.97 0.97 0.97 1378\n",
" Uninfected 0.97 0.97 0.97 1378\n",
"\n",
" accuracy 0.97 2756\n",
" macro avg 0.97 0.97 0.97 2756\n",
"weighted avg 0.97 0.97 0.97 2756\n",
"\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 600x500 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"def evaluate():\n",
" # Get all loaders and datasets\n",
" train_loader, val_loader, test_loader, train_dataset, val_dataset, test_dataset = get_dataloaders()\n",
"\n",
" # Define device\n",
" device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
" print(f\"Using device: {device}\")\n",
"\n",
" # Initialize and load model\n",
" model = MalariaResNet50(num_classes=2)\n",
" model.load(MODEL_PATH)\n",
" model = model.to(device)\n",
" model.eval() # Set to evaluation mode\n",
"\n",
" # Get test data\n",
" y_true = []\n",
" y_pred = []\n",
"\n",
" print(\"Running inference on test set...\")\n",
" with torch.no_grad():\n",
" for inputs, labels in test_loader:\n",
" inputs = inputs.to(device)\n",
" labels = labels.to(device)\n",
"\n",
" outputs = model(inputs)\n",
" _, preds = torch.max(outputs, 1)\n",
"\n",
" y_true.extend(labels.cpu().numpy())\n",
" y_pred.extend(preds.cpu().numpy())\n",
"\n",
" # -----------------------------\n",
" # Compute Metrics\n",
" # -----------------------------\n",
" classes = test_dataset.classes # ['uninfected', 'parasitized']\n",
"\n",
" # Accuracy\n",
" acc = accuracy_score(y_true, y_pred)\n",
" print(f\"\\nTest Accuracy: {acc:.4f}\")\n",
"\n",
" # Classification Report\n",
" print(\"\\nClassification Report:\")\n",
" print(classification_report(y_true, y_pred, target_names=classes))\n",
"\n",
" # Confusion Matrix\n",
" cm = confusion_matrix(y_true, y_pred)\n",
"\n",
" plt.figure(figsize=(6, 5))\n",
" sns.heatmap(cm, annot=True, fmt=\"d\", cmap=\"Blues\", xticklabels=classes, yticklabels=classes)\n",
" plt.xlabel(\"Predicted\")\n",
" plt.ylabel(\"True\")\n",
" plt.title(\"Confusion Matrix\")\n",
" plt.show()\n",
"\n",
"if __name__ == '__main__':\n",
" evaluate()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3b8ec551-2713-4b2e-b33c-cdc7930f8c54",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
|