{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":91844,"databundleVersionId":11361821,"sourceType":"competition"},{"sourceId":11075449,"sourceType":"datasetVersion","datasetId":6902504}],"dockerImageVersionId":30918,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"https://www.kaggle.com/code/docxian/birdclef-2025-eda-geography\n\nhttps://www.kaggle.com/code/xiaoazuzong/lb-0-778-efficientnet-b0-pytorch-inference/notebook\n\nhttps://www.kaggle.com/code/kumarandatascientist/lb-0-784-efficientnet-b0-pytorch-inference","metadata":{}},{"cell_type":"code","source":"import os\nimport gc\nimport warnings\nimport logging\nimport time\nimport math\nimport cv2\nfrom pathlib import Path\n\nimport numpy as np\nimport pandas as pd\nimport librosa\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport timm\nfrom tqdm.auto import tqdm\n\nwarnings.filterwarnings(\"ignore\")\nlogging.basicConfig(level=logging.ERROR)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-21T18:52:58.364227Z","iopub.execute_input":"2025-03-21T18:52:58.364512Z","iopub.status.idle":"2025-03-21T18:53:08.955826Z","shell.execute_reply.started":"2025-03-21T18:52:58.364480Z","shell.execute_reply":"2025-03-21T18:53:08.955184Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class CFG:\n \n    test_soundscapes = '/kaggle/input/birdclef-2025/test_soundscapes'\n    submission_csv = '/kaggle/input/birdclef-2025/sample_submission.csv'\n    taxonomy_csv = '/kaggle/input/birdclef-2025/taxonomy.csv'\n    model_path = '/kaggle/input/birdclef-2025-efficientnet-b0'  \n    \n    # Audio parameters\n    FS = 32000  \n    WINDOW_SIZE = 5  \n    \n    # Mel spectrogram parameters\n    N_FFT = 1024\n    HOP_LENGTH = 512\n    N_MELS = 148\n    FMIN = 50\n    FMAX = 14000\n    TARGET_SHAPE = (256, 256)\n    \n    model_name = 'efficientnet_b0'\n    in_channels = 1\n    device = 'cpu'  \n    \n    # Inference parameters\n    batch_size = 16\n    use_tta = False  \n    tta_count = 3   \n    threshold = 0.5\n    \n    use_specific_folds = False  # If False, use all found models\n    folds = [0, 1]  # Used only if use_specific_folds is True\n    \n    debug = False\n    debug_count = 3\n\ncfg = CFG()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-21T18:53:08.956646Z","iopub.execute_input":"2025-03-21T18:53:08.956982Z","iopub.status.idle":"2025-03-21T18:53:08.961980Z","shell.execute_reply.started":"2025-03-21T18:53:08.956950Z","shell.execute_reply":"2025-03-21T18:53:08.961225Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(f\"Using device: {cfg.device}\")\nprint(f\"Loading taxonomy data...\")\ntaxonomy_df = pd.read_csv(cfg.taxonomy_csv)\nspecies_ids = taxonomy_df['primary_label'].tolist()\nnum_classes = len(species_ids)\nprint(f\"Number of classes: {num_classes}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-21T18:53:08.963522Z","iopub.execute_input":"2025-03-21T18:53:08.963748Z","iopub.status.idle":"2025-03-21T18:53:08.991487Z","shell.execute_reply.started":"2025-03-21T18:53:08.963730Z","shell.execute_reply":"2025-03-21T18:53:08.990867Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n\n# read train data file\ndf = pd.read_csv('../input/birdclef-2025/train.csv')\n\n# read taxonomy file\ndf_taxo = pd.read_csv('../input/birdclef-2025/taxonomy.csv')\n\ndf = pd.merge(left=df, right=df_taxo[['primary_label', 'inat_taxon_id', 'class_name']], how='left', on='primary_label')\n\n\nprint(df.head())\nprint(df.info())\nprint(df.collection.value_counts())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-21T18:53:08.992360Z","iopub.execute_input":"2025-03-21T18:53:08.992651Z","iopub.status.idle":"2025-03-21T18:53:09.200299Z","shell.execute_reply.started":"2025-03-21T18:53:08.992623Z","shell.execute_reply":"2025-03-21T18:53:09.199419Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import ast\nimport librosa\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport plotly.express as px\nimport plotly.graph_objs as go\nfrom collections import Counter\nimport matplotlib.pyplot as plt\nfrom IPython.display import Audio\n\nfig = px.histogram(df, x=\"primary_label\", nbins=len(df[\"primary_label\"].unique()))\nfig.update_layout(title_text=\"Distribution of Primary Labels\")\nfig.show()\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-21T18:53:21.087842Z","iopub.execute_input":"2025-03-21T18:53:21.088264Z","iopub.status.idle":"2025-03-21T18:53:23.765309Z","shell.execute_reply.started":"2025-03-21T18:53:21.088234Z","shell.execute_reply":"2025-03-21T18:53:23.764439Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"secondary_df =  df['secondary_labels'].str.replace('[','').str.replace(']','').str.replace('\\'','').str.split(',', expand=True).stack().reset_index(level=1, drop=True).rename('secondary_label')\nsecondary_df = pd.merge( df.drop(columns=['secondary_labels']), secondary_df, left_index=True, right_index=True)\n\nfig = px.histogram(secondary_df, x=\"secondary_label\", title=\"Distribution of Secondary Labels\")\nfig.update_layout(xaxis_title=\"Secondary Label\", yaxis_title=\"Count\")\nfig.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-20T01:42:29.527482Z","iopub.execute_input":"2025-03-20T01:42:29.527909Z","iopub.status.idle":"2025-03-20T01:42:29.775091Z","shell.execute_reply.started":"2025-03-20T01:42:29.527873Z","shell.execute_reply":"2025-03-20T01:42:29.773861Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Flatten the list of labels in the \"type\" column\nlabels = [label.strip(\"[]'\") for sublist in  df['type'].apply(ast.literal_eval) for label in sublist]\n\n# Count the occurrence of each label\nlabel_counts = Counter(labels)\n\n# Create a bar plot of the label counts\nfig = px.bar(x=list(label_counts.keys()), y=list(label_counts.values()))\nfig.update_layout(title_text=\"Distribution of Types\")\nfig.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-20T01:43:04.245066Z","iopub.execute_input":"2025-03-20T01:43:04.245487Z","iopub.status.idle":"2025-03-20T01:43:04.534670Z","shell.execute_reply.started":"2025-03-20T01:43:04.245442Z","shell.execute_reply":"2025-03-20T01:43:04.533313Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig = px.histogram( df, x=\"scientific_name\", nbins=len( df[\"scientific_name\"].unique()))\nfig.update_layout(title_text=\"Distribution of Scientific Names\")\nfig.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-20T01:44:00.474184Z","iopub.execute_input":"2025-03-20T01:44:00.474641Z","iopub.status.idle":"2025-03-20T01:44:00.582659Z","shell.execute_reply.started":"2025-03-20T01:44:00.474601Z","shell.execute_reply":"2025-03-20T01:44:00.581474Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# first simple plot of locations\nplt.figure(figsize=(12,6))\nsns.scatterplot(data=df, x='longitude', y='latitude', \n                color='darkblue')\nplt.grid()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-21T18:53:25.740454Z","iopub.execute_input":"2025-03-21T18:53:25.740756Z","iopub.status.idle":"2025-03-21T18:53:26.068410Z","shell.execute_reply.started":"2025-03-21T18:53:25.740733Z","shell.execute_reply":"2025-03-21T18:53:26.067613Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nfilename='XC112602.ogg'\ny, sr = librosa.load('../input/birdclef-2025/train_audio/banana/' + filename)\n# play sound\nAudio(y, rate=sr)\n# load audio file\n\n\n# show wave data\nplt.figure(figsize=(14,5))\nplt.plot(y, color='darkblue')\nplt.grid()\nplt.show()\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T22:52:42.037874Z","iopub.execute_input":"2025-03-18T22:52:42.038444Z","iopub.status.idle":"2025-03-18T22:52:42.419502Z","shell.execute_reply.started":"2025-03-18T22:52:42.038415Z","shell.execute_reply":"2025-03-18T22:52:42.418562Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# play sound\nAudio(y, rate=sr)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T22:53:04.01977Z","iopub.execute_input":"2025-03-18T22:53:04.020122Z","iopub.status.idle":"2025-03-18T22:53:04.08809Z","shell.execute_reply.started":"2025-03-18T22:53:04.020094Z","shell.execute_reply":"2025-03-18T22:53:04.086839Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# audio_path = \"../input/birdclef-2025/train_audio/XC12345.ogg\"  # Example audio path\n# y, sr = librosa.load(audio_path, sr=None)\n# duration = librosa.get_duration(y=y, sr=sr)\n# print(f\"Duration: {duration:.2f} seconds\")\n\n# # Plot waveform\n# plt.figure(figsize=(10, 4))\n# librosa.display.waveshow(y, sr=sr)\n# plt.title('Waveform of Sample Audio')\n# plt.xlabel('Time (s)')\n# plt.ylabel('Amplitude')\n# plt.show()\n\n\n# def plot_spectrogram(audio_path):\n#     y, sr = librosa.load(audio_path, sr=None)\n#     S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128)\n#     S_dB = librosa.power_to_db(S, ref=np.max)\n\n#     plt.figure(figsize=(10, 4))\n#     librosa.display.specshow(S_dB, sr=sr, x_axis='time', y_axis='mel')\n#     plt.colorbar(format='%+2.0f dB')\n#     plt.title('Mel Spectrogram')\n#     plt.show()\n\n# # Example usage\n# plot_spectrogram(audio_path)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T23:07:29.518105Z","iopub.execute_input":"2025-03-18T23:07:29.518453Z","iopub.status.idle":"2025-03-18T23:07:29.56871Z","shell.execute_reply.started":"2025-03-18T23:07:29.518426Z","shell.execute_reply":"2025-03-18T23:07:29.56675Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import librosa\n\n# # Correct file path from the list\n# audio_path = \"../input/birdclef-2025/train_audio/greani1/XC132190.ogg\"\n\n# # Load audio\n# y, sr = librosa.load(audio_path, sr=None)\n# print(f\"Audio Loaded! ✅ Duration: {librosa.get_duration(y=y, sr=sr):.2f} seconds\")\n# import glob\n\n# # Get all OGG files from the subdirectories\n# all_audio_files = glob.glob(\"../input/birdclef-2025/train_audio/**/*.ogg\", recursive=True)\n\n# # Load and analyze first 3 files\n# for audio_path in all_audio_files[:3]:\n#     y, sr = librosa.load(audio_path, sr=None)\n#     duration = librosa.get_duration(y=y, sr=sr)\n#     print(f\"Loaded: {audio_path.split('/')[-1]} | Duration: {duration:.2f} seconds\")\n\n# import librosa.display\n# import matplotlib.pyplot as plt\n\n# # Plot waveform\n# plt.figure(figsize=(10, 4))\n# librosa.display.waveshow(y, sr=sr)\n# plt.title('Waveform of Sample Audio')\n# plt.xlabel('Time (s)')\n# plt.ylabel('Amplitude')\n# plt.show()\n\n# # Plot spectrogram\n# S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128)\n# S_dB = librosa.power_to_db(S, ref=np.max)\n\n# plt.figure(figsize=(10, 4))\n# librosa.display.specshow(S_dB, sr=sr, x_axis='time', y_axis='mel')\n# plt.colorbar(format='%+2.0f dB')\n# plt.title('Mel Spectrogram')\n# plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T23:11:26.279352Z","iopub.execute_input":"2025-03-18T23:11:26.279672Z","iopub.status.idle":"2025-03-18T23:11:44.475095Z","shell.execute_reply.started":"2025-03-18T23:11:26.279647Z","shell.execute_reply":"2025-03-18T23:11:44.474043Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# def extract_features(audio_path, max_pad_len=128):\n#     y, sr = librosa.load(audio_path, sr=32000)  # Use 32 kHz as specified\n#     S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128)\n#     S_db = librosa.power_to_db(S, ref=np.max)\n\n#     # Pad or trim spectrogram\n#     if S_db.shape[1] < max_pad_len:\n#         pad_width = max_pad_len - S_db.shape[1]\n#         S_db = np.pad(S_db, ((0, 0), (0, pad_width)), mode='constant')\n#     else:\n#         S_db = S_db[:, :max_pad_len]\n\n#     return S_db\n\n# # Example feature extraction\n# audio_path = \"../input/birdclef-2025/train_audio/greani1/XC132190.ogg\"\n# features = extract_features(audio_path)\n# print(f\"Extracted Features Shape: {features.shape}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T23:12:45.361459Z","iopub.execute_input":"2025-03-18T23:12:45.361811Z","iopub.status.idle":"2025-03-18T23:12:45.429827Z","shell.execute_reply.started":"2025-03-18T23:12:45.361783Z","shell.execute_reply":"2025-03-18T23:12:45.428972Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# train_df = pd.read_csv('../input/birdclef-2025/train.csv')\n# taxonomy_df = pd.read_csv('../input/birdclef-2025/taxonomy.csv')\n# train_df = pd.merge(train_df, taxonomy_df[['primary_label', 'class_name']], how='left', on='primary_label')\n\n# print(train_df.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T23:17:55.461658Z","iopub.execute_input":"2025-03-18T23:17:55.462007Z","iopub.status.idle":"2025-03-18T23:17:55.553337Z","shell.execute_reply.started":"2025-03-18T23:17:55.46198Z","shell.execute_reply":"2025-03-18T23:17:55.552273Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import os\n# import numpy as np\n# import pandas as pd\n# import librosa\n# import cv2\n# from sklearn.model_selection import train_test_split\n# from tensorflow.keras.utils import to_categorical\n\n# # Pad or truncate to fixed shape\n# def pad_or_truncate(S, max_len=128):\n#     \"\"\"Pad or truncate the spectrogram to a fixed size of 128x128.\"\"\"\n#     if S.shape[1] < max_len:\n#         # Pad with zeros if shorter\n#         pad_width = max_len - S.shape[1]\n#         S = np.pad(S, ((0, 0), (0, pad_width)), mode='constant')\n#     else:\n#         # Truncate if longer\n#         S = S[:, :max_len]\n\n#     return S\n\n# # Extract features with padding/truncation\n# def extract_features(audio_path):\n#     try:\n#         y, sr = librosa.load(audio_path, sr=None)\n#         S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128)\n#         S_dB = librosa.power_to_db(S, ref=np.max)\n\n#         # Pad or truncate the spectrogram to 128x128\n#         S_fixed = pad_or_truncate(S_dB, max_len=128)\n        \n#         return S_fixed\n#     except Exception as e:\n#         print(f\"❌ Error processing {audio_path}: {e}\")\n#         return None\n\n# # Load a small portion of the dataset\n# sample_df = train_df.sample(100, random_state=42)  # Use 100 samples to keep it small\n# X, y = [], []\n\n# # Process files and extract features\n# for i, row in sample_df.iterrows():\n#     audio_file = f\"../input/birdclef-2025/train_audio/{row['filename']}\"\n#     if os.path.exists(audio_file):\n#         feature = extract_features(audio_file)\n        \n#         # Check for valid feature shape\n#         if feature is not None and feature.shape == (128, 128):\n#             X.append(feature)\n#             y.append(row['primary_label'])\n#         else:\n#             print(f\"⚠️ Skipping {row['filename']} due to invalid feature shape.\")\n\n# # Convert to numpy arrays and reshape for CNN input\n# if len(X) == 0 or len(y) == 0:\n#     raise ValueError(\"❌ No valid audio files were processed. Check file paths and feature extraction!\")\n\n# X = np.array(X)\n# X = X.reshape(X.shape[0], 128, 128, 1)  # Reshape for CNN input\n# y_encoded, y_labels = pd.factorize(y)  # Encode text labels as integers\n# y = to_categorical(y_encoded)\n\n# # Split data into training and validation\n# X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)\n\n# print(f\"✅ Training data shape: {X_train.shape}, Validation data shape: {X_val.shape}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T23:24:16.027668Z","iopub.execute_input":"2025-03-18T23:24:16.028022Z","iopub.status.idle":"2025-03-18T23:24:24.347858Z","shell.execute_reply.started":"2025-03-18T23:24:16.028Z","shell.execute_reply":"2025-03-18T23:24:24.34698Z"},"_kg_hide-output":true,"_kg_hide-input":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":" ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T23:21:50.035478Z","iopub.execute_input":"2025-03-18T23:21:50.035816Z","iopub.status.idle":"2025-03-18T23:21:50.041842Z","shell.execute_reply.started":"2025-03-18T23:21:50.03579Z","shell.execute_reply":"2025-03-18T23:21:50.040408Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# print(f\"✅ Files successfully processed: {len(X)}\")\n# print(f\"✅ Unique classes: {len(np.unique(y_encoded))}\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# from tensorflow.keras.models import Sequential\n# from tensorflow.keras.layers import (\n#     Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization\n# )\n# from tensorflow.keras.optimizers import Adam\n\n\n# # Define the optimized CNN model\n# def build_cnn_model(input_shape=(128, 128, 1), num_classes=100):\n#     model = Sequential()\n\n#     # Convolutional Block 1\n#     model.add(Conv2D(16, (3, 3), activation=\"relu\", input_shape=input_shape, padding=\"same\"))\n#     model.add(MaxPooling2D((2, 2)))\n\n#     # Convolutional Block 2\n#     model.add(Conv2D(32, (3, 3), activation=\"relu\", padding=\"same\"))\n#     model.add(MaxPooling2D((2, 2)))\n\n#     # Convolutional Block 3\n#     model.add(Conv2D(64, (3, 3), activation=\"relu\", padding=\"same\"))\n#     model.add(MaxPooling2D((2, 2)))\n\n#     # Flatten and Dense Layers\n#     model.add(Flatten())\n#     model.add(Dense(128, activation=\"relu\"))\n#     model.add(Dropout(0.3))  # Reduced dropout to retain useful features\n\n#     # Output Layer\n#     model.add(Dense(num_classes, activation=\"softmax\"))\n\n#     # Compile with lower learning rate\n#     optimizer = Adam(learning_rate=1e-4)  # Slower learning to stabilize training\n#     model.compile(\n#         optimizer=optimizer,\n#         loss=\"categorical_crossentropy\",\n#         metrics=[\"accuracy\"]\n#     )\n\n#     return model\n\n\n# # Build and compile the improved model\n# model = build_cnn_model(input_shape=(128, 128, 1), num_classes=len(y_labels))\n\n# # Print model summary\n# model.summary()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T23:28:22.151028Z","iopub.execute_input":"2025-03-18T23:28:22.151345Z","iopub.status.idle":"2025-03-18T23:28:22.270588Z","shell.execute_reply.started":"2025-03-18T23:28:22.15132Z","shell.execute_reply":"2025-03-18T23:28:22.269554Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import numpy as np\n# import tensorflow as tf\n# from tensorflow.keras.models import Sequential\n# from tensorflow.keras.layers import (Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization)\n# from tensorflow.keras.optimizers import Adam\n\n# # 📚 Dummy Dataset (Replace with real data)\n# X_train = np.random.rand(300, 64, 64, 3)\n# y_train = np.random.randint(0, 5, 300)\n# X_val = np.random.rand(50, 64, 64, 3)\n# y_val = np.random.randint(0, 5, 50)\n\n# # 🧠 One-Hot Encoding\n# y_train_onehot = tf.keras.utils.to_categorical(y_train, 5)\n# y_val_onehot = tf.keras.utils.to_categorical(y_val, 5)\n\n# # 🎨 Model (Back to Basics)\n# model = Sequential()\n\n# # 🔥 Conv Layer 1\n# model.add(Conv2D(64, (3, 3), activation='relu', input_shape=(64, 64, 3)))\n# model.add(BatchNormalization())\n# model.add(MaxPooling2D(pool_size=(2, 2)))\n\n# # 🔥 Conv Layer 2\n# model.add(Conv2D(128, (3, 3), activation='relu'))\n# model.add(BatchNormalization())\n# model.add(MaxPooling2D(pool_size=(2, 2)))\n\n# # 🔥 Conv Layer 3\n# model.add(Conv2D(256, (3, 3), activation='relu'))\n# model.add(BatchNormalization())\n# model.add(MaxPooling2D(pool_size=(2, 2)))\n\n# # 🧠 Flatten and Dense\n# model.add(Flatten())\n# model.add(Dense(512, activation='relu'))\n# model.add(Dropout(0.5))\n# model.add(Dense(5, activation='softmax'))\n\n# # ⚡️ Compile with a higher LR\n# # model.compile(optimizer=Adam(learning_rate=5e-4), loss='categorical_crossentropy', metrics=['accuracy'])\n# model.compile(\n#     optimizer='adam',\n#     loss='categorical_crossentropy',  # Correct loss for one-hot labels\n#     metrics=['accuracy']\n# )\n\n# # 🏋️‍♂️ Training (No Aug, No Class Weights)\n# history = model.fit(\n#     X_train / 255.0, y_train_onehot,\n#     validation_data=(X_val / 255.0, y_val_onehot),\n#     epochs=5,\n#     batch_size=32,\n#     callbacks=[\n#         tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=2, min_lr=1e-6),\n#         tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=4, restore_best_weights=True)\n#     ]\n# )\n\n# # 📈 Evaluate\n# val_loss, val_acc = model.evaluate(X_val / 255.0, y_val_onehot)\n# print(f\"✅ Final Validation Accuracy: {val_acc:.4f}\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# print(y_train[:5])  # If this looks like [0, 1, 2, 3, 4] — use sparse_categorical_crossentropy\n# print(y_train_onehot[:5])  # If this looks like one-hot — use categorical_crossentropy\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T23:43:11.587485Z","iopub.execute_input":"2025-03-18T23:43:11.587774Z","iopub.status.idle":"2025-03-18T23:43:11.593943Z","shell.execute_reply.started":"2025-03-18T23:43:11.587752Z","shell.execute_reply":"2025-03-18T23:43:11.592676Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import numpy as np\n# unique, counts = np.unique(y_train, return_counts=True)\n# print(dict(zip(unique, counts)))\n# print(X_val.shape, y_val.shape)\n# print(np.argmax(y_val[:5], axis=1))  # Check first few labels\n# preds = model.predict(X_val / 255.0)\n# print(np.argmax(preds[:5], axis=1))  # Check predictions\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T23:40:06.724574Z","iopub.execute_input":"2025-03-18T23:40:06.724917Z","iopub.status.idle":"2025-03-18T23:40:06.756315Z","shell.execute_reply.started":"2025-03-18T23:40:06.724867Z","shell.execute_reply":"2025-03-18T23:40:06.75514Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# from tensorflow.keras.applications import MobileNetV2\n# from tensorflow.keras.layers import GlobalAveragePooling2D, Dense, Dropout\n# from tensorflow.keras.models import Model\n# from tensorflow.keras.optimizers import Adam\n# from tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping\n\n# # 📸 Load MobileNetV2 with pre-trained ImageNet weights, excluding the top layer\n# base_model = MobileNetV2(weights='imagenet', include_top=False, input_shape=(64, 64, 3))\n\n# # 🛠️ Add custom classification head\n# x = base_model.output\n# x = GlobalAveragePooling2D()(x)\n# x = Dense(512, activation='relu')(x)\n# x = Dropout(0.5)(x)  # Add dropout to reduce overfitting\n# predictions = Dense(5, activation='softmax')(x)\n\n# # 🧠 Create final model\n# model = Model(inputs=base_model.input, outputs=predictions)\n\n# # 🧊 Freeze base model layers initially\n# for layer in base_model.layers:\n#     layer.trainable = False\n\n# # 🚀 Compile the model with a small learning rate for initial training\n# model.compile(\n#     optimizer=Adam(learning_rate=1e-4),\n#     loss='categorical_crossentropy',\n#     metrics=['accuracy']\n# )\n\n# # 📉 Callbacks for better training\n# reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=3, min_lr=1e-6)\n# early_stop = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)\n\n# # 🏋️‍♂️ Train the model (initial training with frozen base layers)\n# history = model.fit(\n#     X_train / 255.0, y_train_onehot,\n#     validation_data=(X_val / 255.0, y_val_onehot),\n#     epochs=10,\n#     batch_size=32,\n#     callbacks=[reduce_lr, early_stop]\n# )\n\n# # 🔓 Unfreeze some of the top layers in base_model for fine-tuning\n# for layer in base_model.layers[-20:]:\n#     layer.trainable = True\n\n# # 🆙 Recompile with a smaller learning rate for fine-tuning\n# model.compile(\n#     optimizer=Adam(learning_rate=1e-5),  # Smaller LR for fine-tuning\n#     loss='categorical_crossentropy',\n#     metrics=['accuracy']\n# )\n\n# # 🎯 Fine-tuning the model with more epochs\n# fine_tune_history = model.fit(\n#     X_train / 255.0, y_train_onehot,\n#     validation_data=(X_val / 255.0, y_val_onehot),\n#     epochs=10,\n#     batch_size=32,\n#     callbacks=[reduce_lr, early_stop]\n# )\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-18T23:45:41.470966Z","iopub.execute_input":"2025-03-18T23:45:41.471369Z","iopub.status.idle":"2025-03-18T23:46:03.529308Z","shell.execute_reply.started":"2025-03-18T23:45:41.471333Z","shell.execute_reply":"2025-03-18T23:46:03.527589Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# taxonomy_df = pd.read_csv(cfg.taxonomy_csv)\n# species_ids = taxonomy_df['primary_label'].tolist()\n# num_classes = len(species_ids)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-20T03:57:06.737437Z","iopub.execute_input":"2025-03-20T03:57:06.737743Z","iopub.status.idle":"2025-03-20T03:57:06.755689Z","shell.execute_reply.started":"2025-03-20T03:57:06.737720Z","shell.execute_reply":"2025-03-20T03:57:06.754666Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class BirdCLEFModel(nn.Module):\n    def __init__(self, cfg, num_classes):\n        super().__init__()\n        self.cfg = cfg\n        \n        self.backbone = timm.create_model(\n            cfg.model_name,\n            pretrained=False,  \n            in_chans=cfg.in_channels,\n            drop_rate=0.0,    \n            drop_path_rate=0.0\n        )\n        \n        if 'efficientnet' in cfg.model_name:\n            backbone_out = self.backbone.classifier.in_features\n            self.backbone.classifier = nn.Identity()\n        elif 'resnet' in cfg.model_name:\n            backbone_out = self.backbone.fc.in_features\n            self.backbone.fc = nn.Identity()\n        else:\n            backbone_out = self.backbone.get_classifier().in_features\n            self.backbone.reset_classifier(0, '')\n        \n        self.pooling = nn.AdaptiveAvgPool2d(1)\n        self.feat_dim = backbone_out\n        self.classifier = nn.Linear(backbone_out, num_classes)\n        \n    def forward(self, x):\n        features = self.backbone(x)\n        \n        if isinstance(features, dict):\n            features = features['features']\n            \n        if len(features.shape) == 4:\n            features = self.pooling(features)\n            features = features.view(features.size(0), -1)\n        \n        logits = self.classifier(features)\n        return logits","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-21T18:55:10.952272Z","iopub.execute_input":"2025-03-21T18:55:10.952662Z","iopub.status.idle":"2025-03-21T18:55:10.959202Z","shell.execute_reply.started":"2025-03-21T18:55:10.952637Z","shell.execute_reply":"2025-03-21T18:55:10.958406Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def audio2melspec(audio_data, cfg):\n    \"\"\"Convert audio data to mel spectrogram\"\"\"\n    if np.isnan(audio_data).any():\n        mean_signal = np.nanmean(audio_data)\n        audio_data = np.nan_to_num(audio_data, nan=mean_signal)\n\n    mel_spec = librosa.feature.melspectrogram(\n        y=audio_data,\n        sr=cfg.FS,\n        n_fft=cfg.N_FFT,\n        hop_length=cfg.HOP_LENGTH,\n        n_mels=cfg.N_MELS,\n        fmin=cfg.FMIN,\n        fmax=cfg.FMAX,\n        power=2.0\n    )\n\n    mel_spec_db = librosa.power_to_db(mel_spec, ref=np.max)\n    mel_spec_norm = (mel_spec_db - mel_spec_db.min()) / (mel_spec_db.max() - mel_spec_db.min() + 1e-8)\n    \n    return mel_spec_norm\n\ndef process_audio_segment(audio_data, cfg):\n    \"\"\"Process audio segment to get mel spectrogram\"\"\"\n    if len(audio_data) < cfg.FS * cfg.WINDOW_SIZE:\n        audio_data = np.pad(audio_data, \n                          (0, cfg.FS * cfg.WINDOW_SIZE - len(audio_data)), \n                          mode='constant')\n    \n    mel_spec = audio2melspec(audio_data, cfg)\n    \n    # Resize if needed\n    if mel_spec.shape != cfg.TARGET_SHAPE:\n        mel_spec = cv2.resize(mel_spec, cfg.TARGET_SHAPE, interpolation=cv2.INTER_LINEAR)\n        \n    return mel_spec.astype(np.float32)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-21T18:55:29.435400Z","iopub.execute_input":"2025-03-21T18:55:29.435702Z","iopub.status.idle":"2025-03-21T18:55:29.442181Z","shell.execute_reply.started":"2025-03-21T18:55:29.435679Z","shell.execute_reply":"2025-03-21T18:55:29.441304Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def find_model_files(cfg):\n    \"\"\"\n    Find all .pth model files in the specified model directory\n    \"\"\"\n    model_files = []\n    \n    model_dir = Path(cfg.model_path)\n    \n    for path in model_dir.glob('**/*.pth'):\n        model_files.append(str(path))\n    \n    return model_files\n\ndef load_models(cfg, num_classes):\n    \"\"\"\n    Load all found model files and prepare them for ensemble\n    \"\"\"\n    models = []\n    \n    model_files = find_model_files(cfg)\n    \n    if not model_files:\n        print(f\"Warning: No model files found under {cfg.model_path}!\")\n        return models\n    \n    print(f\"Found a total of {len(model_files)} model files.\")\n    \n    if cfg.use_specific_folds:\n        filtered_files = []\n        for fold in cfg.folds:\n            fold_files = [f for f in model_files if f\"fold{fold}\" in f]\n            filtered_files.extend(fold_files)\n        model_files = filtered_files\n        print(f\"Using {len(model_files)} model files for the specified folds ({cfg.folds}).\")\n    \n    for model_path in model_files:\n        try:\n            print(f\"Loading model: {model_path}\")\n            checkpoint = torch.load(model_path, map_location=torch.device(cfg.device))\n            \n            model = BirdCLEFModel(cfg, num_classes)\n            model.load_state_dict(checkpoint['model_state_dict'])\n            model = model.to(cfg.device)\n            model.eval()\n            \n            models.append(model)\n        except Exception as e:\n            print(f\"Error loading model {model_path}: {e}\")\n    \n    return models\n\ndef predict_on_spectrogram(audio_path, models, cfg, species_ids):\n    \"\"\"Process a single audio file and predict species presence for each 5-second segment\"\"\"\n    predictions = []\n    row_ids = []\n    soundscape_id = Path(audio_path).stem\n    \n    try:\n        print(f\"Processing {soundscape_id}\")\n        audio_data, _ = librosa.load(audio_path, sr=cfg.FS)\n        \n        total_segments = int(len(audio_data) / (cfg.FS * cfg.WINDOW_SIZE))\n        \n        for segment_idx in range(total_segments):\n            start_sample = segment_idx * cfg.FS * cfg.WINDOW_SIZE\n            end_sample = start_sample + cfg.FS * cfg.WINDOW_SIZE\n            segment_audio = audio_data[start_sample:end_sample]\n            \n            end_time_sec = (segment_idx + 1) * cfg.WINDOW_SIZE\n            row_id = f\"{soundscape_id}_{end_time_sec}\"\n            row_ids.append(row_id)\n\n            if cfg.use_tta:\n                all_preds = []\n                \n                for tta_idx in range(cfg.tta_count):\n                    mel_spec = process_audio_segment(segment_audio, cfg)\n                    mel_spec = apply_tta(mel_spec, tta_idx)\n\n                    mel_spec = torch.tensor(mel_spec, dtype=torch.float32).unsqueeze(0).unsqueeze(0)\n                    mel_spec = mel_spec.to(cfg.device)\n\n                    if len(models) == 1:\n                        with torch.no_grad():\n                            outputs = models[0](mel_spec)\n                            probs = torch.sigmoid(outputs).cpu().numpy().squeeze()\n                            all_preds.append(probs)\n                    else:\n                        segment_preds = []\n                        for model in models:\n                            with torch.no_grad():\n                                outputs = model(mel_spec)\n                                probs = torch.sigmoid(outputs).cpu().numpy().squeeze()\n                                segment_preds.append(probs)\n                        \n                        avg_preds = np.mean(segment_preds, axis=0)\n                        all_preds.append(avg_preds)\n\n                final_preds = np.mean(all_preds, axis=0)\n            else:\n                mel_spec = process_audio_segment(segment_audio, cfg)\n                \n                mel_spec = torch.tensor(mel_spec, dtype=torch.float32).unsqueeze(0).unsqueeze(0)\n                mel_spec = mel_spec.to(cfg.device)\n                \n                if len(models) == 1:\n                    with torch.no_grad():\n                        outputs = models[0](mel_spec)\n                        final_preds = torch.sigmoid(outputs).cpu().numpy().squeeze()\n                else:\n                    segment_preds = []\n                    for model in models:\n                        with torch.no_grad():\n                            outputs = model(mel_spec)\n                            probs = torch.sigmoid(outputs).cpu().numpy().squeeze()\n                            segment_preds.append(probs)\n\n                    final_preds = np.mean(segment_preds, axis=0)\n                    \n            predictions.append(final_preds)\n            \n    except Exception as e:\n        print(f\"Error processing {audio_path}: {e}\")\n    \n    return row_ids, predictions","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-21T18:55:58.927811Z","iopub.execute_input":"2025-03-21T18:55:58.928190Z","iopub.status.idle":"2025-03-21T18:55:58.941342Z","shell.execute_reply.started":"2025-03-21T18:55:58.928164Z","shell.execute_reply":"2025-03-21T18:55:58.940460Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def apply_tta(spec, tta_idx):\n    \"\"\"Apply test-time augmentation\"\"\"\n    if tta_idx == 0:\n        # Original spectrogram\n        return spec\n    elif tta_idx == 1:\n        # Time shift (horizontal flip)\n        return np.flip(spec, axis=1)\n    elif tta_idx == 2:\n        # Frequency shift (vertical flip)\n        return np.flip(spec, axis=0)\n    else:\n        return spec\n\ndef run_inference(cfg, models, species_ids):\n    \"\"\"Run inference on all test soundscapes\"\"\"\n    test_files = list(Path(cfg.test_soundscapes).glob('*.ogg'))\n    \n    if cfg.debug:\n        print(f\"Debug mode enabled, using only {cfg.debug_count} files\")\n        test_files = test_files[:cfg.debug_count]\n    \n    print(f\"Found {len(test_files)} test soundscapes\")\n\n    all_row_ids = []\n    all_predictions = []\n\n    for audio_path in tqdm(test_files):\n        row_ids, predictions = predict_on_spectrogram(str(audio_path), models, cfg, species_ids)\n        all_row_ids.extend(row_ids)\n        all_predictions.extend(predictions)\n    \n    return all_row_ids, all_predictions\n\ndef create_submission(row_ids, predictions, species_ids, cfg):\n    \"\"\"Create submission dataframe\"\"\"\n    print(\"Creating submission dataframe...\")\n\n    submission_dict = {'row_id': row_ids}\n    \n    for i, species in enumerate(species_ids):\n        submission_dict[species] = [pred[i] for pred in predictions]\n\n    submission_df = pd.DataFrame(submission_dict)\n\n    submission_df.set_index('row_id', inplace=True)\n\n    sample_sub = pd.read_csv(cfg.submission_csv, index_col='row_id')\n\n    missing_cols = set(sample_sub.columns) - set(submission_df.columns)\n    if missing_cols:\n        print(f\"Warning: Missing {len(missing_cols)} species columns in submission\")\n        for col in missing_cols:\n            submission_df[col] = 0.0\n\n    submission_df = submission_df[sample_sub.columns]\n\n    submission_df = submission_df.reset_index()\n    \n    return submission_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-21T18:56:14.186432Z","iopub.execute_input":"2025-03-21T18:56:14.186763Z","iopub.status.idle":"2025-03-21T18:56:14.194432Z","shell.execute_reply.started":"2025-03-21T18:56:14.186733Z","shell.execute_reply":"2025-03-21T18:56:14.193368Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def main():\n    start_time = time.time()\n    print(\"Starting BirdCLEF-2025 inference...\")\n    print(f\"TTA enabled: {cfg.use_tta} (variations: {cfg.tta_count if cfg.use_tta else 0})\")\n\n    models = load_models(cfg, num_classes)\n    \n    if not models:\n        print(\"No models found! Please check model paths.\")\n        return\n    \n    print(f\"Model usage: {'Single model' if len(models) == 1 else f'Ensemble of {len(models)} models'}\")\n\n    row_ids, predictions = run_inference(cfg, models, species_ids)\n\n    submission_df = create_submission(row_ids, predictions, species_ids, cfg)\n\n    submission_path = 'submission.csv'\n    submission_df.to_csv(submission_path, index=False)\n    print(f\"Submission saved to {submission_path}\")\n    \n    end_time = time.time()\n    print(f\"Inference completed in {(end_time - start_time)/60:.2f} minutes\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-21T18:56:28.369568Z","iopub.execute_input":"2025-03-21T18:56:28.369947Z","iopub.status.idle":"2025-03-21T18:56:28.375083Z","shell.execute_reply.started":"2025-03-21T18:56:28.369914Z","shell.execute_reply":"2025-03-21T18:56:28.374115Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n\nif __name__ == \"__main__\":\n    main()\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-21T18:56:31.866359Z","iopub.execute_input":"2025-03-21T18:56:31.866650Z","iopub.status.idle":"2025-03-21T18:56:36.494188Z","shell.execute_reply.started":"2025-03-21T18:56:31.866625Z","shell.execute_reply":"2025-03-21T18:56:36.493330Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import torch\n# import timm\n# import os\n# from pathlib import Path\n# import pandas as pd\n\n# class CFG:\n#     test_soundscapes = '/kaggle/input/birdclef-2025/test_soundscapes'\n#     submission_csv = '/kaggle/input/birdclef-2025/sample_submission.csv'\n#     taxonomy_csv = '/kaggle/input/birdclef-2025/taxonomy.csv'\n#     model_path = '/kaggle/input/birdclef-2025-efficientnet-b0'  \n    \n#     # Audio parameters\n#     FS = 32000  \n#     WINDOW_SIZE = 5  \n    \n#     # Mel spectrogram parameters\n#     N_FFT = 1024\n#     HOP_LENGTH = 512\n#     N_MELS = 128\n#     FMIN = 50\n#     FMAX = 14000\n#     TARGET_SHAPE = (256, 256)\n    \n#     model_name = 'efficientnet_b0'\n#     in_channels = 1\n#     device = 'cpu'  \n    \n#     # Inference parameters\n#     batch_size = 16\n#     use_tta = False  \n#     tta_count = 3   \n#     threshold = 0.5\n    \n#     use_specific_folds = False  # If False, use all found models\n#     folds = [0, 1]  # Used only if use_specific_folds is True\n    \n#     debug = False\n#     debug_count = 3\n\n# # BirdCLEF model class\n# class BirdCLEFModel(torch.nn.Module):\n#     def __init__(self, cfg, num_classes):\n#         super().__init__()\n#         self.cfg = cfg\n        \n#         self.backbone = timm.create_model(\n#             cfg.model_name,\n#             pretrained=False,  \n#             in_chans=cfg.in_channels,\n#             drop_rate=0.0,    \n#             drop_path_rate=0.0\n#         )\n        \n#         if 'efficientnet' in cfg.model_name:\n#             backbone_out = self.backbone.classifier.in_features\n#             self.backbone.classifier = torch.nn.Identity()\n#         elif 'resnet' in cfg.model_name:\n#             backbone_out = self.backbone.fc.in_features\n#             self.backbone.fc = torch.nn.Identity()\n#         else:\n#             backbone_out = self.backbone.get_classifier().in_features\n#             self.backbone.reset_classifier(0, '')\n        \n#         self.pooling = torch.nn.AdaptiveAvgPool2d(1)\n#         self.feat_dim = backbone_out\n#         self.classifier = torch.nn.Linear(backbone_out, num_classes)\n        \n#     def forward(self, x):\n#         features = self.backbone(x)\n        \n#         if isinstance(features, dict):\n#             features = features['features']\n            \n#         if len(features.shape) == 4:\n#             features = self.pooling(features)\n#             features = features.view(features.size(0), -1)\n        \n#         logits = self.classifier(features)\n#         return logits\n\n# def find_model_files(cfg):\n#     \"\"\"\n#     Find all .pth model files in the specified model directory\n#     \"\"\"\n#     model_files = []\n    \n#     model_dir = Path(cfg.model_path)\n    \n#     for path in model_dir.glob('**/*.pth'):\n#         model_files.append(str(path))\n    \n#     return model_files\n\n# def print_model_architecture():\n#     cfg = CFG()\n    \n#     # Read taxonomy to get number of classes\n#     try:\n#         taxonomy_df = pd.read_csv(cfg.taxonomy_csv)\n#         species_ids = taxonomy_df['primary_label'].tolist()\n#         num_classes = len(species_ids)\n#         print(f\"Number of classes: {num_classes}\")\n#     except FileNotFoundError:\n#         print(f\"Taxonomy file not found: {cfg.taxonomy_csv}\")\n#         # Use a default value just to demonstrate the architecture\n#         num_classes = 100\n#         print(f\"Using default number of classes: {num_classes}\")\n    \n#     # Find model files\n#     model_files = find_model_files(cfg)\n    \n#     if not model_files:\n#         print(f\"No model files found in {cfg.model_path}\")\n#         return\n    \n#     print(f\"Found {len(model_files)} model file(s):\")\n#     for i, model_path in enumerate(model_files):\n#         print(f\"{i+1}. {model_path}\")\n    \n#     # Load first model to print architecture\n#     try:\n#         print(\"\\nLoading the first model to print architecture...\")\n#         model_path = model_files[0]\n        \n#         # Create model instance\n#         model = BirdCLEFModel(cfg, num_classes)\n        \n#         # Load model weights\n#         checkpoint = torch.load(model_path, map_location=torch.device(cfg.device))\n#         model.load_state_dict(checkpoint['model_state_dict'])\n        \n#         # Print model architecture\n#         print(\"\\nModel Architecture:\")\n#         print(model)\n        \n#         # Print model summary - number of parameters\n#         num_params = sum(p.numel() for p in model.parameters())\n#         print(f\"\\nTotal number of parameters: {num_params:,}\")\n        \n#         # Print backbone architecture\n#         print(\"\\nBackbone Architecture:\")\n#         print(model.backbone)\n        \n#         # Print classifier architecture\n#         print(\"\\nClassifier Architecture:\")\n#         print(model.classifier)\n        \n#     except Exception as e:\n#         print(f\"Error loading model: {e}\")\n\n# # Run the function\n# print_model_architecture()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-20T02:38:45.673327Z","iopub.execute_input":"2025-03-20T02:38:45.673710Z","iopub.status.idle":"2025-03-20T02:38:46.144912Z","shell.execute_reply.started":"2025-03-20T02:38:45.673679Z","shell.execute_reply":"2025-03-20T02:38:46.143788Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import torch\n# import torch.nn as nn\n# import torch.optim as optim\n# from torch.optim.lr_scheduler import ReduceLROnPlateau\n\n# # Define a simple configuration class\n# class CFG:\n#     model_name = 'efficientnet_b0'  # Example model name\n#     in_channels = 1  # Number of input channels (e.g., for spectrograms)\n#     device = 'cuda' if torch.cuda.is_available() else 'cpu'  # Use GPU if available\n\n# # Set num_classes to 206 (matching the checkpoint)\n# num_classes = 206\n\n# # Create an instance of the configuration class\n# cfg = CFG()\n\n# # Define the BirdCLEFModel class (assuming it's already defined as in your original code)\n# class BirdCLEFModel(nn.Module):\n#     def __init__(self, cfg, num_classes):\n#         super(BirdCLEFModel, self).__init__()\n#         self.cfg = cfg\n#         self.backbone = timm.create_model(\n#             cfg.model_name,\n#             pretrained=False,\n#             in_chans=cfg.in_channels,\n#             drop_rate=0.0,\n#             drop_path_rate=0.0\n#         )\n#         if 'efficientnet' in cfg.model_name:\n#             backbone_out = self.backbone.classifier.in_features\n#             self.backbone.classifier = nn.Identity()\n#         else:\n#             backbone_out = self.backbone.get_classifier().in_features\n#             self.backbone.reset_classifier(0, '')\n#         self.pooling = nn.AdaptiveAvgPool2d(1)\n#         self.feat_dim = backbone_out\n#         self.classifier = nn.Linear(backbone_out, num_classes)\n\n#     def forward(self, x):\n#         features = self.backbone(x)\n#         if isinstance(features, dict):\n#             features = features['features']\n#         if len(features.shape) == 4:\n#             features = self.pooling(features)\n#             features = features.view(features.size(0), -1)\n#         logits = self.classifier(features)\n#         return logits\n\n# # Create an instance of the model with the correct num_classes\n# model = BirdCLEFModel(cfg, num_classes)\n\n# # Load the checkpoint\n# checkpoint = torch.load('/kaggle/input/birdclef-2025-efficientnet-b0/model_fold0.pth', map_location=torch.device('cpu'))\n\n# # Extract the model's state_dict\n# model_state_dict = checkpoint['model_state_dict']\n\n# # Load the model's state_dict into the model\n# model.load_state_dict(model_state_dict)\n\n# # Move the model to the appropriate device (CPU/GPU)\n# model = model.to(cfg.device)\n\n# # Define loss function with label smoothing\n# criterion = nn.CrossEntropyLoss(label_smoothing=0.1)\n\n# # Define optimizer with weight decay\n# optimizer = optim.Adam(model.parameters(), lr=1e-4, weight_decay=1e-5)\n\n# # Define learning rate scheduler\n# scheduler = ReduceLROnPlateau(optimizer, mode='max', factor=0.1, patience=3, verbose=True)\n\n# # Training loop\n# num_epochs = 10  # Example number of epochs\n# for epoch in range(num_epochs):\n#     model.train()\n#     for inputs, labels in train_loader:\n#         # Move inputs and labels to the same device as the model\n#         inputs = inputs.to(cfg.device)\n#         labels = labels.to(cfg.device)\n        \n#         optimizer.zero_grad()\n#         outputs = model(inputs)\n#         loss = criterion(outputs, labels)\n#         loss.backward()\n#         optimizer.step()\n    \n#     # Validation step\n#     model.eval()\n#     val_loss = 0\n#     val_auc = 0\n#     with torch.no_grad():\n#         for inputs, labels in val_loader:\n#             inputs = inputs.to(cfg.device)\n#             labels = labels.to(cfg.device)\n            \n#             outputs = model(inputs)\n#             val_loss += criterion(outputs, labels).item()\n#             val_auc += calculate_auc(outputs, labels)  # Assuming you have a function to calculate AUC\n    \n#     val_loss /= len(val_loader)\n#     val_auc /= len(val_loader)\n    \n#     # Adjust learning rate based on validation AUC\n#     scheduler.step(val_auc)\n    \n#     print(f'Epoch {epoch+1}, Val Loss: {val_loss}, Val AUC: {val_auc}')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-20T21:26:22.202712Z","iopub.execute_input":"2025-03-20T21:26:22.202942Z","iopub.status.idle":"2025-03-20T21:26:22.221956Z","shell.execute_reply.started":"2025-03-20T21:26:22.202914Z","shell.execute_reply":"2025-03-20T21:26:22.221264Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import torch\n# from torch.utils.data import DataLoader, Dataset\n# from torchvision import transforms\n\n# # Example: Define a custom dataset class\n# class BirdCLEFDataset(Dataset):\n#     def __init__(self, data, labels, transform=None):\n#         self.data = data\n#         self.labels = labels\n#         self.transform = transform\n\n#     def __len__(self):\n#         return len(self.data)\n\n#     def __getitem__(self, idx):\n#         sample = self.data[idx]\n#         label = self.labels[idx]\n#         if self.transform:\n#             sample = self.transform(sample)\n#         return sample, label\n\n# # Example: Create dummy data and labels\n# train_data = torch.randn(100, 1, 256, 256)  # Example: 100 samples, 1 channel, 256x256 spectrograms\n# train_labels = torch.randint(0, 206, (100,))  # Example: 100 labels for 206 classes\n\n# val_data = torch.randn(20, 1, 256, 256)  # Example: 20 validation samples\n# val_labels = torch.randint(0, 206, (20,))  # Example: 20 validation labels\n\n# # Define transformations (if needed)\n# transform = transforms.Compose([\n#     transforms.RandomHorizontalFlip(),  # Example: Random horizontal flip for augmentation\n# ])\n\n# # Create datasets\n# train_dataset = BirdCLEFDataset(train_data, train_labels, transform=transform)\n# val_dataset = BirdCLEFDataset(val_data, val_labels)\n\n# # Create data loaders\n# train_loader = DataLoader(train_dataset, batch_size=cfg.batch_size, shuffle=True)\n# val_loader = DataLoader(val_dataset, batch_size=cfg.batch_size, shuffle=False)\n\n# # Training loop\n# num_epochs = 10  # Example number of epochs\n# for epoch in range(num_epochs):\n#     model.train()\n#     for inputs, labels in train_loader:\n#         # Move inputs and labels to the same device as the model\n#         inputs = inputs.to(cfg.device)\n#         labels = labels.to(cfg.device)\n        \n#         optimizer.zero_grad()\n#         outputs = model(inputs)\n#         loss = criterion(outputs, labels)\n#         loss.backward()\n#         optimizer.step()\n    \n#     # Validation step\n#     model.eval()\n#     val_loss = 0\n#     val_auc = 0\n#     with torch.no_grad():\n#         for inputs, labels in val_loader:\n#             inputs = inputs.to(cfg.device)\n#             labels = labels.to(cfg.device)\n            \n#             outputs = model(inputs)\n#             val_loss += criterion(outputs, labels).item()\n#             val_auc += calculate_auc(outputs, labels)  # Assuming you have a function to calculate AUC\n    \n#     val_loss /= len(val_loader)\n#     val_auc /= len(val_loader)\n    \n#     # Adjust learning rate based on validation AUC\n#     scheduler.step(val_auc)\n    \n#     print(f'Epoch {epoch+1}, Val Loss: {val_loss}, Val AUC: {val_auc}')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-20T21:26:22.222885Z","iopub.execute_input":"2025-03-20T21:26:22.223160Z","iopub.status.idle":"2025-03-20T21:26:22.244510Z","shell.execute_reply.started":"2025-03-20T21:26:22.223133Z","shell.execute_reply":"2025-03-20T21:26:22.243639Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# from sklearn.metrics import roc_auc_score\n\n# def calculate_auc(outputs, labels):\n#     \"\"\"\n#     Calculate the AUC score for multi-class classification.\n    \n#     Args:\n#         outputs (torch.Tensor): Model outputs (logits) of shape (batch_size, num_classes).\n#         labels (torch.Tensor): Ground truth labels of shape (batch_size,).\n    \n#     Returns:\n#         float: AUC score.\n#     \"\"\"\n#     # Convert outputs to probabilities using softmax\n#     probs = torch.softmax(outputs, dim=1).cpu().numpy()\n    \n#     # Convert labels to one-hot encoding\n#     labels_one_hot = torch.nn.functional.one_hot(labels, num_classes=probs.shape[1]).cpu().numpy()\n    \n#     # Compute AUC score\n#     auc = roc_auc_score(labels_one_hot, probs, multi_class='ovo')  # 'ovo' for One-vs-One, 'ovr' for One-vs-Rest\n#     return auc\n\n# # Training loop\n# num_epochs = 10  # Example number of epochs\n# for epoch in range(num_epochs):\n#     model.train()\n#     for inputs, labels in train_loader:\n#         # Move inputs and labels to the same device as the model\n#         inputs = inputs.to(cfg.device)\n#         labels = labels.to(cfg.device)\n        \n#         optimizer.zero_grad()\n#         outputs = model(inputs)\n#         loss = criterion(outputs, labels)\n#         loss.backward()\n#         optimizer.step()\n    \n#     # Validation step\n#     model.eval()\n#     val_loss = 0\n#     val_auc = 0\n#     with torch.no_grad():\n#         for inputs, labels in val_loader:\n#             inputs = inputs.to(cfg.device)\n#             labels = labels.to(cfg.device)\n            \n#             outputs = model(inputs)\n#             val_loss += criterion(outputs, labels).item()\n#             val_auc += calculate_auc(outputs, labels)  # Use the calculate_auc function\n    \n#     val_loss /= len(val_loader)\n#     val_auc /= len(val_loader)\n    \n#     # Adjust learning rate based on validation AUC\n#     scheduler.step(val_auc)\n    \n#     print(f'Epoch {epoch+1}, Val Loss: {val_loss}, Val AUC: {val_auc}')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-20T21:26:22.308053Z","iopub.execute_input":"2025-03-20T21:26:22.308292Z","iopub.status.idle":"2025-03-20T21:26:22.312038Z","shell.execute_reply.started":"2025-03-20T21:26:22.308273Z","shell.execute_reply":"2025-03-20T21:26:22.311073Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# from sklearn.metrics import roc_auc_score\n\n# def calculate_auc(outputs, labels):\n#     \"\"\"\n#     Calculate the AUC score for multi-class classification.\n    \n#     Args:\n#         outputs (torch.Tensor): Model outputs (logits) of shape (batch_size, num_classes).\n#         labels (torch.Tensor): Ground truth labels of shape (batch_size,).\n    \n#     Returns:\n#         float: AUC score, or 0.0 if only one class is present.\n#     \"\"\"\n#     # Convert outputs to probabilities using softmax\n#     probs = torch.softmax(outputs, dim=1).cpu().numpy()\n    \n#     # Convert labels to one-hot encoding\n#     labels_one_hot = torch.nn.functional.one_hot(labels, num_classes=probs.shape[1]).cpu().numpy()\n    \n#     # Check if at least two classes are present\n#     if len(np.unique(labels)) < 2:\n#         print(\"Warning: Only one class present in y_true. AUC score is not defined.\")\n#         return 0.0  # Return 0.0 or any placeholder value\n    \n#     # Compute AUC score\n#     auc = roc_auc_score(labels_one_hot, probs, multi_class='ovo')  # 'ovo' for One-vs-One, 'ovr' for One-vs-Rest\n#     return auc\n\n\n# # Training loop\n# num_epochs = 10  # Example number of epochs\n# for epoch in range(num_epochs):\n#     model.train()\n#     for inputs, labels in train_loader:\n#         # Move inputs and labels to the same device as the model\n#         inputs = inputs.to(cfg.device)\n#         labels = labels.to(cfg.device)\n        \n#         optimizer.zero_grad()\n#         outputs = model(inputs)\n#         loss = criterion(outputs, labels)\n#         loss.backward()\n#         optimizer.step()\n    \n#     # Validation step\n#     model.eval()\n#     val_loss = 0\n#     val_auc = 0\n#     with torch.no_grad():\n#         for inputs, labels in val_loader:\n#             inputs = inputs.to(cfg.device)\n#             labels = labels.to(cfg.device)\n            \n#             outputs = model(inputs)\n#             val_loss += criterion(outputs, labels).item()\n#             val_auc += calculate_auc(outputs, labels)  # Use the calculate_auc function\n    \n#     val_loss /= len(val_loader)\n#     val_auc /= len(val_loader)\n    \n#     # Adjust learning rate based on validation AUC\n#     scheduler.step(val_auc)\n    \n#     print(f'Epoch {epoch+1}, Val Loss: {val_loss}, Val AUC: {val_auc}')\n\n\n\n\n# def calculate_accuracy(outputs, labels):\n#     \"\"\"\n#     Calculate the accuracy for classification.\n    \n#     Args:\n#         outputs (torch.Tensor): Model outputs (logits) of shape (batch_size, num_classes).\n#         labels (torch.Tensor): Ground truth labels of shape (batch_size,).\n    \n#     Returns:\n#         float: Accuracy score.\n#     \"\"\"\n#     _, preds = torch.max(outputs, dim=1)\n#     correct = (preds == labels).sum().item()\n#     accuracy = correct / len(labels)\n#     return accuracy","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-20T04:08:39.760092Z","iopub.execute_input":"2025-03-20T04:08:39.760471Z","iopub.status.idle":"2025-03-20T04:08:41.523438Z","shell.execute_reply.started":"2025-03-20T04:08:39.760439Z","shell.execute_reply":"2025-03-20T04:08:41.522218Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import torch\n# import torch.nn as nn\n# import torch.optim as optim\n# from torch.optim.lr_scheduler import ReduceLROnPlateau\n\n# # Define a simple configuration class\n# class CFG:\n#     model_name = 'efficientnet_b0'  # Example model name\n#     in_channels = 1  # Number of input channels (e.g., for spectrograms)\n#     device = 'cuda' if torch.cuda.is_available() else 'cpu'  # Use GPU if available\n\n# # Example: Calculate num_classes (number of species)\n# # Assuming you have a list of species IDs\n# species_ids = [...]  # Replace with your actual list of species IDs\n# num_classes = len(species_ids)\n\n# # Create an instance of the configuration class\n# cfg = CFG()\n\n# # Define the BirdCLEFModel class (assuming it's already defined as in your original code)\n# class BirdCLEFModel(nn.Module):\n#     def __init__(self, cfg, num_classes):\n#         super(BirdCLEFModel, self).__init__()\n#         self.cfg = cfg\n#         self.backbone = timm.create_model(\n#             cfg.model_name,\n#             pretrained=False,\n#             in_chans=cfg.in_channels,\n#             drop_rate=0.0,\n#             drop_path_rate=0.0\n#         )\n#         if 'efficientnet' in cfg.model_name:\n#             backbone_out = self.backbone.classifier.in_features\n#             self.backbone.classifier = nn.Identity()\n#         else:\n#             backbone_out = self.backbone.get_classifier().in_features\n#             self.backbone.reset_classifier(0, '')\n#         self.pooling = nn.AdaptiveAvgPool2d(1)\n#         self.feat_dim = backbone_out\n#         self.classifier = nn.Linear(backbone_out, num_classes)\n\n#     def forward(self, x):\n#         features = self.backbone(x)\n#         if isinstance(features, dict):\n#             features = features['features']\n#         if len(features.shape) == 4:\n#             features = self.pooling(features)\n#             features = features.view(features.size(0), -1)\n#         logits = self.classifier(features)\n#         return logits\n\n# # Create an instance of the model\n# model = BirdCLEFModel(cfg, num_classes)\n\n# # Load the checkpoint\n# checkpoint = torch.load('/kaggle/input/birdclef-2025-efficientnet-b0/model_fold0.pth', map_location=torch.device('cpu'))\n\n# # Extract the model's state_dict\n# model_state_dict = checkpoint['model_state_dict']\n\n# # Load the model's state_dict into the model\n# model.load_state_dict(model_state_dict)\n\n# # Move the model to the appropriate device (CPU/GPU)\n# model = model.to(cfg.device)\n\n# # Define loss function with label smoothing\n# criterion = nn.CrossEntropyLoss(label_smoothing=0.1)\n\n# # Define optimizer with weight decay\n# optimizer = optim.Adam(model.parameters(), lr=1e-4, weight_decay=1e-5)\n\n# # Define learning rate scheduler\n# scheduler = ReduceLROnPlateau(optimizer, mode='max', factor=0.1, patience=3, verbose=True)\n\n# # Training loop\n# num_epochs = 10  # Example number of epochs\n# for epoch in range(num_epochs):\n#     model.train()\n#     for inputs, labels in train_loader:\n#         # Move inputs and labels to the same device as the model\n#         inputs = inputs.to(cfg.device)\n#         labels = labels.to(cfg.device)\n        \n#         optimizer.zero_grad()\n#         outputs = model(inputs)\n#         loss = criterion(outputs, labels)\n#         loss.backward()\n#         optimizer.step()\n    \n#     # Validation step\n#     model.eval()\n#     val_loss = 0\n#     val_auc = 0\n#     with torch.no_grad():\n#         for inputs, labels in val_loader:\n#             inputs = inputs.to(cfg.device)\n#             labels = labels.to(cfg.device)\n            \n#             outputs = model(inputs)\n#             val_loss += criterion(outputs, labels).item()\n#             val_auc += calculate_auc(outputs, labels)  # Assuming you have a function to calculate AUC\n    \n#     val_loss /= len(val_loader)\n#     val_auc /= len(val_loader)\n    \n#     # Adjust learning rate based on validation AUC\n#     scheduler.step(val_auc)\n    \n#     print(f'Epoch {epoch+1}, Val Loss: {val_loss}, Val AUC: {val_auc}')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-20T04:05:36.359414Z","iopub.execute_input":"2025-03-20T04:05:36.359744Z","iopub.status.idle":"2025-03-20T04:05:36.580355Z","shell.execute_reply.started":"2025-03-20T04:05:36.359720Z","shell.execute_reply":"2025-03-20T04:05:36.579089Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}