{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":44224,"databundleVersionId":5188730,"sourceType":"competition"},{"sourceId":11519897,"sourceType":"datasetVersion","datasetId":7224826}],"dockerImageVersionId":31011,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport torch\nimport numpy as np\nimport timm\nimport torch.nn as nn\nimport torch.optim as optim\nimport json\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import f1_score\nfrom PIL import Image\nfrom tqdm import tqdm\n\n# ✅ Paths\nSPECTROGRAM_PATH = \"/kaggle/input/complete-spectrogram-birdclef-2023\"\nMODEL_PATH = \"/kaggle/working/efficientnet_bird.pth\"\nRESULTS_PATH = \"/kaggle/working/results.json\"\n\n# ✅ Device\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n# ✅ Dataset\nclass BirdDataset(Dataset):\n    def __init__(self, file_list, labels, transform=None):\n        self.file_list = file_list\n        self.labels = labels\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.file_list)\n\n    def __getitem__(self, idx):\n        img_path = self.file_list[idx]\n        label = self.labels[idx]\n        image = Image.open(img_path).convert(\"RGB\")\n        if self.transform:\n            image = self.transform(image)\n        return image, label\n\n# ✅ Gather data\nfile_list, labels = [], []\nbird_classes = sorted(os.listdir(SPECTROGRAM_PATH))\nclass_to_idx = {bird: idx for idx, bird in enumerate(bird_classes)}\n\nfor bird_class in bird_classes:\n    class_folder = os.path.join(SPECTROGRAM_PATH, bird_class)\n    if os.path.isdir(class_folder):\n        spectrograms = [os.path.join(class_folder, f) for f in os.listdir(class_folder) if f.endswith(\".png\")]\n        if len(spectrograms) < 2:\n            continue\n        file_list.extend(spectrograms)\n        labels.extend([class_to_idx[bird_class]] * len(spectrograms))\n\nnum_classes = len(class_to_idx)\n\n# ✅ Train-Test Split\ntrain_files, test_files, train_labels, test_labels = train_test_split(\n    file_list, labels, test_size=0.2, stratify=labels, random_state=42\n)\n\n# ✅ Transforms\nno_aug_transform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n])\n\naug_transform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.RandomHorizontalFlip(),\n    transforms.ColorJitter(brightness=0.2, contrast=0.2),\n    transforms.ToTensor(),\n])\n\n# ✅ Model\nclass EfficientNetBirdClassifier(nn.Module):\n    def __init__(self, num_classes):\n        super(EfficientNetBirdClassifier, self).__init__()\n        self.model = timm.create_model(\"efficientnet_b0\", pretrained=True)\n        self.model.classifier = nn.Linear(1280, num_classes)\n\n    def forward(self, x):\n        return self.model(x)\n\n# ✅ Train Function with Progress\ndef train_model(model, train_loader, criterion, optimizer, epochs=5):\n    model.train()\n    for epoch in range(epochs):\n        running_loss = 0.0\n        correct, total = 0, 0\n\n        loop = tqdm(train_loader, desc=f\"Epoch {epoch+1}/{epochs}\", leave=False)\n        for images, labels in loop:\n            images, labels = images.to(device), labels.to(device)\n            optimizer.zero_grad()\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            loss.backward()\n            optimizer.step()\n\n            running_loss += loss.item()\n            _, preds = torch.max(outputs, 1)\n            correct += (preds == labels).sum().item()\n            total += labels.size(0)\n\n            loop.set_postfix(loss=running_loss / (total // images.size(0) + 1), accuracy=correct / total * 100)\n\n        print(f\"[Epoch {epoch+1}] Loss: {running_loss / len(train_loader):.4f} | Accuracy: {correct / total * 100:.2f}%\")\n\n# ✅ Evaluation with Progress\ndef evaluate_model(model, test_loader):\n    model.eval()\n    all_preds, all_labels = [], []\n    loop = tqdm(test_loader, desc=\"Evaluating\", leave=False)\n\n    with torch.no_grad():\n        for images, labels in loop:\n            images, labels = images.to(device), labels.to(device)\n            outputs = model(images)\n            _, preds = torch.max(outputs, 1)\n            all_preds.extend(preds.cpu().numpy())\n            all_labels.extend(labels.cpu().numpy())\n\n    f1 = f1_score(all_labels, all_preds, average=\"weighted\")\n    print(f\"F1 Score: {f1:.4f}\")\n    return f1\n\n\n# ✅ Run With Augmentation\nprint(\"\\nTraining with augmentation...\")\ntrain_dataset_aug = BirdDataset(train_files, train_labels, transform=aug_transform)\ntrain_loader_aug = DataLoader(train_dataset_aug, batch_size=16, shuffle=True)\n\nmodel_aug = EfficientNetBirdClassifier(num_classes).to(device)\noptimizer_aug = optim.Adam(model_aug.parameters(), lr=0.001)\n\ntrain_model(model_aug, train_loader_aug, criterion, optimizer_aug, epochs=10)\nf1_aug = evaluate_model(model_aug, test_loader)\n\n# ✅ Save Results\nresults = {\n    \"f1_score_with_augmentation\": f1_aug\n}\n\nwith open(RESULTS_PATH, \"w\") as f:\n    json.dump(results, f, indent=4)\n\nprint(\"\\nFinal Results:\")\nprint(json.dumps(results, indent=4))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-04-23T08:34:03.626411Z","iopub.execute_input":"2025-04-23T08:34:03.626598Z","execution_failed":"2025-04-23T06:58:27.304Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport torch\nimport numpy as np\nimport timm\nimport torch.nn as nn\nimport torch.optim as optim\nimport json\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import f1_score\nfrom PIL import Image\nfrom tqdm import tqdm\nfrom torch.cuda.amp import GradScaler, autocast\n\n# ✅ Paths\nSPECTROGRAM_PATH = \"/kaggle/input/complete-spectrogram-birdclef-2023\"\nMODEL_PATH = \"/kaggle/working/efficientnet_bird.pth\"\nRESULTS_PATH = \"/kaggle/working/results.json\"\n\n# ✅ Device\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n# ✅ Dataset\nclass BirdDataset(Dataset):\n    def __init__(self, file_list, labels, transform=None):\n        self.file_list = file_list\n        self.labels = labels\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.file_list)\n\n    def __getitem__(self, idx):\n        img_path = self.file_list[idx]\n        label = self.labels[idx]\n        image = Image.open(img_path).convert(\"RGB\")\n        if self.transform:\n            image = self.transform(image)\n        return image, label\n\n# ✅ Gather data\nfile_list, labels = [], []\nbird_classes = sorted(os.listdir(SPECTROGRAM_PATH))\nclass_to_idx = {bird: idx for idx, bird in enumerate(bird_classes)}\n\nfor bird_class in bird_classes:\n    class_folder = os.path.join(SPECTROGRAM_PATH, bird_class)\n    if os.path.isdir(class_folder):\n        spectrograms = [os.path.join(class_folder, f) for f in os.listdir(class_folder) if f.endswith(\".png\")]\n        if len(spectrograms) < 2:\n            continue\n        file_list.extend(spectrograms)\n        labels.extend([class_to_idx[bird_class]] * len(spectrograms))\n\nnum_classes = len(class_to_idx)\n\n# ✅ Train-Test Split\ntrain_files, test_files, train_labels, test_labels = train_test_split(\n    file_list, labels, test_size=0.2, stratify=labels, random_state=42\n)\n\n# ✅ Transforms\nno_aug_transform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n])\n\naug_transform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.RandomHorizontalFlip(),\n    transforms.ColorJitter(brightness=0.2, contrast=0.2),\n    transforms.ToTensor(),\n])\n\n# ✅ Model\nclass EfficientNetBirdClassifier(nn.Module):\n    def __init__(self, num_classes):\n        super(EfficientNetBirdClassifier, self).__init__()\n        self.model = timm.create_model(\"efficientnet_b0\", pretrained=True)\n        self.model.classifier = nn.Linear(1280, num_classes)\n\n    def forward(self, x):\n        return self.model(x)\n\n# ✅ Train Function with AMP and Progress\ndef train_model(model, train_loader, criterion, optimizer, epochs=5, accumulation_steps=1):\n    model.train()\n    scaler = GradScaler()\n\n    for epoch in range(epochs):\n        running_loss = 0.0\n        correct, total = 0, 0\n\n        loop = tqdm(enumerate(train_loader), total=len(train_loader), desc=f\"Epoch {epoch+1}/{epochs}\", leave=False)\n        optimizer.zero_grad()\n\n        for i, (images, labels) in loop:\n            images, labels = images.to(device), labels.to(device)\n\n            with autocast():\n                outputs = model(images)\n                loss = criterion(outputs, labels)\n                loss = loss / accumulation_steps\n\n            scaler.scale(loss).backward()\n\n            if (i + 1) % accumulation_steps == 0 or (i + 1) == len(train_loader):\n                scaler.step(optimizer)\n                scaler.update()\n                optimizer.zero_grad()\n\n            running_loss += loss.item() * accumulation_steps\n            _, preds = torch.max(outputs, 1)\n            correct += (preds == labels).sum().item()\n            total += labels.size(0)\n\n            loop.set_postfix(loss=running_loss / (i + 1), accuracy=correct / total * 100)\n\n        print(f\"[Epoch {epoch+1}] Loss: {running_loss / len(train_loader):.4f} | Accuracy: {correct / total * 100:.2f}%\")\n\n# ✅ Evaluation\ndef evaluate_model(model, test_loader):\n    model.eval()\n    all_preds, all_labels = [], []\n    loop = tqdm(test_loader, desc=\"Evaluating\", leave=False)\n\n    with torch.no_grad():\n        for images, labels in loop:\n            images, labels = images.to(device), labels.to(device)\n            outputs = model(images)\n            _, preds = torch.max(outputs, 1)\n            all_preds.extend(preds.cpu().numpy())\n            all_labels.extend(labels.cpu().numpy())\n\n    f1 = f1_score(all_labels, all_preds, average=\"weighted\")\n    print(f\"F1 Score: {f1:.4f}\")\n    return f1\n\n# ✅ Run With Augmentation\nprint(\"\\nTraining with augmentation...\")\ntrain_dataset_aug = BirdDataset(train_files, train_labels, transform=aug_transform)\ntrain_loader_aug = DataLoader(train_dataset_aug, batch_size=32, shuffle=True, num_workers=4, pin_memory=True)\n\ntest_dataset = BirdDataset(test_files, test_labels, transform=no_aug_transform)\ntest_loader = DataLoader(test_dataset, batch_size=32, shuffle=False, num_workers=4, pin_memory=True)\n\nmodel_aug = EfficientNetBirdClassifier(num_classes).to(device)\noptimizer_aug = optim.Adam(model_aug.parameters(), lr=0.001)\ncriterion = nn.CrossEntropyLoss()\n\ntrain_model(model_aug, train_loader_aug, criterion, optimizer_aug, epochs=10)\n\nf1_aug = evaluate_model(model_aug, test_loader)\n\n# ✅ Save Results\nresults = {\n    \"f1_score_with_augmentation\": f1_aug\n}\n\nwith open(RESULTS_PATH, \"w\") as f:\n    json.dump(results, f, indent=4)\n\nprint(\"\\nFinal Results:\")\nprint(json.dumps(results, indent=4))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-23T08:34:33.395811Z","iopub.execute_input":"2025-04-23T08:34:33.396525Z","iopub.status.idle":"2025-04-23T08:41:52.997379Z","shell.execute_reply.started":"2025-04-23T08:34:33.39649Z","shell.execute_reply":"2025-04-23T08:41:52.99625Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install -q git+https://github.com/openai/whisper.git","metadata":{"trusted":true,"execution":{"execution_failed":"2025-04-23T06:58:27.305Z"}},"outputs":[],"execution_count":null}]}