{"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":"none","dataSources":[{"sourceId":91844,"databundleVersionId":11361821,"sourceType":"competition"}],"dockerImageVersionId":30918,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"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\n'''import os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))'''\n\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,"execution":{"iopub.status.busy":"2025-04-12T00:24:33.403931Z","iopub.execute_input":"2025-04-12T00:24:33.404448Z","iopub.status.idle":"2025-04-12T00:24:34.825673Z","shell.execute_reply.started":"2025-04-12T00:24:33.404409Z","shell.execute_reply":"2025-04-12T00:24:34.824205Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport sklearn as sk\nimport os\n\ntrain_data=  pd.read_csv('/kaggle/input/birdclef-2025/train.csv')\ntaxonomy = pd.read_csv('/kaggle/input/birdclef-2025/taxonomy.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T00:32:17.250225Z","iopub.execute_input":"2025-04-12T00:32:17.250710Z","iopub.status.idle":"2025-04-12T00:32:18.485532Z","shell.execute_reply.started":"2025-04-12T00:32:17.250677Z","shell.execute_reply":"2025-04-12T00:32:18.484268Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_data.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T00:32:32.214884Z","iopub.execute_input":"2025-04-12T00:32:32.215350Z","iopub.status.idle":"2025-04-12T00:32:32.248852Z","shell.execute_reply.started":"2025-04-12T00:32:32.215294Z","shell.execute_reply":"2025-04-12T00:32:32.247450Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import librosa\nimport sklearn\nimport json\nimport matplotlib.pyplot as plt\nimport wandb\nimport torchaudio\nimport plotly.express as px\nfrom IPython.display import Audio\nfrom shapely.geometry import Point\nimport plotly.express as px","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T00:36:20.493771Z","iopub.execute_input":"2025-04-12T00:36:20.494750Z","iopub.status.idle":"2025-04-12T00:36:20.501071Z","shell.execute_reply.started":"2025-04-12T00:36:20.494705Z","shell.execute_reply":"2025-04-12T00:36:20.499377Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"base_dir = \"/kaggle/input/birdclef-2025/train_audio\"\ndata, sampling_rate = torchaudio.load(os.path.join(base_dir, train_data['filename'][3]))\ndata","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T00:36:37.719297Z","iopub.execute_input":"2025-04-12T00:36:37.719706Z","iopub.status.idle":"2025-04-12T00:36:38.063625Z","shell.execute_reply.started":"2025-04-12T00:36:37.719674Z","shell.execute_reply":"2025-04-12T00:36:38.062454Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"display(Audio(data[0, :sampling_rate*100], rate=sampling_rate))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T01:03:57.776122Z","iopub.execute_input":"2025-04-12T01:03:57.776625Z","iopub.status.idle":"2025-04-12T01:03:57.966628Z","shell.execute_reply.started":"2025-04-12T01:03:57.776583Z","shell.execute_reply":"2025-04-12T01:03:57.964871Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(20, 5))\nplt.plot(data[0, :sampling_rate*6])\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T01:39:26.220766Z","iopub.execute_input":"2025-04-12T01:39:26.221199Z","iopub.status.idle":"2025-04-12T01:39:31.861891Z","shell.execute_reply.started":"2025-04-12T01:39:26.221165Z","shell.execute_reply":"2025-04-12T01:39:31.860563Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**High Pass Filter**","metadata":{}},{"cell_type":"code","source":"import scipy\nfrom scipy import signal as sp_signal\ndef butter_highpass_filter(data, cutoff=300, fs=sampling_rate, order=10):\n    normal_cutoff = cutoff / (fs / 2)\n    b, a = sp_signal.butter(order, normal_cutoff, btype=\"high\", analog=False)\n    y = sp_signal.filtfilt(b, a, data)\n    return y","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T01:08:42.426761Z","iopub.execute_input":"2025-04-12T01:08:42.427120Z","iopub.status.idle":"2025-04-12T01:08:42.432741Z","shell.execute_reply.started":"2025-04-12T01:08:42.427091Z","shell.execute_reply":"2025-04-12T01:08:42.431419Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torchaudio.functional as T\n\nfiltered_audio = T.highpass_biquad(waveform=data[:sampling_rate*40],sample_rate=32000, cutoff_freq=15950)  # remove low speechy hum\ndisplay(Audio(filtered_audio, rate=sampling_rate))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T01:34:28.511857Z","iopub.execute_input":"2025-04-12T01:34:28.512387Z","iopub.status.idle":"2025-04-12T01:34:28.833701Z","shell.execute_reply.started":"2025-04-12T01:34:28.512339Z","shell.execute_reply":"2025-04-12T01:34:28.831777Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Low Pass Filtering**","metadata":{}},{"cell_type":"code","source":"def fft_low_pass(data, cutoff, rate):\n    stft = librosa.stft(data,  n_fft =int(rate * 0.093), hop_length = 128 )\n    print(stft.shape)\n    freqs = librosa.fft_frequencies(sr=rate, n_fft=stft.shape[0] * 2 - 1)\n    stft[freqs < cutoff, :] = 0  \n    \n    filtered_audio = librosa.istft(stft)\n    \n    return filtered_audio","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T01:41:55.726497Z","iopub.execute_input":"2025-04-12T01:41:55.726871Z","iopub.status.idle":"2025-04-12T01:41:55.733041Z","shell.execute_reply.started":"2025-04-12T01:41:55.726842Z","shell.execute_reply":"2025-04-12T01:41:55.731812Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data_np = data[0].numpy()\nlow_fft_filtered_data  = fft_low_pass(data_np[:sampling_rate*6], cutoff=2800,rate= sampling_rate)\nplt.figure(figsize=(20, 5))\nplt.plot(low_fft_filtered_data)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T01:41:58.570820Z","iopub.execute_input":"2025-04-12T01:41:58.571254Z","iopub.status.idle":"2025-04-12T01:41:59.078356Z","shell.execute_reply.started":"2025-04-12T01:41:58.571221Z","shell.execute_reply":"2025-04-12T01:41:59.076907Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"display(Audio(low_fft_filtered_data, rate=sampling_rate))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T01:42:05.181591Z","iopub.execute_input":"2025-04-12T01:42:05.182010Z","iopub.status.idle":"2025-04-12T01:42:05.244239Z","shell.execute_reply.started":"2025-04-12T01:42:05.181973Z","shell.execute_reply":"2025-04-12T01:42:05.242657Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install tensorflow librosa noisereduce matplotlib opencv-python pandas","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T17:45:36.089492Z","iopub.execute_input":"2025-04-12T17:45:36.089881Z","iopub.status.idle":"2025-04-12T17:45:42.005017Z","shell.execute_reply.started":"2025-04-12T17:45:36.089854Z","shell.execute_reply":"2025-04-12T17:45:42.003684Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Denoising Example**","metadata":{}},{"cell_type":"code","source":"# Cell: Check for CUDA/GPU Availability\nimport tensorflow as tf\n\ngpus = tf.config.list_physical_devices('GPU')\nif gpus:\n    print(\"GPU(s) found:\")\n    for gpu in gpus:\n        print(\"  \", gpu)\n    try:\n        # Enable memory growth to avoid allocating all GPU memory at once\n        for gpu in gpus:\n            tf.config.experimental.set_memory_growth(gpu, True)\n        print(\"Memory growth enabled on GPU(s).\")\n    except RuntimeError as e:\n        print(\"Error enabling memory growth:\", e)\nelse:\n    print(\"No GPU found. Using CPU.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T17:39:24.091006Z","iopub.execute_input":"2025-04-12T17:39:24.091373Z","iopub.status.idle":"2025-04-12T17:39:39.698205Z","shell.execute_reply.started":"2025-04-12T17:39:24.091341Z","shell.execute_reply":"2025-04-12T17:39:39.696990Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport librosa\nimport librosa.display\nimport noisereduce as nr\nfrom tensorflow.keras import layers, models\nfrom tensorflow.keras.callbacks import ModelCheckpoint\nimport cv2\n\n# Ensure reproducibility\nnp.random.seed(42)\ntf.random.set_seed(42)\n\ndef load_audio_file(file_path, sr=None):\n    \"\"\"Load an audio file and return the audio time series and sample rate.\"\"\"\n    audio, sr = librosa.load(file_path, sr=sr)\n    return audio, sr\n\ndef compute_spectrogram(audio, sr, n_fft=2048, hop_length=512):\n    \"\"\"Compute a spectrogram (in dB) from an audio signal.\"\"\"\n    S = librosa.stft(audio, n_fft=n_fft, hop_length=hop_length)\n    S_db = librosa.amplitude_to_db(np.abs(S), ref=np.max)\n    return S_db\n\ndef save_spectrogram(S_db, sr, filename_prefix):\n    \"\"\"Save the spectrogram as an image and as a NumPy array.\"\"\"\n    plt.figure(figsize=(10, 4))\n    librosa.display.specshow(S_db, sr=sr, x_axis='time', y_axis='log')\n    plt.colorbar(format='%+2.0f dB')\n    plt.title(f'{filename_prefix} Spectrogram')\n    plt.savefig(f'{filename_prefix}_spectrogram.png')\n    plt.close()\n    \n    np.save(f'{filename_prefix}_spectrogram.npy', S_db)\n\ndef build_noise_profile(noise_dir, sr=None):\n    \"\"\"Load all .ogg noise recordings from a directory and concatenate them into a combined noise profile.\"\"\"\n    noise_files = [os.path.join(noise_dir, f) for f in os.listdir(noise_dir) if f.endswith('.ogg')]\n    noise_profiles = []\n    \n    for nf in noise_files:\n        audio, file_sr = load_audio_file(nf, sr=sr)\n        noise_profiles.append(audio)\n    \n    combined_noise = np.concatenate(noise_profiles)\n    return combined_noise\n\ndef resize_spectrogram(S_db, target_shape=(256, 256)):\n    \"\"\"Resize the spectrogram to a fixed target shape using OpenCV.\"\"\"\n    S_db_resized = cv2.resize(S_db.astype(np.float32), target_shape, interpolation=cv2.INTER_AREA)\n    return S_db_resized\n\ndef create_training_pair(file_path, noise_profile, sr=None, target_shape=(256,256)):\n    \"\"\"Generate a (noisy spectrogram, denoised spectrogram) pair for a given audio file.\"\"\"\n    # Load the animal sound audio\n    audio, sr = load_audio_file(file_path, sr=sr)\n    \n    # Compute and resize the original (noisy) spectrogram\n    S_db_noisy = compute_spectrogram(audio, sr)\n    S_db_noisy = resize_spectrogram(S_db_noisy, target_shape)\n    \n    # Apply noise reduction using the combined noise profile\n    reduced_audio = nr.reduce_noise(audio_clip=audio, noise_clip=noise_profile, verbose=False)\n    S_db_denoised = compute_spectrogram(reduced_audio, sr)\n    S_db_denoised = resize_spectrogram(S_db_denoised, target_shape)\n    \n    # Expand dimensions to add a channel (grayscale image)\n    S_db_noisy = np.expand_dims(S_db_noisy, axis=-1)\n    S_db_denoised = np.expand_dims(S_db_denoised, axis=-1)\n    \n    return S_db_noisy, S_db_denoised","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T17:45:49.410426Z","iopub.execute_input":"2025-04-12T17:45:49.410855Z","iopub.status.idle":"2025-04-12T17:45:54.754626Z","shell.execute_reply.started":"2025-04-12T17:45:49.410820Z","shell.execute_reply":"2025-04-12T17:45:54.752946Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Set paths","metadata":{}},{"cell_type":"code","source":"# Set paths (adjust these to your environment)\ntrain_audio_dir = 'birdclef-2025/train_audio' \ntrain_soundscapes_dir = 'birdclef-2025/train_soundscapes'\ncsv_path = 'birdclef-2025/train.csv'  # Optional; use for later classification steps","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T17:46:27.279649Z","iopub.execute_input":"2025-04-12T17:46:27.280378Z","iopub.status.idle":"2025-04-12T17:46:27.285693Z","shell.execute_reply.started":"2025-04-12T17:46:27.280347Z","shell.execute_reply":"2025-04-12T17:46:27.284361Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Process one train_audio file**","metadata":{}},{"cell_type":"code","source":"import glob\n\n# Collect all .ogg files from any subfolder within train_audio_dir\ntrain_audio_files = glob.glob(os.path.join(train_audio_dir, '**/*.ogg'), recursive=True)\nprint(f\"Found {len(train_audio_files)} .ogg files in train_audio (including subfolders).\")\n\n# Pick a sample animal sound from train_audio_files\nif train_audio_files:\n    sample_audio_path = train_audio_files[0]\n    audio, sr = load_audio_file(sample_audio_path, sr=44100)\n    print(f\"Sample audio loaded: {len(audio)/sr:.2f} seconds at {sr} Hz\")\n    S_db_before = compute_spectrogram(audio, sr)\n    save_spectrogram(S_db_before, sr, 'sample_before_noise_reduction')\nelse:\n    print(\"No sample audio found in train_audio.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-12T17:48:42.595102Z","iopub.execute_input":"2025-04-12T17:48:42.595480Z","iopub.status.idle":"2025-04-12T17:48:42.602496Z","shell.execute_reply.started":"2025-04-12T17:48:42.595435Z","shell.execute_reply":"2025-04-12T17:48:42.601178Z"}},"outputs":[],"execution_count":null}]}