{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":70203,"databundleVersionId":8068726,"sourceType":"competition"},{"sourceId":8906235,"sourceType":"datasetVersion","datasetId":5354844}],"dockerImageVersionId":30733,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# import torch\n# import torch.nn as nn\n# import torch.nn.functional as F\n\n# class BasicBlock(nn.Module):\n#     expansion = 1\n    \n#     def __init__(self, in_channels, out_channels, stride=1, downsample=None):\n#         super(BasicBlock, self).__init__()\n#         self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)\n#         self.bn1 = nn.BatchNorm2d(out_channels)\n#         self.relu = nn.ReLU(inplace=True)\n#         self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False)\n#         self.bn2 = nn.BatchNorm2d(out_channels)\n#         self.downsample = downsample\n\n#     def forward(self, x):\n#         identity = x\n        \n#         out = self.conv1(x)\n#         out = self.bn1(out)\n#         out = self.relu(out)\n        \n#         out = self.conv2(out)\n#         out = self.bn ko2(out)\n        \n#         if self.downsample is not None:\n#             identity = self.downsample(x)\n        \n#         out += identity\n#         out = self.relu(out)\n        \n#         return out\n\n# class ResNet(nn.Module):\n#     def __init__(self, block, layers, num_classes=1000):\n#         super(ResNet, self).__init__()\n#         self.in_channels = 64\n#         self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)\n#         self.bn1 = nn.BatchNorm2d(64)\n#         self.relu = nn.ReLU(inplace=True)\n#         self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n        \n#         self.layer1 = self._make_layer(block, 64, layers[0])\n#         self.layer2 = self._make_layer(block, 128, layers[1], stride=2)\n#         self.layer3 = self._make_layer(block, 256, layers[2], stride=2)\n#         self.layer4 = self._make_layer(block, 512, layers[3], stride=2)\n        \n#         self.avgpool = nn.AdaptiveAvgPool2d((1, 1))\n#         self.fc = nn.Linear(512 * block.expansion, num_classes)\n\n#     def _make_layer(self, block, out_channels, blocks, stride=1):\n#         downsample = None\n#         if stride != 1 or self.in_channels != out_channels * block.expansion:\n#             downsample = nn.Sequential(\n#                 nn.Conv2d(self.in_channels, out_channels * block.expansion, kernel_size=1, stride=stride, bias=False),\n#                 nn.BatchNorm2d(out_channels * block.expansion)\n#             )\n        \n#         layers = []\n#         layers.append(block(self.in_channels, out_channels, stride, downsample))\n#         self.in_channels = out_channels * block.expansion\n#         for _ in range(1, blocks):\n#             layers.append(block(self.in_channels, out_channels))\n        \n#         return nn.Sequential(*layers)\n\n#     def forward(self, x):\n#         x = self.conv1(x)\n#         x = self.bn1(x)\n#         x = self.relu(x)\n#         x = self.maxpool(x)\n        \n#         x = self.layer1(x)\n#         x = self.layer2(x)\n#         x = self.layer3(x)\n#         x = self.layer4(x)\n        \n#         x = self.avgpool(x)\n#         x = torch.flatten(x, 1)\n#         x = self.fc(x)\n        \n#         return x\n\n# def resnet18(num_classes=1000):\n#     return ResNet(BasicBlock, [2, 2, 2, 2], num_classes=num_classes)\n\n# # Example usage\n# model = resnet18(num_classes=10)  # for 10 classes\n# print(model)\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-06-17T15:52:40.601837Z","iopub.execute_input":"2024-06-17T15:52:40.602278Z","iopub.status.idle":"2024-06-17T15:52:40.744673Z","shell.execute_reply.started":"2024-06-17T15:52:40.602247Z","shell.execute_reply":"2024-06-17T15:52:40.743676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import os\n# import librosa\n# import numpy as np\n# import torch\n# from torch.utils.data import Dataset, DataLoader\n\n# import os\n# import librosa\n# import numpy as np\n# import cv2  # OpenCV for resizing\n\n# def compute_melgram(audio_path):\n#     ''' Compute a mel-spectrogram and returns it in a shape of (3, 244, 244), where\n#     3 == #channels, 244 == #height and 244 == #width.\n\n#     Parameters:\n#     ----------\n#     audio_path: str\n#         Path for the audio file. Any format supported by audioread will work.\n\n#     Returns:\n#     -------\n#     np.ndarray\n#         Mel-spectrogram data with shape (3, 244, 244).\n#     '''\n#     SR = 12000\n#     N_FFT = 512\n#     N_MELS = 256\n#     HOP_LEN = 256\n#     DURA = 10  # to make it 1366 frames\n\n#     src, sr = librosa.load(audio_path, sr=SR)\n\n#     n_sample = src.shape[0]\n#     n_sample_fit = int(DURA * SR)\n#     if n_sample < n_sample_fit:\n#         src = np.hstack((src, np.zeros((int(DURA * SR) - n_sample,))))\n#     elif n_sample > n_sample_fit:\n#         src = src[(n_sample - n_sample_fit) // 2:(n_sample + n_sample_fit) // 2]\n\n#     melgram = librosa.feature.melspectrogram(y=src, sr=SR, hop_length=HOP_LEN, n_fft=N_FFT, n_mels=N_MELS)\n\n#     log_melgram = librosa.power_to_db(melgram ** 2, ref=np.max)\n\n#     # Resize to 244x244\n#     log_melgram = cv2.resize(log_melgram, (244, 244))\n\n#     # Convert single channel to 3 channels by duplicating\n#     log_melgram = np.stack([log_melgram] * 3, axis=0)\n\n#     return log_melgram\n","metadata":{"execution":{"iopub.status.busy":"2024-06-17T15:52:40.746406Z","iopub.execute_input":"2024-06-17T15:52:40.746682Z","iopub.status.idle":"2024-06-17T15:52:41.002587Z","shell.execute_reply.started":"2024-06-17T15:52:40.746658Z","shell.execute_reply":"2024-06-17T15:52:41.001897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import torch\n# from torch.utils.data import Dataset, DataLoader, random_split\n\n# class AudioDataset(Dataset):\n#     def __init__(self, audio_dir):\n#         self.data, self.labels = self.process_audio_files(audio_dir)\n#         self.label_to_idx = {label: idx for idx, label in enumerate(sorted(set(self.labels)))}\n#         self.idx_to_label = {idx: label for label, idx in self.label_to_idx.items()}\n#         self.labels = [self.label_to_idx[label] for label in self.labels]\n\n#     def process_audio_files(self, audio_dir):\n#         data = []\n#         labels = []\n#         for genre_folder in os.listdir(audio_dir):\n#             genre_path = os.path.join(audio_dir, genre_folder)\n#             if os.path.isdir(genre_path):\n#                 for filename in os.listdir(genre_path):\n#                     if filename.endswith('.ogg'):\n#                         file_path = os.path.join(genre_path, filename)\n#                         log_mel_spectrogram = compute_melgram(file_path)\n#                         data.append(log_mel_spectrogram)\n#                         labels.append(genre_folder)\n#         return data, labels\n\n#     def __len__(self):\n#         return len(self.data)\n\n#     def __getitem__(self, idx):\n#         mel_spectrogram = self.data[idx]\n#         label = self.labels[idx]\n#         mel_spectrogram = torch.tensor(mel_spectrogram, dtype=torch.float32)\n#         label = torch.tensor(label, dtype=torch.long)\n#         return mel_spectrogram, label\n\n","metadata":{"execution":{"iopub.status.busy":"2024-06-17T15:52:41.003632Z","iopub.execute_input":"2024-06-17T15:52:41.003902Z","iopub.status.idle":"2024-06-17T15:52:41.014567Z","shell.execute_reply.started":"2024-06-17T15:52:41.003878Z","shell.execute_reply":"2024-06-17T15:52:41.013668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n# print(f'Using device: {device}')","metadata":{"execution":{"iopub.status.busy":"2024-06-17T15:52:41.015503Z","iopub.execute_input":"2024-06-17T15:52:41.015735Z","iopub.status.idle":"2024-06-17T15:52:41.074064Z","shell.execute_reply.started":"2024-06-17T15:52:41.015715Z","shell.execute_reply":"2024-06-17T15:52:41.073186Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Parameters\n# batch_size = 16\n# learning_rate = 0.001\n# num_epochs = 10\n# audio_dir = r\"/kaggle/input/birdclef-2024/train_audio\"\n\n# # Dataset\n# dataset = AudioDataset(audio_dir)\n# train_size = int(0.8 * len(dataset))\n# test_size = len(dataset) - train_size\n# train_dataset, test_dataset = random_split(dataset, [train_size, test_size])\n\n# # DataLoader\n# train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\n# test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)\n\n# # Model, Loss, Optimizer\n# model = resnet18(num_classes=len(dataset.label_to_idx))\n# model = model.to(device)  # Move model to GPU\n\n# criterion = nn.CrossEntropyLoss()\n# optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)\n\n# # Training loop\n# for epoch in range(num_epochs):\n#     model.train()\n#     running_loss = 0.0\n#     for i, (inputs, labels) in enumerate(train_loader):\n#         inputs, labels = inputs.to(device), labels.to(device)  # Move data to GPU\n#         optimizer.zero_grad()\n#         outputs = model(inputs)\n#         loss = criterion(outputs, labels)\n#         loss.backward()\n#         optimizer.step()\n#         running_loss += loss.item()\n#         if i % 10 == 9:  # Print every 10 mini-batches\n#             print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {running_loss/10:.4f}')\n#             running_loss = 0.0\n\n# print('Finished Training')","metadata":{"execution":{"iopub.status.busy":"2024-06-17T15:52:41.075992Z","iopub.execute_input":"2024-06-17T15:52:41.076272Z","iopub.status.idle":"2024-06-17T16:52:45.239758Z","shell.execute_reply.started":"2024-06-17T15:52:41.076247Z","shell.execute_reply":"2024-06-17T16:52:45.238710Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Evaluation function\n# def evaluate_model(model, test_loader, criterion):\n#     model.eval()\n#     test_loss = 0.0\n#     correct = 0\n#     total = 0\n#     with torch.no_grad():\n#         for inputs, labels in test_loader:\n#             inputs, labels = inputs.to(device), labels.to(device)  # Move data to GPU\n#             outputs = model(inputs)\n#             loss = criterion(outputs, labels)\n#             test_loss += loss.item()\n#             _, predicted = torch.max(outputs, 1)\n#             total += labels.size(0)\n#             correct += (predicted == labels).sum().item()\n\n#     avg_loss = test_loss / len(test_loader)\n#     accuracy = 100 * correct / total\n#     print(f'Test Loss: {avg_loss:.4f}, Test Accuracy: {accuracy:.2f}%')\n\n# # Evaluate the model\n# evaluate_model(model, test_loader, criterion)\n","metadata":{"execution":{"iopub.status.busy":"2024-06-17T16:52:45.241052Z","iopub.execute_input":"2024-06-17T16:52:45.241529Z","iopub.status.idle":"2024-06-17T16:52:51.854899Z","shell.execute_reply.started":"2024-06-17T16:52:45.241501Z","shell.execute_reply":"2024-06-17T16:52:51.853983Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !pip install resnest","metadata":{"execution":{"iopub.status.busy":"2024-07-08T09:36:23.288549Z","iopub.execute_input":"2024-07-08T09:36:23.289208Z","iopub.status.idle":"2024-07-08T09:36:38.162465Z","shell.execute_reply.started":"2024-07-08T09:36:23.289169Z","shell.execute_reply":"2024-07-08T09:36:38.161303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import numpy as np\n# import pandas as pd\n# import tensorflow as tf\n# from resnest.torch import resnest50\n# from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout, Input\n# from tensorflow.keras.models import Model\n# from tensorflow.keras.optimizers import Adam\n# from sklearn.model_selection import train_test_split\n# from tensorflow.keras.utils import to_categorical\n# from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping\n\n# # Check GPU availability\n# print(\"Num GPUs Available: \", len(tf.config.experimental.list_physical_devices('GPU')))\n\n# # Paths to data\n# train_csv_path = '/kaggle/input/birdclef-2024/train_metadata.csv'\n# train_output_path = '/kaggle/working/train_mels/'\n\n# # Read metadata\n# data = pd.read_csv(train_csv_path)\n# data['mel_path'] = train_output_path + data[\"filename\"].apply(lambda s: s.replace('.ogg', '.npy'))\n\n# # Create labels\n# labels = data['primary_label'].astype('category').cat.codes\n# data['label'] = labels\n\n# # Split data\n# train_data, val_data = train_test_split(data, test_size=0.2, stratify=labels, random_state=42)\n\n# def load_mel(file_path):\n#     mel = np.load(file_path)\n#     if mel.shape[1] < 64:\n#         pad_width = 64 - mel.shape[1]\n#         mel = np.pad(mel, ((0, 0), (0, pad_width)), mode='constant')\n#     elif mel.shape[1] > 64:\n#         mel = mel[:, :64]\n#     return mel\n\n# class DataGenerator(tf.keras.utils.Sequence):\n#     def __init__(self, dataframe, batch_size=32, shuffle=True):\n#         self.dataframe = dataframe\n#         self.batch_size = batch_size\n#         self.shuffle = shuffle\n#         self.indices = np.arange(len(self.dataframe))\n#         self.on_epoch_end()\n\n#     def __len__(self):\n#         return len(self.dataframe) // self.batch_size\n\n#     def __getitem__(self, index):\n#         batch_indices = self.indices[index*self.batch_size:(index+1)*self.batch_size]\n#         batch_data = self.dataframe.iloc[batch_indices]\n#         X, y = self.__data_generation(batch_data)\n#         return X, y\n\n#     def on_epoch_end(self):\n#         if self.shuffle:\n#             np.random.shuffle(self.indices)\n\n#     def __data_generation(self, batch_data):\n#         X = np.array([load_mel(file_path) for file_path in batch_data['mel_path']])\n#         X = X[..., np.newaxis]\n#         y = to_categorical(batch_data['label'], num_classes=len(data['label'].unique()))\n#         return X, y\n\n# batch_size = 64  # Reduce batch size if you encounter out-of-memory issues\n# train_generator = DataGenerator(train_data, batch_size=batch_size)\n# val_generator = DataGenerator(val_data, batch_size=batch_size, shuffle=False)\n\n# input_shape = (128, 64, 1)\n# base_model = resnest50(pretrained=True)\n# x = base_model.output\n# x = GlobalAveragePooling2D()(x)\n# x = Dropout(0.3)(x)  # Add Dropout layer with 30% dropout rate\n# output = Dense(len(data['label'].unique()), activation='softmax')(x)\n# model = Model(inputs=base_model.input, outputs=output)\n\n# model.compile(optimizer=Adam(learning_rate=0.001), loss='categorical_crossentropy', metrics=['accuracy'])\n\n# # Save best model during training\n# checkpoint = ModelCheckpoint('/kaggle/working/best_model_early.keras', monitor='val_accuracy', save_best_only=True, mode='max')\n\n# # Early stopping\n# early_stopping = EarlyStopping(monitor='val_accuracy', patience=5, restore_best_weights=True)\n\n# epochs = 50\n# history = model.fit(train_generator, validation_data=val_generator, epochs=epochs, callbacks=[checkpoint, early_stopping])\n\n# # Save final model\n# model.save('/kaggle/working/resnest50_model_early.keras')\n\n# print(\"Training complete and model saved.\")\n","metadata":{"execution":{"iopub.status.busy":"2024-07-08T09:36:38.164585Z","iopub.execute_input":"2024-07-08T09:36:38.164947Z","iopub.status.idle":"2024-07-08T09:36:43.478856Z","shell.execute_reply.started":"2024-07-08T09:36:38.164915Z","shell.execute_reply":"2024-07-08T09:36:43.477165Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport tensorflow as tf\nfrom tensorflow.keras.applications import ResNet50  # Import ResNet50\nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout, Input\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.optimizers import Adam\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping\n\n# Check GPU availability\nprint(\"Num GPUs Available: \", len(tf.config.experimental.list_physical_devices('GPU')))\n\n# Paths to data\ntrain_csv_path = '/kaggle/input/birdclef-2024/train_metadata.csv'\ntrain_output_path = '/kaggle/input/birdclef-train-mels/train_mels/'\n\n# Read metadata\ndata = pd.read_csv(train_csv_path)\ndata['mel_path'] = train_output_path + data[\"filename\"].apply(lambda s: s.replace('.ogg', '.npy'))\n\n# Create labels\nlabels = data['primary_label'].astype('category').cat.codes\ndata['label'] = labels\n\n# Split data\ntrain_data, val_data = train_test_split(data, test_size=0.2, stratify=labels, random_state=42)\n\ndef load_mel(file_path):\n    mel = np.load(file_path)\n    if mel.shape[1] < 64:\n        pad_width = 64 - mel.shape[1]\n        mel = np.pad(mel, ((0, 0), (0, pad_width)), mode='constant')\n    elif mel.shape[1] > 64:\n        mel = mel[:, :64]\n    return mel\n\nclass DataGenerator(tf.keras.utils.Sequence):\n    def __init__(self, dataframe, batch_size=32, shuffle=True):\n        self.dataframe = dataframe\n        self.batch_size = batch_size\n        self.shuffle = shuffle\n        self.indices = np.arange(len(self.dataframe))\n        self.on_epoch_end()\n\n    def __len__(self):\n        return len(self.dataframe) // self.batch_size\n\n    def __getitem__(self, index):\n        batch_indices = self.indices[index*self.batch_size:(index+1)*self.batch_size]\n        batch_data = self.dataframe.iloc[batch_indices]\n        X, y = self.__data_generation(batch_data)\n        return X, y\n\n    def on_epoch_end(self):\n        if self.shuffle:\n            np.random.shuffle(self.indices)\n\n    def __data_generation(self, batch_data):\n        X = np.array([load_mel(file_path) for file_path in batch_data['mel_path']])\n        X = X[..., np.newaxis]\n        y = to_categorical(batch_data['label'], num_classes=len(data['label'].unique()))\n        return X, y\n\nbatch_size = 64  # Reduce batch size if you encounter out-of-memory issues\ntrain_generator = DataGenerator(train_data, batch_size=batch_size)\nval_generator = DataGenerator(val_data, batch_size=batch_size, shuffle=False)\n\ninput_shape = (128, 64, 1)  # Adjust according to your actual mel spectrogram shape\nbase_model = ResNet50(include_top=False, weights=None, input_tensor=Input(shape=input_shape))  # Change to ResNet50\nx = base_model.output\nx = GlobalAveragePooling2D()(x)\nx = Dropout(0.3)(x)  # Add Dropout layer with 30% dropout rate\noutput = Dense(len(data['label'].unique()), activation='softmax')(x)\nmodel = Model(inputs=base_model.input, outputs=output)\n\nmodel.compile(optimizer=Adam(learning_rate=0.001), loss='categorical_crossentropy', metrics=['accuracy'])\n\n# Save best model during training\ncheckpoint = ModelCheckpoint('/kaggle/working/best_model_early.keras', monitor='val_accuracy', save_best_only=True, mode='max')\n\n# Early stopping\nearly_stopping = EarlyStopping(monitor='val_accuracy', patience=10, restore_best_weights=True)\n\nepochs = 50\nhistory = model.fit(train_generator, validation_data=val_generator, epochs=epochs, callbacks=[checkpoint, early_stopping])\n\n# Save final model\nmodel.save('/kaggle/working/resnet50_model_early.keras')\n\nprint(\"Training complete and model saved.\")\n","metadata":{"execution":{"iopub.status.busy":"2024-07-08T14:59:09.993068Z","iopub.execute_input":"2024-07-08T14:59:09.993753Z"},"trusted":true},"execution_count":null,"outputs":[]}]}