{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":13836,"databundleVersionId":1718836,"sourceType":"competition"}],"dockerImageVersionId":30787,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport json\nimport pandas as pd\nimport numpy as np\nimport torch\nimport torch.nn as nn\nimport torchvision.transforms as transforms\nfrom torchvision import models\nfrom torch.utils.data import DataLoader, Dataset\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score\nfrom PIL import Image\n\n# Step 1: Load the original annotations\nannotations = pd.read_csv(\"/kaggle/input/cassava-leaf-disease-classification/train.csv\")\n\n# Step 2: Split the data into training and validation sets\ntrain_df, val_df = train_test_split(\n    annotations,\n    test_size=0.2,\n    stratify=annotations['label'],\n    random_state=42\n)\n\n# Step 3: Load label mappings\nwith open(\"/kaggle/input/cassava-leaf-disease-classification/label_num_to_disease_map.json\") as f:\n    label_map = json.load(f)\n\n# Convert the mapping to a more usable format\nlabel_map = {int(k): v for k, v in label_map.items()}\n\n# Step 4: Create a custom Dataset class\nclass CassavaDataset(Dataset):\n    def __init__(self, annotations, root_dir, transform=None):\n        self.annotations = annotations\n        self.root_dir = root_dir\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.annotations)\n\n    def __getitem__(self, idx):\n        img_path = os.path.join(self.root_dir, self.annotations.iloc[idx, 0])\n        image = Image.open(img_path).convert(\"RGB\")\n        label = int(self.annotations.iloc[idx, 1])\n\n        if self.transform:\n            image = self.transform(image)\n\n        return image, label\n\n# Step 5: Define transformations\ntrain_transforms = transforms.Compose([\n    transforms.RandomResizedCrop(224),\n    transforms.RandomHorizontalFlip(),\n    transforms.ColorJitter(),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n])\n\nval_transforms = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n])\n\n# Step 6: Create Dataset and DataLoader objects\ntrain_dataset = CassavaDataset(train_df, root_dir='/kaggle/input/cassava-leaf-disease-classification/train_images', transform=train_transforms)\nval_dataset = CassavaDataset(val_df, root_dir='/kaggle/input/cassava-leaf-disease-classification/train_images', transform=val_transforms)\n\ntrain_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=32, shuffle=False)\n\n# Step 7: Set device\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(device)\n# Step 8: Define evaluation function\ndef evaluate_model(model, val_loader):\n    model.eval()  # Set model to evaluation mode\n    all_labels = []\n    all_preds = []\n\n    with torch.no_grad():\n        for images, labels in val_loader:\n            images, labels = images.to(device), labels.to(device)\n            outputs = model(images)\n            _, preds = torch.max(outputs, 1)\n            \n            all_labels.extend(labels.cpu().numpy())\n            all_preds.extend(preds.cpu().numpy())\n\n    # Calculate metrics\n    accuracy = accuracy_score(all_labels, all_preds)\n    precision = precision_score(all_labels, all_preds, average='weighted')\n    recall = recall_score(all_labels, all_preds, average='weighted')\n    f1 = f1_score(all_labels, all_preds, average='weighted')\n\n    print(f'Accuracy: {accuracy * 100:.2f}%')\n    print(f'Precision: {precision:.2f}')\n    print(f'Recall: {recall:.2f}')\n    print(f'F1 Score: {f1:.2f}')\n\n    # Print a classification report\n    for i in range(5):  # Assuming 5 classes\n        print(f\"{label_map[i]}: {np.sum(np.array(all_preds) == i)} predictions\")\n\n# Step 9: Training and evaluation for EfficientNet\ndef train_efficientnet(num_epochs=10):\n    model = models.efficientnet_b0(pretrained=True)\n    model.classifier[1] = nn.Linear(model.classifier[1].in_features, 5)  # 5 classes\n    model = model.to(device)\n\n    criterion = nn.CrossEntropyLoss()\n    optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n\n    for epoch in range(num_epochs):\n        model.train()  # Set model to training mode\n        running_loss = 0.0\n        for images, labels in train_loader:\n            images, labels = images.to(device), labels.to(device)\n\n            # Zero the gradients\n            optimizer.zero_grad()\n\n            # Forward pass\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n\n            # Backward pass and optimization\n            loss.backward()\n            optimizer.step()\n\n            running_loss += loss.item()\n\n        print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {running_loss / len(train_loader):.4f}')\n\n    print(\"Evaluating EfficientNet:\")\n    evaluate_model(model, val_loader)\n\n# Step 10: Training and evaluation for MobileNetV2\ndef train_mobilenet(num_epochs=10):\n    model = models.mobilenet_v2(pretrained=True)\n    model.classifier[1] = nn.Linear(model.classifier[1].in_features, 5)  # 5 classes\n    model = model.to(device)\n\n    criterion = nn.CrossEntropyLoss()\n    optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n\n    for epoch in range(num_epochs):\n        model.train()  # Set model to training mode\n        running_loss = 0.0\n        for images, labels in train_loader:\n            images, labels = images.to(device), labels.to(device)\n\n            # Zero the gradients\n            optimizer.zero_grad()\n\n            # Forward pass\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n\n            # Backward pass and optimization\n            loss.backward()\n            optimizer.step()\n\n            running_loss += loss.item()\n\n        print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {running_loss / len(train_loader):.4f}')\n\n    print(\"Evaluating MobileNetV2:\")\n    evaluate_model(model, val_loader)\n\n# Step 11: Run training and evaluation\nnum_epochs = 10\ntrain_efficientnet(num_epochs)\ntrain_mobilenet(num_epochs)\n","metadata":{"execution":{"iopub.status.busy":"2024-10-27T13:45:21.534261Z","iopub.execute_input":"2024-10-27T13:45:21.534564Z","iopub.status.idle":"2024-10-27T14:51:01.366936Z","shell.execute_reply.started":"2024-10-27T13:45:21.534529Z","shell.execute_reply":"2024-10-27T14:51:01.365946Z"},"trusted":true},"execution_count":null,"outputs":[]}]}