From 9477ec9dbde1955f1016b0e59c586fd679a9b1a2 Mon Sep 17 00:00:00 2001 From: David Pellhammer Date: Fri, 21 Nov 2025 12:55:06 +0000 Subject: [PATCH 01/11] ADDED encapsulating the yamnet model in class --- src/nightingale/model/yamnet_base.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/nightingale/model/yamnet_base.py diff --git a/src/nightingale/model/yamnet_base.py b/src/nightingale/model/yamnet_base.py new file mode 100644 index 0000000..4d1f9e4 --- /dev/null +++ b/src/nightingale/model/yamnet_base.py @@ -0,0 +1,15 @@ +import tensorflow_hub as hub +import tensorflow as tf + +class YamnetEmbedding(tf.keras.Model): + def __init__(self): + super().__init__() + self.yamnet = hub.KerasLayer("https://tfhub.dev/google/yamnet/1") + + def call(self, audio_waveform, label): + scores, embeddings, spectrogram = self.yamnet(audio_waveform) + num_embeddings = tf.shape(embeddings)[0] + return (embeddings, tf.repeat(label, num_embeddings)) + + + From adb08b88b313ce3de09894abd82af992c7fb1a73 Mon Sep 17 00:00:00 2001 From: David Pellhammer Date: Sun, 23 Nov 2025 22:35:40 +0000 Subject: [PATCH 02/11] encapusulated audio loader und prepprocessing and filtering --- notebooks/train_nightingale_2.ipynb | 697 ++++++++++++++++++ pyproject.toml | 41 +- .../data_pipeline/audio_preprocessor.py | 40 + .../data_pipeline/filter_birdclef_data.py | 31 + src/nightingale/data_pipeline/wav_loader.py | 14 - uv.lock | 150 ++++ 6 files changed, 939 insertions(+), 34 deletions(-) create mode 100644 notebooks/train_nightingale_2.ipynb create mode 100644 src/nightingale/data_pipeline/audio_preprocessor.py create mode 100644 src/nightingale/data_pipeline/filter_birdclef_data.py delete mode 100644 src/nightingale/data_pipeline/wav_loader.py diff --git a/notebooks/train_nightingale_2.ipynb b/notebooks/train_nightingale_2.ipynb new file mode 100644 index 0000000..b9be909 --- /dev/null +++ b/notebooks/train_nightingale_2.ipynb @@ -0,0 +1,697 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "a9cd6428", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/workspaces/nightingale/.venv/lib/python3.11/site-packages/tensorflow_hub/__init__.py:61: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.\n", + " from pkg_resources import parse_version\n" + ] + } + ], + "source": [ + "import pandas as pd\n", + "import os\n", + "import glob\n", + "from sklearn.model_selection import train_test_split\n", + "import tensorflow_hub as hub\n", + "import tensorflow as tf\n", + "import numpy as np\n", + "\n", + "from nightingale.model.classifier_head import ClassifierHead\n", + "from nightingale.model.yamnet_base import YamnetEmbedding\n", + "from nightingale.data_pipeline.wav_loader import load_wav_16k_mono\n", + "from nightingale.data_pipeline.filter_birdclef_data import load_birdclef_metadata\n", + "from nightingale.data_pipeline.audio_preprocessor import AudioPreprocessor\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "18953a0d", + "metadata": {}, + "source": [ + "### Load and Explore birdclef-2024 data (pre conversion)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "d504fa73", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.microsoft.datawrangler.viewer.v0+json": { + "columns": [ + { + "name": "index", + "rawType": "int64", + "type": "integer" + }, + { + "name": "primary_label", + "rawType": "object", + "type": "string" + }, + { + "name": "secondary_labels", + "rawType": "object", + "type": "string" + }, + { + "name": "type", + "rawType": "object", + "type": "string" + }, + { + "name": "latitude", + "rawType": "float64", + "type": "float" + }, + { + "name": "longitude", + "rawType": "float64", + "type": "float" + }, + { + "name": "scientific_name", + "rawType": "object", + "type": "string" + }, + { + "name": "common_name", + "rawType": "object", + "type": "string" + }, + { + "name": "author", + "rawType": "object", + "type": "string" + }, + { + "name": "license", + "rawType": "object", + "type": "string" + }, + { + "name": "rating", + "rawType": "float64", + "type": "float" + }, + { + "name": "url", + "rawType": "object", + "type": "string" + }, + { + "name": "filename", + "rawType": "object", + "type": "string" + } + ], + "ref": "f4f8004d-7c40-4de5-8d4f-0fdc724b2674", + "rows": [ + [ + "0", + "asbfly", + "[]", + "['call']", + "39.2297", + "118.1987", + "Muscicapa dauurica", + "Asian Brown Flycatcher", + "Matt Slaymaker", + "Creative Commons Attribution-NonCommercial-ShareAlike 3.0", + "5.0", + "https://www.xeno-canto.org/134896", + "asbfly/XC134896.ogg" + ], + [ + "1", + "asbfly", + "[]", + "['song']", + "51.403", + "104.6401", + "Muscicapa dauurica", + "Asian Brown Flycatcher", + "Magnus Hellström", + "Creative Commons Attribution-NonCommercial-ShareAlike 3.0", + "2.5", + "https://www.xeno-canto.org/164848", + "asbfly/XC164848.ogg" + ], + [ + "2", + "asbfly", + "[]", + "['song']", + "36.3319", + "127.3555", + "Muscicapa dauurica", + "Asian Brown Flycatcher", + "Stuart Fisher", + "Creative Commons Attribution-NonCommercial-ShareAlike 4.0", + "2.5", + "https://www.xeno-canto.org/175797", + "asbfly/XC175797.ogg" + ], + [ + "3", + "asbfly", + "[]", + "['call']", + "21.1697", + "70.6005", + "Muscicapa dauurica", + "Asian Brown Flycatcher", + "vir joshi", + "Creative Commons Attribution-NonCommercial-ShareAlike 4.0", + "4.0", + "https://www.xeno-canto.org/207738", + "asbfly/XC207738.ogg" + ], + [ + "4", + "asbfly", + "[]", + "['call']", + "15.5442", + "73.7733", + "Muscicapa dauurica", + "Asian Brown Flycatcher", + "Albert Lastukhin & Sergei Karpeev", + "Creative Commons Attribution-NonCommercial-ShareAlike 4.0", + "4.0", + "https://www.xeno-canto.org/209218", + "asbfly/XC209218.ogg" + ] + ], + "shape": { + "columns": 12, + "rows": 5 + } + }, + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
primary_labelsecondary_labelstypelatitudelongitudescientific_namecommon_nameauthorlicenseratingurlfilename
0asbfly[]['call']39.2297118.1987Muscicapa dauuricaAsian Brown FlycatcherMatt SlaymakerCreative Commons Attribution-NonCommercial-Sha...5.0https://www.xeno-canto.org/134896asbfly/XC134896.ogg
1asbfly[]['song']51.4030104.6401Muscicapa dauuricaAsian Brown FlycatcherMagnus HellströmCreative Commons Attribution-NonCommercial-Sha...2.5https://www.xeno-canto.org/164848asbfly/XC164848.ogg
2asbfly[]['song']36.3319127.3555Muscicapa dauuricaAsian Brown FlycatcherStuart FisherCreative Commons Attribution-NonCommercial-Sha...2.5https://www.xeno-canto.org/175797asbfly/XC175797.ogg
3asbfly[]['call']21.169770.6005Muscicapa dauuricaAsian Brown Flycatchervir joshiCreative Commons Attribution-NonCommercial-Sha...4.0https://www.xeno-canto.org/207738asbfly/XC207738.ogg
4asbfly[]['call']15.544273.7733Muscicapa dauuricaAsian Brown FlycatcherAlbert Lastukhin & Sergei KarpeevCreative Commons Attribution-NonCommercial-Sha...4.0https://www.xeno-canto.org/209218asbfly/XC209218.ogg
\n", + "
" + ], + "text/plain": [ + " primary_label secondary_labels type latitude longitude \\\n", + "0 asbfly [] ['call'] 39.2297 118.1987 \n", + "1 asbfly [] ['song'] 51.4030 104.6401 \n", + "2 asbfly [] ['song'] 36.3319 127.3555 \n", + "3 asbfly [] ['call'] 21.1697 70.6005 \n", + "4 asbfly [] ['call'] 15.5442 73.7733 \n", + "\n", + " scientific_name common_name \\\n", + "0 Muscicapa dauurica Asian Brown Flycatcher \n", + "1 Muscicapa dauurica Asian Brown Flycatcher \n", + "2 Muscicapa dauurica Asian Brown Flycatcher \n", + "3 Muscicapa dauurica Asian Brown Flycatcher \n", + "4 Muscicapa dauurica Asian Brown Flycatcher \n", + "\n", + " author \\\n", + "0 Matt Slaymaker \n", + "1 Magnus Hellström \n", + "2 Stuart Fisher \n", + "3 vir joshi \n", + "4 Albert Lastukhin & Sergei Karpeev \n", + "\n", + " license rating \\\n", + "0 Creative Commons Attribution-NonCommercial-Sha... 5.0 \n", + "1 Creative Commons Attribution-NonCommercial-Sha... 2.5 \n", + "2 Creative Commons Attribution-NonCommercial-Sha... 2.5 \n", + "3 Creative Commons Attribution-NonCommercial-Sha... 4.0 \n", + "4 Creative Commons Attribution-NonCommercial-Sha... 4.0 \n", + "\n", + " url filename \n", + "0 https://www.xeno-canto.org/134896 asbfly/XC134896.ogg \n", + "1 https://www.xeno-canto.org/164848 asbfly/XC164848.ogg \n", + "2 https://www.xeno-canto.org/175797 asbfly/XC175797.ogg \n", + "3 https://www.xeno-canto.org/207738 asbfly/XC207738.ogg \n", + "4 https://www.xeno-canto.org/209218 asbfly/XC209218.ogg " + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Read train meta data\n", + "train_metadata_path = \"../data/birdclef-2024/train_metadata.csv\"\n", + "train_df = pd.read_csv(train_metadata_path)\n", + "train_df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "71495869", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.microsoft.datawrangler.viewer.v0+json": { + "columns": [ + { + "name": "index", + "rawType": "object", + "type": "string" + }, + { + "name": "latitude", + "rawType": "float64", + "type": "float" + }, + { + "name": "longitude", + "rawType": "float64", + "type": "float" + }, + { + "name": "rating", + "rawType": "float64", + "type": "float" + } + ], + "ref": "46c8ca05-b7c4-4893-8184-253450b5212f", + "rows": [ + [ + "count", + "24081.0", + "24081.0", + "24459.0" + ], + [ + "mean", + "32.53703967894161", + "43.64069944245256", + "3.8434931926898073" + ], + [ + "std", + "19.440382482421175", + "50.19135150350931", + "1.1008399312899093" + ], + [ + "min", + "-43.524", + "-171.7654", + "0.0" + ], + [ + "25%", + "17.1601", + "2.5457", + "3.0" + ], + [ + "50%", + "37.1551", + "26.6876", + "4.0" + ], + [ + "75%", + "49.1144", + "85.3193", + "5.0" + ], + [ + "max", + "71.964", + "177.4478", + "5.0" + ] + ], + "shape": { + "columns": 3, + "rows": 8 + } + }, + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
latitudelongituderating
count24081.00000024081.00000024459.000000
mean32.53704043.6406993.843493
std19.44038250.1913521.100840
min-43.524000-171.7654000.000000
25%17.1601002.5457003.000000
50%37.15510026.6876004.000000
75%49.11440085.3193005.000000
max71.964000177.4478005.000000
\n", + "
" + ], + "text/plain": [ + " latitude longitude rating\n", + "count 24081.000000 24081.000000 24459.000000\n", + "mean 32.537040 43.640699 3.843493\n", + "std 19.440382 50.191352 1.100840\n", + "min -43.524000 -171.765400 0.000000\n", + "25% 17.160100 2.545700 3.000000\n", + "50% 37.155100 26.687600 4.000000\n", + "75% 49.114400 85.319300 5.000000\n", + "max 71.964000 177.447800 5.000000" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train_df.describe()" + ] + }, + { + "cell_type": "markdown", + "id": "34f8f2e3", + "metadata": {}, + "source": [ + "### Prepare dataframe pointing to bird call audio data in wav format" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "6ef7c047", + "metadata": {}, + "outputs": [], + "source": [ + "# Read train meta data\n", + "\n", + "base_data_path = \"../data/birdclef-2024\"\n", + "\n", + "# Convert to yamnet compatible format\n", + "preprocessor = AudioPreprocessor()\n", + "\n", + "##TODO do the conversion here and save to new folder\n", + "\n", + "# filter the metadata csv file for th data that is actually in the data folder\n", + "filtered_bird_df = load_birdclef_metadata(base_data_path)\n", + "# filtered_bird_df.head(10)" + ] + }, + { + "cell_type": "markdown", + "id": "5e287445", + "metadata": {}, + "source": [ + "### Split data: Training, Validation and Test" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "62a4886f", + "metadata": {}, + "outputs": [], + "source": [ + "# Step 1: Split the data into training (60%), validation (20%) and test (20%) sets\n", + "train_df_idx, temp_df_idx = train_test_split(filtered_bird_df.index, test_size=0.4, random_state=42, stratify=filtered_bird_df['target'])\n", + "val_df_idx, test_df_idx = train_test_split(temp_df_idx, test_size=0.5, random_state=42, stratify=filtered_bird_df.loc[temp_df_idx, 'target'])\n", + "\n", + "# Step 2: Create 'fold' column in original filtered_bird_df\n", + "filtered_bird_df['fold'] = '' # initialize empty\n", + "filtered_bird_df.loc[train_df_idx, 'fold'] = 1\n", + "filtered_bird_df.loc[val_df_idx, 'fold'] = 2\n", + "filtered_bird_df.loc[test_df_idx, 'fold'] = 3\n", + "\n", + "filenames_train = filtered_bird_df[filtered_bird_df['fold'] == 1]['filename']\n", + "targets_train = filtered_bird_df[filtered_bird_df['fold'] == 1]['target']\n", + "\n", + "filenames_val = filtered_bird_df[filtered_bird_df['fold'] == 2]['filename']\n", + "targets_val = filtered_bird_df[filtered_bird_df['fold'] == 2]['target']\n", + "\n", + "filenames_test = filtered_bird_df[filtered_bird_df['fold'] == 3]['filename']\n", + "targets_test = filtered_bird_df[filtered_bird_df['fold'] == 3]['target']\n", + "\n", + "\n", + "train_ds = tf.data.Dataset.from_tensor_slices((filenames_train, targets_train))\n", + "val_ds = tf.data.Dataset.from_tensor_slices((filenames_val, targets_val))\n", + "test_ds = tf.data.Dataset.from_tensor_slices((filenames_test, targets_test))\n", + "\n", + "# filtered_bird_df.head(10)\n", + "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 1]['target'], bins=len(bird_classes), alpha=0.7, label='Train')\n", + "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 2]['target'], bins=len(bird_classes), alpha=0.7, label='Val')\n", + "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 3]['target'], bins=len(bird_classes), alpha=0.7, label='Test')\n", + "# plt.xlabel('Bird Classes')\n", + "# plt.ylabel('Count')\n", + "# plt.title('Distribution of Bird Classes in Train, Val, and Test Sets')\n", + "# plt.legend()\n", + "# plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "59c00cc1", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "def load_wav_for_map(filename, label):\n", + " audio = tf.io.read_file(filename)\n", + " wav, sr = tf.audio.decode_wav(audio, desired_channels=1)\n", + " wav = tf.squeeze(wav, axis=-1)\n", + " return wav, label\n", + "\n", + "\n", + "train_ds = train_ds.map(load_wav_for_map)\n", + "val_ds = val_ds.map(load_wav_for_map)\n", + "test_ds = test_ds.map(load_wav_for_map)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "5aca4873", + "metadata": {}, + "outputs": [], + "source": [ + "yam = YamnetEmbedding()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "1852e16e", + "metadata": {}, + "outputs": [], + "source": [ + "train_ds = train_ds.map(yam).unbatch()\n", + "val_ds = val_ds.map(yam).unbatch()\n", + "test_ds = test_ds.map(yam).unbatch()\n", + "train_ds.element_spec\n", + "\n", + "train_ds = train_ds.cache().shuffle(1000).batch(32).prefetch(tf.data.AUTOTUNE)\n", + "val_ds = val_ds.cache().batch(32).prefetch(tf.data.AUTOTUNE)\n", + "test_ds = test_ds.cache().batch(32).prefetch(tf.data.AUTOTUNE)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "nightingale", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/pyproject.toml b/pyproject.toml index c980c18..a10027a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,34 +10,35 @@ readme = "README.md" license-files = [ "LICENSE" ] requires-python = ">=3.11,<3.12" dependencies = [ - "tensorflow (==2.20.0)", - "tensorflow-hub (==0.16.1)", - "fastapi (==0.116.2)", - "mlflow[databricks] (>=3.4.0,<4.0.0)", - "uvicorn (==0.37.0)", - "python-multipart (==0.0.20)", - "python-dotenv (>=1.1.1,<2.0.0)" + "tensorflow==2.20.0", + "tensorflow-hub==0.16.1", + "fastapi==0.116.2", + "mlflow[databricks]>=3.4.0,<4.0.0", + "uvicorn==0.37.0", + "python-multipart==0.0.20", + "python-dotenv>=1.1.1,<2.0.0" ] [dependency-groups] doc = [ - "sphinx (==8.2.3)", - "sphinx-rtd-theme (==3.0.2)" + "sphinx==8.2.3", + "sphinx-rtd-theme==3.0.2" ] dev = [ - "numpy (==2.3.3)", - "scikit-learn (==1.7.2)", - "matplotlib (==3.10.6)", - "seaborn (==0.13.2)", - "ipykernel (==6.30.1)", - "ipywidgets (==8.1.7)", - "tensorflow (==2.20.0)", - "tensorflow-io (==0.37.1)", - "tensorflow-hub (==0.16.1)", - "pydub (==0.25.1)" + "numpy==2.3.3", + "scikit-learn==1.7.2", + "matplotlib==3.10.6", + "seaborn==0.13.2", + "ipykernel==6.30.1", + "ipywidgets==8.1.7", + "tensorflow==2.20.0", + "tensorflow-io==0.37.1", + "tensorflow-hub==0.16.1", + "pydub==0.25.1", + "librosa==0.11.0" ] test = [ - "pytest (==8.4.2)" + "pytest==8.4.2" ] [project.urls] diff --git a/src/nightingale/data_pipeline/audio_preprocessor.py b/src/nightingale/data_pipeline/audio_preprocessor.py new file mode 100644 index 0000000..0e146f6 --- /dev/null +++ b/src/nightingale/data_pipeline/audio_preprocessor.py @@ -0,0 +1,40 @@ +import os +import librosa +import soundfile as sf +import numpy as np + +class AudioPreprocessor: + def __init__(self, target_sr=16000, mono=True): + self.target_sr = target_sr + self.mono = mono + + def is_yamnet_ready(self, file_path): + """Check if audio file is already in correct format.""" + try: + # Read audio info + with sf.SoundFile(file_path) as f: + sr = f.samplerate + channels = f.channels + ext = os.path.splitext(file_path)[1].lower() + + return ext == ".wav" and sr == self.target_sr and (channels == 1 if self.mono else True) + except RuntimeError: + # Can't read file + return False + + def load_audio(self, file_path): + """Load audio and convert if necessary""" + if self.is_yamnet_ready(file_path): + # Already ready, load directly + waveform, sr = librosa.load(file_path, sr=None, mono=self.mono) + else: + # Load and resample/convert + waveform, sr = librosa.load(file_path, sr=self.target_sr, mono=self.mono) + + waveform = waveform.astype(np.float32) + return waveform, sr + + def save_wav(self, waveform, sr, output_path): + sf.write(output_path, waveform, sr) + + diff --git a/src/nightingale/data_pipeline/filter_birdclef_data.py b/src/nightingale/data_pipeline/filter_birdclef_data.py new file mode 100644 index 0000000..a8e5aca --- /dev/null +++ b/src/nightingale/data_pipeline/filter_birdclef_data.py @@ -0,0 +1,31 @@ +import glob +import os +import pandas as pd + +def load_birdclef_metadata(base_data_path="../data/birdclef-2024"): + + # Read train meta data + base_data_path = "../data/birdclef-2024" + bird_metadata_path = os.path.join(base_data_path, "train_metadata.csv") + bird_df = pd.read_csv(bird_metadata_path) + + # Change the filename endings from .ogg to .wav in the filename column of bird_df + bird_df['filename'] = bird_df['filename'].str.replace('.ogg', '.wav', regex=False) + + # Show rows where the filename matches the pattern "cohcuc1/*.wav" + wav_files = glob.glob(base_data_path + "/train_audio_16/**/*.wav", recursive=True) + wav_files = [f.replace(base_data_path + "/train_audio_16/", "") for f in wav_files] + + filtered_bird_df = bird_df[bird_df['filename'].isin(wav_files)] + + bird_classes = list(set(filtered_bird_df['common_name'])) + + map_class_to_id = {name: idx for idx, name in enumerate(bird_classes)} + + class_id = filtered_bird_df['common_name'].apply(lambda name: map_class_to_id[name]) + filtered_bird_df = filtered_bird_df.assign(target=class_id) + + full_path = filtered_bird_df['filename'].apply(lambda row: os.path.join(base_data_path + "/train_audio_16/", row)) + filtered_bird_df = filtered_bird_df.assign(filename=full_path) + + return filtered_bird_df diff --git a/src/nightingale/data_pipeline/wav_loader.py b/src/nightingale/data_pipeline/wav_loader.py deleted file mode 100644 index 6f5b984..0000000 --- a/src/nightingale/data_pipeline/wav_loader.py +++ /dev/null @@ -1,14 +0,0 @@ -from pydub import AudioSegment -import tensorflow as tf - -def load_wav_16k_mono(filename): - """ Load a WAV file, convert it to a float tensor, resample to 16 kHz single-channel audio. """ - file_contents = tf.io.read_file(filename) - wav, sample_rate = tf.audio.decode_wav( - file_contents, - desired_channels=1) - wav = tf.squeeze(wav, axis=-1) - - #sample_rate = tf.cast(sample_rate, dtype=tf.int64) - #wav = tfio.audio.resample(wav, rate_in=sample_rate, rate_out=16000) - return wav \ No newline at end of file diff --git a/uv.lock b/uv.lock index c596699..3536712 100644 --- a/uv.lock +++ b/uv.lock @@ -153,6 +153,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, ] +[[package]] +name = "audioread" +version = "3.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/4a/874ecf9b472f998130c2b5e145dcdb9f6131e84786111489103b66772143/audioread-3.1.0.tar.gz", hash = "sha256:1c4ab2f2972764c896a8ac61ac53e261c8d29f0c6ccd652f84e18f08a4cab190", size = 20082, upload-time = "2025-10-26T19:44:13.484Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/16/fbe8e1e185a45042f7cd3a282def5bb8d95bb69ab9e9ef6a5368aa17e426/audioread-3.1.0-py3-none-any.whl", hash = "sha256:b30d1df6c5d3de5dcef0fb0e256f6ea17bdcf5f979408df0297d8a408e2971b4", size = 23143, upload-time = "2025-10-26T19:44:12.016Z" }, +] + [[package]] name = "azure-core" version = "1.36.0" @@ -879,6 +888,8 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1f/8e/abdd3f14d735b2929290a018ecf133c901be4874b858dd1c604b9319f064/greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8", size = 587684, upload-time = "2025-08-07T13:18:25.164Z" }, { url = "https://files.pythonhosted.org/packages/5d/65/deb2a69c3e5996439b0176f6651e0052542bb6c8f8ec2e3fba97c9768805/greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52", size = 1116647, upload-time = "2025-08-07T13:42:38.655Z" }, { url = "https://files.pythonhosted.org/packages/3f/cc/b07000438a29ac5cfb2194bfc128151d52f333cee74dd7dfe3fb733fc16c/greenlet-3.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa", size = 1142073, upload-time = "2025-08-07T13:18:21.737Z" }, + { url = "https://files.pythonhosted.org/packages/67/24/28a5b2fa42d12b3d7e5614145f0bd89714c34c08be6aabe39c14dd52db34/greenlet-3.2.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c9c6de1940a7d828635fbd254d69db79e54619f165ee7ce32fda763a9cb6a58c", size = 1548385, upload-time = "2025-11-04T12:42:11.067Z" }, + { url = "https://files.pythonhosted.org/packages/6a/05/03f2f0bdd0b0ff9a4f7b99333d57b53a7709c27723ec8123056b084e69cd/greenlet-3.2.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03c5136e7be905045160b1b9fdca93dd6727b180feeafda6818e6496434ed8c5", size = 1613329, upload-time = "2025-11-04T12:42:12.928Z" }, { url = "https://files.pythonhosted.org/packages/d8/0f/30aef242fcab550b0b3520b8e3561156857c94288f0332a79928c31a52cf/greenlet-3.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9", size = 299100, upload-time = "2025-08-07T13:44:12.287Z" }, ] @@ -1400,6 +1411,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b4/2b/7e0248f65e35800ea8e4e3dbb3bcc36c61b81f5b8abeddaceec8320ab491/langsmith-0.4.38-py3-none-any.whl", hash = "sha256:326232a24b1c6dd308a3188557cc023adf8fb14144263b2982c115a6be5141e7", size = 397341, upload-time = "2025-10-23T22:28:18.333Z" }, ] +[[package]] +name = "lazy-loader" +version = "0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6f/6b/c875b30a1ba490860c93da4cabf479e03f584eba06fe5963f6f6644653d8/lazy_loader-0.4.tar.gz", hash = "sha256:47c75182589b91a4e1a85a136c074285a5ad4d9f39c63e0d7fb76391c4574cd1", size = 15431, upload-time = "2024-04-05T13:03:12.261Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/60/d497a310bde3f01cb805196ac61b7ad6dc5dcf8dce66634dc34364b20b4f/lazy_loader-0.4-py3-none-any.whl", hash = "sha256:342aa8e14d543a154047afb4ba8ef17f5563baad3fc610d7b15b213b0f119efc", size = 12097, upload-time = "2024-04-05T13:03:10.514Z" }, +] + [[package]] name = "libclang" version = "18.1.1" @@ -1417,6 +1440,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/71/cf/e01dc4cc79779cd82d77888a88ae2fa424d93b445ad4f6c02bfc18335b70/libclang-18.1.1-py2.py3-none-win_arm64.whl", hash = "sha256:3f0e1f49f04d3cd198985fea0511576b0aee16f9ff0e0f0cad7f9c57ec3c20e8", size = 22361112, upload-time = "2024-03-17T16:42:59.565Z" }, ] +[[package]] +name = "librosa" +version = "0.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "audioread" }, + { name = "decorator" }, + { name = "joblib" }, + { name = "lazy-loader" }, + { name = "msgpack" }, + { name = "numba" }, + { name = "numpy" }, + { name = "pooch" }, + { name = "scikit-learn" }, + { name = "scipy" }, + { name = "soundfile" }, + { name = "soxr" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/64/36/360b5aafa0238e29758729e9486c6ed92a6f37fa403b7875e06c115cdf4a/librosa-0.11.0.tar.gz", hash = "sha256:f5ed951ca189b375bbe2e33b2abd7e040ceeee302b9bbaeeffdfddb8d0ace908", size = 327001, upload-time = "2025-03-11T15:09:54.884Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/ba/c63c5786dfee4c3417094c4b00966e61e4a63efecee22cb7b4c0387dda83/librosa-0.11.0-py3-none-any.whl", hash = "sha256:0b6415c4fd68bff4c29288abe67c6d80b587e0e1e2cfb0aad23e4559504a7fa1", size = 260749, upload-time = "2025-03-11T15:09:52.982Z" }, +] + [[package]] name = "litellm" version = "1.75.9" @@ -1439,6 +1486,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5d/b2/f21db9636d9fcd67b2c557c58aafb8a6e9b53864f7a40d645e09c2e3ab98/litellm-1.75.9-py3-none-any.whl", hash = "sha256:a72c3e05bcb0e50ac1804f0df09d0d7bf5cb41e84351e1609a960033b0ef01c1", size = 8920144, upload-time = "2025-08-20T17:43:48.327Z" }, ] +[[package]] +name = "llvmlite" +version = "0.45.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/99/8d/5baf1cef7f9c084fb35a8afbde88074f0d6a727bc63ef764fe0e7543ba40/llvmlite-0.45.1.tar.gz", hash = "sha256:09430bb9d0bb58fc45a45a57c7eae912850bedc095cd0810a57de109c69e1c32", size = 185600, upload-time = "2025-10-01T17:59:52.046Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/ad/9bdc87b2eb34642c1cfe6bcb4f5db64c21f91f26b010f263e7467e7536a3/llvmlite-0.45.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:60f92868d5d3af30b4239b50e1717cb4e4e54f6ac1c361a27903b318d0f07f42", size = 43043526, upload-time = "2025-10-01T18:03:15.051Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ea/c25c6382f452a943b4082da5e8c1665ce29a62884e2ec80608533e8e82d5/llvmlite-0.45.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:98baab513e19beb210f1ef39066288784839a44cd504e24fff5d17f1b3cf0860", size = 37253118, upload-time = "2025-10-01T18:04:06.783Z" }, + { url = "https://files.pythonhosted.org/packages/fe/af/85fc237de98b181dbbe8647324331238d6c52a3554327ccdc83ced28efba/llvmlite-0.45.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3adc2355694d6a6fbcc024d59bb756677e7de506037c878022d7b877e7613a36", size = 56288209, upload-time = "2025-10-01T18:01:00.168Z" }, + { url = "https://files.pythonhosted.org/packages/0a/df/3daf95302ff49beff4230065e3178cd40e71294968e8d55baf4a9e560814/llvmlite-0.45.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f3377a6db40f563058c9515dedcc8a3e562d8693a106a28f2ddccf2c8fcf6ca", size = 55140958, upload-time = "2025-10-01T18:02:11.199Z" }, + { url = "https://files.pythonhosted.org/packages/a4/56/4c0d503fe03bac820ecdeb14590cf9a248e120f483bcd5c009f2534f23f0/llvmlite-0.45.1-cp311-cp311-win_amd64.whl", hash = "sha256:f9c272682d91e0d57f2a76c6d9ebdfccc603a01828cdbe3d15273bdca0c3363a", size = 38132232, upload-time = "2025-10-01T18:04:52.181Z" }, +] + [[package]] name = "mako" version = "1.3.10" @@ -1655,6 +1715,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/29/7f/99006f6c261ef694363e8599ad858c223aa9918231e8bd7a1569041967ac/mlflow_tracing-3.5.1-py3-none-any.whl", hash = "sha256:4fd685347158e0d2c48f5bec3d15ecfc6fadc1dbb48073cb220ded438408fa65", size = 1273904, upload-time = "2025-10-22T17:56:10.748Z" }, ] +[[package]] +name = "msgpack" +version = "1.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4d/f2/bfb55a6236ed8725a96b0aa3acbd0ec17588e6a2c3b62a93eb513ed8783f/msgpack-1.1.2.tar.gz", hash = "sha256:3b60763c1373dd60f398488069bcdc703cd08a711477b5d480eecc9f9626f47e", size = 173581, upload-time = "2025-10-08T09:15:56.596Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/97/560d11202bcd537abca693fd85d81cebe2107ba17301de42b01ac1677b69/msgpack-1.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2e86a607e558d22985d856948c12a3fa7b42efad264dca8a3ebbcfa2735d786c", size = 82271, upload-time = "2025-10-08T09:14:49.967Z" }, + { url = "https://files.pythonhosted.org/packages/83/04/28a41024ccbd67467380b6fb440ae916c1e4f25e2cd4c63abe6835ac566e/msgpack-1.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:283ae72fc89da59aa004ba147e8fc2f766647b1251500182fac0350d8af299c0", size = 84914, upload-time = "2025-10-08T09:14:50.958Z" }, + { url = "https://files.pythonhosted.org/packages/71/46/b817349db6886d79e57a966346cf0902a426375aadc1e8e7a86a75e22f19/msgpack-1.1.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:61c8aa3bd513d87c72ed0b37b53dd5c5a0f58f2ff9f26e1555d3bd7948fb7296", size = 416962, upload-time = "2025-10-08T09:14:51.997Z" }, + { url = "https://files.pythonhosted.org/packages/da/e0/6cc2e852837cd6086fe7d8406af4294e66827a60a4cf60b86575a4a65ca8/msgpack-1.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:454e29e186285d2ebe65be34629fa0e8605202c60fbc7c4c650ccd41870896ef", size = 426183, upload-time = "2025-10-08T09:14:53.477Z" }, + { url = "https://files.pythonhosted.org/packages/25/98/6a19f030b3d2ea906696cedd1eb251708e50a5891d0978b012cb6107234c/msgpack-1.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7bc8813f88417599564fafa59fd6f95be417179f76b40325b500b3c98409757c", size = 411454, upload-time = "2025-10-08T09:14:54.648Z" }, + { url = "https://files.pythonhosted.org/packages/b7/cd/9098fcb6adb32187a70b7ecaabf6339da50553351558f37600e53a4a2a23/msgpack-1.1.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bafca952dc13907bdfdedfc6a5f579bf4f292bdd506fadb38389afa3ac5b208e", size = 422341, upload-time = "2025-10-08T09:14:56.328Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ae/270cecbcf36c1dc85ec086b33a51a4d7d08fc4f404bdbc15b582255d05ff/msgpack-1.1.2-cp311-cp311-win32.whl", hash = "sha256:602b6740e95ffc55bfb078172d279de3773d7b7db1f703b2f1323566b878b90e", size = 64747, upload-time = "2025-10-08T09:14:57.882Z" }, + { url = "https://files.pythonhosted.org/packages/2a/79/309d0e637f6f37e83c711f547308b91af02b72d2326ddd860b966080ef29/msgpack-1.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68", size = 71633, upload-time = "2025-10-08T09:14:59.177Z" }, + { url = "https://files.pythonhosted.org/packages/73/4d/7c4e2b3d9b1106cd0aa6cb56cc57c6267f59fa8bfab7d91df5adc802c847/msgpack-1.1.2-cp311-cp311-win_arm64.whl", hash = "sha256:86f8136dfa5c116365a8a651a7d7484b65b13339731dd6faebb9a0242151c406", size = 64755, upload-time = "2025-10-08T09:15:00.48Z" }, +] + [[package]] name = "multidict" version = "6.7.0" @@ -1727,6 +1804,7 @@ dependencies = [ dev = [ { name = "ipykernel" }, { name = "ipywidgets" }, + { name = "librosa" }, { name = "matplotlib" }, { name = "numpy" }, { name = "pydub" }, @@ -1759,6 +1837,7 @@ requires-dist = [ dev = [ { name = "ipykernel", specifier = "==6.30.1" }, { name = "ipywidgets", specifier = "==8.1.7" }, + { name = "librosa", specifier = "==0.11.0" }, { name = "matplotlib", specifier = "==3.10.6" }, { name = "numpy", specifier = "==2.3.3" }, { name = "pydub", specifier = "==0.25.1" }, @@ -1774,6 +1853,23 @@ doc = [ ] test = [{ name = "pytest", specifier = "==8.4.2" }] +[[package]] +name = "numba" +version = "0.62.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llvmlite" }, + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/20/33dbdbfe60e5fd8e3dbfde299d106279a33d9f8308346022316781368591/numba-0.62.1.tar.gz", hash = "sha256:7b774242aa890e34c21200a1fc62e5b5757d5286267e71103257f4e2af0d5161", size = 2749817, upload-time = "2025-09-29T10:46:31.551Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dd/5f/8b3491dd849474f55e33c16ef55678ace1455c490555337899c35826836c/numba-0.62.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:f43e24b057714e480fe44bc6031de499e7cf8150c63eb461192caa6cc8530bc8", size = 2684279, upload-time = "2025-09-29T10:43:37.213Z" }, + { url = "https://files.pythonhosted.org/packages/bf/18/71969149bfeb65a629e652b752b80167fe8a6a6f6e084f1f2060801f7f31/numba-0.62.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:57cbddc53b9ee02830b828a8428757f5c218831ccc96490a314ef569d8342b7b", size = 2687330, upload-time = "2025-09-29T10:43:59.601Z" }, + { url = "https://files.pythonhosted.org/packages/0e/7d/403be3fecae33088027bc8a95dc80a2fda1e3beff3e0e5fc4374ada3afbe/numba-0.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:604059730c637c7885386521bb1b0ddcbc91fd56131a6dcc54163d6f1804c872", size = 3739727, upload-time = "2025-09-29T10:42:45.922Z" }, + { url = "https://files.pythonhosted.org/packages/e0/c3/3d910d08b659a6d4c62ab3cd8cd93c4d8b7709f55afa0d79a87413027ff6/numba-0.62.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6c540880170bee817011757dc9049dba5a29db0c09b4d2349295991fe3ee55f", size = 3445490, upload-time = "2025-09-29T10:43:12.692Z" }, + { url = "https://files.pythonhosted.org/packages/5b/82/9d425c2f20d9f0a37f7cb955945a553a00fa06a2b025856c3550227c5543/numba-0.62.1-cp311-cp311-win_amd64.whl", hash = "sha256:03de6d691d6b6e2b76660ba0f38f37b81ece8b2cc524a62f2a0cfae2bfb6f9da", size = 2745550, upload-time = "2025-09-29T10:44:20.571Z" }, +] + [[package]] name = "numpy" version = "2.3.3" @@ -2023,6 +2119,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] +[[package]] +name = "pooch" +version = "1.8.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, + { name = "platformdirs" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c6/77/b3d3e00c696c16cf99af81ef7b1f5fe73bd2a307abca41bd7605429fe6e5/pooch-1.8.2.tar.gz", hash = "sha256:76561f0de68a01da4df6af38e9955c4c9d1a5c90da73f7e40276a5728ec83d10", size = 59353, upload-time = "2024-06-06T16:53:46.224Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/87/77cc11c7a9ea9fd05503def69e3d18605852cd0d4b0d3b8f15bbeb3ef1d1/pooch-1.8.2-py3-none-any.whl", hash = "sha256:3529a57096f7198778a5ceefd5ac3ef0e4d06a6ddaf9fc2d609b806f25302c47", size = 64574, upload-time = "2024-06-06T16:53:44.343Z" }, +] + [[package]] name = "prompt-toolkit" version = "3.0.52" @@ -2621,6 +2731,46 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064", size = 103274, upload-time = "2025-05-09T16:34:50.371Z" }, ] +[[package]] +name = "soundfile" +version = "0.13.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e1/41/9b873a8c055582859b239be17902a85339bec6a30ad162f98c9b0288a2cc/soundfile-0.13.1.tar.gz", hash = "sha256:b2c68dab1e30297317080a5b43df57e302584c49e2942defdde0acccc53f0e5b", size = 46156, upload-time = "2025-01-25T09:17:04.831Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/28/e2a36573ccbcf3d57c00626a21fe51989380636e821b341d36ccca0c1c3a/soundfile-0.13.1-py2.py3-none-any.whl", hash = "sha256:a23c717560da2cf4c7b5ae1142514e0fd82d6bbd9dfc93a50423447142f2c445", size = 25751, upload-time = "2025-01-25T09:16:44.235Z" }, + { url = "https://files.pythonhosted.org/packages/ea/ab/73e97a5b3cc46bba7ff8650a1504348fa1863a6f9d57d7001c6b67c5f20e/soundfile-0.13.1-py2.py3-none-macosx_10_9_x86_64.whl", hash = "sha256:82dc664d19831933fe59adad199bf3945ad06d84bc111a5b4c0d3089a5b9ec33", size = 1142250, upload-time = "2025-01-25T09:16:47.583Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e5/58fd1a8d7b26fc113af244f966ee3aecf03cb9293cb935daaddc1e455e18/soundfile-0.13.1-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:743f12c12c4054921e15736c6be09ac26b3b3d603aef6fd69f9dde68748f2593", size = 1101406, upload-time = "2025-01-25T09:16:49.662Z" }, + { url = "https://files.pythonhosted.org/packages/58/ae/c0e4a53d77cf6e9a04179535766b3321b0b9ced5f70522e4caf9329f0046/soundfile-0.13.1-py2.py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:9c9e855f5a4d06ce4213f31918653ab7de0c5a8d8107cd2427e44b42df547deb", size = 1235729, upload-time = "2025-01-25T09:16:53.018Z" }, + { url = "https://files.pythonhosted.org/packages/57/5e/70bdd9579b35003a489fc850b5047beeda26328053ebadc1fb60f320f7db/soundfile-0.13.1-py2.py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:03267c4e493315294834a0870f31dbb3b28a95561b80b134f0bd3cf2d5f0e618", size = 1313646, upload-time = "2025-01-25T09:16:54.872Z" }, + { url = "https://files.pythonhosted.org/packages/fe/df/8c11dc4dfceda14e3003bb81a0d0edcaaf0796dd7b4f826ea3e532146bba/soundfile-0.13.1-py2.py3-none-win32.whl", hash = "sha256:c734564fab7c5ddf8e9be5bf70bab68042cd17e9c214c06e365e20d64f9a69d5", size = 899881, upload-time = "2025-01-25T09:16:56.663Z" }, + { url = "https://files.pythonhosted.org/packages/14/e9/6b761de83277f2f02ded7e7ea6f07828ec78e4b229b80e4ca55dd205b9dc/soundfile-0.13.1-py2.py3-none-win_amd64.whl", hash = "sha256:1e70a05a0626524a69e9f0f4dd2ec174b4e9567f4d8b6c11d38b5c289be36ee9", size = 1019162, upload-time = "2025-01-25T09:16:59.573Z" }, +] + +[[package]] +name = "soxr" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/7e/f4b461944662ad75036df65277d6130f9411002bfb79e9df7dff40a31db9/soxr-1.0.0.tar.gz", hash = "sha256:e07ee6c1d659bc6957034f4800c60cb8b98de798823e34d2a2bba1caa85a4509", size = 171415, upload-time = "2025-09-07T13:22:21.317Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/ce/a3262bc8733d3a4ce5f660ed88c3d97f4b12658b0909e71334cba1721dcb/soxr-1.0.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:28e19d74a5ef45c0d7000f3c70ec1719e89077379df2a1215058914d9603d2d8", size = 206739, upload-time = "2025-09-07T13:21:54.572Z" }, + { url = "https://files.pythonhosted.org/packages/64/dc/e8cbd100b652697cc9865dbed08832e7e135ff533f453eb6db9e6168d153/soxr-1.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8dc69fc18884e53b72f6141fdf9d80997edbb4fec9dc2942edcb63abbe0d023", size = 165233, upload-time = "2025-09-07T13:21:55.887Z" }, + { url = "https://files.pythonhosted.org/packages/75/12/4b49611c9ba5e9fe6f807d0a83352516808e8e573f8b4e712fc0c17f3363/soxr-1.0.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3f15450e6f65f22f02fcd4c5a9219c873b1e583a73e232805ff160c759a6b586", size = 208867, upload-time = "2025-09-07T13:21:57.076Z" }, + { url = "https://files.pythonhosted.org/packages/cc/70/92146ab970a3ef8c43ac160035b1e52fde5417f89adb10572f7e788d9596/soxr-1.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f73f57452f9df37b4de7a4052789fcbd474a5b28f38bba43278ae4b489d4384", size = 242633, upload-time = "2025-09-07T13:21:58.621Z" }, + { url = "https://files.pythonhosted.org/packages/b5/a7/628479336206959463d08260bffed87905e7ba9e3bd83ca6b405a0736e94/soxr-1.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:9f417c3d69236051cf5a1a7bad7c4bff04eb3d8fcaa24ac1cb06e26c8d48d8dc", size = 173814, upload-time = "2025-09-07T13:21:59.798Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c7/f92b81f1a151c13afb114f57799b86da9330bec844ea5a0d3fe6a8732678/soxr-1.0.0-cp312-abi3-macosx_10_14_x86_64.whl", hash = "sha256:abecf4e39017f3fadb5e051637c272ae5778d838e5c3926a35db36a53e3a607f", size = 205508, upload-time = "2025-09-07T13:22:01.252Z" }, + { url = "https://files.pythonhosted.org/packages/ff/1d/c945fea9d83ea1f2be9d116b3674dbaef26ed090374a77c394b31e3b083b/soxr-1.0.0-cp312-abi3-macosx_11_0_arm64.whl", hash = "sha256:e973d487ee46aa8023ca00a139db6e09af053a37a032fe22f9ff0cc2e19c94b4", size = 163568, upload-time = "2025-09-07T13:22:03.558Z" }, + { url = "https://files.pythonhosted.org/packages/b5/80/10640970998a1d2199bef6c4d92205f36968cddaf3e4d0e9fe35ddd405bd/soxr-1.0.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e8ce273cca101aff3d8c387db5a5a41001ba76ef1837883438d3c652507a9ccc", size = 204707, upload-time = "2025-09-07T13:22:05.125Z" }, + { url = "https://files.pythonhosted.org/packages/b1/87/2726603c13c2126cb8ded9e57381b7377f4f0df6ba4408e1af5ddbfdc3dd/soxr-1.0.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8f2a69686f2856d37823bbb7b78c3d44904f311fe70ba49b893af11d6b6047b", size = 238032, upload-time = "2025-09-07T13:22:06.428Z" }, + { url = "https://files.pythonhosted.org/packages/ce/04/530252227f4d0721a5524a936336485dfb429bb206a66baf8e470384f4a2/soxr-1.0.0-cp312-abi3-win_amd64.whl", hash = "sha256:2a3b77b115ae7c478eecdbd060ed4f61beda542dfb70639177ac263aceda42a2", size = 172070, upload-time = "2025-09-07T13:22:07.62Z" }, +] + [[package]] name = "sphinx" version = "8.2.3" From 1751cc60db3cb94900d0b43ec3997cf5cef6baf4 Mon Sep 17 00:00:00 2001 From: David Pellhammer Date: Mon, 24 Nov 2025 13:24:48 +0000 Subject: [PATCH 03/11] encasulated splitter and extended audio preprocessor --- notebooks/train_nightingale.ipynb | 702 ++++++++++++++++-- notebooks/train_nightingale_2.ipynb | 645 +++++++++++++--- .../data_pipeline/audio_dataset_splitter.py | 109 +++ .../data_pipeline/audio_preprocessor.py | 125 +++- .../data_pipeline/filter_birdclef_data.py | 38 +- 5 files changed, 1437 insertions(+), 182 deletions(-) create mode 100644 src/nightingale/data_pipeline/audio_dataset_splitter.py diff --git a/notebooks/train_nightingale.ipynb b/notebooks/train_nightingale.ipynb index 4948fc0..c5b5a8d 100644 --- a/notebooks/train_nightingale.ipynb +++ b/notebooks/train_nightingale.ipynb @@ -10,14 +10,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "ac694b25", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "TensorFlow version: 2.20.0\n", + "tf.keras version: 3.12.0\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/workspaces/nightingale/.venv/lib/python3.11/site-packages/tensorflow_hub/__init__.py:61: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.\n", + " from pkg_resources import parse_version\n" + ] + } + ], "source": [ "import pandas as pd\n", "from nightingale.model.classifier_head import ClassifierHead\n", - "from nightingale.data_pipeline.wav_loader import load_wav_16k_mono\n", + "\n", + "from nightingale.data_pipeline.audio_preprocessor import AudioPreprocessor\n", "import os\n", "import glob\n", "from sklearn.model_selection import train_test_split\n", @@ -39,10 +57,318 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "1137cde9", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "application/vnd.microsoft.datawrangler.viewer.v0+json": { + "columns": [ + { + "name": "index", + "rawType": "int64", + "type": "integer" + }, + { + "name": "primary_label", + "rawType": "object", + "type": "string" + }, + { + "name": "secondary_labels", + "rawType": "object", + "type": "string" + }, + { + "name": "type", + "rawType": "object", + "type": "string" + }, + { + "name": "latitude", + "rawType": "float64", + "type": "float" + }, + { + "name": "longitude", + "rawType": "float64", + "type": "float" + }, + { + "name": "scientific_name", + "rawType": "object", + "type": "string" + }, + { + "name": "common_name", + "rawType": "object", + "type": "string" + }, + { + "name": "author", + "rawType": "object", + "type": "string" + }, + { + "name": "license", + "rawType": "object", + "type": "string" + }, + { + "name": "rating", + "rawType": "float64", + "type": "float" + }, + { + "name": "url", + "rawType": "object", + "type": "string" + }, + { + "name": "filename", + "rawType": "object", + "type": "string" + } + ], + "ref": "4ff9dbb9-c493-4ca1-aab2-bbc2744d8fe7", + "rows": [ + [ + "0", + "asbfly", + "[]", + "['call']", + "39.2297", + "118.1987", + "Muscicapa dauurica", + "Asian Brown Flycatcher", + "Matt Slaymaker", + "Creative Commons Attribution-NonCommercial-ShareAlike 3.0", + "5.0", + "https://www.xeno-canto.org/134896", + "asbfly/XC134896.ogg" + ], + [ + "1", + "asbfly", + "[]", + "['song']", + "51.403", + "104.6401", + "Muscicapa dauurica", + "Asian Brown Flycatcher", + "Magnus Hellström", + "Creative Commons Attribution-NonCommercial-ShareAlike 3.0", + "2.5", + "https://www.xeno-canto.org/164848", + "asbfly/XC164848.ogg" + ], + [ + "2", + "asbfly", + "[]", + "['song']", + "36.3319", + "127.3555", + "Muscicapa dauurica", + "Asian Brown Flycatcher", + "Stuart Fisher", + "Creative Commons Attribution-NonCommercial-ShareAlike 4.0", + "2.5", + "https://www.xeno-canto.org/175797", + "asbfly/XC175797.ogg" + ], + [ + "3", + "asbfly", + "[]", + "['call']", + "21.1697", + "70.6005", + "Muscicapa dauurica", + "Asian Brown Flycatcher", + "vir joshi", + "Creative Commons Attribution-NonCommercial-ShareAlike 4.0", + "4.0", + "https://www.xeno-canto.org/207738", + "asbfly/XC207738.ogg" + ], + [ + "4", + "asbfly", + "[]", + "['call']", + "15.5442", + "73.7733", + "Muscicapa dauurica", + "Asian Brown Flycatcher", + "Albert Lastukhin & Sergei Karpeev", + "Creative Commons Attribution-NonCommercial-ShareAlike 4.0", + "4.0", + "https://www.xeno-canto.org/209218", + "asbfly/XC209218.ogg" + ] + ], + "shape": { + "columns": 12, + "rows": 5 + } + }, + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
primary_labelsecondary_labelstypelatitudelongitudescientific_namecommon_nameauthorlicenseratingurlfilename
0asbfly[]['call']39.2297118.1987Muscicapa dauuricaAsian Brown FlycatcherMatt SlaymakerCreative Commons Attribution-NonCommercial-Sha...5.0https://www.xeno-canto.org/134896asbfly/XC134896.ogg
1asbfly[]['song']51.4030104.6401Muscicapa dauuricaAsian Brown FlycatcherMagnus HellströmCreative Commons Attribution-NonCommercial-Sha...2.5https://www.xeno-canto.org/164848asbfly/XC164848.ogg
2asbfly[]['song']36.3319127.3555Muscicapa dauuricaAsian Brown FlycatcherStuart FisherCreative Commons Attribution-NonCommercial-Sha...2.5https://www.xeno-canto.org/175797asbfly/XC175797.ogg
3asbfly[]['call']21.169770.6005Muscicapa dauuricaAsian Brown Flycatchervir joshiCreative Commons Attribution-NonCommercial-Sha...4.0https://www.xeno-canto.org/207738asbfly/XC207738.ogg
4asbfly[]['call']15.544273.7733Muscicapa dauuricaAsian Brown FlycatcherAlbert Lastukhin & Sergei KarpeevCreative Commons Attribution-NonCommercial-Sha...4.0https://www.xeno-canto.org/209218asbfly/XC209218.ogg
\n", + "
" + ], + "text/plain": [ + " primary_label secondary_labels type latitude longitude \\\n", + "0 asbfly [] ['call'] 39.2297 118.1987 \n", + "1 asbfly [] ['song'] 51.4030 104.6401 \n", + "2 asbfly [] ['song'] 36.3319 127.3555 \n", + "3 asbfly [] ['call'] 21.1697 70.6005 \n", + "4 asbfly [] ['call'] 15.5442 73.7733 \n", + "\n", + " scientific_name common_name \\\n", + "0 Muscicapa dauurica Asian Brown Flycatcher \n", + "1 Muscicapa dauurica Asian Brown Flycatcher \n", + "2 Muscicapa dauurica Asian Brown Flycatcher \n", + "3 Muscicapa dauurica Asian Brown Flycatcher \n", + "4 Muscicapa dauurica Asian Brown Flycatcher \n", + "\n", + " author \\\n", + "0 Matt Slaymaker \n", + "1 Magnus Hellström \n", + "2 Stuart Fisher \n", + "3 vir joshi \n", + "4 Albert Lastukhin & Sergei Karpeev \n", + "\n", + " license rating \\\n", + "0 Creative Commons Attribution-NonCommercial-Sha... 5.0 \n", + "1 Creative Commons Attribution-NonCommercial-Sha... 2.5 \n", + "2 Creative Commons Attribution-NonCommercial-Sha... 2.5 \n", + "3 Creative Commons Attribution-NonCommercial-Sha... 4.0 \n", + "4 Creative Commons Attribution-NonCommercial-Sha... 4.0 \n", + "\n", + " url filename \n", + "0 https://www.xeno-canto.org/134896 asbfly/XC134896.ogg \n", + "1 https://www.xeno-canto.org/164848 asbfly/XC164848.ogg \n", + "2 https://www.xeno-canto.org/175797 asbfly/XC175797.ogg \n", + "3 https://www.xeno-canto.org/207738 asbfly/XC207738.ogg \n", + "4 https://www.xeno-canto.org/209218 asbfly/XC209218.ogg " + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# Read train meta data\n", "train_metadata_path = \"../data/birdclef-2024/train_metadata.csv\"\n", @@ -70,7 +396,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "c0ba8473", "metadata": {}, "outputs": [], @@ -110,34 +436,6 @@ "### Split data: Training, Validation and Test" ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "ade4a54a", - "metadata": {}, - "outputs": [], - "source": [ - "# Step 1: Split the data into training (60%), validation (20%) and test (20%) sets\n", - "train_df_idx, temp_df_idx = train_test_split(filtered_bird_df.index, test_size=0.4, random_state=42, stratify=filtered_bird_df['target'])\n", - "val_df_idx, test_df_idx = train_test_split(temp_df_idx, test_size=0.5, random_state=42, stratify=filtered_bird_df.loc[temp_df_idx, 'target'])\n", - "\n", - "# Step 2: Create 'fold' column in original filtered_bird_df\n", - "filtered_bird_df['fold'] = '' # initialize empty\n", - "filtered_bird_df.loc[train_df_idx, 'fold'] = 1\n", - "filtered_bird_df.loc[val_df_idx, 'fold'] = 2\n", - "filtered_bird_df.loc[test_df_idx, 'fold'] = 3\n", - "\n", - "# filtered_bird_df.head(10)\n", - "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 1]['target'], bins=len(bird_classes), alpha=0.7, label='Train')\n", - "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 2]['target'], bins=len(bird_classes), alpha=0.7, label='Val')\n", - "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 3]['target'], bins=len(bird_classes), alpha=0.7, label='Test')\n", - "# plt.xlabel('Bird Classes')\n", - "# plt.ylabel('Count')\n", - "# plt.title('Distribution of Bird Classes in Train, Val, and Test Sets')\n", - "# plt.legend()\n", - "# plt.show()" - ] - }, { "cell_type": "markdown", "id": "9721db5e", @@ -161,7 +459,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "ba052c95", "metadata": {}, "outputs": [], @@ -180,40 +478,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "9a647265", "metadata": {}, "outputs": [], "source": [ - "filenames_train = filtered_bird_df[filtered_bird_df['fold'] == 1]['filename']\n", - "targets_train = filtered_bird_df[filtered_bird_df['fold'] == 1]['target']\n", - "\n", - "filenames_val = filtered_bird_df[filtered_bird_df['fold'] == 2]['filename']\n", - "targets_val = filtered_bird_df[filtered_bird_df['fold'] == 2]['target']\n", + "from nightingale.data_pipeline.audio_dataset_splitter import AudioDatasetSplitter\n", "\n", - "filenames_test = filtered_bird_df[filtered_bird_df['fold'] == 3]['filename']\n", - "targets_test = filtered_bird_df[filtered_bird_df['fold'] == 3]['target']\n", - "\n", - "\n", - "train_ds = tf.data.Dataset.from_tensor_slices((filenames_train, targets_train))\n", - "val_ds = tf.data.Dataset.from_tensor_slices((filenames_val, targets_val))\n", - "test_ds = tf.data.Dataset.from_tensor_slices((filenames_test, targets_test))\n", - "\n", - "def load_wav_for_map(filename, label):\n", - " return load_wav_16k_mono(filename), label\n", - "\n", - "train_ds = train_ds.map(load_wav_for_map)\n", - "val_ds = val_ds.map(load_wav_for_map)\n", - "test_ds = test_ds.map(load_wav_for_map)" + "data_split = AudioDatasetSplitter()\n", + "train_ds, val_ds, test_ds = data_split.build(filtered_bird_df)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "41c181bb", "metadata": {}, "outputs": [], "source": [ + "model = hub.load('https://tfhub.dev/google/yamnet/1')\n", "def extract_embedding(wav_data, label):\n", " ''' run YAMNet to extract embedding from the wav data '''\n", " scores, embeddings, spectrogram = model(wav_data)\n", @@ -241,10 +524,88 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "83eb0ddf", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
Model: \"classifier_head\"\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1mModel: \"classifier_head\"\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
+       "┃ Layer (type)                     Output Shape                  Param # ┃\n",
+       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
+       "│ dense (Dense)                   │ ?                      │   0 (unbuilt) │\n",
+       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+       "│ dense_1 (Dense)                 │ ?                      │   0 (unbuilt) │\n",
+       "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
+       "
\n" + ], + "text/plain": [ + "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n", + "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n", + "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n", + "│ dense (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ dense_1 (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", + "└─────────────────────────────────┴────────────────────────┴───────────────┘\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
 Total params: 0 (0.00 B)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
 Trainable params: 0 (0.00 B)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
 Non-trainable params: 0 (0.00 B)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "num_bird_classes = len(bird_classes)\n", "bird_class_model = ClassifierHead(num_classes=num_bird_classes)\n", @@ -254,7 +615,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "09c44c15", "metadata": {}, "outputs": [], @@ -280,10 +641,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "3d70881d", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# import mlflow\n", "# from mlflow import MlflowClient\n", @@ -304,10 +676,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "id": "ea50b3d5", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Env: None\n", + "From MLflow: file:///workspaces/nightingale/notebooks/mlruns\n" + ] + } + ], "source": [ "import os\n", "print(\"Env:\", os.getenv(\"MLFLOW_TRACKING_URI\"))\n", @@ -325,7 +706,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "id": "1dcec8ff", "metadata": {}, "outputs": [], @@ -357,10 +738,155 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "id": "80f0dd2a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/20\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/workspaces/nightingale/.venv/lib/python3.11/site-packages/keras/src/backend/tensorflow/nn.py:717: UserWarning: \"`sparse_categorical_crossentropy` received `from_logits=True`, but the `output` argument was produced by a Softmax activation and thus does not represent logits. Was this intended?\n", + " output, from_logits = _get_logits(\n", + "2025-11-24 13:20:15.356312: W external/local_xla/xla/tsl/framework/cpu_allocator_impl.cc:84] Allocation of 24870912 exceeds 10% of free system memory.\n", + "2025-11-24 13:20:15.362225: W external/local_xla/xla/tsl/framework/cpu_allocator_impl.cc:84] Allocation of 24968064 exceeds 10% of free system memory.\n", + "2025-11-24 13:20:15.374365: W external/local_xla/xla/tsl/framework/cpu_allocator_impl.cc:84] Allocation of 49545216 exceeds 10% of free system memory.\n", + "2025-11-24 13:20:15.421970: W external/local_xla/xla/tsl/framework/cpu_allocator_impl.cc:84] Allocation of 49545216 exceeds 10% of free system memory.\n", + "2025-11-24 13:20:15.450114: W external/local_xla/xla/tsl/framework/cpu_allocator_impl.cc:84] Allocation of 49545216 exceeds 10% of free system memory.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 24/Unknown \u001b[1m3s\u001b[0m 2ms/step - accuracy: 0.8219 - loss: 0.4678" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2025-11-24 13:20:17.297713: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n", + "/workspaces/nightingale/.venv/lib/python3.11/site-packages/keras/src/trainers/epoch_iterator.py:164: UserWarning: Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least `steps_per_epoch * epochs` batches. You may need to use the `.repeat()` function when building your dataset.\n", + " self._interrupted_warning()\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 50ms/step - accuracy: 0.9218 - loss: 0.2627 - val_accuracy: 0.7048 - val_loss: 1.3252\n", + "Epoch 2/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 0.9769 - loss: 0.0706 - val_accuracy: 0.7004 - val_loss: 1.6772\n", + "Epoch 3/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9901 - loss: 0.0360 - val_accuracy: 0.7026 - val_loss: 1.9530\n", + "Epoch 4/20\n", + "\u001b[1m 1/29\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m0s\u001b[0m 4ms/step - accuracy: 0.9688 - loss: 0.0634" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2025-11-24 13:20:18.624689: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n", + "2025-11-24 13:20:18.710861: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 4ms/step - accuracy: 0.9923 - loss: 0.0257 - val_accuracy: 0.7004 - val_loss: 1.8766\n", + "Epoch 5/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 0.9967 - loss: 0.0157 - val_accuracy: 0.6982 - val_loss: 2.0125\n", + "Epoch 6/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0097 - val_accuracy: 0.7048 - val_loss: 2.1867\n", + "Epoch 7/20\n", + "\u001b[1m 1/29\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m0s\u001b[0m 5ms/step - accuracy: 1.0000 - loss: 0.0033" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2025-11-24 13:20:18.889192: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 0.9989 - loss: 0.0076 - val_accuracy: 0.6960 - val_loss: 2.2336\n", + "Epoch 8/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 0.9989 - loss: 0.0098 - val_accuracy: 0.6960 - val_loss: 2.3949\n", + "Epoch 9/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0054 - val_accuracy: 0.7070 - val_loss: 2.4787\n", + "Epoch 10/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0036 - val_accuracy: 0.7048 - val_loss: 2.4777\n", + "Epoch 11/20\n", + "\u001b[1m 1/29\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m0s\u001b[0m 4ms/step - accuracy: 1.0000 - loss: 0.0018" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2025-11-24 13:20:19.203583: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0027 - val_accuracy: 0.7048 - val_loss: 2.5876\n", + "Epoch 12/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0022 - val_accuracy: 0.7070 - val_loss: 2.6581\n", + "Epoch 13/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0019 - val_accuracy: 0.6982 - val_loss: 2.7069\n", + "Epoch 14/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0017 - val_accuracy: 0.7048 - val_loss: 2.7296\n", + "Epoch 15/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0014 - val_accuracy: 0.7026 - val_loss: 2.7604\n", + "Epoch 16/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0012 - val_accuracy: 0.7048 - val_loss: 2.8253\n", + "Epoch 17/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0011 - val_accuracy: 0.7048 - val_loss: 2.8632\n", + "Epoch 18/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 9.3358e-04 - val_accuracy: 0.7048 - val_loss: 2.9056\n", + "Epoch 19/20\n", + "\u001b[1m 1/29\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m0s\u001b[0m 5ms/step - accuracy: 1.0000 - loss: 0.0016" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2025-11-24 13:20:19.832534: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 8.9333e-04 - val_accuracy: 0.6982 - val_loss: 2.9335\n", + "Epoch 20/20\n", + "\u001b[1m29/29\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 8.0682e-04 - val_accuracy: 0.7048 - val_loss: 2.9797\n" + ] + } + ], "source": [ "history = bird_class_model.fit(train_ds,\n", " epochs=20,\n", @@ -378,10 +904,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "id": "0dfe1437", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m13/13\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 56ms/step - accuracy: 0.8396 - loss: 0.7635\n", + "Loss: 0.7634812593460083\n", + "Accuracy: 0.8395990133285522\n" + ] + } + ], "source": [ "loss, accuracy = bird_class_model.evaluate(test_ds)\n", "\n", @@ -391,10 +927,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "id": "8bd2dcaf", "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "MissingConfigException", + "evalue": "Yaml file '/workspaces/nightingale/notebooks/mlruns/0/meta.yaml' does not exist.", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mMissingConfigException\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[17]\u001b[39m\u001b[32m, line 15\u001b[39m\n\u001b[32m 3\u001b[39m params = {\n\u001b[32m 4\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mnum_bird_classes\u001b[39m\u001b[33m\"\u001b[39m: num_bird_classes,\n\u001b[32m 5\u001b[39m \u001b[33m\"\u001b[39m\u001b[33moptimizer\u001b[39m\u001b[33m\"\u001b[39m: \u001b[33m\"\u001b[39m\u001b[33madam\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 11\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mearly_stopping_patience\u001b[39m\u001b[33m\"\u001b[39m: \u001b[32m3\u001b[39m,\n\u001b[32m 12\u001b[39m }\n\u001b[32m 14\u001b[39m \u001b[38;5;66;03m# Initiate the MLflow run context\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m15\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[43mmlflow\u001b[49m\u001b[43m.\u001b[49m\u001b[43mstart_run\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m run:\n\u001b[32m 16\u001b[39m \u001b[38;5;66;03m# Log the parameters used for the model fit\u001b[39;00m\n\u001b[32m 17\u001b[39m mlflow.log_params(params)\n\u001b[32m 19\u001b[39m \u001b[38;5;66;03m# Log the error metrics that were calculated during validation\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/fluent.py:475\u001b[39m, in \u001b[36mstart_run\u001b[39m\u001b[34m(run_id, experiment_id, run_name, nested, parent_run_id, tags, description, log_system_metrics)\u001b[39m\n\u001b[32m 471\u001b[39m user_specified_tags[MLFLOW_RUN_NAME] = run_name\n\u001b[32m 473\u001b[39m resolved_tags = context_registry.resolve_tags(user_specified_tags)\n\u001b[32m--> \u001b[39m\u001b[32m475\u001b[39m active_run_obj = \u001b[43mclient\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_run\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 476\u001b[39m \u001b[43m \u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43mexp_id_for_run\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 477\u001b[39m \u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m=\u001b[49m\u001b[43mresolved_tags\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 478\u001b[39m \u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 479\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 481\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m log_system_metrics \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 482\u001b[39m \u001b[38;5;66;03m# If `log_system_metrics` is not specified, we will check environment variable.\u001b[39;00m\n\u001b[32m 483\u001b[39m log_system_metrics = MLFLOW_ENABLE_SYSTEM_METRICS_LOGGING.get()\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/client.py:479\u001b[39m, in \u001b[36mMlflowClient.create_run\u001b[39m\u001b[34m(self, experiment_id, start_time, tags, run_name)\u001b[39m\n\u001b[32m 425\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mcreate_run\u001b[39m(\n\u001b[32m 426\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 427\u001b[39m experiment_id: \u001b[38;5;28mstr\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 430\u001b[39m run_name: \u001b[38;5;28mstr\u001b[39m | \u001b[38;5;28;01mNone\u001b[39;00m = \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m 431\u001b[39m ) -> Run:\n\u001b[32m 432\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 433\u001b[39m \u001b[33;03m Create a :py:class:`mlflow.entities.Run` object that can be associated with\u001b[39;00m\n\u001b[32m 434\u001b[39m \u001b[33;03m metrics, parameters, artifacts, etc.\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 477\u001b[39m \u001b[33;03m status: RUNNING\u001b[39;00m\n\u001b[32m 478\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m479\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_tracking_client\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_run\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstart_time\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/telemetry/track.py:30\u001b[39m, in \u001b[36mrecord_usage_event..decorator..wrapper\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 28\u001b[39m start_time = time.time()\n\u001b[32m 29\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m30\u001b[39m result = \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 31\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m result \u001b[38;5;66;03m# noqa: RET504\u001b[39;00m\n\u001b[32m 32\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m:\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/_tracking_service/client.py:183\u001b[39m, in \u001b[36mTrackingServiceClient.create_run\u001b[39m\u001b[34m(self, experiment_id, start_time, tags, run_name)\u001b[39m\n\u001b[32m 178\u001b[39m \u001b[38;5;66;03m# Extract user from tags\u001b[39;00m\n\u001b[32m 179\u001b[39m \u001b[38;5;66;03m# This logic is temporary; the user_id attribute of runs is deprecated and will be removed\u001b[39;00m\n\u001b[32m 180\u001b[39m \u001b[38;5;66;03m# in a later release.\u001b[39;00m\n\u001b[32m 181\u001b[39m user_id = tags.get(MLFLOW_USER, \u001b[33m\"\u001b[39m\u001b[33munknown\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m183\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mstore\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_run\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 184\u001b[39m \u001b[43m \u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 185\u001b[39m \u001b[43m \u001b[49m\u001b[43muser_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43muser_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 186\u001b[39m \u001b[43m \u001b[49m\u001b[43mstart_time\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstart_time\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mget_current_time_millis\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 187\u001b[39m \u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m=\u001b[49m\u001b[43m[\u001b[49m\u001b[43mRunTag\u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvalue\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvalue\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m.\u001b[49m\u001b[43mitems\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 188\u001b[39m \u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 189\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:689\u001b[39m, in \u001b[36mFileStore.create_run\u001b[39m\u001b[34m(self, experiment_id, user_id, start_time, tags, run_name)\u001b[39m\n\u001b[32m 685\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 686\u001b[39m \u001b[33;03mCreates a run with the specified attributes.\u001b[39;00m\n\u001b[32m 687\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 688\u001b[39m experiment_id = FileStore.DEFAULT_EXPERIMENT_ID \u001b[38;5;28;01mif\u001b[39;00m experiment_id \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m experiment_id\n\u001b[32m--> \u001b[39m\u001b[32m689\u001b[39m experiment = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mget_experiment\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 690\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m experiment \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 691\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MlflowException(\n\u001b[32m 692\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mCould not create run under experiment with ID \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m - no such \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 693\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mexperiment exists.\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 694\u001b[39m databricks_pb2.RESOURCE_DOES_NOT_EXIST,\n\u001b[32m 695\u001b[39m )\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:498\u001b[39m, in \u001b[36mFileStore.get_experiment\u001b[39m\u001b[34m(self, experiment_id)\u001b[39m\n\u001b[32m 487\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 488\u001b[39m \u001b[33;03mFetch the experiment.\u001b[39;00m\n\u001b[32m 489\u001b[39m \u001b[33;03mNote: This API will search for active as well as deleted experiments.\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 495\u001b[39m \u001b[33;03m A single Experiment object if it exists, otherwise raises an Exception.\u001b[39;00m\n\u001b[32m 496\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 497\u001b[39m experiment_id = FileStore.DEFAULT_EXPERIMENT_ID \u001b[38;5;28;01mif\u001b[39;00m experiment_id \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m experiment_id\n\u001b[32m--> \u001b[39m\u001b[32m498\u001b[39m experiment = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_get_experiment\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 499\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m experiment \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 500\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MlflowException(\n\u001b[32m 501\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mExperiment \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m does not exist.\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 502\u001b[39m databricks_pb2.RESOURCE_DOES_NOT_EXIST,\n\u001b[32m 503\u001b[39m )\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:466\u001b[39m, in \u001b[36mFileStore._get_experiment\u001b[39m\u001b[34m(self, experiment_id, view_type)\u001b[39m\n\u001b[32m 461\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m experiment_dir \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 462\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MlflowException(\n\u001b[32m 463\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mCould not find experiment with ID \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m,\n\u001b[32m 464\u001b[39m databricks_pb2.RESOURCE_DOES_NOT_EXIST,\n\u001b[32m 465\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m466\u001b[39m meta = \u001b[43mFileStore\u001b[49m\u001b[43m.\u001b[49m\u001b[43m_read_yaml\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_dir\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mFileStore\u001b[49m\u001b[43m.\u001b[49m\u001b[43mMETA_DATA_FILE_NAME\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 467\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m meta \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 468\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MissingConfigException(\n\u001b[32m 469\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mExperiment \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m is invalid with empty \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 470\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mFileStore.META_DATA_FILE_NAME\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m in directory \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_dir\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 471\u001b[39m )\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:1636\u001b[39m, in \u001b[36mFileStore._read_yaml\u001b[39m\u001b[34m(root, file_name, retries)\u001b[39m\n\u001b[32m 1633\u001b[39m time.sleep(\u001b[32m0.1\u001b[39m * (\u001b[32m3\u001b[39m - attempts_remaining))\n\u001b[32m 1634\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m _read_helper(root, file_name, attempts_remaining - \u001b[32m1\u001b[39m)\n\u001b[32m-> \u001b[39m\u001b[32m1636\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_read_helper\u001b[49m\u001b[43m(\u001b[49m\u001b[43mroot\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfile_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mattempts_remaining\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:1629\u001b[39m, in \u001b[36mFileStore._read_yaml.._read_helper\u001b[39m\u001b[34m(root, file_name, attempts_remaining)\u001b[39m\n\u001b[32m 1628\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m_read_helper\u001b[39m(root, file_name, attempts_remaining=\u001b[32m2\u001b[39m):\n\u001b[32m-> \u001b[39m\u001b[32m1629\u001b[39m result = \u001b[43mread_yaml\u001b[49m\u001b[43m(\u001b[49m\u001b[43mroot\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfile_name\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1630\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m result \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mor\u001b[39;00m attempts_remaining == \u001b[32m0\u001b[39m:\n\u001b[32m 1631\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m result\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/yaml_utils.py:107\u001b[39m, in \u001b[36mread_yaml\u001b[39m\u001b[34m(root, file_name)\u001b[39m\n\u001b[32m 105\u001b[39m file_path = os.path.join(root, file_name)\n\u001b[32m 106\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m exists(file_path):\n\u001b[32m--> \u001b[39m\u001b[32m107\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MissingConfigException(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mYaml file \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfile_path\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m does not exist.\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 108\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m codecs.open(file_path, mode=\u001b[33m\"\u001b[39m\u001b[33mr\u001b[39m\u001b[33m\"\u001b[39m, encoding=ENCODING) \u001b[38;5;28;01mas\u001b[39;00m yaml_file:\n\u001b[32m 109\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m yaml.load(yaml_file, Loader=YamlSafeLoader)\n", + "\u001b[31mMissingConfigException\u001b[39m: Yaml file '/workspaces/nightingale/notebooks/mlruns/0/meta.yaml' does not exist." + ] + } + ], "source": [ "# Assemble the metrics we're going to write into a collection\n", "metrics = {\"Loss\": loss, \"Accuracy\": accuracy}\n", @@ -470,7 +1028,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "nightingale", "language": "python", "name": "python3" }, @@ -484,7 +1042,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.12" + "version": "3.11.14" } }, "nbformat": 4, diff --git a/notebooks/train_nightingale_2.ipynb b/notebooks/train_nightingale_2.ipynb index b9be909..42057fc 100644 --- a/notebooks/train_nightingale_2.ipynb +++ b/notebooks/train_nightingale_2.ipynb @@ -2,33 +2,17 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "a9cd6428", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/workspaces/nightingale/.venv/lib/python3.11/site-packages/tensorflow_hub/__init__.py:61: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.\n", - " from pkg_resources import parse_version\n" - ] - } - ], + "outputs": [], "source": [ "import pandas as pd\n", "import os\n", - "import glob\n", - "from sklearn.model_selection import train_test_split\n", - "import tensorflow_hub as hub\n", "import tensorflow as tf\n", - "import numpy as np\n", "\n", "from nightingale.model.classifier_head import ClassifierHead\n", "from nightingale.model.yamnet_base import YamnetEmbedding\n", - "from nightingale.data_pipeline.wav_loader import load_wav_16k_mono\n", - "from nightingale.data_pipeline.filter_birdclef_data import load_birdclef_metadata\n", - "from nightingale.data_pipeline.audio_preprocessor import AudioPreprocessor\n", "\n" ] }, @@ -42,7 +26,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 16, "id": "d504fa73", "metadata": {}, "outputs": [ @@ -116,7 +100,7 @@ "type": "string" } ], - "ref": "f4f8004d-7c40-4de5-8d4f-0fdc724b2674", + "ref": "0a5db620-a593-46c2-9c9f-81c8ec8288f5", "rows": [ [ "0", @@ -349,7 +333,7 @@ "4 https://www.xeno-canto.org/209218 asbfly/XC209218.ogg " ] }, - "execution_count": 2, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -363,7 +347,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 17, "id": "71495869", "metadata": {}, "outputs": [ @@ -392,7 +376,7 @@ "type": "float" } ], - "ref": "46c8ca05-b7c4-4893-8184-253450b5212f", + "ref": "f13f021b-6565-4f04-81d6-545ab79db622", "rows": [ [ "count", @@ -537,7 +521,7 @@ "max 71.964000 177.447800 5.000000" ] }, - "execution_count": 3, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -556,23 +540,80 @@ }, { "cell_type": "code", - "execution_count": 4, - "id": "6ef7c047", + "execution_count": null, + "id": "b9c56857", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Processing 4 folders\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/cohcuc1/XC214005.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/cohcuc1/XC214006.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/cohcuc1/XC19645.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/cohcuc1/XC174932.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/cohcuc1/XC177780.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/cohcuc1/XC140254.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/cohcuc1/XC191169.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/cohcuc1/XC136837.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/integr/XC842970.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/integr/XC401712.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/integr/XC397702.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/integr/XC840667.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/integr/XC810654.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/tilwar1/XC42645.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/tilwar1/XC42646.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/tilwar1/XC133404.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/tilwar1/XC189206.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/tilwar1/XC191453.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/tilwar1/XC176794.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/tilwar1/XC191454.wav\n", + "Skipped (already exists): ../data/birdclef-2024/train_audio_16/tilwar1/XC191455.wav\n" + ] + } + ], "source": [ - "# Read train meta data\n", - "\n", - "base_data_path = \"../data/birdclef-2024\"\n", + "from nightingale.data_pipeline.audio_preprocessor import AudioPreprocessor\n", "\n", - "# Convert to yamnet compatible format\n", + "# convert data if necessary\n", "preprocessor = AudioPreprocessor()\n", - "\n", - "##TODO do the conversion here and save to new folder\n", + "# Read train meta data. Convert to yamnet compatible format. Skip if file already exists.\n", + "preprocessor.process_folder(\n", + " input_root=\"../data/birdclef-2024/train_audio\",\n", + " output_root=\"../data/birdclef-2024/train_audio_16\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "8000c8b8", + "metadata": {}, + "source": [ + "### Filter the Metadata for the folder that are actually existing" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6ef7c047", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of bird classes in dataset: 3\n" + ] + } + ], + "source": [ + "from nightingale.data_pipeline.filter_birdclef_data import load_birdclef_metadata\n", "\n", "# filter the metadata csv file for th data that is actually in the data folder\n", - "filtered_bird_df = load_birdclef_metadata(base_data_path)\n", - "# filtered_bird_df.head(10)" + "filtered_bird_df, num_of_bird_classes_in_dataset = load_birdclef_metadata(metadata_path=\"../data/birdclef-2024/train_metadata.csv\", \n", + " audio_root=\"../data/birdclef-2024/train_audio_16\")\n", + "print(f\"Number of bird classes in dataset: {num_of_bird_classes_in_dataset}\")" ] }, { @@ -585,91 +626,527 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "id": "62a4886f", "metadata": {}, "outputs": [], "source": [ - "# Step 1: Split the data into training (60%), validation (20%) and test (20%) sets\n", - "train_df_idx, temp_df_idx = train_test_split(filtered_bird_df.index, test_size=0.4, random_state=42, stratify=filtered_bird_df['target'])\n", - "val_df_idx, test_df_idx = train_test_split(temp_df_idx, test_size=0.5, random_state=42, stratify=filtered_bird_df.loc[temp_df_idx, 'target'])\n", + "from nightingale.data_pipeline.audio_dataset_splitter import AudioDatasetSplitter\n", "\n", - "# Step 2: Create 'fold' column in original filtered_bird_df\n", - "filtered_bird_df['fold'] = '' # initialize empty\n", - "filtered_bird_df.loc[train_df_idx, 'fold'] = 1\n", - "filtered_bird_df.loc[val_df_idx, 'fold'] = 2\n", - "filtered_bird_df.loc[test_df_idx, 'fold'] = 3\n", + "data_split = AudioDatasetSplitter()\n", + "train_ds, val_ds, test_ds = data_split.build(filtered_bird_df)" + ] + }, + { + "cell_type": "markdown", + "id": "03c82358", + "metadata": {}, + "source": [ + "# Load the Yamnet Model and extract Embeddings" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "5aca4873", + "metadata": {}, + "outputs": [], + "source": [ + "#object of the yamnet Model\n", + "yam = YamnetEmbedding()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "1852e16e", + "metadata": {}, + "outputs": [], + "source": [ + "train_ds = train_ds.map(yam).unbatch()\n", + "val_ds = val_ds.map(yam).unbatch()\n", + "test_ds = test_ds.map(yam).unbatch()\n", + "train_ds.element_spec\n", + "\n", + "train_ds = train_ds.cache().shuffle(1000).batch(32).prefetch(tf.data.AUTOTUNE)\n", + "val_ds = val_ds.cache().batch(32).prefetch(tf.data.AUTOTUNE)\n", + "test_ds = test_ds.cache().batch(32).prefetch(tf.data.AUTOTUNE)" + ] + }, + { + "cell_type": "markdown", + "id": "e22d4b33", + "metadata": {}, + "source": [ + "## Create Model for Classifier" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "c1b433b4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Model: \"classifier_head_1\"\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1mModel: \"classifier_head_1\"\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
+       "┃ Layer (type)                     Output Shape                  Param # ┃\n",
+       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
+       "│ dense_2 (Dense)                 │ ?                      │   0 (unbuilt) │\n",
+       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+       "│ dense_3 (Dense)                 │ ?                      │   0 (unbuilt) │\n",
+       "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
+       "
\n" + ], + "text/plain": [ + "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n", + "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n", + "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n", + "│ dense_2 (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ dense_3 (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", + "└─────────────────────────────────┴────────────────────────┴───────────────┘\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
 Total params: 0 (0.00 B)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
 Trainable params: 0 (0.00 B)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
 Non-trainable params: 0 (0.00 B)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "bird_class_model = ClassifierHead(num_classes=num_of_bird_classes_in_dataset)\n", + "\n", + "bird_class_model.summary()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "3c380b83", + "metadata": {}, + "outputs": [], + "source": [ + "bird_class_model.compile(loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n", + " optimizer=\"adam\",\n", + " metrics=['accuracy'])\n", + "\n", + "callback = tf.keras.callbacks.EarlyStopping(monitor='loss',\n", + " patience=3,\n", + " restore_best_weights=True)" + ] + }, + { + "cell_type": "markdown", + "id": "36763755", + "metadata": {}, + "source": [ + "# Train the model" + ] + }, + { + "cell_type": "markdown", + "id": "7aa56ec4", + "metadata": {}, + "source": [ + "#### Train classifier" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "5256d5fc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/20\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/workspaces/nightingale/.venv/lib/python3.11/site-packages/keras/src/backend/tensorflow/nn.py:717: UserWarning: \"`sparse_categorical_crossentropy` received `from_logits=True`, but the `output` argument was produced by a Softmax activation and thus does not represent logits. Was this intended?\n", + " output, from_logits = _get_logits(\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 17/Unknown \u001b[1m3s\u001b[0m 3ms/step - accuracy: 0.7222 - loss: 0.6694" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/workspaces/nightingale/.venv/lib/python3.11/site-packages/keras/src/trainers/epoch_iterator.py:164: UserWarning: Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least `steps_per_epoch * epochs` batches. You may need to use the `.repeat()` function when building your dataset.\n", + " self._interrupted_warning()\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 33ms/step - accuracy: 0.8949 - loss: 0.3259 - val_accuracy: 0.9314 - val_loss: 0.1980\n", + "Epoch 2/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9639 - loss: 0.1086 - val_accuracy: 0.9346 - val_loss: 0.2097\n", + "Epoch 3/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9851 - loss: 0.0609 - val_accuracy: 0.9477 - val_loss: 0.1863\n", + "Epoch 4/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9894 - loss: 0.0448 - val_accuracy: 0.9281 - val_loss: 0.1908\n", + "Epoch 5/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9894 - loss: 0.0353 - val_accuracy: 0.9412 - val_loss: 0.1769\n", + "Epoch 6/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9958 - loss: 0.0231 - val_accuracy: 0.9379 - val_loss: 0.1791\n", + "Epoch 7/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9968 - loss: 0.0205 - val_accuracy: 0.9379 - val_loss: 0.2042\n", + "Epoch 8/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9968 - loss: 0.0138 - val_accuracy: 0.9346 - val_loss: 0.2004\n", + "Epoch 9/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0092 - val_accuracy: 0.9346 - val_loss: 0.1922\n", + "Epoch 10/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0067 - val_accuracy: 0.9379 - val_loss: 0.2078\n", + "Epoch 11/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0054 - val_accuracy: 0.9379 - val_loss: 0.1982\n", + "Epoch 12/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0042 - val_accuracy: 0.9346 - val_loss: 0.2054\n", + "Epoch 13/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0036 - val_accuracy: 0.9314 - val_loss: 0.2117\n", + "Epoch 14/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0035 - val_accuracy: 0.9346 - val_loss: 0.2153\n", + "Epoch 15/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0028 - val_accuracy: 0.9346 - val_loss: 0.2203\n", + "Epoch 16/20\n", + "\u001b[1m 1/30\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0012" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2025-11-24 13:16:18.535927: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0023 - val_accuracy: 0.9346 - val_loss: 0.2200\n", + "Epoch 17/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0020 - val_accuracy: 0.9346 - val_loss: 0.2270\n", + "Epoch 18/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0018 - val_accuracy: 0.9346 - val_loss: 0.2288\n", + "Epoch 19/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0016 - val_accuracy: 0.9379 - val_loss: 0.2358\n", + "Epoch 20/20\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0014 - val_accuracy: 0.9346 - val_loss: 0.2310\n" + ] + } + ], + "source": [ + "history = bird_class_model.fit(train_ds,\n", + " epochs=20,\n", + " validation_data=val_ds,\n", + " callbacks=callback)" + ] + }, + { + "cell_type": "markdown", + "id": "ea8359a6", + "metadata": {}, + "source": [ + "#### Evaluate classifier" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "bd931dfe", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 7/Unknown \u001b[1m1s\u001b[0m 43ms/step - accuracy: 0.6563 - loss: 1.0617" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2025-11-24 13:14:27.048688: W external/local_xla/xla/tsl/framework/cpu_allocator_impl.cc:84] Allocation of 82182144 exceeds 10% of free system memory.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m17/17\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 67ms/step - accuracy: 0.8421 - loss: 0.6074\n", + "Loss: 0.6073823571205139\n", + "Accuracy: 0.8421052694320679\n" + ] + } + ], + "source": [ + "loss, accuracy = bird_class_model.evaluate(test_ds)\n", "\n", - "filenames_train = filtered_bird_df[filtered_bird_df['fold'] == 1]['filename']\n", - "targets_train = filtered_bird_df[filtered_bird_df['fold'] == 1]['target']\n", + "print(\"Loss: \", loss)\n", + "print(\"Accuracy: \", accuracy)" + ] + }, + { + "cell_type": "markdown", + "id": "af8b5ef8", + "metadata": {}, + "source": [ + "# Create the MLFlow Server" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "ba9a394a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# import mlflow\n", + "# from mlflow import MlflowClient\n", "\n", - "filenames_val = filtered_bird_df[filtered_bird_df['fold'] == 2]['filename']\n", - "targets_val = filtered_bird_df[filtered_bird_df['fold'] == 2]['target']\n", + "# TRACKING_URI_LOCAL = \"http://host.docker.internal:5757\"\n", "\n", - "filenames_test = filtered_bird_df[filtered_bird_df['fold'] == 3]['filename']\n", - "targets_test = filtered_bird_df[filtered_bird_df['fold'] == 3]['target']\n", + "# client = MlflowClient(tracking_uri=TRACKING_URI_LOCAL)\n", "\n", + "import mlflow\n", + "# from mlflow import MlflowClient\n", "\n", - "train_ds = tf.data.Dataset.from_tensor_slices((filenames_train, targets_train))\n", - "val_ds = tf.data.Dataset.from_tensor_slices((filenames_val, targets_val))\n", - "test_ds = tf.data.Dataset.from_tensor_slices((filenames_test, targets_test))\n", + "# At the beginning of your Python script\n", + "from dotenv import load_dotenv\n", "\n", - "# filtered_bird_df.head(10)\n", - "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 1]['target'], bins=len(bird_classes), alpha=0.7, label='Train')\n", - "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 2]['target'], bins=len(bird_classes), alpha=0.7, label='Val')\n", - "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 3]['target'], bins=len(bird_classes), alpha=0.7, label='Test')\n", - "# plt.xlabel('Bird Classes')\n", - "# plt.ylabel('Count')\n", - "# plt.title('Distribution of Bird Classes in Train, Val, and Test Sets')\n", - "# plt.legend()\n", - "# plt.show()" + "# Load environment variables from .env file\n", + "load_dotenv()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "5c8283f2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Env: None\n", + "From MLflow: file:///workspaces/nightingale/notebooks/mlruns\n" + ] + } + ], + "source": [ + "import os\n", + "print(\"Env:\", os.getenv(\"MLFLOW_TRACKING_URI\"))\n", + "print(\"From MLflow:\", mlflow.get_tracking_uri())" + ] + }, + { + "cell_type": "markdown", + "id": "19dc625e", + "metadata": {}, + "source": [ + "### Create experiment \n", + "RUN THE FOLLOWING CODE BLOCK ONLY ONCE FOR INITIAL EXPERIMENT SETUP!!" ] }, { "cell_type": "code", "execution_count": null, - "id": "59c00cc1", + "id": "1c1d179a", "metadata": {}, "outputs": [], "source": [ + "# experiment_description = (\n", + "# \"Nightingale is a bird call classification project.\"\n", + "# )\n", "\n", - "def load_wav_for_map(filename, label):\n", - " audio = tf.io.read_file(filename)\n", - " wav, sr = tf.audio.decode_wav(audio, desired_channels=1)\n", - " wav = tf.squeeze(wav, axis=-1)\n", - " return wav, label\n", + "# experiment_tags = {\n", + "# \"project_name\": \"nightingale\",\n", + "# \"mlflow.note.content\": experiment_description,\n", + "# }\n", "\n", + "# # only run following command once to create the experiment after the server has been started for the first time\n", + "# # client.create_experiment(name=\"Nightingale Bird Call Classification\", tags=experiment_tags)\n", + "# mlflow.set_experiment(\n", + "# experiment_name=\"/Workspace/Users/ephraim.eckl@posteo.de/nightingale\",\n", + "# experiment_id=\"2165278269360514\"\n", + "# )" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "f29e4b9e", + "metadata": {}, + "outputs": [ + { + "ename": "MissingConfigException", + "evalue": "Yaml file '/workspaces/nightingale/notebooks/mlruns/0/meta.yaml' does not exist.", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mMissingConfigException\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[28]\u001b[39m\u001b[32m, line 15\u001b[39m\n\u001b[32m 3\u001b[39m params = {\n\u001b[32m 4\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mnum_bird_classes\u001b[39m\u001b[33m\"\u001b[39m: num_of_bird_classes_in_dataset,\n\u001b[32m 5\u001b[39m \u001b[33m\"\u001b[39m\u001b[33moptimizer\u001b[39m\u001b[33m\"\u001b[39m: \u001b[33m\"\u001b[39m\u001b[33madam\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 11\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mearly_stopping_patience\u001b[39m\u001b[33m\"\u001b[39m: \u001b[32m3\u001b[39m,\n\u001b[32m 12\u001b[39m }\n\u001b[32m 14\u001b[39m \u001b[38;5;66;03m# Initiate the MLflow run context\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m15\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[43mmlflow\u001b[49m\u001b[43m.\u001b[49m\u001b[43mstart_run\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m run:\n\u001b[32m 16\u001b[39m \u001b[38;5;66;03m# Log the parameters used for the model fit\u001b[39;00m\n\u001b[32m 17\u001b[39m mlflow.log_params(params)\n\u001b[32m 19\u001b[39m \u001b[38;5;66;03m# Log the error metrics that were calculated during validation\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/fluent.py:475\u001b[39m, in \u001b[36mstart_run\u001b[39m\u001b[34m(run_id, experiment_id, run_name, nested, parent_run_id, tags, description, log_system_metrics)\u001b[39m\n\u001b[32m 471\u001b[39m user_specified_tags[MLFLOW_RUN_NAME] = run_name\n\u001b[32m 473\u001b[39m resolved_tags = context_registry.resolve_tags(user_specified_tags)\n\u001b[32m--> \u001b[39m\u001b[32m475\u001b[39m active_run_obj = \u001b[43mclient\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_run\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 476\u001b[39m \u001b[43m \u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43mexp_id_for_run\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 477\u001b[39m \u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m=\u001b[49m\u001b[43mresolved_tags\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 478\u001b[39m \u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 479\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 481\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m log_system_metrics \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 482\u001b[39m \u001b[38;5;66;03m# If `log_system_metrics` is not specified, we will check environment variable.\u001b[39;00m\n\u001b[32m 483\u001b[39m log_system_metrics = MLFLOW_ENABLE_SYSTEM_METRICS_LOGGING.get()\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/client.py:479\u001b[39m, in \u001b[36mMlflowClient.create_run\u001b[39m\u001b[34m(self, experiment_id, start_time, tags, run_name)\u001b[39m\n\u001b[32m 425\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mcreate_run\u001b[39m(\n\u001b[32m 426\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 427\u001b[39m experiment_id: \u001b[38;5;28mstr\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 430\u001b[39m run_name: \u001b[38;5;28mstr\u001b[39m | \u001b[38;5;28;01mNone\u001b[39;00m = \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m 431\u001b[39m ) -> Run:\n\u001b[32m 432\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 433\u001b[39m \u001b[33;03m Create a :py:class:`mlflow.entities.Run` object that can be associated with\u001b[39;00m\n\u001b[32m 434\u001b[39m \u001b[33;03m metrics, parameters, artifacts, etc.\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 477\u001b[39m \u001b[33;03m status: RUNNING\u001b[39;00m\n\u001b[32m 478\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m479\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_tracking_client\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_run\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstart_time\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/telemetry/track.py:30\u001b[39m, in \u001b[36mrecord_usage_event..decorator..wrapper\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 28\u001b[39m start_time = time.time()\n\u001b[32m 29\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m30\u001b[39m result = \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 31\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m result \u001b[38;5;66;03m# noqa: RET504\u001b[39;00m\n\u001b[32m 32\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m:\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/_tracking_service/client.py:183\u001b[39m, in \u001b[36mTrackingServiceClient.create_run\u001b[39m\u001b[34m(self, experiment_id, start_time, tags, run_name)\u001b[39m\n\u001b[32m 178\u001b[39m \u001b[38;5;66;03m# Extract user from tags\u001b[39;00m\n\u001b[32m 179\u001b[39m \u001b[38;5;66;03m# This logic is temporary; the user_id attribute of runs is deprecated and will be removed\u001b[39;00m\n\u001b[32m 180\u001b[39m \u001b[38;5;66;03m# in a later release.\u001b[39;00m\n\u001b[32m 181\u001b[39m user_id = tags.get(MLFLOW_USER, \u001b[33m\"\u001b[39m\u001b[33munknown\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m183\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mstore\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_run\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 184\u001b[39m \u001b[43m \u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 185\u001b[39m \u001b[43m \u001b[49m\u001b[43muser_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43muser_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 186\u001b[39m \u001b[43m \u001b[49m\u001b[43mstart_time\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstart_time\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mget_current_time_millis\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 187\u001b[39m \u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m=\u001b[49m\u001b[43m[\u001b[49m\u001b[43mRunTag\u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvalue\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvalue\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m.\u001b[49m\u001b[43mitems\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 188\u001b[39m \u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 189\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:689\u001b[39m, in \u001b[36mFileStore.create_run\u001b[39m\u001b[34m(self, experiment_id, user_id, start_time, tags, run_name)\u001b[39m\n\u001b[32m 685\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 686\u001b[39m \u001b[33;03mCreates a run with the specified attributes.\u001b[39;00m\n\u001b[32m 687\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 688\u001b[39m experiment_id = FileStore.DEFAULT_EXPERIMENT_ID \u001b[38;5;28;01mif\u001b[39;00m experiment_id \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m experiment_id\n\u001b[32m--> \u001b[39m\u001b[32m689\u001b[39m experiment = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mget_experiment\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 690\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m experiment \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 691\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MlflowException(\n\u001b[32m 692\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mCould not create run under experiment with ID \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m - no such \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 693\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mexperiment exists.\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 694\u001b[39m databricks_pb2.RESOURCE_DOES_NOT_EXIST,\n\u001b[32m 695\u001b[39m )\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:498\u001b[39m, in \u001b[36mFileStore.get_experiment\u001b[39m\u001b[34m(self, experiment_id)\u001b[39m\n\u001b[32m 487\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 488\u001b[39m \u001b[33;03mFetch the experiment.\u001b[39;00m\n\u001b[32m 489\u001b[39m \u001b[33;03mNote: This API will search for active as well as deleted experiments.\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 495\u001b[39m \u001b[33;03m A single Experiment object if it exists, otherwise raises an Exception.\u001b[39;00m\n\u001b[32m 496\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 497\u001b[39m experiment_id = FileStore.DEFAULT_EXPERIMENT_ID \u001b[38;5;28;01mif\u001b[39;00m experiment_id \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m experiment_id\n\u001b[32m--> \u001b[39m\u001b[32m498\u001b[39m experiment = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_get_experiment\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 499\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m experiment \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 500\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MlflowException(\n\u001b[32m 501\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mExperiment \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m does not exist.\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 502\u001b[39m databricks_pb2.RESOURCE_DOES_NOT_EXIST,\n\u001b[32m 503\u001b[39m )\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:466\u001b[39m, in \u001b[36mFileStore._get_experiment\u001b[39m\u001b[34m(self, experiment_id, view_type)\u001b[39m\n\u001b[32m 461\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m experiment_dir \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 462\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MlflowException(\n\u001b[32m 463\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mCould not find experiment with ID \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m,\n\u001b[32m 464\u001b[39m databricks_pb2.RESOURCE_DOES_NOT_EXIST,\n\u001b[32m 465\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m466\u001b[39m meta = \u001b[43mFileStore\u001b[49m\u001b[43m.\u001b[49m\u001b[43m_read_yaml\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_dir\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mFileStore\u001b[49m\u001b[43m.\u001b[49m\u001b[43mMETA_DATA_FILE_NAME\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 467\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m meta \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 468\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MissingConfigException(\n\u001b[32m 469\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mExperiment \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m is invalid with empty \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 470\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mFileStore.META_DATA_FILE_NAME\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m in directory \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_dir\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 471\u001b[39m )\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:1636\u001b[39m, in \u001b[36mFileStore._read_yaml\u001b[39m\u001b[34m(root, file_name, retries)\u001b[39m\n\u001b[32m 1633\u001b[39m time.sleep(\u001b[32m0.1\u001b[39m * (\u001b[32m3\u001b[39m - attempts_remaining))\n\u001b[32m 1634\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m _read_helper(root, file_name, attempts_remaining - \u001b[32m1\u001b[39m)\n\u001b[32m-> \u001b[39m\u001b[32m1636\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_read_helper\u001b[49m\u001b[43m(\u001b[49m\u001b[43mroot\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfile_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mattempts_remaining\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:1629\u001b[39m, in \u001b[36mFileStore._read_yaml.._read_helper\u001b[39m\u001b[34m(root, file_name, attempts_remaining)\u001b[39m\n\u001b[32m 1628\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m_read_helper\u001b[39m(root, file_name, attempts_remaining=\u001b[32m2\u001b[39m):\n\u001b[32m-> \u001b[39m\u001b[32m1629\u001b[39m result = \u001b[43mread_yaml\u001b[49m\u001b[43m(\u001b[49m\u001b[43mroot\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfile_name\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1630\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m result \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mor\u001b[39;00m attempts_remaining == \u001b[32m0\u001b[39m:\n\u001b[32m 1631\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m result\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/yaml_utils.py:107\u001b[39m, in \u001b[36mread_yaml\u001b[39m\u001b[34m(root, file_name)\u001b[39m\n\u001b[32m 105\u001b[39m file_path = os.path.join(root, file_name)\n\u001b[32m 106\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m exists(file_path):\n\u001b[32m--> \u001b[39m\u001b[32m107\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MissingConfigException(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mYaml file \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfile_path\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m does not exist.\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 108\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m codecs.open(file_path, mode=\u001b[33m\"\u001b[39m\u001b[33mr\u001b[39m\u001b[33m\"\u001b[39m, encoding=ENCODING) \u001b[38;5;28;01mas\u001b[39;00m yaml_file:\n\u001b[32m 109\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m yaml.load(yaml_file, Loader=YamlSafeLoader)\n", + "\u001b[31mMissingConfigException\u001b[39m: Yaml file '/workspaces/nightingale/notebooks/mlruns/0/meta.yaml' does not exist." + ] + } + ], + "source": [ + "# Assemble the metrics we're going to write into a collection\n", + "metrics = {\"Loss\": loss, \"Accuracy\": accuracy}\n", + "params = {\n", + " \"num_bird_classes\": num_of_bird_classes_in_dataset,\n", + " \"optimizer\": \"adam\",\n", + " \"loss_function\": \"SparseCategoricalCrossentropy\",\n", + " \"loss_from_logits\": True,\n", + " \"epochs\": len(history.epoch),\n", + " \"batch_size\": 32,\n", + " \"early_stopping_monitor\": \"loss\",\n", + " \"early_stopping_patience\": 3,\n", + "}\n", + "\n", + "# Initiate the MLflow run context\n", + "with mlflow.start_run() as run:\n", + " # Log the parameters used for the model fit\n", + " mlflow.log_params(params)\n", + "\n", + " # Log the error metrics that were calculated during validation\n", + " mlflow.log_metrics(metrics)\n", + "\n", + " # Take one batch from the dataset\n", + " x_batch, y_batch = next(iter(train_ds))\n", "\n", - "train_ds = train_ds.map(load_wav_for_map)\n", - "val_ds = val_ds.map(load_wav_for_map)\n", - "test_ds = test_ds.map(load_wav_for_map)" + " # Convert to numpy (MLflow expects numpy or tensor-like input, not a tf.data.Dataset)\n", + " sample_input = x_batch.numpy()\n", + " sample_output = bird_class_model.predict(sample_input)\n", + "\n", + " # Infer signature from data\n", + " signature = mlflow.models.infer_signature(sample_input, sample_output)\n", + "\n", + " print(\"Shape of input_example:\", sample_input.shape)\n", + " # Log an instance of the trained model for later use\n", + " model_info = mlflow.keras.log_model(model=bird_class_model, name = \"Bird-Call-Classifier-Head\", signature=signature, pip_requirements=['keras==3.10.0'], registered_model_name=\"nightingale-dev.default.Reg-Bird-Call-Classifier-Head\")\n", + "# # mlflow.sklearn.log_model(sk_model=rf, input_example=X_val, name=artifact_path)\n", + " " + ] + }, + { + "cell_type": "markdown", + "id": "52cc0920", + "metadata": {}, + "source": [ + "#### Run inference on a bird call audio sample (YAMNet + classifier head)" ] }, { "cell_type": "code", - "execution_count": 7, - "id": "5aca4873", + "execution_count": null, + "id": "1c293abf", "metadata": {}, "outputs": [], "source": [ - "yam = YamnetEmbedding()" + "# wav = load_wav_16k_mono(filtered_bird_df[filtered_bird_df['fold'] == 3]['filename'].values[1])\n", + "# scores, embeddings, spectrogram = model(wav)\n", + "# result = bird_class_model(embeddings).numpy()\n", + "\n", + "# inferred_class = bird_classes[result.mean(axis=0).argmax()]\n", + "# print(f'The main sound is: {inferred_class}')" ] }, { "cell_type": "code", - "execution_count": 8, - "id": "1852e16e", + "execution_count": null, + "id": "76a0540f", "metadata": {}, "outputs": [], "source": [ - "train_ds = train_ds.map(yam).unbatch()\n", - "val_ds = val_ds.map(yam).unbatch()\n", - "test_ds = test_ds.map(yam).unbatch()\n", - "train_ds.element_spec\n", - "\n", - "train_ds = train_ds.cache().shuffle(1000).batch(32).prefetch(tf.data.AUTOTUNE)\n", - "val_ds = val_ds.cache().batch(32).prefetch(tf.data.AUTOTUNE)\n", - "test_ds = test_ds.cache().batch(32).prefetch(tf.data.AUTOTUNE)" + "# bird_class_model.save('bird_classifier_head.keras')" ] } ], diff --git a/src/nightingale/data_pipeline/audio_dataset_splitter.py b/src/nightingale/data_pipeline/audio_dataset_splitter.py new file mode 100644 index 0000000..5ba997f --- /dev/null +++ b/src/nightingale/data_pipeline/audio_dataset_splitter.py @@ -0,0 +1,109 @@ +import tensorflow as tf +from sklearn.model_selection import train_test_split + +class AudioDatasetSplitter: + """ + Utility class to split a dataframe of audio file paths and labels into + TensorFlow datasets for training, validation and testing. + + Usage: + splitter = AudioDatasetSplitter(filename_col='filename', label_col='target', seed=42) + train_ds, val_ds, test_ds = splitter.build(df) + + Attributes: + filename_col: Name of the dataframe column containing the audio file path. + label_col: Name of the dataframe column containing the class label. + seed: Random seed used for reproducible train/val/test splits. + df: Internal copy of the dataframe provided to build(). + train_ds, val_ds, test_ds: tf.data.Dataset objects produced by build(). + """ + + def __init__(self, filename_col='filename', label_col='target', seed=42): + # Column names and RNG seed configuration + self.filename_col = filename_col + self.label_col = label_col + self.seed = seed + # Placeholder for the dataframe once build() is called + self.df = None + + def build(self, df): + """ + Create train/validation/test splits and return corresponding tf.data.Datasets. + + The function: + - makes an internal copy of the provided dataframe, + - performs a stratified split (60% train, 20% val, 20% test), + - annotates the dataframe with a 'fold' column (1=train, 2=val, 3=test), + - builds and returns datasets for each fold. + + Args: + df: pandas.DataFrame containing at least filename_col and label_col. + + Returns: + (train_ds, val_ds, test_ds): tuple of tf.data.Dataset objects where each + yielded element is (wav_tensor, label). + """ + # Work on a copy to avoid mutating caller's dataframe + self.df = df.copy() + + # Split indices: first into train (60%) and temp (40%), then split temp into val/test evenly. + train_idx, temp_idx = train_test_split( + self.df.index, test_size=0.4, random_state=self.seed, stratify=self.df[self.label_col] + ) + val_idx, test_idx = train_test_split( + temp_idx, test_size=0.5, random_state=self.seed, stratify=self.df.loc[temp_idx, self.label_col] + ) + + # Annotate the dataframe with fold labels for later selection + self.df['fold'] = '' + self.df.loc[train_idx, 'fold'] = 1 + self.df.loc[val_idx, 'fold'] = 2 + self.df.loc[test_idx, 'fold'] = 3 + + # Build tf.data.Datasets for each fold + self.train_ds = self._build_dataset(1) + self.val_ds = self._build_dataset(2) + self.test_ds = self._build_dataset(3) + + return self.train_ds, self.val_ds, self.test_ds + + def _build_dataset(self, fold): + """ + Construct a tf.data.Dataset for a given fold. + + The dataset is created from the filename and label columns and mapped through + _load_wav to decode audio files into waveform tensors. + + Args: + fold: integer 1/2/3 selecting train/val/test subset. + + Returns: + A tf.data.Dataset yielding (wav_tensor, label). + """ + subset = self.df[self.df['fold'] == fold] + ds = tf.data.Dataset.from_tensor_slices( + (subset[self.filename_col].to_numpy(), subset[self.label_col].to_numpy()) + ) + # Map the dataset to load and decode the wav files + return ds.map(self._load_wav) + + @staticmethod + def _load_wav(filename, label): + """ + Read and decode a WAV file into a mono waveform tensor. + + Uses tf.io.read_file + tf.audio.decode_wav to load the file, squeezes the + channel dimension so the returned tensor has shape [num_samples]. + + Args: + filename: path to the audio file (string tensor). + label: associated label. + + Returns: + (wav, label): tuple where wav is a 1-D float32 tensor and label is unchanged. + """ + audio = tf.io.read_file(filename) + wav, sr = tf.audio.decode_wav(audio, desired_channels=1) + # Remove the trailing channel dimension -> shape [num_samples] + wav = tf.squeeze(wav, axis=-1) + return wav, label diff --git a/src/nightingale/data_pipeline/audio_preprocessor.py b/src/nightingale/data_pipeline/audio_preprocessor.py index 0e146f6..87dc93d 100644 --- a/src/nightingale/data_pipeline/audio_preprocessor.py +++ b/src/nightingale/data_pipeline/audio_preprocessor.py @@ -4,37 +4,136 @@ import numpy as np class AudioPreprocessor: + """ + Helper for loading, converting, resampling and saving audio files to a + format suitable for YAMNet (16 kHz mono WAV by default). + + Responsibilities: + - Check whether a file already matches the target format (is_yamnet_ready) + - Load an audio file, resampling/mono-converting when necessary (load_audio) + - Write a waveform to disk as WAV, creating parent folders if needed (save_wav) + - Process a single file, skipping if already processed (process_file) + - Walk an input folder tree and process all supported audio files while + preserving folder structure under an output root (process_folder) + + The class intentionally does not alter the audio data beyond resampling + and channel conversion. It returns/accepts numpy float32 waveforms and + uses soundfile for saving to ensure stable WAV output. + """ + def __init__(self, target_sr=16000, mono=True): + # Target sample rate for YAMNet and whether to force mono output. self.target_sr = target_sr self.mono = mono def is_yamnet_ready(self, file_path): - """Check if audio file is already in correct format.""" + """ + Quick check whether the given file is already a WAV with the target + sample rate and (optionally) a single channel. + + Returns: + True when the file is a .wav with sample rate == target_sr and, + if mono==True, has 1 channel. False for any error or mismatch. + """ try: - # Read audio info + # Use soundfile to inspect headers without decoding entire file. with sf.SoundFile(file_path) as f: sr = f.samplerate channels = f.channels ext = os.path.splitext(file_path)[1].lower() - + # Match extension, sample rate and channel count (if required). return ext == ".wav" and sr == self.target_sr and (channels == 1 if self.mono else True) - except RuntimeError: - # Can't read file + except: + # If file can't be opened or inspected, treat as not-ready. return False def load_audio(self, file_path): - """Load audio and convert if necessary""" + """ + Load audio into a numpy float32 waveform. + + If the file is already YAMNet-ready (checked by is_yamnet_ready) the + function loads it without resampling to keep original samples when + possible. Otherwise it forces resampling to target_sr and mono according + to the object configuration. + + Returns: + (wav, sr) where wav is a 1-D numpy.float32 array and sr == target_sr. + """ + # If file already matches the desired format, load raw (no resample). if self.is_yamnet_ready(file_path): - # Already ready, load directly - waveform, sr = librosa.load(file_path, sr=None, mono=self.mono) + wav, sr = librosa.load(file_path, sr=None, mono=self.mono) else: - # Load and resample/convert - waveform, sr = librosa.load(file_path, sr=self.target_sr, mono=self.mono) - - waveform = waveform.astype(np.float32) - return waveform, sr + # Force conversion/resampling to target sample rate and channel config. + wav, sr = librosa.load(file_path, sr=self.target_sr, mono=self.mono) + # Ensure dtype is float32 which downstream models expect. + return wav.astype(np.float32), self.target_sr def save_wav(self, waveform, sr, output_path): + """ + Save a numpy waveform to disk as a WAV file. + + Ensures parent directories exist before writing. + """ + os.makedirs(os.path.dirname(output_path), exist_ok=True) sf.write(output_path, waveform, sr) + def process_file(self, input_file, output_file): + """ + Convert and save a single input file to the output path. + + Behavior: + - If output_file already exists, skip processing. + - Otherwise load (and convert/resample if needed) and save as WAV. + - Prints simple status messages; exceptions are caught and printed. + """ + if os.path.exists(output_file): + print(f"Skipped (already exists): {output_file}") + return + + try: + wav, sr = self.load_audio(input_file) + self.save_wav(wav, sr, output_file) + print(f"Processed: {output_file}") + except Exception as e: + # Do not raise here; just report the problem and continue processing other files. + print(f"Error processing {input_file}: {e}") + + def process_folder(self, input_root, output_root, max_folders=None): + """ + Recursively process supported audio files under input_root and write + converted files under output_root while preserving relative paths. + + Args: + input_root: top-level folder to traverse. + output_root: destination root where converted files will be placed. + max_folders: optional int to limit number of top-level subfolders processed. + + Notes: + - Only files with extensions (ogg, wav, mp3, flac) are processed. + - The folder traversal preserves the input folder structure relative to input_root. + """ + # Collect immediate subfolders under the input root (sorted for determinism). + subfolders = sorted( + [os.path.join(input_root, d) for d in os.listdir(input_root) + if os.path.isdir(os.path.join(input_root, d))] + ) + + # Optionally limit the number of subfolders to process. + if max_folders is not None: + subfolders = subfolders[:max_folders] + + print(f"Processing {len(subfolders)} folders") + + # Walk each selected subfolder recursively and process supported files. + for folder in subfolders: + for dirpath, _, filenames in os.walk(folder): + for filename in filenames: + if filename.lower().endswith((".ogg", ".wav", ".mp3", ".flac")): + in_path = os.path.join(dirpath, filename) + + # Build output path that mirrors the input structure and ensures .wav extension. + rel_path = os.path.relpath(in_path, input_root) + rel_path = os.path.splitext(rel_path)[0] + ".wav" + out_path = os.path.join(output_root, rel_path) + self.process_file(in_path, out_path) diff --git a/src/nightingale/data_pipeline/filter_birdclef_data.py b/src/nightingale/data_pipeline/filter_birdclef_data.py index a8e5aca..e05835c 100644 --- a/src/nightingale/data_pipeline/filter_birdclef_data.py +++ b/src/nightingale/data_pipeline/filter_birdclef_data.py @@ -2,30 +2,42 @@ import os import pandas as pd -def load_birdclef_metadata(base_data_path="../data/birdclef-2024"): +def load_birdclef_metadata(metadata_path="../data/birdclef-2024/train_metadata.csv", + audio_root="../data/birdclef-2024/train_audio_16"): + """ + Load and filter BirdClef metadata to include only wav files present under audio_root. - # Read train meta data - base_data_path = "../data/birdclef-2024" - bird_metadata_path = os.path.join(base_data_path, "train_metadata.csv") - bird_df = pd.read_csv(bird_metadata_path) + Args: + metadata_path: Path to the CSV metadata file (e.g. ../data/birdclef-2024/train_metadata.csv). + audio_root: Root folder containing audio files (e.g. ../data/birdclef-2024/train_audio_16). - # Change the filename endings from .ogg to .wav in the filename column of bird_df + Returns: + Tuple (filtered_bird_df, num_of_bird_classes_in_dataset) + - filtered_bird_df: DataFrame with absolute paths in the 'filename' column and a 'target' column. + - num_of_bird_classes_in_dataset: int count of unique bird classes present in the filtered set. + """ + + # Read metadata CSV + bird_df = pd.read_csv(metadata_path) + + # Change the filename endings from .ogg to .wav in the filename column bird_df['filename'] = bird_df['filename'].str.replace('.ogg', '.wav', regex=False) - # Show rows where the filename matches the pattern "cohcuc1/*.wav" - wav_files = glob.glob(base_data_path + "/train_audio_16/**/*.wav", recursive=True) - wav_files = [f.replace(base_data_path + "/train_audio_16/", "") for f in wav_files] + # Find all wav files under audio_root and convert to relative paths for matching against metadata + wav_paths = glob.glob(os.path.join(audio_root, "**", "*.wav"), recursive=True) + wav_rel = [os.path.relpath(p, audio_root) for p in wav_paths] - filtered_bird_df = bird_df[bird_df['filename'].isin(wav_files)] + filtered_bird_df = bird_df[bird_df['filename'].isin(wav_rel)] bird_classes = list(set(filtered_bird_df['common_name'])) + num_of_bird_classes_in_dataset = len(bird_classes) map_class_to_id = {name: idx for idx, name in enumerate(bird_classes)} - class_id = filtered_bird_df['common_name'].apply(lambda name: map_class_to_id[name]) filtered_bird_df = filtered_bird_df.assign(target=class_id) - full_path = filtered_bird_df['filename'].apply(lambda row: os.path.join(base_data_path + "/train_audio_16/", row)) + # Convert filenames to absolute paths under audio_root + full_path = filtered_bird_df['filename'].apply(lambda row: os.path.join(audio_root, row)) filtered_bird_df = filtered_bird_df.assign(filename=full_path) - return filtered_bird_df + return filtered_bird_df, num_of_bird_classes_in_dataset From 4d40a21afceed9b8822eea1e3ccdcd1785bc597d Mon Sep 17 00:00:00 2001 From: David Pellhammer Date: Mon, 24 Nov 2025 14:28:36 +0000 Subject: [PATCH 04/11] tested on mlflow serve --- notebooks/train_nightingale_2.ipynb | 329 +++++++++++++++++----------- 1 file changed, 206 insertions(+), 123 deletions(-) diff --git a/notebooks/train_nightingale_2.ipynb b/notebooks/train_nightingale_2.ipynb index 42057fc..cc77884 100644 --- a/notebooks/train_nightingale_2.ipynb +++ b/notebooks/train_nightingale_2.ipynb @@ -2,10 +2,19 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "a9cd6428", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/workspaces/nightingale/.venv/lib/python3.11/site-packages/tensorflow_hub/__init__.py:61: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.\n", + " from pkg_resources import parse_version\n" + ] + } + ], "source": [ "import pandas as pd\n", "import os\n", @@ -26,7 +35,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 2, "id": "d504fa73", "metadata": {}, "outputs": [ @@ -100,7 +109,7 @@ "type": "string" } ], - "ref": "0a5db620-a593-46c2-9c9f-81c8ec8288f5", + "ref": "57c29a60-d75b-40c7-bee9-0b3206ecdfab", "rows": [ [ "0", @@ -333,7 +342,7 @@ "4 https://www.xeno-canto.org/209218 asbfly/XC209218.ogg " ] }, - "execution_count": 16, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -347,7 +356,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 3, "id": "71495869", "metadata": {}, "outputs": [ @@ -376,7 +385,7 @@ "type": "float" } ], - "ref": "f13f021b-6565-4f04-81d6-545ab79db622", + "ref": "afa68c35-7943-4d34-8436-46b7df73b427", "rows": [ [ "count", @@ -521,7 +530,7 @@ "max 71.964000 177.447800 5.000000" ] }, - "execution_count": 17, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -540,7 +549,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "b9c56857", "metadata": {}, "outputs": [ @@ -595,7 +604,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "6ef7c047", "metadata": {}, "outputs": [ @@ -626,7 +635,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 6, "id": "62a4886f", "metadata": {}, "outputs": [], @@ -647,7 +656,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 7, "id": "5aca4873", "metadata": {}, "outputs": [], @@ -658,7 +667,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 8, "id": "1852e16e", "metadata": {}, "outputs": [], @@ -683,18 +692,18 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 9, "id": "c1b433b4", "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
Model: \"classifier_head_1\"\n",
+       "
Model: \"classifier_head\"\n",
        "
\n" ], "text/plain": [ - "\u001b[1mModel: \"classifier_head_1\"\u001b[0m\n" + "\u001b[1mModel: \"classifier_head\"\u001b[0m\n" ] }, "metadata": {}, @@ -706,9 +715,9 @@ "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
        "┃ Layer (type)                     Output Shape                  Param # ┃\n",
        "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
-       "│ dense_2 (Dense)                 │ ?                      │   0 (unbuilt) │\n",
+       "│ dense (Dense)                   │ ?                      │   0 (unbuilt) │\n",
        "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
-       "│ dense_3 (Dense)                 │ ?                      │   0 (unbuilt) │\n",
+       "│ dense_1 (Dense)                 │ ?                      │   0 (unbuilt) │\n",
        "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
        "
\n" ], @@ -716,9 +725,9 @@ "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n", "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n", "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n", - "│ dense_2 (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", + "│ dense (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", - "│ dense_3 (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", + "│ dense_1 (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", "└─────────────────────────────────┴────────────────────────┴───────────────┘\n" ] }, @@ -773,7 +782,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 10, "id": "3c380b83", "metadata": {}, "outputs": [], @@ -805,7 +814,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 11, "id": "5256d5fc", "metadata": {}, "outputs": [ @@ -828,13 +837,15 @@ "name": "stdout", "output_type": "stream", "text": [ - " 17/Unknown \u001b[1m3s\u001b[0m 3ms/step - accuracy: 0.7222 - loss: 0.6694" + " 1/Unknown \u001b[1m2s\u001b[0m 2s/step - accuracy: 0.1875 - loss: 1.1980" ] }, { "name": "stderr", "output_type": "stream", "text": [ + "2025-11-24 14:23:38.498667: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n", "/workspaces/nightingale/.venv/lib/python3.11/site-packages/keras/src/trainers/epoch_iterator.py:164: UserWarning: Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least `steps_per_epoch * epochs` batches. You may need to use the `.repeat()` function when building your dataset.\n", " self._interrupted_warning()\n" ] @@ -843,44 +854,55 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 33ms/step - accuracy: 0.8949 - loss: 0.3259 - val_accuracy: 0.9314 - val_loss: 0.1980\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 50ms/step - accuracy: 0.8603 - loss: 0.3829 - val_accuracy: 0.9339 - val_loss: 0.2406\n", "Epoch 2/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9639 - loss: 0.1086 - val_accuracy: 0.9346 - val_loss: 0.2097\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9622 - loss: 0.1107 - val_accuracy: 0.9392 - val_loss: 0.2304\n", "Epoch 3/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9851 - loss: 0.0609 - val_accuracy: 0.9477 - val_loss: 0.1863\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9796 - loss: 0.0668 - val_accuracy: 0.9365 - val_loss: 0.2341\n", "Epoch 4/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9894 - loss: 0.0448 - val_accuracy: 0.9281 - val_loss: 0.1908\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9927 - loss: 0.0427 - val_accuracy: 0.9259 - val_loss: 0.1934\n", "Epoch 5/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9894 - loss: 0.0353 - val_accuracy: 0.9412 - val_loss: 0.1769\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9956 - loss: 0.0279 - val_accuracy: 0.9206 - val_loss: 0.2071\n", "Epoch 6/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9958 - loss: 0.0231 - val_accuracy: 0.9379 - val_loss: 0.1791\n", + "\u001b[1m 1/22\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0145" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2025-11-24 14:23:39.498318: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n", + "2025-11-24 14:23:39.550032: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n", + "2025-11-24 14:23:39.644102: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9985 - loss: 0.0209 - val_accuracy: 0.9101 - val_loss: 0.2173\n", "Epoch 7/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9968 - loss: 0.0205 - val_accuracy: 0.9379 - val_loss: 0.2042\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9985 - loss: 0.0160 - val_accuracy: 0.9074 - val_loss: 0.2412\n", "Epoch 8/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9968 - loss: 0.0138 - val_accuracy: 0.9346 - val_loss: 0.2004\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0119 - val_accuracy: 0.9180 - val_loss: 0.2225\n", "Epoch 9/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0092 - val_accuracy: 0.9346 - val_loss: 0.1922\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0084 - val_accuracy: 0.9021 - val_loss: 0.2290\n", "Epoch 10/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0067 - val_accuracy: 0.9379 - val_loss: 0.2078\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0067 - val_accuracy: 0.9206 - val_loss: 0.2191\n", "Epoch 11/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0054 - val_accuracy: 0.9379 - val_loss: 0.1982\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0056 - val_accuracy: 0.9127 - val_loss: 0.2259\n", "Epoch 12/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0042 - val_accuracy: 0.9346 - val_loss: 0.2054\n", - "Epoch 13/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0036 - val_accuracy: 0.9314 - val_loss: 0.2117\n", - "Epoch 14/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0035 - val_accuracy: 0.9346 - val_loss: 0.2153\n", - "Epoch 15/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0028 - val_accuracy: 0.9346 - val_loss: 0.2203\n", - "Epoch 16/20\n", - "\u001b[1m 1/30\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0012" + "\u001b[1m 1/22\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m0s\u001b[0m 5ms/step - accuracy: 1.0000 - loss: 0.0054" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "2025-11-24 13:16:18.535927: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "2025-11-24 14:23:39.840078: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", "\t [[{{node IteratorGetNext}}]]\n" ] }, @@ -888,15 +910,31 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0023 - val_accuracy: 0.9346 - val_loss: 0.2200\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0046 - val_accuracy: 0.9153 - val_loss: 0.2285\n", + "Epoch 13/20\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0042 - val_accuracy: 0.9021 - val_loss: 0.2493\n", + "Epoch 14/20\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0033 - val_accuracy: 0.9127 - val_loss: 0.2401\n", + "Epoch 15/20\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0029 - val_accuracy: 0.9101 - val_loss: 0.2409\n", + "Epoch 16/20\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0025 - val_accuracy: 0.9153 - val_loss: 0.2423\n", "Epoch 17/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0020 - val_accuracy: 0.9346 - val_loss: 0.2270\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0022 - val_accuracy: 0.9048 - val_loss: 0.2589\n", "Epoch 18/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0018 - val_accuracy: 0.9346 - val_loss: 0.2288\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0019 - val_accuracy: 0.9101 - val_loss: 0.2519\n", "Epoch 19/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0016 - val_accuracy: 0.9379 - val_loss: 0.2358\n", + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0017 - val_accuracy: 0.9048 - val_loss: 0.2602\n", "Epoch 20/20\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0014 - val_accuracy: 0.9346 - val_loss: 0.2310\n" + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0015 - val_accuracy: 0.9101 - val_loss: 0.2594\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2025-11-24 14:23:40.261067: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n" ] } ], @@ -917,7 +955,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 12, "id": "bd931dfe", "metadata": {}, "outputs": [ @@ -925,23 +963,9 @@ "name": "stdout", "output_type": "stream", "text": [ - " 7/Unknown \u001b[1m1s\u001b[0m 43ms/step - accuracy: 0.6563 - loss: 1.0617" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2025-11-24 13:14:27.048688: W external/local_xla/xla/tsl/framework/cpu_allocator_impl.cc:84] Allocation of 82182144 exceeds 10% of free system memory.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1m17/17\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 67ms/step - accuracy: 0.8421 - loss: 0.6074\n", - "Loss: 0.6073823571205139\n", - "Accuracy: 0.8421052694320679\n" + "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 62ms/step - accuracy: 0.8218 - loss: 0.5900\n", + "Loss: 0.5899819731712341\n", + "Accuracy: 0.8218390941619873\n" ] } ], @@ -962,42 +986,20 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": null, "id": "ba9a394a", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "# import mlflow\n", - "# from mlflow import MlflowClient\n", - "\n", - "# TRACKING_URI_LOCAL = \"http://host.docker.internal:5757\"\n", - "\n", - "# client = MlflowClient(tracking_uri=TRACKING_URI_LOCAL)\n", - "\n", "import mlflow\n", - "# from mlflow import MlflowClient\n", - "\n", - "# At the beginning of your Python script\n", - "from dotenv import load_dotenv\n", "\n", - "# Load environment variables from .env file\n", - "load_dotenv()" + "mlflow.set_tracking_uri(\"http://0.0.0.0:5000\")\n", + "\n" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 14, "id": "5c8283f2", "metadata": {}, "outputs": [ @@ -1005,8 +1007,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Env: None\n", - "From MLflow: file:///workspaces/nightingale/notebooks/mlruns\n" + "Env: http://host.docker.internal:5757\n", + "From MLflow: http://host.docker.internal:5757\n" ] } ], @@ -1027,53 +1029,134 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "id": "1c1d179a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING:urllib3.connectionpool:Retrying (Retry(total=6, connect=6, read=7, redirect=7, status=7)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno 101] Network is unreachable')': /api/2.0/mlflow/experiments/get-by-name?experiment_name=nightingale\n", + "WARNING:urllib3.connectionpool:Retrying (Retry(total=5, connect=5, read=7, redirect=7, status=7)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno 101] Network is unreachable')': /api/2.0/mlflow/experiments/get-by-name?experiment_name=nightingale\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mOSError\u001b[39m Traceback (most recent call last)", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:198\u001b[39m, in \u001b[36mHTTPConnection._new_conn\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 197\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m198\u001b[39m sock = \u001b[43mconnection\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_connection\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 199\u001b[39m \u001b[43m \u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_dns_host\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mport\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 200\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 201\u001b[39m \u001b[43m \u001b[49m\u001b[43msource_address\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msource_address\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 202\u001b[39m \u001b[43m \u001b[49m\u001b[43msocket_options\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msocket_options\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 203\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 204\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m socket.gaierror \u001b[38;5;28;01mas\u001b[39;00m e:\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/connection.py:85\u001b[39m, in \u001b[36mcreate_connection\u001b[39m\u001b[34m(address, timeout, source_address, socket_options)\u001b[39m\n\u001b[32m 84\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m85\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m err\n\u001b[32m 86\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 87\u001b[39m \u001b[38;5;66;03m# Break explicitly a reference cycle\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/connection.py:73\u001b[39m, in \u001b[36mcreate_connection\u001b[39m\u001b[34m(address, timeout, source_address, socket_options)\u001b[39m\n\u001b[32m 72\u001b[39m sock.bind(source_address)\n\u001b[32m---> \u001b[39m\u001b[32m73\u001b[39m \u001b[43msock\u001b[49m\u001b[43m.\u001b[49m\u001b[43mconnect\u001b[49m\u001b[43m(\u001b[49m\u001b[43msa\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 74\u001b[39m \u001b[38;5;66;03m# Break explicitly a reference cycle\u001b[39;00m\n", + "\u001b[31mOSError\u001b[39m: [Errno 101] Network is unreachable", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[31mNewConnectionError\u001b[39m Traceback (most recent call last)", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:787\u001b[39m, in \u001b[36mHTTPConnectionPool.urlopen\u001b[39m\u001b[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[39m\n\u001b[32m 786\u001b[39m \u001b[38;5;66;03m# Make the request on the HTTPConnection object\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m787\u001b[39m response = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_make_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 788\u001b[39m \u001b[43m \u001b[49m\u001b[43mconn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 789\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 790\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 791\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout_obj\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 792\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 793\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 794\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 795\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 796\u001b[39m \u001b[43m \u001b[49m\u001b[43mresponse_conn\u001b[49m\u001b[43m=\u001b[49m\u001b[43mresponse_conn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 797\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 798\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 799\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mresponse_kw\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 800\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 802\u001b[39m \u001b[38;5;66;03m# Everything went great!\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:493\u001b[39m, in \u001b[36mHTTPConnectionPool._make_request\u001b[39m\u001b[34m(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)\u001b[39m\n\u001b[32m 492\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m493\u001b[39m \u001b[43mconn\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 494\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 495\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 496\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 497\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 498\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 499\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 500\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 501\u001b[39m \u001b[43m \u001b[49m\u001b[43menforce_content_length\u001b[49m\u001b[43m=\u001b[49m\u001b[43menforce_content_length\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 502\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 504\u001b[39m \u001b[38;5;66;03m# We are swallowing BrokenPipeError (errno.EPIPE) since the server is\u001b[39;00m\n\u001b[32m 505\u001b[39m \u001b[38;5;66;03m# legitimately able to close the connection after sending a valid response.\u001b[39;00m\n\u001b[32m 506\u001b[39m \u001b[38;5;66;03m# With this behaviour, the received response is still readable.\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:494\u001b[39m, in \u001b[36mHTTPConnection.request\u001b[39m\u001b[34m(self, method, url, body, headers, chunked, preload_content, decode_content, enforce_content_length)\u001b[39m\n\u001b[32m 493\u001b[39m \u001b[38;5;28mself\u001b[39m.putheader(header, value)\n\u001b[32m--> \u001b[39m\u001b[32m494\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mendheaders\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 496\u001b[39m \u001b[38;5;66;03m# If we're given a body we start sending that in chunks.\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/http/client.py:1298\u001b[39m, in \u001b[36mHTTPConnection.endheaders\u001b[39m\u001b[34m(self, message_body, encode_chunked)\u001b[39m\n\u001b[32m 1297\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m CannotSendHeader()\n\u001b[32m-> \u001b[39m\u001b[32m1298\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_send_output\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmessage_body\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mencode_chunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mencode_chunked\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/http/client.py:1058\u001b[39m, in \u001b[36mHTTPConnection._send_output\u001b[39m\u001b[34m(self, message_body, encode_chunked)\u001b[39m\n\u001b[32m 1057\u001b[39m \u001b[38;5;28;01mdel\u001b[39;00m \u001b[38;5;28mself\u001b[39m._buffer[:]\n\u001b[32m-> \u001b[39m\u001b[32m1058\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmsg\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1060\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m message_body \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 1061\u001b[39m \n\u001b[32m 1062\u001b[39m \u001b[38;5;66;03m# create a consistent interface to message_body\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/http/client.py:996\u001b[39m, in \u001b[36mHTTPConnection.send\u001b[39m\u001b[34m(self, data)\u001b[39m\n\u001b[32m 995\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.auto_open:\n\u001b[32m--> \u001b[39m\u001b[32m996\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mconnect\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 997\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:325\u001b[39m, in \u001b[36mHTTPConnection.connect\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 324\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mconnect\u001b[39m(\u001b[38;5;28mself\u001b[39m) -> \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m325\u001b[39m \u001b[38;5;28mself\u001b[39m.sock = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_new_conn\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 326\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._tunnel_host:\n\u001b[32m 327\u001b[39m \u001b[38;5;66;03m# If we're tunneling it means we're connected to our proxy.\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:213\u001b[39m, in \u001b[36mHTTPConnection._new_conn\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 212\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[32m--> \u001b[39m\u001b[32m213\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m NewConnectionError(\n\u001b[32m 214\u001b[39m \u001b[38;5;28mself\u001b[39m, \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mFailed to establish a new connection: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00me\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m\n\u001b[32m 215\u001b[39m ) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01me\u001b[39;00m\n\u001b[32m 217\u001b[39m sys.audit(\u001b[33m\"\u001b[39m\u001b[33mhttp.client.connect\u001b[39m\u001b[33m\"\u001b[39m, \u001b[38;5;28mself\u001b[39m, \u001b[38;5;28mself\u001b[39m.host, \u001b[38;5;28mself\u001b[39m.port)\n", + "\u001b[31mNewConnectionError\u001b[39m: : Failed to establish a new connection: [Errno 101] Network is unreachable", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[31mKeyboardInterrupt\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[15]\u001b[39m\u001b[32m, line 12\u001b[39m\n\u001b[32m 5\u001b[39m experiment_tags = {\n\u001b[32m 6\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mproject_name\u001b[39m\u001b[33m\"\u001b[39m: \u001b[33m\"\u001b[39m\u001b[33mnightingale\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 7\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mmlflow.note.content\u001b[39m\u001b[33m\"\u001b[39m: experiment_description,\n\u001b[32m 8\u001b[39m }\n\u001b[32m 10\u001b[39m \u001b[38;5;66;03m# only run following command once to create the experiment after the server has been started for the first time\u001b[39;00m\n\u001b[32m 11\u001b[39m \u001b[38;5;66;03m# client.create_experiment(name=\"Nightingale Bird Call Classification\", tags=experiment_tags)\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m12\u001b[39m \u001b[43mmlflow\u001b[49m\u001b[43m.\u001b[49m\u001b[43mset_experiment\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 13\u001b[39m \u001b[43m \u001b[49m\u001b[43mexperiment_name\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mnightingale\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\n\u001b[32m 14\u001b[39m \u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/fluent.py:184\u001b[39m, in \u001b[36mset_experiment\u001b[39m\u001b[34m(experiment_name, experiment_id)\u001b[39m\n\u001b[32m 182\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m _experiment_lock:\n\u001b[32m 183\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m experiment_id \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m184\u001b[39m experiment = \u001b[43mclient\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget_experiment_by_name\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_name\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 185\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m experiment:\n\u001b[32m 186\u001b[39m _logger.info(\n\u001b[32m 187\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mExperiment with name \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m does not exist. Creating a new experiment.\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 188\u001b[39m experiment_name,\n\u001b[32m 189\u001b[39m )\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/_tracking_service/client.py:280\u001b[39m, in \u001b[36mTrackingServiceClient.get_experiment_by_name\u001b[39m\u001b[34m(self, name)\u001b[39m\n\u001b[32m 272\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mget_experiment_by_name\u001b[39m(\u001b[38;5;28mself\u001b[39m, name):\n\u001b[32m 273\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 274\u001b[39m \u001b[33;03m Args:\u001b[39;00m\n\u001b[32m 275\u001b[39m \u001b[33;03m name: The experiment name.\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 278\u001b[39m \u001b[33;03m :py:class:`mlflow.entities.Experiment`\u001b[39;00m\n\u001b[32m 279\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m280\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mstore\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget_experiment_by_name\u001b[49m\u001b[43m(\u001b[49m\u001b[43mname\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/rest_store.py:827\u001b[39m, in \u001b[36mRestStore.get_experiment_by_name\u001b[39m\u001b[34m(self, experiment_name)\u001b[39m\n\u001b[32m 825\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 826\u001b[39m req_body = message_to_json(GetExperimentByName(experiment_name=experiment_name))\n\u001b[32m--> \u001b[39m\u001b[32m827\u001b[39m response_proto = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_call_endpoint\u001b[49m\u001b[43m(\u001b[49m\u001b[43mGetExperimentByName\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreq_body\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 828\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m Experiment.from_proto(response_proto.experiment)\n\u001b[32m 829\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m MlflowException \u001b[38;5;28;01mas\u001b[39;00m e:\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/rest_store.py:201\u001b[39m, in \u001b[36mRestStore._call_endpoint\u001b[39m\u001b[34m(self, api, json_body, endpoint, retry_timeout_seconds, response_proto)\u001b[39m\n\u001b[32m 199\u001b[39m endpoint, method = \u001b[38;5;28mself\u001b[39m._METHOD_TO_INFO[api]\n\u001b[32m 200\u001b[39m response_proto = response_proto \u001b[38;5;129;01mor\u001b[39;00m api.Response()\n\u001b[32m--> \u001b[39m\u001b[32m201\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mcall_endpoint\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 202\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mget_host_creds\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 203\u001b[39m \u001b[43m \u001b[49m\u001b[43mendpoint\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 204\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 205\u001b[39m \u001b[43m \u001b[49m\u001b[43mjson_body\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 206\u001b[39m \u001b[43m \u001b[49m\u001b[43mresponse_proto\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 207\u001b[39m \u001b[43m \u001b[49m\u001b[43mretry_timeout_seconds\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretry_timeout_seconds\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 208\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/rest_utils.py:587\u001b[39m, in \u001b[36mcall_endpoint\u001b[39m\u001b[34m(host_creds, endpoint, method, json_body, response_proto, extra_headers, retry_timeout_seconds)\u001b[39m\n\u001b[32m 585\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m method == \u001b[33m\"\u001b[39m\u001b[33mGET\u001b[39m\u001b[33m\"\u001b[39m:\n\u001b[32m 586\u001b[39m call_kwargs[\u001b[33m\"\u001b[39m\u001b[33mparams\u001b[39m\u001b[33m\"\u001b[39m] = json_body\n\u001b[32m--> \u001b[39m\u001b[32m587\u001b[39m response = \u001b[43mhttp_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mcall_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 588\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 589\u001b[39m call_kwargs[\u001b[33m\"\u001b[39m\u001b[33mjson\u001b[39m\u001b[33m\"\u001b[39m] = json_body\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/rest_utils.py:232\u001b[39m, in \u001b[36mhttp_request\u001b[39m\u001b[34m(host_creds, endpoint, method, max_retries, backoff_factor, backoff_jitter, extra_headers, retry_codes, timeout, raise_on_status, respect_retry_after_header, retry_timeout_seconds, **kwargs)\u001b[39m\n\u001b[32m 229\u001b[39m kwargs[\u001b[33m\"\u001b[39m\u001b[33mauth\u001b[39m\u001b[33m\"\u001b[39m] = fetch_auth(host_creds.auth)\n\u001b[32m 231\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m232\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_get_http_response_with_retries\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 233\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 234\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 235\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_retries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 236\u001b[39m \u001b[43m \u001b[49m\u001b[43mbackoff_factor\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 237\u001b[39m \u001b[43m \u001b[49m\u001b[43mbackoff_jitter\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 238\u001b[39m \u001b[43m \u001b[49m\u001b[43mretry_codes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 239\u001b[39m \u001b[43m \u001b[49m\u001b[43mraise_on_status\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 240\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 241\u001b[39m \u001b[43m \u001b[49m\u001b[43mverify\u001b[49m\u001b[43m=\u001b[49m\u001b[43mhost_creds\u001b[49m\u001b[43m.\u001b[49m\u001b[43mverify\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 242\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 243\u001b[39m \u001b[43m \u001b[49m\u001b[43mrespect_retry_after_header\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrespect_retry_after_header\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 244\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 245\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 246\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m requests.exceptions.Timeout \u001b[38;5;28;01mas\u001b[39;00m to:\n\u001b[32m 247\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MlflowException(\n\u001b[32m 248\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mAPI request to \u001b[39m\u001b[38;5;132;01m{\u001b[39;00murl\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m failed with timeout exception \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mto\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 249\u001b[39m \u001b[33m\"\u001b[39m\u001b[33m To increase the timeout, set the environment variable \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 250\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mMLFLOW_HTTP_REQUEST_TIMEOUT\u001b[38;5;132;01m!s}\u001b[39;00m\u001b[33m to a larger value.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 251\u001b[39m ) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mto\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/request_utils.py:237\u001b[39m, in \u001b[36m_get_http_response_with_retries\u001b[39m\u001b[34m(method, url, max_retries, backoff_factor, backoff_jitter, retry_codes, raise_on_status, allow_redirects, respect_retry_after_header, **kwargs)\u001b[39m\n\u001b[32m 234\u001b[39m env_value = os.getenv(\u001b[33m\"\u001b[39m\u001b[33mMLFLOW_ALLOW_HTTP_REDIRECTS\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mtrue\u001b[39m\u001b[33m\"\u001b[39m).lower() \u001b[38;5;129;01min\u001b[39;00m [\u001b[33m\"\u001b[39m\u001b[33mtrue\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33m1\u001b[39m\u001b[33m\"\u001b[39m]\n\u001b[32m 235\u001b[39m allow_redirects = env_value \u001b[38;5;28;01mif\u001b[39;00m allow_redirects \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m allow_redirects\n\u001b[32m--> \u001b[39m\u001b[32m237\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43msession\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mallow_redirects\u001b[49m\u001b[43m=\u001b[49m\u001b[43mallow_redirects\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/requests/sessions.py:589\u001b[39m, in \u001b[36mSession.request\u001b[39m\u001b[34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001b[39m\n\u001b[32m 584\u001b[39m send_kwargs = {\n\u001b[32m 585\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mtimeout\u001b[39m\u001b[33m\"\u001b[39m: timeout,\n\u001b[32m 586\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mallow_redirects\u001b[39m\u001b[33m\"\u001b[39m: allow_redirects,\n\u001b[32m 587\u001b[39m }\n\u001b[32m 588\u001b[39m send_kwargs.update(settings)\n\u001b[32m--> \u001b[39m\u001b[32m589\u001b[39m resp = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprep\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43msend_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 591\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m resp\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/requests/sessions.py:703\u001b[39m, in \u001b[36mSession.send\u001b[39m\u001b[34m(self, request, **kwargs)\u001b[39m\n\u001b[32m 700\u001b[39m start = preferred_clock()\n\u001b[32m 702\u001b[39m \u001b[38;5;66;03m# Send the request\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m703\u001b[39m r = \u001b[43madapter\u001b[49m\u001b[43m.\u001b[49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 705\u001b[39m \u001b[38;5;66;03m# Total elapsed time of the request (approximately)\u001b[39;00m\n\u001b[32m 706\u001b[39m elapsed = preferred_clock() - start\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/requests/adapters.py:644\u001b[39m, in \u001b[36mHTTPAdapter.send\u001b[39m\u001b[34m(self, request, stream, timeout, verify, cert, proxies)\u001b[39m\n\u001b[32m 641\u001b[39m timeout = TimeoutSauce(connect=timeout, read=timeout)\n\u001b[32m 643\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m644\u001b[39m resp = \u001b[43mconn\u001b[49m\u001b[43m.\u001b[49m\u001b[43murlopen\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 645\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 646\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m=\u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 647\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m.\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 648\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m.\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 649\u001b[39m \u001b[43m \u001b[49m\u001b[43mredirect\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 650\u001b[39m \u001b[43m \u001b[49m\u001b[43massert_same_host\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 651\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 652\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 653\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mmax_retries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 654\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 655\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 656\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 658\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m (ProtocolError, \u001b[38;5;167;01mOSError\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m err:\n\u001b[32m 659\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mConnectionError\u001b[39;00m(err, request=request)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:871\u001b[39m, in \u001b[36mHTTPConnectionPool.urlopen\u001b[39m\u001b[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[39m\n\u001b[32m 866\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m conn:\n\u001b[32m 867\u001b[39m \u001b[38;5;66;03m# Try again\u001b[39;00m\n\u001b[32m 868\u001b[39m log.warning(\n\u001b[32m 869\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mRetrying (\u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[33m) after connection broken by \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m\"\u001b[39m, retries, err, url\n\u001b[32m 870\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m871\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43murlopen\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 872\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 873\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 874\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 875\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 876\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 877\u001b[39m \u001b[43m \u001b[49m\u001b[43mredirect\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 878\u001b[39m \u001b[43m \u001b[49m\u001b[43massert_same_host\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 879\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 880\u001b[39m \u001b[43m \u001b[49m\u001b[43mpool_timeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpool_timeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 881\u001b[39m \u001b[43m \u001b[49m\u001b[43mrelease_conn\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrelease_conn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 882\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 883\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody_pos\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody_pos\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 884\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 885\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 886\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mresponse_kw\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 887\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 889\u001b[39m \u001b[38;5;66;03m# Handle redirect?\u001b[39;00m\n\u001b[32m 890\u001b[39m redirect_location = redirect \u001b[38;5;129;01mand\u001b[39;00m response.get_redirect_location()\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:871\u001b[39m, in \u001b[36mHTTPConnectionPool.urlopen\u001b[39m\u001b[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[39m\n\u001b[32m 866\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m conn:\n\u001b[32m 867\u001b[39m \u001b[38;5;66;03m# Try again\u001b[39;00m\n\u001b[32m 868\u001b[39m log.warning(\n\u001b[32m 869\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mRetrying (\u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[33m) after connection broken by \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m\"\u001b[39m, retries, err, url\n\u001b[32m 870\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m871\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43murlopen\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 872\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 873\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 874\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 875\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 876\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 877\u001b[39m \u001b[43m \u001b[49m\u001b[43mredirect\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 878\u001b[39m \u001b[43m \u001b[49m\u001b[43massert_same_host\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 879\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 880\u001b[39m \u001b[43m \u001b[49m\u001b[43mpool_timeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpool_timeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 881\u001b[39m \u001b[43m \u001b[49m\u001b[43mrelease_conn\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrelease_conn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 882\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 883\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody_pos\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody_pos\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 884\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 885\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 886\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mresponse_kw\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 887\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 889\u001b[39m \u001b[38;5;66;03m# Handle redirect?\u001b[39;00m\n\u001b[32m 890\u001b[39m redirect_location = redirect \u001b[38;5;129;01mand\u001b[39;00m response.get_redirect_location()\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:844\u001b[39m, in \u001b[36mHTTPConnectionPool.urlopen\u001b[39m\u001b[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[39m\n\u001b[32m 839\u001b[39m new_e = ProtocolError(\u001b[33m\"\u001b[39m\u001b[33mConnection aborted.\u001b[39m\u001b[33m\"\u001b[39m, new_e)\n\u001b[32m 841\u001b[39m retries = retries.increment(\n\u001b[32m 842\u001b[39m method, url, error=new_e, _pool=\u001b[38;5;28mself\u001b[39m, _stacktrace=sys.exc_info()[\u001b[32m2\u001b[39m]\n\u001b[32m 843\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m844\u001b[39m \u001b[43mretries\u001b[49m\u001b[43m.\u001b[49m\u001b[43msleep\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 846\u001b[39m \u001b[38;5;66;03m# Keep track of the error for the retry warning.\u001b[39;00m\n\u001b[32m 847\u001b[39m err = e\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/retry.py:363\u001b[39m, in \u001b[36mRetry.sleep\u001b[39m\u001b[34m(self, response)\u001b[39m\n\u001b[32m 360\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m slept:\n\u001b[32m 361\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m363\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_sleep_backoff\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/retry.py:347\u001b[39m, in \u001b[36mRetry._sleep_backoff\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 345\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m backoff <= \u001b[32m0\u001b[39m:\n\u001b[32m 346\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m347\u001b[39m \u001b[43mtime\u001b[49m\u001b[43m.\u001b[49m\u001b[43msleep\u001b[49m\u001b[43m(\u001b[49m\u001b[43mbackoff\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[31mKeyboardInterrupt\u001b[39m: " + ] + } + ], "source": [ - "# experiment_description = (\n", - "# \"Nightingale is a bird call classification project.\"\n", - "# )\n", + "experiment_description = (\n", + " \"Nightingale is a bird call classification project.\"\n", + ")\n", "\n", - "# experiment_tags = {\n", - "# \"project_name\": \"nightingale\",\n", - "# \"mlflow.note.content\": experiment_description,\n", - "# }\n", + "experiment_tags = {\n", + " \"project_name\": \"nightingale\",\n", + " \"mlflow.note.content\": experiment_description,\n", + "}\n", "\n", - "# # only run following command once to create the experiment after the server has been started for the first time\n", - "# # client.create_experiment(name=\"Nightingale Bird Call Classification\", tags=experiment_tags)\n", - "# mlflow.set_experiment(\n", - "# experiment_name=\"/Workspace/Users/ephraim.eckl@posteo.de/nightingale\",\n", - "# experiment_id=\"2165278269360514\"\n", - "# )" + "# only run following command once to create the experiment after the server has been started for the first time\n", + "# client.create_experiment(name=\"Nightingale Bird Call Classification\", tags=experiment_tags)\n", + "mlflow.set_experiment(\n", + " experiment_name=\"nightingale\"\n", + ")" ] }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 26, "id": "f29e4b9e", "metadata": {}, "outputs": [ { - "ename": "MissingConfigException", - "evalue": "Yaml file '/workspaces/nightingale/notebooks/mlruns/0/meta.yaml' does not exist.", + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING:urllib3.connectionpool:Retrying (Retry(total=6, connect=6, read=7, redirect=7, status=7)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno 101] Network is unreachable')': /api/2.0/mlflow/runs/create\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mMissingConfigException\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[28]\u001b[39m\u001b[32m, line 15\u001b[39m\n\u001b[32m 3\u001b[39m params = {\n\u001b[32m 4\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mnum_bird_classes\u001b[39m\u001b[33m\"\u001b[39m: num_of_bird_classes_in_dataset,\n\u001b[32m 5\u001b[39m \u001b[33m\"\u001b[39m\u001b[33moptimizer\u001b[39m\u001b[33m\"\u001b[39m: \u001b[33m\"\u001b[39m\u001b[33madam\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 11\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mearly_stopping_patience\u001b[39m\u001b[33m\"\u001b[39m: \u001b[32m3\u001b[39m,\n\u001b[32m 12\u001b[39m }\n\u001b[32m 14\u001b[39m \u001b[38;5;66;03m# Initiate the MLflow run context\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m15\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[43mmlflow\u001b[49m\u001b[43m.\u001b[49m\u001b[43mstart_run\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m run:\n\u001b[32m 16\u001b[39m \u001b[38;5;66;03m# Log the parameters used for the model fit\u001b[39;00m\n\u001b[32m 17\u001b[39m mlflow.log_params(params)\n\u001b[32m 19\u001b[39m \u001b[38;5;66;03m# Log the error metrics that were calculated during validation\u001b[39;00m\n", + "\u001b[31mOSError\u001b[39m Traceback (most recent call last)", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:198\u001b[39m, in \u001b[36mHTTPConnection._new_conn\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 197\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m198\u001b[39m sock = \u001b[43mconnection\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_connection\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 199\u001b[39m \u001b[43m \u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_dns_host\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mport\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 200\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 201\u001b[39m \u001b[43m \u001b[49m\u001b[43msource_address\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msource_address\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 202\u001b[39m \u001b[43m \u001b[49m\u001b[43msocket_options\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msocket_options\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 203\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 204\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m socket.gaierror \u001b[38;5;28;01mas\u001b[39;00m e:\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/connection.py:85\u001b[39m, in \u001b[36mcreate_connection\u001b[39m\u001b[34m(address, timeout, source_address, socket_options)\u001b[39m\n\u001b[32m 84\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m85\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m err\n\u001b[32m 86\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 87\u001b[39m \u001b[38;5;66;03m# Break explicitly a reference cycle\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/connection.py:73\u001b[39m, in \u001b[36mcreate_connection\u001b[39m\u001b[34m(address, timeout, source_address, socket_options)\u001b[39m\n\u001b[32m 72\u001b[39m sock.bind(source_address)\n\u001b[32m---> \u001b[39m\u001b[32m73\u001b[39m \u001b[43msock\u001b[49m\u001b[43m.\u001b[49m\u001b[43mconnect\u001b[49m\u001b[43m(\u001b[49m\u001b[43msa\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 74\u001b[39m \u001b[38;5;66;03m# Break explicitly a reference cycle\u001b[39;00m\n", + "\u001b[31mOSError\u001b[39m: [Errno 101] Network is unreachable", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[31mNewConnectionError\u001b[39m Traceback (most recent call last)", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:787\u001b[39m, in \u001b[36mHTTPConnectionPool.urlopen\u001b[39m\u001b[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[39m\n\u001b[32m 786\u001b[39m \u001b[38;5;66;03m# Make the request on the HTTPConnection object\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m787\u001b[39m response = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_make_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 788\u001b[39m \u001b[43m \u001b[49m\u001b[43mconn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 789\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 790\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 791\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout_obj\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 792\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 793\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 794\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 795\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 796\u001b[39m \u001b[43m \u001b[49m\u001b[43mresponse_conn\u001b[49m\u001b[43m=\u001b[49m\u001b[43mresponse_conn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 797\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 798\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 799\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mresponse_kw\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 800\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 802\u001b[39m \u001b[38;5;66;03m# Everything went great!\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:493\u001b[39m, in \u001b[36mHTTPConnectionPool._make_request\u001b[39m\u001b[34m(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)\u001b[39m\n\u001b[32m 492\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m493\u001b[39m \u001b[43mconn\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 494\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 495\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 496\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 497\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 498\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 499\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 500\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 501\u001b[39m \u001b[43m \u001b[49m\u001b[43menforce_content_length\u001b[49m\u001b[43m=\u001b[49m\u001b[43menforce_content_length\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 502\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 504\u001b[39m \u001b[38;5;66;03m# We are swallowing BrokenPipeError (errno.EPIPE) since the server is\u001b[39;00m\n\u001b[32m 505\u001b[39m \u001b[38;5;66;03m# legitimately able to close the connection after sending a valid response.\u001b[39;00m\n\u001b[32m 506\u001b[39m \u001b[38;5;66;03m# With this behaviour, the received response is still readable.\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:494\u001b[39m, in \u001b[36mHTTPConnection.request\u001b[39m\u001b[34m(self, method, url, body, headers, chunked, preload_content, decode_content, enforce_content_length)\u001b[39m\n\u001b[32m 493\u001b[39m \u001b[38;5;28mself\u001b[39m.putheader(header, value)\n\u001b[32m--> \u001b[39m\u001b[32m494\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mendheaders\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 496\u001b[39m \u001b[38;5;66;03m# If we're given a body we start sending that in chunks.\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/http/client.py:1298\u001b[39m, in \u001b[36mHTTPConnection.endheaders\u001b[39m\u001b[34m(self, message_body, encode_chunked)\u001b[39m\n\u001b[32m 1297\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m CannotSendHeader()\n\u001b[32m-> \u001b[39m\u001b[32m1298\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_send_output\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmessage_body\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mencode_chunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mencode_chunked\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/http/client.py:1058\u001b[39m, in \u001b[36mHTTPConnection._send_output\u001b[39m\u001b[34m(self, message_body, encode_chunked)\u001b[39m\n\u001b[32m 1057\u001b[39m \u001b[38;5;28;01mdel\u001b[39;00m \u001b[38;5;28mself\u001b[39m._buffer[:]\n\u001b[32m-> \u001b[39m\u001b[32m1058\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmsg\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1060\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m message_body \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 1061\u001b[39m \n\u001b[32m 1062\u001b[39m \u001b[38;5;66;03m# create a consistent interface to message_body\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/http/client.py:996\u001b[39m, in \u001b[36mHTTPConnection.send\u001b[39m\u001b[34m(self, data)\u001b[39m\n\u001b[32m 995\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.auto_open:\n\u001b[32m--> \u001b[39m\u001b[32m996\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mconnect\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 997\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:325\u001b[39m, in \u001b[36mHTTPConnection.connect\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 324\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mconnect\u001b[39m(\u001b[38;5;28mself\u001b[39m) -> \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m325\u001b[39m \u001b[38;5;28mself\u001b[39m.sock = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_new_conn\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 326\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._tunnel_host:\n\u001b[32m 327\u001b[39m \u001b[38;5;66;03m# If we're tunneling it means we're connected to our proxy.\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:213\u001b[39m, in \u001b[36mHTTPConnection._new_conn\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 212\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[32m--> \u001b[39m\u001b[32m213\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m NewConnectionError(\n\u001b[32m 214\u001b[39m \u001b[38;5;28mself\u001b[39m, \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mFailed to establish a new connection: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00me\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m\n\u001b[32m 215\u001b[39m ) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01me\u001b[39;00m\n\u001b[32m 217\u001b[39m sys.audit(\u001b[33m\"\u001b[39m\u001b[33mhttp.client.connect\u001b[39m\u001b[33m\"\u001b[39m, \u001b[38;5;28mself\u001b[39m, \u001b[38;5;28mself\u001b[39m.host, \u001b[38;5;28mself\u001b[39m.port)\n", + "\u001b[31mNewConnectionError\u001b[39m: : Failed to establish a new connection: [Errno 101] Network is unreachable", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[31mKeyboardInterrupt\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[26]\u001b[39m\u001b[32m, line 15\u001b[39m\n\u001b[32m 3\u001b[39m params = {\n\u001b[32m 4\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mnum_bird_classes\u001b[39m\u001b[33m\"\u001b[39m: num_of_bird_classes_in_dataset,\n\u001b[32m 5\u001b[39m \u001b[33m\"\u001b[39m\u001b[33moptimizer\u001b[39m\u001b[33m\"\u001b[39m: \u001b[33m\"\u001b[39m\u001b[33madam\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 11\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mearly_stopping_patience\u001b[39m\u001b[33m\"\u001b[39m: \u001b[32m3\u001b[39m,\n\u001b[32m 12\u001b[39m }\n\u001b[32m 14\u001b[39m \u001b[38;5;66;03m# Initiate the MLflow run context\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m15\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[43mmlflow\u001b[49m\u001b[43m.\u001b[49m\u001b[43mstart_run\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m run:\n\u001b[32m 16\u001b[39m \u001b[38;5;66;03m# Log the parameters used for the model fit\u001b[39;00m\n\u001b[32m 17\u001b[39m mlflow.log_params(params)\n\u001b[32m 19\u001b[39m \u001b[38;5;66;03m# Log the error metrics that were calculated during validation\u001b[39;00m\n", "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/fluent.py:475\u001b[39m, in \u001b[36mstart_run\u001b[39m\u001b[34m(run_id, experiment_id, run_name, nested, parent_run_id, tags, description, log_system_metrics)\u001b[39m\n\u001b[32m 471\u001b[39m user_specified_tags[MLFLOW_RUN_NAME] = run_name\n\u001b[32m 473\u001b[39m resolved_tags = context_registry.resolve_tags(user_specified_tags)\n\u001b[32m--> \u001b[39m\u001b[32m475\u001b[39m active_run_obj = \u001b[43mclient\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_run\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 476\u001b[39m \u001b[43m \u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43mexp_id_for_run\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 477\u001b[39m \u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m=\u001b[49m\u001b[43mresolved_tags\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 478\u001b[39m \u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 479\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 481\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m log_system_metrics \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 482\u001b[39m \u001b[38;5;66;03m# If `log_system_metrics` is not specified, we will check environment variable.\u001b[39;00m\n\u001b[32m 483\u001b[39m log_system_metrics = MLFLOW_ENABLE_SYSTEM_METRICS_LOGGING.get()\n", "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/client.py:479\u001b[39m, in \u001b[36mMlflowClient.create_run\u001b[39m\u001b[34m(self, experiment_id, start_time, tags, run_name)\u001b[39m\n\u001b[32m 425\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mcreate_run\u001b[39m(\n\u001b[32m 426\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 427\u001b[39m experiment_id: \u001b[38;5;28mstr\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 430\u001b[39m run_name: \u001b[38;5;28mstr\u001b[39m | \u001b[38;5;28;01mNone\u001b[39;00m = \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m 431\u001b[39m ) -> Run:\n\u001b[32m 432\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 433\u001b[39m \u001b[33;03m Create a :py:class:`mlflow.entities.Run` object that can be associated with\u001b[39;00m\n\u001b[32m 434\u001b[39m \u001b[33;03m metrics, parameters, artifacts, etc.\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 477\u001b[39m \u001b[33;03m status: RUNNING\u001b[39;00m\n\u001b[32m 478\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m479\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_tracking_client\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_run\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstart_time\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/telemetry/track.py:30\u001b[39m, in \u001b[36mrecord_usage_event..decorator..wrapper\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 28\u001b[39m start_time = time.time()\n\u001b[32m 29\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m30\u001b[39m result = \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 31\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m result \u001b[38;5;66;03m# noqa: RET504\u001b[39;00m\n\u001b[32m 32\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m:\n", "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/_tracking_service/client.py:183\u001b[39m, in \u001b[36mTrackingServiceClient.create_run\u001b[39m\u001b[34m(self, experiment_id, start_time, tags, run_name)\u001b[39m\n\u001b[32m 178\u001b[39m \u001b[38;5;66;03m# Extract user from tags\u001b[39;00m\n\u001b[32m 179\u001b[39m \u001b[38;5;66;03m# This logic is temporary; the user_id attribute of runs is deprecated and will be removed\u001b[39;00m\n\u001b[32m 180\u001b[39m \u001b[38;5;66;03m# in a later release.\u001b[39;00m\n\u001b[32m 181\u001b[39m user_id = tags.get(MLFLOW_USER, \u001b[33m\"\u001b[39m\u001b[33munknown\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m183\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mstore\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_run\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 184\u001b[39m \u001b[43m \u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 185\u001b[39m \u001b[43m \u001b[49m\u001b[43muser_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43muser_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 186\u001b[39m \u001b[43m \u001b[49m\u001b[43mstart_time\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstart_time\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mget_current_time_millis\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 187\u001b[39m \u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m=\u001b[49m\u001b[43m[\u001b[49m\u001b[43mRunTag\u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvalue\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvalue\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m.\u001b[49m\u001b[43mitems\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 188\u001b[39m \u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 189\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:689\u001b[39m, in \u001b[36mFileStore.create_run\u001b[39m\u001b[34m(self, experiment_id, user_id, start_time, tags, run_name)\u001b[39m\n\u001b[32m 685\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 686\u001b[39m \u001b[33;03mCreates a run with the specified attributes.\u001b[39;00m\n\u001b[32m 687\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 688\u001b[39m experiment_id = FileStore.DEFAULT_EXPERIMENT_ID \u001b[38;5;28;01mif\u001b[39;00m experiment_id \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m experiment_id\n\u001b[32m--> \u001b[39m\u001b[32m689\u001b[39m experiment = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mget_experiment\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 690\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m experiment \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 691\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MlflowException(\n\u001b[32m 692\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mCould not create run under experiment with ID \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m - no such \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 693\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mexperiment exists.\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 694\u001b[39m databricks_pb2.RESOURCE_DOES_NOT_EXIST,\n\u001b[32m 695\u001b[39m )\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:498\u001b[39m, in \u001b[36mFileStore.get_experiment\u001b[39m\u001b[34m(self, experiment_id)\u001b[39m\n\u001b[32m 487\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 488\u001b[39m \u001b[33;03mFetch the experiment.\u001b[39;00m\n\u001b[32m 489\u001b[39m \u001b[33;03mNote: This API will search for active as well as deleted experiments.\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 495\u001b[39m \u001b[33;03m A single Experiment object if it exists, otherwise raises an Exception.\u001b[39;00m\n\u001b[32m 496\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 497\u001b[39m experiment_id = FileStore.DEFAULT_EXPERIMENT_ID \u001b[38;5;28;01mif\u001b[39;00m experiment_id \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m experiment_id\n\u001b[32m--> \u001b[39m\u001b[32m498\u001b[39m experiment = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_get_experiment\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 499\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m experiment \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 500\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MlflowException(\n\u001b[32m 501\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mExperiment \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m does not exist.\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 502\u001b[39m databricks_pb2.RESOURCE_DOES_NOT_EXIST,\n\u001b[32m 503\u001b[39m )\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:466\u001b[39m, in \u001b[36mFileStore._get_experiment\u001b[39m\u001b[34m(self, experiment_id, view_type)\u001b[39m\n\u001b[32m 461\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m experiment_dir \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 462\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MlflowException(\n\u001b[32m 463\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mCould not find experiment with ID \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m,\n\u001b[32m 464\u001b[39m databricks_pb2.RESOURCE_DOES_NOT_EXIST,\n\u001b[32m 465\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m466\u001b[39m meta = \u001b[43mFileStore\u001b[49m\u001b[43m.\u001b[49m\u001b[43m_read_yaml\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_dir\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mFileStore\u001b[49m\u001b[43m.\u001b[49m\u001b[43mMETA_DATA_FILE_NAME\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 467\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m meta \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 468\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MissingConfigException(\n\u001b[32m 469\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mExperiment \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m is invalid with empty \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 470\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mFileStore.META_DATA_FILE_NAME\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m in directory \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mexperiment_dir\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 471\u001b[39m )\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:1636\u001b[39m, in \u001b[36mFileStore._read_yaml\u001b[39m\u001b[34m(root, file_name, retries)\u001b[39m\n\u001b[32m 1633\u001b[39m time.sleep(\u001b[32m0.1\u001b[39m * (\u001b[32m3\u001b[39m - attempts_remaining))\n\u001b[32m 1634\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m _read_helper(root, file_name, attempts_remaining - \u001b[32m1\u001b[39m)\n\u001b[32m-> \u001b[39m\u001b[32m1636\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_read_helper\u001b[49m\u001b[43m(\u001b[49m\u001b[43mroot\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfile_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mattempts_remaining\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/file_store.py:1629\u001b[39m, in \u001b[36mFileStore._read_yaml.._read_helper\u001b[39m\u001b[34m(root, file_name, attempts_remaining)\u001b[39m\n\u001b[32m 1628\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m_read_helper\u001b[39m(root, file_name, attempts_remaining=\u001b[32m2\u001b[39m):\n\u001b[32m-> \u001b[39m\u001b[32m1629\u001b[39m result = \u001b[43mread_yaml\u001b[49m\u001b[43m(\u001b[49m\u001b[43mroot\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfile_name\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1630\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m result \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mor\u001b[39;00m attempts_remaining == \u001b[32m0\u001b[39m:\n\u001b[32m 1631\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m result\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/yaml_utils.py:107\u001b[39m, in \u001b[36mread_yaml\u001b[39m\u001b[34m(root, file_name)\u001b[39m\n\u001b[32m 105\u001b[39m file_path = os.path.join(root, file_name)\n\u001b[32m 106\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m exists(file_path):\n\u001b[32m--> \u001b[39m\u001b[32m107\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MissingConfigException(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mYaml file \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfile_path\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m does not exist.\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 108\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m codecs.open(file_path, mode=\u001b[33m\"\u001b[39m\u001b[33mr\u001b[39m\u001b[33m\"\u001b[39m, encoding=ENCODING) \u001b[38;5;28;01mas\u001b[39;00m yaml_file:\n\u001b[32m 109\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m yaml.load(yaml_file, Loader=YamlSafeLoader)\n", - "\u001b[31mMissingConfigException\u001b[39m: Yaml file '/workspaces/nightingale/notebooks/mlruns/0/meta.yaml' does not exist." + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/rest_store.py:338\u001b[39m, in \u001b[36mRestStore.create_run\u001b[39m\u001b[34m(self, experiment_id, user_id, start_time, tags, run_name)\u001b[39m\n\u001b[32m 328\u001b[39m tag_protos = [tag.to_proto() \u001b[38;5;28;01mfor\u001b[39;00m tag \u001b[38;5;129;01min\u001b[39;00m tags]\n\u001b[32m 329\u001b[39m req_body = message_to_json(\n\u001b[32m 330\u001b[39m CreateRun(\n\u001b[32m 331\u001b[39m experiment_id=\u001b[38;5;28mstr\u001b[39m(experiment_id),\n\u001b[32m (...)\u001b[39m\u001b[32m 336\u001b[39m )\n\u001b[32m 337\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m338\u001b[39m response_proto = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_call_endpoint\u001b[49m\u001b[43m(\u001b[49m\u001b[43mCreateRun\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreq_body\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 339\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m Run.from_proto(response_proto.run)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/rest_store.py:201\u001b[39m, in \u001b[36mRestStore._call_endpoint\u001b[39m\u001b[34m(self, api, json_body, endpoint, retry_timeout_seconds, response_proto)\u001b[39m\n\u001b[32m 199\u001b[39m endpoint, method = \u001b[38;5;28mself\u001b[39m._METHOD_TO_INFO[api]\n\u001b[32m 200\u001b[39m response_proto = response_proto \u001b[38;5;129;01mor\u001b[39;00m api.Response()\n\u001b[32m--> \u001b[39m\u001b[32m201\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mcall_endpoint\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 202\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mget_host_creds\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 203\u001b[39m \u001b[43m \u001b[49m\u001b[43mendpoint\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 204\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 205\u001b[39m \u001b[43m \u001b[49m\u001b[43mjson_body\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 206\u001b[39m \u001b[43m \u001b[49m\u001b[43mresponse_proto\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 207\u001b[39m \u001b[43m \u001b[49m\u001b[43mretry_timeout_seconds\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretry_timeout_seconds\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 208\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/rest_utils.py:590\u001b[39m, in \u001b[36mcall_endpoint\u001b[39m\u001b[34m(host_creds, endpoint, method, json_body, response_proto, extra_headers, retry_timeout_seconds)\u001b[39m\n\u001b[32m 588\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 589\u001b[39m call_kwargs[\u001b[33m\"\u001b[39m\u001b[33mjson\u001b[39m\u001b[33m\"\u001b[39m] = json_body\n\u001b[32m--> \u001b[39m\u001b[32m590\u001b[39m response = \u001b[43mhttp_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mcall_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 592\u001b[39m response = verify_rest_response(response, endpoint)\n\u001b[32m 593\u001b[39m response_to_parse = response.text\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/rest_utils.py:232\u001b[39m, in \u001b[36mhttp_request\u001b[39m\u001b[34m(host_creds, endpoint, method, max_retries, backoff_factor, backoff_jitter, extra_headers, retry_codes, timeout, raise_on_status, respect_retry_after_header, retry_timeout_seconds, **kwargs)\u001b[39m\n\u001b[32m 229\u001b[39m kwargs[\u001b[33m\"\u001b[39m\u001b[33mauth\u001b[39m\u001b[33m\"\u001b[39m] = fetch_auth(host_creds.auth)\n\u001b[32m 231\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m232\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_get_http_response_with_retries\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 233\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 234\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 235\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_retries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 236\u001b[39m \u001b[43m \u001b[49m\u001b[43mbackoff_factor\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 237\u001b[39m \u001b[43m \u001b[49m\u001b[43mbackoff_jitter\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 238\u001b[39m \u001b[43m \u001b[49m\u001b[43mretry_codes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 239\u001b[39m \u001b[43m \u001b[49m\u001b[43mraise_on_status\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 240\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 241\u001b[39m \u001b[43m \u001b[49m\u001b[43mverify\u001b[49m\u001b[43m=\u001b[49m\u001b[43mhost_creds\u001b[49m\u001b[43m.\u001b[49m\u001b[43mverify\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 242\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 243\u001b[39m \u001b[43m \u001b[49m\u001b[43mrespect_retry_after_header\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrespect_retry_after_header\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 244\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 245\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 246\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m requests.exceptions.Timeout \u001b[38;5;28;01mas\u001b[39;00m to:\n\u001b[32m 247\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MlflowException(\n\u001b[32m 248\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mAPI request to \u001b[39m\u001b[38;5;132;01m{\u001b[39;00murl\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m failed with timeout exception \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mto\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 249\u001b[39m \u001b[33m\"\u001b[39m\u001b[33m To increase the timeout, set the environment variable \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 250\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mMLFLOW_HTTP_REQUEST_TIMEOUT\u001b[38;5;132;01m!s}\u001b[39;00m\u001b[33m to a larger value.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 251\u001b[39m ) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mto\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/request_utils.py:237\u001b[39m, in \u001b[36m_get_http_response_with_retries\u001b[39m\u001b[34m(method, url, max_retries, backoff_factor, backoff_jitter, retry_codes, raise_on_status, allow_redirects, respect_retry_after_header, **kwargs)\u001b[39m\n\u001b[32m 234\u001b[39m env_value = os.getenv(\u001b[33m\"\u001b[39m\u001b[33mMLFLOW_ALLOW_HTTP_REDIRECTS\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mtrue\u001b[39m\u001b[33m\"\u001b[39m).lower() \u001b[38;5;129;01min\u001b[39;00m [\u001b[33m\"\u001b[39m\u001b[33mtrue\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33m1\u001b[39m\u001b[33m\"\u001b[39m]\n\u001b[32m 235\u001b[39m allow_redirects = env_value \u001b[38;5;28;01mif\u001b[39;00m allow_redirects \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m allow_redirects\n\u001b[32m--> \u001b[39m\u001b[32m237\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43msession\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mallow_redirects\u001b[49m\u001b[43m=\u001b[49m\u001b[43mallow_redirects\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/requests/sessions.py:589\u001b[39m, in \u001b[36mSession.request\u001b[39m\u001b[34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001b[39m\n\u001b[32m 584\u001b[39m send_kwargs = {\n\u001b[32m 585\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mtimeout\u001b[39m\u001b[33m\"\u001b[39m: timeout,\n\u001b[32m 586\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mallow_redirects\u001b[39m\u001b[33m\"\u001b[39m: allow_redirects,\n\u001b[32m 587\u001b[39m }\n\u001b[32m 588\u001b[39m send_kwargs.update(settings)\n\u001b[32m--> \u001b[39m\u001b[32m589\u001b[39m resp = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprep\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43msend_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 591\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m resp\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/requests/sessions.py:703\u001b[39m, in \u001b[36mSession.send\u001b[39m\u001b[34m(self, request, **kwargs)\u001b[39m\n\u001b[32m 700\u001b[39m start = preferred_clock()\n\u001b[32m 702\u001b[39m \u001b[38;5;66;03m# Send the request\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m703\u001b[39m r = \u001b[43madapter\u001b[49m\u001b[43m.\u001b[49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 705\u001b[39m \u001b[38;5;66;03m# Total elapsed time of the request (approximately)\u001b[39;00m\n\u001b[32m 706\u001b[39m elapsed = preferred_clock() - start\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/requests/adapters.py:644\u001b[39m, in \u001b[36mHTTPAdapter.send\u001b[39m\u001b[34m(self, request, stream, timeout, verify, cert, proxies)\u001b[39m\n\u001b[32m 641\u001b[39m timeout = TimeoutSauce(connect=timeout, read=timeout)\n\u001b[32m 643\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m644\u001b[39m resp = \u001b[43mconn\u001b[49m\u001b[43m.\u001b[49m\u001b[43murlopen\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 645\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 646\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m=\u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 647\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m.\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 648\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m.\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 649\u001b[39m \u001b[43m \u001b[49m\u001b[43mredirect\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 650\u001b[39m \u001b[43m \u001b[49m\u001b[43massert_same_host\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 651\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 652\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 653\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mmax_retries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 654\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 655\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 656\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 658\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m (ProtocolError, \u001b[38;5;167;01mOSError\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m err:\n\u001b[32m 659\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mConnectionError\u001b[39;00m(err, request=request)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:871\u001b[39m, in \u001b[36mHTTPConnectionPool.urlopen\u001b[39m\u001b[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[39m\n\u001b[32m 866\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m conn:\n\u001b[32m 867\u001b[39m \u001b[38;5;66;03m# Try again\u001b[39;00m\n\u001b[32m 868\u001b[39m log.warning(\n\u001b[32m 869\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mRetrying (\u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[33m) after connection broken by \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m\"\u001b[39m, retries, err, url\n\u001b[32m 870\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m871\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43murlopen\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 872\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 873\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 874\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 875\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 876\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 877\u001b[39m \u001b[43m \u001b[49m\u001b[43mredirect\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 878\u001b[39m \u001b[43m \u001b[49m\u001b[43massert_same_host\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 879\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 880\u001b[39m \u001b[43m \u001b[49m\u001b[43mpool_timeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpool_timeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 881\u001b[39m \u001b[43m \u001b[49m\u001b[43mrelease_conn\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrelease_conn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 882\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 883\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody_pos\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody_pos\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 884\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 885\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 886\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mresponse_kw\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 887\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 889\u001b[39m \u001b[38;5;66;03m# Handle redirect?\u001b[39;00m\n\u001b[32m 890\u001b[39m redirect_location = redirect \u001b[38;5;129;01mand\u001b[39;00m response.get_redirect_location()\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:844\u001b[39m, in \u001b[36mHTTPConnectionPool.urlopen\u001b[39m\u001b[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[39m\n\u001b[32m 839\u001b[39m new_e = ProtocolError(\u001b[33m\"\u001b[39m\u001b[33mConnection aborted.\u001b[39m\u001b[33m\"\u001b[39m, new_e)\n\u001b[32m 841\u001b[39m retries = retries.increment(\n\u001b[32m 842\u001b[39m method, url, error=new_e, _pool=\u001b[38;5;28mself\u001b[39m, _stacktrace=sys.exc_info()[\u001b[32m2\u001b[39m]\n\u001b[32m 843\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m844\u001b[39m \u001b[43mretries\u001b[49m\u001b[43m.\u001b[49m\u001b[43msleep\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 846\u001b[39m \u001b[38;5;66;03m# Keep track of the error for the retry warning.\u001b[39;00m\n\u001b[32m 847\u001b[39m err = e\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/retry.py:363\u001b[39m, in \u001b[36mRetry.sleep\u001b[39m\u001b[34m(self, response)\u001b[39m\n\u001b[32m 360\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m slept:\n\u001b[32m 361\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m363\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_sleep_backoff\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/retry.py:347\u001b[39m, in \u001b[36mRetry._sleep_backoff\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 345\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m backoff <= \u001b[32m0\u001b[39m:\n\u001b[32m 346\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m347\u001b[39m time.sleep(backoff)\n", + "\u001b[31mKeyboardInterrupt\u001b[39m: " ] } ], From affb543b946e4932c40d55f2553bffa82b52c0c4 Mon Sep 17 00:00:00 2001 From: David Pellhammer Date: Tue, 25 Nov 2025 12:09:49 +0000 Subject: [PATCH 05/11] restructured jupyter notebook --- notebooks/train_nightingale_2.ipynb | 297 ++++++++-------------------- 1 file changed, 80 insertions(+), 217 deletions(-) diff --git a/notebooks/train_nightingale_2.ipynb b/notebooks/train_nightingale_2.ipynb index cc77884..f5c2258 100644 --- a/notebooks/train_nightingale_2.ipynb +++ b/notebooks/train_nightingale_2.ipynb @@ -2,27 +2,14 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "a9cd6428", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/workspaces/nightingale/.venv/lib/python3.11/site-packages/tensorflow_hub/__init__.py:61: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.\n", - " from pkg_resources import parse_version\n" - ] - } - ], + "outputs": [], "source": [ "import pandas as pd\n", "import os\n", - "import tensorflow as tf\n", - "\n", - "from nightingale.model.classifier_head import ClassifierHead\n", - "from nightingale.model.yamnet_base import YamnetEmbedding\n", - "\n" + "import tensorflow as tf" ] }, { @@ -35,7 +22,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 24, "id": "d504fa73", "metadata": {}, "outputs": [ @@ -109,7 +96,7 @@ "type": "string" } ], - "ref": "57c29a60-d75b-40c7-bee9-0b3206ecdfab", + "ref": "d2523eaa-58de-498e-af9d-1b8fff2b44c3", "rows": [ [ "0", @@ -342,7 +329,7 @@ "4 https://www.xeno-canto.org/209218 asbfly/XC209218.ogg " ] }, - "execution_count": 2, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -356,7 +343,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 25, "id": "71495869", "metadata": {}, "outputs": [ @@ -385,7 +372,7 @@ "type": "float" } ], - "ref": "afa68c35-7943-4d34-8436-46b7df73b427", + "ref": "6ad0bd56-fe4a-4746-bb70-95031c01fa68", "rows": [ [ "count", @@ -530,7 +517,7 @@ "max 71.964000 177.447800 5.000000" ] }, - "execution_count": 3, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -549,7 +536,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 26, "id": "b9c56857", "metadata": {}, "outputs": [ @@ -604,7 +591,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 27, "id": "6ef7c047", "metadata": {}, "outputs": [ @@ -620,8 +607,9 @@ "from nightingale.data_pipeline.filter_birdclef_data import load_birdclef_metadata\n", "\n", "# filter the metadata csv file for th data that is actually in the data folder\n", - "filtered_bird_df, num_of_bird_classes_in_dataset = load_birdclef_metadata(metadata_path=\"../data/birdclef-2024/train_metadata.csv\", \n", + "filtered_bird_df, num_of_bird_classes_in_dataset = load_birdclef_metadata(metadata_path=train_metadata_path, \n", " audio_root=\"../data/birdclef-2024/train_audio_16\")\n", + "\n", "print(f\"Number of bird classes in dataset: {num_of_bird_classes_in_dataset}\")" ] }, @@ -635,7 +623,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 28, "id": "62a4886f", "metadata": {}, "outputs": [], @@ -656,18 +644,20 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 29, "id": "5aca4873", "metadata": {}, "outputs": [], "source": [ + "from nightingale.model.yamnet_base import YamnetEmbedding\n", + "\n", "#object of the yamnet Model\n", "yam = YamnetEmbedding()" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 30, "id": "1852e16e", "metadata": {}, "outputs": [], @@ -692,18 +682,18 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 31, "id": "c1b433b4", "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
Model: \"classifier_head\"\n",
+       "
Model: \"classifier_head_1\"\n",
        "
\n" ], "text/plain": [ - "\u001b[1mModel: \"classifier_head\"\u001b[0m\n" + "\u001b[1mModel: \"classifier_head_1\"\u001b[0m\n" ] }, "metadata": {}, @@ -715,9 +705,9 @@ "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
        "┃ Layer (type)                     Output Shape                  Param # ┃\n",
        "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
-       "│ dense (Dense)                   │ ?                      │   0 (unbuilt) │\n",
+       "│ dense_2 (Dense)                 │ ?                      │   0 (unbuilt) │\n",
        "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
-       "│ dense_1 (Dense)                 │ ?                      │   0 (unbuilt) │\n",
+       "│ dense_3 (Dense)                 │ ?                      │   0 (unbuilt) │\n",
        "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
        "
\n" ], @@ -725,9 +715,9 @@ "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n", "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n", "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n", - "│ dense (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", + "│ dense_2 (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", - "│ dense_1 (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", + "│ dense_3 (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", "└─────────────────────────────────┴────────────────────────┴───────────────┘\n" ] }, @@ -775,6 +765,8 @@ } ], "source": [ + "from nightingale.model.classifier_head import ClassifierHead\n", + "\n", "bird_class_model = ClassifierHead(num_classes=num_of_bird_classes_in_dataset)\n", "\n", "bird_class_model.summary()" @@ -782,7 +774,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 32, "id": "3c380b83", "metadata": {}, "outputs": [], @@ -814,7 +806,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 33, "id": "5256d5fc", "metadata": {}, "outputs": [ @@ -822,7 +814,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 1/20\n" + "Epoch 1/5\n" ] }, { @@ -837,15 +829,13 @@ "name": "stdout", "output_type": "stream", "text": [ - " 1/Unknown \u001b[1m2s\u001b[0m 2s/step - accuracy: 0.1875 - loss: 1.1980" + " 18/Unknown \u001b[1m3s\u001b[0m 3ms/step - accuracy: 0.7579 - loss: 0.6477" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "2025-11-24 14:23:38.498667: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", - "\t [[{{node IteratorGetNext}}]]\n", "/workspaces/nightingale/.venv/lib/python3.11/site-packages/keras/src/trainers/epoch_iterator.py:164: UserWarning: Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least `steps_per_epoch * epochs` batches. You may need to use the `.repeat()` function when building your dataset.\n", " self._interrupted_warning()\n" ] @@ -854,93 +844,29 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 50ms/step - accuracy: 0.8603 - loss: 0.3829 - val_accuracy: 0.9339 - val_loss: 0.2406\n", - "Epoch 2/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9622 - loss: 0.1107 - val_accuracy: 0.9392 - val_loss: 0.2304\n", - "Epoch 3/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9796 - loss: 0.0668 - val_accuracy: 0.9365 - val_loss: 0.2341\n", - "Epoch 4/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9927 - loss: 0.0427 - val_accuracy: 0.9259 - val_loss: 0.1934\n", - "Epoch 5/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9956 - loss: 0.0279 - val_accuracy: 0.9206 - val_loss: 0.2071\n", - "Epoch 6/20\n", - "\u001b[1m 1/22\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0145" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2025-11-24 14:23:39.498318: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", - "\t [[{{node IteratorGetNext}}]]\n", - "2025-11-24 14:23:39.550032: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", - "\t [[{{node IteratorGetNext}}]]\n", - "2025-11-24 14:23:39.644102: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", - "\t [[{{node IteratorGetNext}}]]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9985 - loss: 0.0209 - val_accuracy: 0.9101 - val_loss: 0.2173\n", - "Epoch 7/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9985 - loss: 0.0160 - val_accuracy: 0.9074 - val_loss: 0.2412\n", - "Epoch 8/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0119 - val_accuracy: 0.9180 - val_loss: 0.2225\n", - "Epoch 9/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0084 - val_accuracy: 0.9021 - val_loss: 0.2290\n", - "Epoch 10/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0067 - val_accuracy: 0.9206 - val_loss: 0.2191\n", - "Epoch 11/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0056 - val_accuracy: 0.9127 - val_loss: 0.2259\n", - "Epoch 12/20\n", - "\u001b[1m 1/22\u001b[0m \u001b[37m━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[1m0s\u001b[0m 5ms/step - accuracy: 1.0000 - loss: 0.0054" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2025-11-24 14:23:39.840078: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", - "\t [[{{node IteratorGetNext}}]]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0046 - val_accuracy: 0.9153 - val_loss: 0.2285\n", - "Epoch 13/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 1.0000 - loss: 0.0042 - val_accuracy: 0.9021 - val_loss: 0.2493\n", - "Epoch 14/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0033 - val_accuracy: 0.9127 - val_loss: 0.2401\n", - "Epoch 15/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0029 - val_accuracy: 0.9101 - val_loss: 0.2409\n", - "Epoch 16/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0025 - val_accuracy: 0.9153 - val_loss: 0.2423\n", - "Epoch 17/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0022 - val_accuracy: 0.9048 - val_loss: 0.2589\n", - "Epoch 18/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0019 - val_accuracy: 0.9101 - val_loss: 0.2519\n", - "Epoch 19/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0017 - val_accuracy: 0.9048 - val_loss: 0.2602\n", - "Epoch 20/20\n", - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 1.0000 - loss: 0.0015 - val_accuracy: 0.9101 - val_loss: 0.2594\n" + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 34ms/step - accuracy: 0.8949 - loss: 0.3456 - val_accuracy: 0.9346 - val_loss: 0.2245\n", + "Epoch 2/5\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9660 - loss: 0.1097 - val_accuracy: 0.9085 - val_loss: 0.1891\n", + "Epoch 3/5\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9766 - loss: 0.0792 - val_accuracy: 0.9314 - val_loss: 0.1977\n", + "Epoch 4/5\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9915 - loss: 0.0442 - val_accuracy: 0.9346 - val_loss: 0.1977\n", + "Epoch 5/5\n", + "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9904 - loss: 0.0359 - val_accuracy: 0.9314 - val_loss: 0.1988\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "2025-11-24 14:23:40.261067: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "2025-11-25 09:16:11.687201: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", "\t [[{{node IteratorGetNext}}]]\n" ] } ], "source": [ "history = bird_class_model.fit(train_ds,\n", - " epochs=20,\n", + " epochs=5,\n", " validation_data=val_ds,\n", " callbacks=callback)" ] @@ -955,7 +881,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 34, "id": "bd931dfe", "metadata": {}, "outputs": [ @@ -963,9 +889,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[1m22/22\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 62ms/step - accuracy: 0.8218 - loss: 0.5900\n", - "Loss: 0.5899819731712341\n", - "Accuracy: 0.8218390941619873\n" + "\u001b[1m17/17\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 66ms/step - accuracy: 0.8694 - loss: 0.3808\n", + "Loss: 0.38082048296928406\n", + "Accuracy: 0.8693957328796387\n" ] } ], @@ -986,7 +912,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "id": "ba9a394a", "metadata": {}, "outputs": [], @@ -999,7 +925,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 36, "id": "5c8283f2", "metadata": {}, "outputs": [ @@ -1007,8 +933,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Env: http://host.docker.internal:5757\n", - "From MLflow: http://host.docker.internal:5757\n" + "Env: http://0.0.0.0:5000\n", + "From MLflow: http://0.0.0.0:5000\n" ] } ], @@ -1029,60 +955,19 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 18, "id": "1c1d179a", "metadata": {}, "outputs": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING:urllib3.connectionpool:Retrying (Retry(total=6, connect=6, read=7, redirect=7, status=7)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno 101] Network is unreachable')': /api/2.0/mlflow/experiments/get-by-name?experiment_name=nightingale\n", - "WARNING:urllib3.connectionpool:Retrying (Retry(total=5, connect=5, read=7, redirect=7, status=7)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno 101] Network is unreachable')': /api/2.0/mlflow/experiments/get-by-name?experiment_name=nightingale\n" - ] - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mOSError\u001b[39m Traceback (most recent call last)", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:198\u001b[39m, in \u001b[36mHTTPConnection._new_conn\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 197\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m198\u001b[39m sock = \u001b[43mconnection\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_connection\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 199\u001b[39m \u001b[43m \u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_dns_host\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mport\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 200\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 201\u001b[39m \u001b[43m \u001b[49m\u001b[43msource_address\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msource_address\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 202\u001b[39m \u001b[43m \u001b[49m\u001b[43msocket_options\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msocket_options\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 203\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 204\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m socket.gaierror \u001b[38;5;28;01mas\u001b[39;00m e:\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/connection.py:85\u001b[39m, in \u001b[36mcreate_connection\u001b[39m\u001b[34m(address, timeout, source_address, socket_options)\u001b[39m\n\u001b[32m 84\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m85\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m err\n\u001b[32m 86\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 87\u001b[39m \u001b[38;5;66;03m# Break explicitly a reference cycle\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/connection.py:73\u001b[39m, in \u001b[36mcreate_connection\u001b[39m\u001b[34m(address, timeout, source_address, socket_options)\u001b[39m\n\u001b[32m 72\u001b[39m sock.bind(source_address)\n\u001b[32m---> \u001b[39m\u001b[32m73\u001b[39m \u001b[43msock\u001b[49m\u001b[43m.\u001b[49m\u001b[43mconnect\u001b[49m\u001b[43m(\u001b[49m\u001b[43msa\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 74\u001b[39m \u001b[38;5;66;03m# Break explicitly a reference cycle\u001b[39;00m\n", - "\u001b[31mOSError\u001b[39m: [Errno 101] Network is unreachable", - "\nThe above exception was the direct cause of the following exception:\n", - "\u001b[31mNewConnectionError\u001b[39m Traceback (most recent call last)", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:787\u001b[39m, in \u001b[36mHTTPConnectionPool.urlopen\u001b[39m\u001b[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[39m\n\u001b[32m 786\u001b[39m \u001b[38;5;66;03m# Make the request on the HTTPConnection object\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m787\u001b[39m response = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_make_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 788\u001b[39m \u001b[43m \u001b[49m\u001b[43mconn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 789\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 790\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 791\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout_obj\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 792\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 793\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 794\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 795\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 796\u001b[39m \u001b[43m \u001b[49m\u001b[43mresponse_conn\u001b[49m\u001b[43m=\u001b[49m\u001b[43mresponse_conn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 797\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 798\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 799\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mresponse_kw\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 800\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 802\u001b[39m \u001b[38;5;66;03m# Everything went great!\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:493\u001b[39m, in \u001b[36mHTTPConnectionPool._make_request\u001b[39m\u001b[34m(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)\u001b[39m\n\u001b[32m 492\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m493\u001b[39m \u001b[43mconn\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 494\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 495\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 496\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 497\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 498\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 499\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 500\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 501\u001b[39m \u001b[43m \u001b[49m\u001b[43menforce_content_length\u001b[49m\u001b[43m=\u001b[49m\u001b[43menforce_content_length\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 502\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 504\u001b[39m \u001b[38;5;66;03m# We are swallowing BrokenPipeError (errno.EPIPE) since the server is\u001b[39;00m\n\u001b[32m 505\u001b[39m \u001b[38;5;66;03m# legitimately able to close the connection after sending a valid response.\u001b[39;00m\n\u001b[32m 506\u001b[39m \u001b[38;5;66;03m# With this behaviour, the received response is still readable.\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:494\u001b[39m, in \u001b[36mHTTPConnection.request\u001b[39m\u001b[34m(self, method, url, body, headers, chunked, preload_content, decode_content, enforce_content_length)\u001b[39m\n\u001b[32m 493\u001b[39m \u001b[38;5;28mself\u001b[39m.putheader(header, value)\n\u001b[32m--> \u001b[39m\u001b[32m494\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mendheaders\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 496\u001b[39m \u001b[38;5;66;03m# If we're given a body we start sending that in chunks.\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/http/client.py:1298\u001b[39m, in \u001b[36mHTTPConnection.endheaders\u001b[39m\u001b[34m(self, message_body, encode_chunked)\u001b[39m\n\u001b[32m 1297\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m CannotSendHeader()\n\u001b[32m-> \u001b[39m\u001b[32m1298\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_send_output\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmessage_body\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mencode_chunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mencode_chunked\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/http/client.py:1058\u001b[39m, in \u001b[36mHTTPConnection._send_output\u001b[39m\u001b[34m(self, message_body, encode_chunked)\u001b[39m\n\u001b[32m 1057\u001b[39m \u001b[38;5;28;01mdel\u001b[39;00m \u001b[38;5;28mself\u001b[39m._buffer[:]\n\u001b[32m-> \u001b[39m\u001b[32m1058\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmsg\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1060\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m message_body \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 1061\u001b[39m \n\u001b[32m 1062\u001b[39m \u001b[38;5;66;03m# create a consistent interface to message_body\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/http/client.py:996\u001b[39m, in \u001b[36mHTTPConnection.send\u001b[39m\u001b[34m(self, data)\u001b[39m\n\u001b[32m 995\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.auto_open:\n\u001b[32m--> \u001b[39m\u001b[32m996\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mconnect\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 997\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:325\u001b[39m, in \u001b[36mHTTPConnection.connect\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 324\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mconnect\u001b[39m(\u001b[38;5;28mself\u001b[39m) -> \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m325\u001b[39m \u001b[38;5;28mself\u001b[39m.sock = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_new_conn\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 326\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._tunnel_host:\n\u001b[32m 327\u001b[39m \u001b[38;5;66;03m# If we're tunneling it means we're connected to our proxy.\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:213\u001b[39m, in \u001b[36mHTTPConnection._new_conn\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 212\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[32m--> \u001b[39m\u001b[32m213\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m NewConnectionError(\n\u001b[32m 214\u001b[39m \u001b[38;5;28mself\u001b[39m, \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mFailed to establish a new connection: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00me\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m\n\u001b[32m 215\u001b[39m ) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01me\u001b[39;00m\n\u001b[32m 217\u001b[39m sys.audit(\u001b[33m\"\u001b[39m\u001b[33mhttp.client.connect\u001b[39m\u001b[33m\"\u001b[39m, \u001b[38;5;28mself\u001b[39m, \u001b[38;5;28mself\u001b[39m.host, \u001b[38;5;28mself\u001b[39m.port)\n", - "\u001b[31mNewConnectionError\u001b[39m: : Failed to establish a new connection: [Errno 101] Network is unreachable", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[31mKeyboardInterrupt\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[15]\u001b[39m\u001b[32m, line 12\u001b[39m\n\u001b[32m 5\u001b[39m experiment_tags = {\n\u001b[32m 6\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mproject_name\u001b[39m\u001b[33m\"\u001b[39m: \u001b[33m\"\u001b[39m\u001b[33mnightingale\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 7\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mmlflow.note.content\u001b[39m\u001b[33m\"\u001b[39m: experiment_description,\n\u001b[32m 8\u001b[39m }\n\u001b[32m 10\u001b[39m \u001b[38;5;66;03m# only run following command once to create the experiment after the server has been started for the first time\u001b[39;00m\n\u001b[32m 11\u001b[39m \u001b[38;5;66;03m# client.create_experiment(name=\"Nightingale Bird Call Classification\", tags=experiment_tags)\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m12\u001b[39m \u001b[43mmlflow\u001b[49m\u001b[43m.\u001b[49m\u001b[43mset_experiment\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 13\u001b[39m \u001b[43m \u001b[49m\u001b[43mexperiment_name\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mnightingale\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\n\u001b[32m 14\u001b[39m \u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/fluent.py:184\u001b[39m, in \u001b[36mset_experiment\u001b[39m\u001b[34m(experiment_name, experiment_id)\u001b[39m\n\u001b[32m 182\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m _experiment_lock:\n\u001b[32m 183\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m experiment_id \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m184\u001b[39m experiment = \u001b[43mclient\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget_experiment_by_name\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_name\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 185\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m experiment:\n\u001b[32m 186\u001b[39m _logger.info(\n\u001b[32m 187\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mExperiment with name \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m does not exist. Creating a new experiment.\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 188\u001b[39m experiment_name,\n\u001b[32m 189\u001b[39m )\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/_tracking_service/client.py:280\u001b[39m, in \u001b[36mTrackingServiceClient.get_experiment_by_name\u001b[39m\u001b[34m(self, name)\u001b[39m\n\u001b[32m 272\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mget_experiment_by_name\u001b[39m(\u001b[38;5;28mself\u001b[39m, name):\n\u001b[32m 273\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 274\u001b[39m \u001b[33;03m Args:\u001b[39;00m\n\u001b[32m 275\u001b[39m \u001b[33;03m name: The experiment name.\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 278\u001b[39m \u001b[33;03m :py:class:`mlflow.entities.Experiment`\u001b[39;00m\n\u001b[32m 279\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m280\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mstore\u001b[49m\u001b[43m.\u001b[49m\u001b[43mget_experiment_by_name\u001b[49m\u001b[43m(\u001b[49m\u001b[43mname\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/rest_store.py:827\u001b[39m, in \u001b[36mRestStore.get_experiment_by_name\u001b[39m\u001b[34m(self, experiment_name)\u001b[39m\n\u001b[32m 825\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m 826\u001b[39m req_body = message_to_json(GetExperimentByName(experiment_name=experiment_name))\n\u001b[32m--> \u001b[39m\u001b[32m827\u001b[39m response_proto = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_call_endpoint\u001b[49m\u001b[43m(\u001b[49m\u001b[43mGetExperimentByName\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreq_body\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 828\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m Experiment.from_proto(response_proto.experiment)\n\u001b[32m 829\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m MlflowException \u001b[38;5;28;01mas\u001b[39;00m e:\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/rest_store.py:201\u001b[39m, in \u001b[36mRestStore._call_endpoint\u001b[39m\u001b[34m(self, api, json_body, endpoint, retry_timeout_seconds, response_proto)\u001b[39m\n\u001b[32m 199\u001b[39m endpoint, method = \u001b[38;5;28mself\u001b[39m._METHOD_TO_INFO[api]\n\u001b[32m 200\u001b[39m response_proto = response_proto \u001b[38;5;129;01mor\u001b[39;00m api.Response()\n\u001b[32m--> \u001b[39m\u001b[32m201\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mcall_endpoint\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 202\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mget_host_creds\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 203\u001b[39m \u001b[43m \u001b[49m\u001b[43mendpoint\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 204\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 205\u001b[39m \u001b[43m \u001b[49m\u001b[43mjson_body\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 206\u001b[39m \u001b[43m \u001b[49m\u001b[43mresponse_proto\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 207\u001b[39m \u001b[43m \u001b[49m\u001b[43mretry_timeout_seconds\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretry_timeout_seconds\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 208\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/rest_utils.py:587\u001b[39m, in \u001b[36mcall_endpoint\u001b[39m\u001b[34m(host_creds, endpoint, method, json_body, response_proto, extra_headers, retry_timeout_seconds)\u001b[39m\n\u001b[32m 585\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m method == \u001b[33m\"\u001b[39m\u001b[33mGET\u001b[39m\u001b[33m\"\u001b[39m:\n\u001b[32m 586\u001b[39m call_kwargs[\u001b[33m\"\u001b[39m\u001b[33mparams\u001b[39m\u001b[33m\"\u001b[39m] = json_body\n\u001b[32m--> \u001b[39m\u001b[32m587\u001b[39m response = \u001b[43mhttp_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mcall_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 588\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 589\u001b[39m call_kwargs[\u001b[33m\"\u001b[39m\u001b[33mjson\u001b[39m\u001b[33m\"\u001b[39m] = json_body\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/rest_utils.py:232\u001b[39m, in \u001b[36mhttp_request\u001b[39m\u001b[34m(host_creds, endpoint, method, max_retries, backoff_factor, backoff_jitter, extra_headers, retry_codes, timeout, raise_on_status, respect_retry_after_header, retry_timeout_seconds, **kwargs)\u001b[39m\n\u001b[32m 229\u001b[39m kwargs[\u001b[33m\"\u001b[39m\u001b[33mauth\u001b[39m\u001b[33m\"\u001b[39m] = fetch_auth(host_creds.auth)\n\u001b[32m 231\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m232\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_get_http_response_with_retries\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 233\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 234\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 235\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_retries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 236\u001b[39m \u001b[43m \u001b[49m\u001b[43mbackoff_factor\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 237\u001b[39m \u001b[43m \u001b[49m\u001b[43mbackoff_jitter\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 238\u001b[39m \u001b[43m \u001b[49m\u001b[43mretry_codes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 239\u001b[39m \u001b[43m \u001b[49m\u001b[43mraise_on_status\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 240\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 241\u001b[39m \u001b[43m \u001b[49m\u001b[43mverify\u001b[49m\u001b[43m=\u001b[49m\u001b[43mhost_creds\u001b[49m\u001b[43m.\u001b[49m\u001b[43mverify\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 242\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 243\u001b[39m \u001b[43m \u001b[49m\u001b[43mrespect_retry_after_header\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrespect_retry_after_header\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 244\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 245\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 246\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m requests.exceptions.Timeout \u001b[38;5;28;01mas\u001b[39;00m to:\n\u001b[32m 247\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MlflowException(\n\u001b[32m 248\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mAPI request to \u001b[39m\u001b[38;5;132;01m{\u001b[39;00murl\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m failed with timeout exception \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mto\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 249\u001b[39m \u001b[33m\"\u001b[39m\u001b[33m To increase the timeout, set the environment variable \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 250\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mMLFLOW_HTTP_REQUEST_TIMEOUT\u001b[38;5;132;01m!s}\u001b[39;00m\u001b[33m to a larger value.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 251\u001b[39m ) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mto\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/request_utils.py:237\u001b[39m, in \u001b[36m_get_http_response_with_retries\u001b[39m\u001b[34m(method, url, max_retries, backoff_factor, backoff_jitter, retry_codes, raise_on_status, allow_redirects, respect_retry_after_header, **kwargs)\u001b[39m\n\u001b[32m 234\u001b[39m env_value = os.getenv(\u001b[33m\"\u001b[39m\u001b[33mMLFLOW_ALLOW_HTTP_REDIRECTS\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mtrue\u001b[39m\u001b[33m\"\u001b[39m).lower() \u001b[38;5;129;01min\u001b[39;00m [\u001b[33m\"\u001b[39m\u001b[33mtrue\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33m1\u001b[39m\u001b[33m\"\u001b[39m]\n\u001b[32m 235\u001b[39m allow_redirects = env_value \u001b[38;5;28;01mif\u001b[39;00m allow_redirects \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m allow_redirects\n\u001b[32m--> \u001b[39m\u001b[32m237\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43msession\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mallow_redirects\u001b[49m\u001b[43m=\u001b[49m\u001b[43mallow_redirects\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/requests/sessions.py:589\u001b[39m, in \u001b[36mSession.request\u001b[39m\u001b[34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001b[39m\n\u001b[32m 584\u001b[39m send_kwargs = {\n\u001b[32m 585\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mtimeout\u001b[39m\u001b[33m\"\u001b[39m: timeout,\n\u001b[32m 586\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mallow_redirects\u001b[39m\u001b[33m\"\u001b[39m: allow_redirects,\n\u001b[32m 587\u001b[39m }\n\u001b[32m 588\u001b[39m send_kwargs.update(settings)\n\u001b[32m--> \u001b[39m\u001b[32m589\u001b[39m resp = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprep\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43msend_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 591\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m resp\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/requests/sessions.py:703\u001b[39m, in \u001b[36mSession.send\u001b[39m\u001b[34m(self, request, **kwargs)\u001b[39m\n\u001b[32m 700\u001b[39m start = preferred_clock()\n\u001b[32m 702\u001b[39m \u001b[38;5;66;03m# Send the request\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m703\u001b[39m r = \u001b[43madapter\u001b[49m\u001b[43m.\u001b[49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 705\u001b[39m \u001b[38;5;66;03m# Total elapsed time of the request (approximately)\u001b[39;00m\n\u001b[32m 706\u001b[39m elapsed = preferred_clock() - start\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/requests/adapters.py:644\u001b[39m, in \u001b[36mHTTPAdapter.send\u001b[39m\u001b[34m(self, request, stream, timeout, verify, cert, proxies)\u001b[39m\n\u001b[32m 641\u001b[39m timeout = TimeoutSauce(connect=timeout, read=timeout)\n\u001b[32m 643\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m644\u001b[39m resp = \u001b[43mconn\u001b[49m\u001b[43m.\u001b[49m\u001b[43murlopen\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 645\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 646\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m=\u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 647\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m.\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 648\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m.\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 649\u001b[39m \u001b[43m \u001b[49m\u001b[43mredirect\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 650\u001b[39m \u001b[43m \u001b[49m\u001b[43massert_same_host\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 651\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 652\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 653\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mmax_retries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 654\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 655\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 656\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 658\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m (ProtocolError, \u001b[38;5;167;01mOSError\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m err:\n\u001b[32m 659\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mConnectionError\u001b[39;00m(err, request=request)\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:871\u001b[39m, in \u001b[36mHTTPConnectionPool.urlopen\u001b[39m\u001b[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[39m\n\u001b[32m 866\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m conn:\n\u001b[32m 867\u001b[39m \u001b[38;5;66;03m# Try again\u001b[39;00m\n\u001b[32m 868\u001b[39m log.warning(\n\u001b[32m 869\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mRetrying (\u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[33m) after connection broken by \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m\"\u001b[39m, retries, err, url\n\u001b[32m 870\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m871\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43murlopen\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 872\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 873\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 874\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 875\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 876\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 877\u001b[39m \u001b[43m \u001b[49m\u001b[43mredirect\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 878\u001b[39m \u001b[43m \u001b[49m\u001b[43massert_same_host\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 879\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 880\u001b[39m \u001b[43m \u001b[49m\u001b[43mpool_timeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpool_timeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 881\u001b[39m \u001b[43m \u001b[49m\u001b[43mrelease_conn\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrelease_conn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 882\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 883\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody_pos\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody_pos\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 884\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 885\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 886\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mresponse_kw\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 887\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 889\u001b[39m \u001b[38;5;66;03m# Handle redirect?\u001b[39;00m\n\u001b[32m 890\u001b[39m redirect_location = redirect \u001b[38;5;129;01mand\u001b[39;00m response.get_redirect_location()\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:871\u001b[39m, in \u001b[36mHTTPConnectionPool.urlopen\u001b[39m\u001b[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[39m\n\u001b[32m 866\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m conn:\n\u001b[32m 867\u001b[39m \u001b[38;5;66;03m# Try again\u001b[39;00m\n\u001b[32m 868\u001b[39m log.warning(\n\u001b[32m 869\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mRetrying (\u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[33m) after connection broken by \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m\"\u001b[39m, retries, err, url\n\u001b[32m 870\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m871\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43murlopen\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 872\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 873\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 874\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 875\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 876\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 877\u001b[39m \u001b[43m \u001b[49m\u001b[43mredirect\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 878\u001b[39m \u001b[43m \u001b[49m\u001b[43massert_same_host\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 879\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 880\u001b[39m \u001b[43m \u001b[49m\u001b[43mpool_timeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpool_timeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 881\u001b[39m \u001b[43m \u001b[49m\u001b[43mrelease_conn\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrelease_conn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 882\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 883\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody_pos\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody_pos\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 884\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 885\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 886\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mresponse_kw\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 887\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 889\u001b[39m \u001b[38;5;66;03m# Handle redirect?\u001b[39;00m\n\u001b[32m 890\u001b[39m redirect_location = redirect \u001b[38;5;129;01mand\u001b[39;00m response.get_redirect_location()\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:844\u001b[39m, in \u001b[36mHTTPConnectionPool.urlopen\u001b[39m\u001b[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[39m\n\u001b[32m 839\u001b[39m new_e = ProtocolError(\u001b[33m\"\u001b[39m\u001b[33mConnection aborted.\u001b[39m\u001b[33m\"\u001b[39m, new_e)\n\u001b[32m 841\u001b[39m retries = retries.increment(\n\u001b[32m 842\u001b[39m method, url, error=new_e, _pool=\u001b[38;5;28mself\u001b[39m, _stacktrace=sys.exc_info()[\u001b[32m2\u001b[39m]\n\u001b[32m 843\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m844\u001b[39m \u001b[43mretries\u001b[49m\u001b[43m.\u001b[49m\u001b[43msleep\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 846\u001b[39m \u001b[38;5;66;03m# Keep track of the error for the retry warning.\u001b[39;00m\n\u001b[32m 847\u001b[39m err = e\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/retry.py:363\u001b[39m, in \u001b[36mRetry.sleep\u001b[39m\u001b[34m(self, response)\u001b[39m\n\u001b[32m 360\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m slept:\n\u001b[32m 361\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m363\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_sleep_backoff\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/retry.py:347\u001b[39m, in \u001b[36mRetry._sleep_backoff\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 345\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m backoff <= \u001b[32m0\u001b[39m:\n\u001b[32m 346\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m347\u001b[39m \u001b[43mtime\u001b[49m\u001b[43m.\u001b[49m\u001b[43msleep\u001b[49m\u001b[43m(\u001b[49m\u001b[43mbackoff\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[31mKeyboardInterrupt\u001b[39m: " - ] + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -1104,59 +989,37 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 19, "id": "f29e4b9e", "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 27ms/step\n", + "Shape of input_example: (32, 1024)\n" + ] + }, { "name": "stderr", "output_type": "stream", "text": [ - "WARNING:urllib3.connectionpool:Retrying (Retry(total=6, connect=6, read=7, redirect=7, status=7)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno 101] Network is unreachable')': /api/2.0/mlflow/runs/create\n" + "2025/11/25 08:38:33 WARNING mlflow.utils.requirements_utils: Detected one or more mismatches between the model's dependencies and the current Python environment:\n", + " - keras (current: 3.12.0, required: keras==3.10.0)\n", + "To fix the mismatches, call `mlflow.pyfunc.get_model_dependencies(model_uri)` to fetch the model's environment and install dependencies using the resulting environment file.\n", + "2025/11/25 08:38:33 WARNING mlflow.utils.environment: Failed to resolve installed pip version. ``pip`` will be added to conda.yaml environment spec without a version specifier.\n", + "Registered model 'nightingale-dev.default.Reg-Bird-Call-Classifier-Head' already exists. Creating a new version of this model...\n", + "2025/11/25 08:38:33 INFO mlflow.store.model_registry.abstract_store: Waiting up to 300 seconds for model version to finish creation. Model name: nightingale-dev.default.Reg-Bird-Call-Classifier-Head, version 2\n", + "Created version '2' of model 'nightingale-dev.default.Reg-Bird-Call-Classifier-Head'.\n" ] }, { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mOSError\u001b[39m Traceback (most recent call last)", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:198\u001b[39m, in \u001b[36mHTTPConnection._new_conn\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 197\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m198\u001b[39m sock = \u001b[43mconnection\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_connection\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 199\u001b[39m \u001b[43m \u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_dns_host\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mport\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 200\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 201\u001b[39m \u001b[43m \u001b[49m\u001b[43msource_address\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msource_address\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 202\u001b[39m \u001b[43m \u001b[49m\u001b[43msocket_options\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msocket_options\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 203\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 204\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m socket.gaierror \u001b[38;5;28;01mas\u001b[39;00m e:\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/connection.py:85\u001b[39m, in \u001b[36mcreate_connection\u001b[39m\u001b[34m(address, timeout, source_address, socket_options)\u001b[39m\n\u001b[32m 84\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m85\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m err\n\u001b[32m 86\u001b[39m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[32m 87\u001b[39m \u001b[38;5;66;03m# Break explicitly a reference cycle\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/connection.py:73\u001b[39m, in \u001b[36mcreate_connection\u001b[39m\u001b[34m(address, timeout, source_address, socket_options)\u001b[39m\n\u001b[32m 72\u001b[39m sock.bind(source_address)\n\u001b[32m---> \u001b[39m\u001b[32m73\u001b[39m \u001b[43msock\u001b[49m\u001b[43m.\u001b[49m\u001b[43mconnect\u001b[49m\u001b[43m(\u001b[49m\u001b[43msa\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 74\u001b[39m \u001b[38;5;66;03m# Break explicitly a reference cycle\u001b[39;00m\n", - "\u001b[31mOSError\u001b[39m: [Errno 101] Network is unreachable", - "\nThe above exception was the direct cause of the following exception:\n", - "\u001b[31mNewConnectionError\u001b[39m Traceback (most recent call last)", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:787\u001b[39m, in \u001b[36mHTTPConnectionPool.urlopen\u001b[39m\u001b[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[39m\n\u001b[32m 786\u001b[39m \u001b[38;5;66;03m# Make the request on the HTTPConnection object\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m787\u001b[39m response = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_make_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 788\u001b[39m \u001b[43m \u001b[49m\u001b[43mconn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 789\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 790\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 791\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout_obj\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 792\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 793\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 794\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 795\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 796\u001b[39m \u001b[43m \u001b[49m\u001b[43mresponse_conn\u001b[49m\u001b[43m=\u001b[49m\u001b[43mresponse_conn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 797\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 798\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 799\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mresponse_kw\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 800\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 802\u001b[39m \u001b[38;5;66;03m# Everything went great!\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:493\u001b[39m, in \u001b[36mHTTPConnectionPool._make_request\u001b[39m\u001b[34m(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)\u001b[39m\n\u001b[32m 492\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m493\u001b[39m \u001b[43mconn\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 494\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 495\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 496\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 497\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 498\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 499\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 500\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 501\u001b[39m \u001b[43m \u001b[49m\u001b[43menforce_content_length\u001b[49m\u001b[43m=\u001b[49m\u001b[43menforce_content_length\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 502\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 504\u001b[39m \u001b[38;5;66;03m# We are swallowing BrokenPipeError (errno.EPIPE) since the server is\u001b[39;00m\n\u001b[32m 505\u001b[39m \u001b[38;5;66;03m# legitimately able to close the connection after sending a valid response.\u001b[39;00m\n\u001b[32m 506\u001b[39m \u001b[38;5;66;03m# With this behaviour, the received response is still readable.\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:494\u001b[39m, in \u001b[36mHTTPConnection.request\u001b[39m\u001b[34m(self, method, url, body, headers, chunked, preload_content, decode_content, enforce_content_length)\u001b[39m\n\u001b[32m 493\u001b[39m \u001b[38;5;28mself\u001b[39m.putheader(header, value)\n\u001b[32m--> \u001b[39m\u001b[32m494\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mendheaders\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 496\u001b[39m \u001b[38;5;66;03m# If we're given a body we start sending that in chunks.\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/http/client.py:1298\u001b[39m, in \u001b[36mHTTPConnection.endheaders\u001b[39m\u001b[34m(self, message_body, encode_chunked)\u001b[39m\n\u001b[32m 1297\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m CannotSendHeader()\n\u001b[32m-> \u001b[39m\u001b[32m1298\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_send_output\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmessage_body\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mencode_chunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mencode_chunked\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/http/client.py:1058\u001b[39m, in \u001b[36mHTTPConnection._send_output\u001b[39m\u001b[34m(self, message_body, encode_chunked)\u001b[39m\n\u001b[32m 1057\u001b[39m \u001b[38;5;28;01mdel\u001b[39;00m \u001b[38;5;28mself\u001b[39m._buffer[:]\n\u001b[32m-> \u001b[39m\u001b[32m1058\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmsg\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1060\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m message_body \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 1061\u001b[39m \n\u001b[32m 1062\u001b[39m \u001b[38;5;66;03m# create a consistent interface to message_body\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/usr/local/lib/python3.11/http/client.py:996\u001b[39m, in \u001b[36mHTTPConnection.send\u001b[39m\u001b[34m(self, data)\u001b[39m\n\u001b[32m 995\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.auto_open:\n\u001b[32m--> \u001b[39m\u001b[32m996\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mconnect\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 997\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:325\u001b[39m, in \u001b[36mHTTPConnection.connect\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 324\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mconnect\u001b[39m(\u001b[38;5;28mself\u001b[39m) -> \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m325\u001b[39m \u001b[38;5;28mself\u001b[39m.sock = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_new_conn\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 326\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m._tunnel_host:\n\u001b[32m 327\u001b[39m \u001b[38;5;66;03m# If we're tunneling it means we're connected to our proxy.\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connection.py:213\u001b[39m, in \u001b[36mHTTPConnection._new_conn\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 212\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[32m--> \u001b[39m\u001b[32m213\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m NewConnectionError(\n\u001b[32m 214\u001b[39m \u001b[38;5;28mself\u001b[39m, \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mFailed to establish a new connection: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00me\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m\n\u001b[32m 215\u001b[39m ) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01me\u001b[39;00m\n\u001b[32m 217\u001b[39m sys.audit(\u001b[33m\"\u001b[39m\u001b[33mhttp.client.connect\u001b[39m\u001b[33m\"\u001b[39m, \u001b[38;5;28mself\u001b[39m, \u001b[38;5;28mself\u001b[39m.host, \u001b[38;5;28mself\u001b[39m.port)\n", - "\u001b[31mNewConnectionError\u001b[39m: : Failed to establish a new connection: [Errno 101] Network is unreachable", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[31mKeyboardInterrupt\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[26]\u001b[39m\u001b[32m, line 15\u001b[39m\n\u001b[32m 3\u001b[39m params = {\n\u001b[32m 4\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mnum_bird_classes\u001b[39m\u001b[33m\"\u001b[39m: num_of_bird_classes_in_dataset,\n\u001b[32m 5\u001b[39m \u001b[33m\"\u001b[39m\u001b[33moptimizer\u001b[39m\u001b[33m\"\u001b[39m: \u001b[33m\"\u001b[39m\u001b[33madam\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 11\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mearly_stopping_patience\u001b[39m\u001b[33m\"\u001b[39m: \u001b[32m3\u001b[39m,\n\u001b[32m 12\u001b[39m }\n\u001b[32m 14\u001b[39m \u001b[38;5;66;03m# Initiate the MLflow run context\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m15\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[43mmlflow\u001b[49m\u001b[43m.\u001b[49m\u001b[43mstart_run\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mas\u001b[39;00m run:\n\u001b[32m 16\u001b[39m \u001b[38;5;66;03m# Log the parameters used for the model fit\u001b[39;00m\n\u001b[32m 17\u001b[39m mlflow.log_params(params)\n\u001b[32m 19\u001b[39m \u001b[38;5;66;03m# Log the error metrics that were calculated during validation\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/fluent.py:475\u001b[39m, in \u001b[36mstart_run\u001b[39m\u001b[34m(run_id, experiment_id, run_name, nested, parent_run_id, tags, description, log_system_metrics)\u001b[39m\n\u001b[32m 471\u001b[39m user_specified_tags[MLFLOW_RUN_NAME] = run_name\n\u001b[32m 473\u001b[39m resolved_tags = context_registry.resolve_tags(user_specified_tags)\n\u001b[32m--> \u001b[39m\u001b[32m475\u001b[39m active_run_obj = \u001b[43mclient\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_run\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 476\u001b[39m \u001b[43m \u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43mexp_id_for_run\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 477\u001b[39m \u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m=\u001b[49m\u001b[43mresolved_tags\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 478\u001b[39m \u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 479\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 481\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m log_system_metrics \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 482\u001b[39m \u001b[38;5;66;03m# If `log_system_metrics` is not specified, we will check environment variable.\u001b[39;00m\n\u001b[32m 483\u001b[39m log_system_metrics = MLFLOW_ENABLE_SYSTEM_METRICS_LOGGING.get()\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/client.py:479\u001b[39m, in \u001b[36mMlflowClient.create_run\u001b[39m\u001b[34m(self, experiment_id, start_time, tags, run_name)\u001b[39m\n\u001b[32m 425\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mcreate_run\u001b[39m(\n\u001b[32m 426\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 427\u001b[39m experiment_id: \u001b[38;5;28mstr\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 430\u001b[39m run_name: \u001b[38;5;28mstr\u001b[39m | \u001b[38;5;28;01mNone\u001b[39;00m = \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m 431\u001b[39m ) -> Run:\n\u001b[32m 432\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 433\u001b[39m \u001b[33;03m Create a :py:class:`mlflow.entities.Run` object that can be associated with\u001b[39;00m\n\u001b[32m 434\u001b[39m \u001b[33;03m metrics, parameters, artifacts, etc.\u001b[39;00m\n\u001b[32m (...)\u001b[39m\u001b[32m 477\u001b[39m \u001b[33;03m status: RUNNING\u001b[39;00m\n\u001b[32m 478\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m479\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_tracking_client\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_run\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstart_time\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/telemetry/track.py:30\u001b[39m, in \u001b[36mrecord_usage_event..decorator..wrapper\u001b[39m\u001b[34m(*args, **kwargs)\u001b[39m\n\u001b[32m 28\u001b[39m start_time = time.time()\n\u001b[32m 29\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m30\u001b[39m result = \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 31\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m result \u001b[38;5;66;03m# noqa: RET504\u001b[39;00m\n\u001b[32m 32\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m:\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/tracking/_tracking_service/client.py:183\u001b[39m, in \u001b[36mTrackingServiceClient.create_run\u001b[39m\u001b[34m(self, experiment_id, start_time, tags, run_name)\u001b[39m\n\u001b[32m 178\u001b[39m \u001b[38;5;66;03m# Extract user from tags\u001b[39;00m\n\u001b[32m 179\u001b[39m \u001b[38;5;66;03m# This logic is temporary; the user_id attribute of runs is deprecated and will be removed\u001b[39;00m\n\u001b[32m 180\u001b[39m \u001b[38;5;66;03m# in a later release.\u001b[39;00m\n\u001b[32m 181\u001b[39m user_id = tags.get(MLFLOW_USER, \u001b[33m\"\u001b[39m\u001b[33munknown\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m183\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mstore\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcreate_run\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 184\u001b[39m \u001b[43m \u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43mexperiment_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 185\u001b[39m \u001b[43m \u001b[49m\u001b[43muser_id\u001b[49m\u001b[43m=\u001b[49m\u001b[43muser_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 186\u001b[39m \u001b[43m \u001b[49m\u001b[43mstart_time\u001b[49m\u001b[43m=\u001b[49m\u001b[43mstart_time\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mget_current_time_millis\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 187\u001b[39m \u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m=\u001b[49m\u001b[43m[\u001b[49m\u001b[43mRunTag\u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvalue\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m(\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvalue\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[43m.\u001b[49m\u001b[43mitems\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 188\u001b[39m \u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrun_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 189\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/rest_store.py:338\u001b[39m, in \u001b[36mRestStore.create_run\u001b[39m\u001b[34m(self, experiment_id, user_id, start_time, tags, run_name)\u001b[39m\n\u001b[32m 328\u001b[39m tag_protos = [tag.to_proto() \u001b[38;5;28;01mfor\u001b[39;00m tag \u001b[38;5;129;01min\u001b[39;00m tags]\n\u001b[32m 329\u001b[39m req_body = message_to_json(\n\u001b[32m 330\u001b[39m CreateRun(\n\u001b[32m 331\u001b[39m experiment_id=\u001b[38;5;28mstr\u001b[39m(experiment_id),\n\u001b[32m (...)\u001b[39m\u001b[32m 336\u001b[39m )\n\u001b[32m 337\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m338\u001b[39m response_proto = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_call_endpoint\u001b[49m\u001b[43m(\u001b[49m\u001b[43mCreateRun\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreq_body\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 339\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m Run.from_proto(response_proto.run)\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/store/tracking/rest_store.py:201\u001b[39m, in \u001b[36mRestStore._call_endpoint\u001b[39m\u001b[34m(self, api, json_body, endpoint, retry_timeout_seconds, response_proto)\u001b[39m\n\u001b[32m 199\u001b[39m endpoint, method = \u001b[38;5;28mself\u001b[39m._METHOD_TO_INFO[api]\n\u001b[32m 200\u001b[39m response_proto = response_proto \u001b[38;5;129;01mor\u001b[39;00m api.Response()\n\u001b[32m--> \u001b[39m\u001b[32m201\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mcall_endpoint\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 202\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mget_host_creds\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 203\u001b[39m \u001b[43m \u001b[49m\u001b[43mendpoint\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 204\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 205\u001b[39m \u001b[43m \u001b[49m\u001b[43mjson_body\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 206\u001b[39m \u001b[43m \u001b[49m\u001b[43mresponse_proto\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 207\u001b[39m \u001b[43m \u001b[49m\u001b[43mretry_timeout_seconds\u001b[49m\u001b[43m=\u001b[49m\u001b[43mretry_timeout_seconds\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 208\u001b[39m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/rest_utils.py:590\u001b[39m, in \u001b[36mcall_endpoint\u001b[39m\u001b[34m(host_creds, endpoint, method, json_body, response_proto, extra_headers, retry_timeout_seconds)\u001b[39m\n\u001b[32m 588\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 589\u001b[39m call_kwargs[\u001b[33m\"\u001b[39m\u001b[33mjson\u001b[39m\u001b[33m\"\u001b[39m] = json_body\n\u001b[32m--> \u001b[39m\u001b[32m590\u001b[39m response = \u001b[43mhttp_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mcall_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 592\u001b[39m response = verify_rest_response(response, endpoint)\n\u001b[32m 593\u001b[39m response_to_parse = response.text\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/rest_utils.py:232\u001b[39m, in \u001b[36mhttp_request\u001b[39m\u001b[34m(host_creds, endpoint, method, max_retries, backoff_factor, backoff_jitter, extra_headers, retry_codes, timeout, raise_on_status, respect_retry_after_header, retry_timeout_seconds, **kwargs)\u001b[39m\n\u001b[32m 229\u001b[39m kwargs[\u001b[33m\"\u001b[39m\u001b[33mauth\u001b[39m\u001b[33m\"\u001b[39m] = fetch_auth(host_creds.auth)\n\u001b[32m 231\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m232\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_get_http_response_with_retries\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 233\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 234\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 235\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_retries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 236\u001b[39m \u001b[43m \u001b[49m\u001b[43mbackoff_factor\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 237\u001b[39m \u001b[43m \u001b[49m\u001b[43mbackoff_jitter\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 238\u001b[39m \u001b[43m \u001b[49m\u001b[43mretry_codes\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 239\u001b[39m \u001b[43m \u001b[49m\u001b[43mraise_on_status\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 240\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 241\u001b[39m \u001b[43m \u001b[49m\u001b[43mverify\u001b[49m\u001b[43m=\u001b[49m\u001b[43mhost_creds\u001b[49m\u001b[43m.\u001b[49m\u001b[43mverify\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 242\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 243\u001b[39m \u001b[43m \u001b[49m\u001b[43mrespect_retry_after_header\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrespect_retry_after_header\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 244\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 245\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 246\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m requests.exceptions.Timeout \u001b[38;5;28;01mas\u001b[39;00m to:\n\u001b[32m 247\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m MlflowException(\n\u001b[32m 248\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mAPI request to \u001b[39m\u001b[38;5;132;01m{\u001b[39;00murl\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m failed with timeout exception \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mto\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 249\u001b[39m \u001b[33m\"\u001b[39m\u001b[33m To increase the timeout, set the environment variable \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 250\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mMLFLOW_HTTP_REQUEST_TIMEOUT\u001b[38;5;132;01m!s}\u001b[39;00m\u001b[33m to a larger value.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 251\u001b[39m ) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mto\u001b[39;00m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/mlflow/utils/request_utils.py:237\u001b[39m, in \u001b[36m_get_http_response_with_retries\u001b[39m\u001b[34m(method, url, max_retries, backoff_factor, backoff_jitter, retry_codes, raise_on_status, allow_redirects, respect_retry_after_header, **kwargs)\u001b[39m\n\u001b[32m 234\u001b[39m env_value = os.getenv(\u001b[33m\"\u001b[39m\u001b[33mMLFLOW_ALLOW_HTTP_REDIRECTS\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mtrue\u001b[39m\u001b[33m\"\u001b[39m).lower() \u001b[38;5;129;01min\u001b[39;00m [\u001b[33m\"\u001b[39m\u001b[33mtrue\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33m1\u001b[39m\u001b[33m\"\u001b[39m]\n\u001b[32m 235\u001b[39m allow_redirects = env_value \u001b[38;5;28;01mif\u001b[39;00m allow_redirects \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m allow_redirects\n\u001b[32m--> \u001b[39m\u001b[32m237\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43msession\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mallow_redirects\u001b[49m\u001b[43m=\u001b[49m\u001b[43mallow_redirects\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/requests/sessions.py:589\u001b[39m, in \u001b[36mSession.request\u001b[39m\u001b[34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001b[39m\n\u001b[32m 584\u001b[39m send_kwargs = {\n\u001b[32m 585\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mtimeout\u001b[39m\u001b[33m\"\u001b[39m: timeout,\n\u001b[32m 586\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mallow_redirects\u001b[39m\u001b[33m\"\u001b[39m: allow_redirects,\n\u001b[32m 587\u001b[39m }\n\u001b[32m 588\u001b[39m send_kwargs.update(settings)\n\u001b[32m--> \u001b[39m\u001b[32m589\u001b[39m resp = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprep\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43msend_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 591\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m resp\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/requests/sessions.py:703\u001b[39m, in \u001b[36mSession.send\u001b[39m\u001b[34m(self, request, **kwargs)\u001b[39m\n\u001b[32m 700\u001b[39m start = preferred_clock()\n\u001b[32m 702\u001b[39m \u001b[38;5;66;03m# Send the request\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m703\u001b[39m r = \u001b[43madapter\u001b[49m\u001b[43m.\u001b[49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 705\u001b[39m \u001b[38;5;66;03m# Total elapsed time of the request (approximately)\u001b[39;00m\n\u001b[32m 706\u001b[39m elapsed = preferred_clock() - start\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/requests/adapters.py:644\u001b[39m, in \u001b[36mHTTPAdapter.send\u001b[39m\u001b[34m(self, request, stream, timeout, verify, cert, proxies)\u001b[39m\n\u001b[32m 641\u001b[39m timeout = TimeoutSauce(connect=timeout, read=timeout)\n\u001b[32m 643\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m644\u001b[39m resp = \u001b[43mconn\u001b[49m\u001b[43m.\u001b[49m\u001b[43murlopen\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 645\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 646\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m=\u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 647\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m.\u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 648\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m.\u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 649\u001b[39m \u001b[43m \u001b[49m\u001b[43mredirect\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 650\u001b[39m \u001b[43m \u001b[49m\u001b[43massert_same_host\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 651\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 652\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 653\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mmax_retries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 654\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 655\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 656\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 658\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m (ProtocolError, \u001b[38;5;167;01mOSError\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m err:\n\u001b[32m 659\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mConnectionError\u001b[39;00m(err, request=request)\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:871\u001b[39m, in \u001b[36mHTTPConnectionPool.urlopen\u001b[39m\u001b[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[39m\n\u001b[32m 866\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m conn:\n\u001b[32m 867\u001b[39m \u001b[38;5;66;03m# Try again\u001b[39;00m\n\u001b[32m 868\u001b[39m log.warning(\n\u001b[32m 869\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mRetrying (\u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[33m) after connection broken by \u001b[39m\u001b[33m'\u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[33m'\u001b[39m\u001b[33m: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m\"\u001b[39m, retries, err, url\n\u001b[32m 870\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m871\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43murlopen\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 872\u001b[39m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 873\u001b[39m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 874\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 875\u001b[39m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 876\u001b[39m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 877\u001b[39m \u001b[43m \u001b[49m\u001b[43mredirect\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 878\u001b[39m \u001b[43m \u001b[49m\u001b[43massert_same_host\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 879\u001b[39m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 880\u001b[39m \u001b[43m \u001b[49m\u001b[43mpool_timeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpool_timeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 881\u001b[39m \u001b[43m \u001b[49m\u001b[43mrelease_conn\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrelease_conn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 882\u001b[39m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m=\u001b[49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 883\u001b[39m \u001b[43m \u001b[49m\u001b[43mbody_pos\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbody_pos\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 884\u001b[39m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 885\u001b[39m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 886\u001b[39m \u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mresponse_kw\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 887\u001b[39m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 889\u001b[39m \u001b[38;5;66;03m# Handle redirect?\u001b[39;00m\n\u001b[32m 890\u001b[39m redirect_location = redirect \u001b[38;5;129;01mand\u001b[39;00m response.get_redirect_location()\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py:844\u001b[39m, in \u001b[36mHTTPConnectionPool.urlopen\u001b[39m\u001b[34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[39m\n\u001b[32m 839\u001b[39m new_e = ProtocolError(\u001b[33m\"\u001b[39m\u001b[33mConnection aborted.\u001b[39m\u001b[33m\"\u001b[39m, new_e)\n\u001b[32m 841\u001b[39m retries = retries.increment(\n\u001b[32m 842\u001b[39m method, url, error=new_e, _pool=\u001b[38;5;28mself\u001b[39m, _stacktrace=sys.exc_info()[\u001b[32m2\u001b[39m]\n\u001b[32m 843\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m844\u001b[39m \u001b[43mretries\u001b[49m\u001b[43m.\u001b[49m\u001b[43msleep\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 846\u001b[39m \u001b[38;5;66;03m# Keep track of the error for the retry warning.\u001b[39;00m\n\u001b[32m 847\u001b[39m err = e\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/retry.py:363\u001b[39m, in \u001b[36mRetry.sleep\u001b[39m\u001b[34m(self, response)\u001b[39m\n\u001b[32m 360\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m slept:\n\u001b[32m 361\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m363\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_sleep_backoff\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[36mFile \u001b[39m\u001b[32m/workspaces/nightingale/.venv/lib/python3.11/site-packages/urllib3/util/retry.py:347\u001b[39m, in \u001b[36mRetry._sleep_backoff\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 345\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m backoff <= \u001b[32m0\u001b[39m:\n\u001b[32m 346\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m347\u001b[39m time.sleep(backoff)\n", - "\u001b[31mKeyboardInterrupt\u001b[39m: " + "name": "stdout", + "output_type": "stream", + "text": [ + "🏃 View run rambunctious-owl-571 at: http://0.0.0.0:5000/#/experiments/960222781255945012/runs/66a682e224794c09a32d93acf6d6e51a\n", + "🧪 View experiment at: http://0.0.0.0:5000/#/experiments/960222781255945012\n" ] } ], From c619954ed87f35e2d060a2b4c812f8d2e03fe38c Mon Sep 17 00:00:00 2001 From: David Pellhammer Date: Tue, 25 Nov 2025 12:36:53 +0000 Subject: [PATCH 06/11] removed dateset splitter --- .../data_pipeline/audio_dataset_splitter.py | 109 ------------------ 1 file changed, 109 deletions(-) delete mode 100644 src/nightingale/data_pipeline/audio_dataset_splitter.py diff --git a/src/nightingale/data_pipeline/audio_dataset_splitter.py b/src/nightingale/data_pipeline/audio_dataset_splitter.py deleted file mode 100644 index 5ba997f..0000000 --- a/src/nightingale/data_pipeline/audio_dataset_splitter.py +++ /dev/null @@ -1,109 +0,0 @@ -import tensorflow as tf -from sklearn.model_selection import train_test_split - -class AudioDatasetSplitter: - """ - Utility class to split a dataframe of audio file paths and labels into - TensorFlow datasets for training, validation and testing. - - Usage: - splitter = AudioDatasetSplitter(filename_col='filename', label_col='target', seed=42) - train_ds, val_ds, test_ds = splitter.build(df) - - Attributes: - filename_col: Name of the dataframe column containing the audio file path. - label_col: Name of the dataframe column containing the class label. - seed: Random seed used for reproducible train/val/test splits. - df: Internal copy of the dataframe provided to build(). - train_ds, val_ds, test_ds: tf.data.Dataset objects produced by build(). - """ - - def __init__(self, filename_col='filename', label_col='target', seed=42): - # Column names and RNG seed configuration - self.filename_col = filename_col - self.label_col = label_col - self.seed = seed - # Placeholder for the dataframe once build() is called - self.df = None - - def build(self, df): - """ - Create train/validation/test splits and return corresponding tf.data.Datasets. - - The function: - - makes an internal copy of the provided dataframe, - - performs a stratified split (60% train, 20% val, 20% test), - - annotates the dataframe with a 'fold' column (1=train, 2=val, 3=test), - - builds and returns datasets for each fold. - - Args: - df: pandas.DataFrame containing at least filename_col and label_col. - - Returns: - (train_ds, val_ds, test_ds): tuple of tf.data.Dataset objects where each - yielded element is (wav_tensor, label). - """ - # Work on a copy to avoid mutating caller's dataframe - self.df = df.copy() - - # Split indices: first into train (60%) and temp (40%), then split temp into val/test evenly. - train_idx, temp_idx = train_test_split( - self.df.index, test_size=0.4, random_state=self.seed, stratify=self.df[self.label_col] - ) - val_idx, test_idx = train_test_split( - temp_idx, test_size=0.5, random_state=self.seed, stratify=self.df.loc[temp_idx, self.label_col] - ) - - # Annotate the dataframe with fold labels for later selection - self.df['fold'] = '' - self.df.loc[train_idx, 'fold'] = 1 - self.df.loc[val_idx, 'fold'] = 2 - self.df.loc[test_idx, 'fold'] = 3 - - # Build tf.data.Datasets for each fold - self.train_ds = self._build_dataset(1) - self.val_ds = self._build_dataset(2) - self.test_ds = self._build_dataset(3) - - return self.train_ds, self.val_ds, self.test_ds - - def _build_dataset(self, fold): - """ - Construct a tf.data.Dataset for a given fold. - - The dataset is created from the filename and label columns and mapped through - _load_wav to decode audio files into waveform tensors. - - Args: - fold: integer 1/2/3 selecting train/val/test subset. - - Returns: - A tf.data.Dataset yielding (wav_tensor, label). - """ - subset = self.df[self.df['fold'] == fold] - ds = tf.data.Dataset.from_tensor_slices( - (subset[self.filename_col].to_numpy(), subset[self.label_col].to_numpy()) - ) - # Map the dataset to load and decode the wav files - return ds.map(self._load_wav) - - @staticmethod - def _load_wav(filename, label): - """ - Read and decode a WAV file into a mono waveform tensor. - - Uses tf.io.read_file + tf.audio.decode_wav to load the file, squeezes the - channel dimension so the returned tensor has shape [num_samples]. - - Args: - filename: path to the audio file (string tensor). - label: associated label. - - Returns: - (wav, label): tuple where wav is a 1-D float32 tensor and label is unchanged. - """ - audio = tf.io.read_file(filename) - wav, sr = tf.audio.decode_wav(audio, desired_channels=1) - # Remove the trailing channel dimension -> shape [num_samples] - wav = tf.squeeze(wav, axis=-1) - return wav, label From b04318f22c1a063870b1231cff35724cc92e521b Mon Sep 17 00:00:00 2001 From: David Pellhammer Date: Tue, 25 Nov 2025 12:37:11 +0000 Subject: [PATCH 07/11] removed yamnet wrapper --- src/nightingale/model/yamnet_base.py | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 src/nightingale/model/yamnet_base.py diff --git a/src/nightingale/model/yamnet_base.py b/src/nightingale/model/yamnet_base.py deleted file mode 100644 index 4d1f9e4..0000000 --- a/src/nightingale/model/yamnet_base.py +++ /dev/null @@ -1,15 +0,0 @@ -import tensorflow_hub as hub -import tensorflow as tf - -class YamnetEmbedding(tf.keras.Model): - def __init__(self): - super().__init__() - self.yamnet = hub.KerasLayer("https://tfhub.dev/google/yamnet/1") - - def call(self, audio_waveform, label): - scores, embeddings, spectrogram = self.yamnet(audio_waveform) - num_embeddings = tf.shape(embeddings)[0] - return (embeddings, tf.repeat(label, num_embeddings)) - - - From bd3625b49bf765defa11caa364e9eda840cb348f Mon Sep 17 00:00:00 2001 From: David Pellhammer Date: Tue, 25 Nov 2025 12:37:21 +0000 Subject: [PATCH 08/11] removed depricated converter --- .../data_pipeline/convert_audio.py | 69 ------------------- 1 file changed, 69 deletions(-) delete mode 100644 src/nightingale/data_pipeline/convert_audio.py diff --git a/src/nightingale/data_pipeline/convert_audio.py b/src/nightingale/data_pipeline/convert_audio.py deleted file mode 100644 index 2ffb022..0000000 --- a/src/nightingale/data_pipeline/convert_audio.py +++ /dev/null @@ -1,69 +0,0 @@ -import os -from pydub import AudioSegment - -def convert_and_resample(input_file: str, output_file: str): - """ - Converts an audio file to WAV format and resamples it to 16 kHz. - Skips conversion if the output file already exists. - - Args: - input_file (str): Path to the input audio file (e.g., .ogg, .mp3). - output_file (str): Path to save the converted and resampled .wav file. - """ - print("start conversion") - if os.path.exists(output_file): - print(f"Skipped (already exists): {output_file}") - return - - try: - # Load the input audio file - audio = AudioSegment.from_file(input_file) - #set quantisation - audio_quant16 = audio.set_sample_width(2) # 2 bytes = 16 bit - # Resample to 16 kHz - audio_16k = audio_quant16.set_frame_rate(16000) - # Export as .wav - audio_16k.export(output_file, format="wav") - print(f"Conversion and resampling successful: {output_file}") - except Exception as e: - print(f"Error during conversion and resampling: {e}") - - -def batch_convert_and_resample(input_root, output_root, convert_and_resample, max_folders=None): - """ - Walk through input_root, find all .ogg files, and convert them to .wav - in output_root with the same folder structure. - - Parameters: - input_root (str): Path to the root folder containing .ogg files. - output_root (str): Path where converted .wav files will be saved. - convert_and_resample (func): Function that takes (in_path, out_path). - max_folders (int, optional): If set, only process the first N subfolders. - """ - # List top-level subfolders in input_root - subfolders = sorted( - [os.path.join(input_root, d) for d in os.listdir(input_root) - if os.path.isdir(os.path.join(input_root, d))] - ) - print("start conversion") - # Limit to first N folders if requested - if max_folders is not None: - subfolders = subfolders[:max_folders] - - for folder in subfolders: - for dirpath, _, filenames in os.walk(folder): - for filename in filenames: - if filename.lower().endswith(".ogg") or filename.lower().endswith(".wav"): - in_path = os.path.join(dirpath, filename) - - # Build matching output path - rel_path = os.path.relpath(in_path, input_root) - rel_path_no_ext = os.path.splitext(rel_path)[0] + ".wav" - out_path = os.path.join(output_root, rel_path_no_ext) - - # Ensure output directory exists - os.makedirs(os.path.dirname(out_path), exist_ok=True) - - # Convert - convert_and_resample(in_path, out_path) - print(f"Converted: {in_path} -> {out_path}") \ No newline at end of file From 6284871eb41ae0ba3e143cce2195e67f0bc8c981 Mon Sep 17 00:00:00 2001 From: David Pellhammer Date: Tue, 25 Nov 2025 12:37:40 +0000 Subject: [PATCH 09/11] added runnable jupyter notebook --- notebooks/train_nightingale_2.ipynb | 191 ++++++++++++++++++++-------- 1 file changed, 140 insertions(+), 51 deletions(-) diff --git a/notebooks/train_nightingale_2.ipynb b/notebooks/train_nightingale_2.ipynb index f5c2258..c709dd2 100644 --- a/notebooks/train_nightingale_2.ipynb +++ b/notebooks/train_nightingale_2.ipynb @@ -2,14 +2,17 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 38, "id": "a9cd6428", "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import os\n", - "import tensorflow as tf" + "import tensorflow as tf\n", + "from sklearn.model_selection import train_test_split\n", + "import tensorflow_hub as hub\n", + "\n" ] }, { @@ -22,7 +25,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 39, "id": "d504fa73", "metadata": {}, "outputs": [ @@ -96,7 +99,7 @@ "type": "string" } ], - "ref": "d2523eaa-58de-498e-af9d-1b8fff2b44c3", + "ref": "8b388208-6c6d-4e82-bf7e-042781df15b5", "rows": [ [ "0", @@ -329,7 +332,7 @@ "4 https://www.xeno-canto.org/209218 asbfly/XC209218.ogg " ] }, - "execution_count": 24, + "execution_count": 39, "metadata": {}, "output_type": "execute_result" } @@ -337,13 +340,14 @@ "source": [ "# Read train meta data\n", "train_metadata_path = \"../data/birdclef-2024/train_metadata.csv\"\n", + "\n", "train_df = pd.read_csv(train_metadata_path)\n", "train_df.head()" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 40, "id": "71495869", "metadata": {}, "outputs": [ @@ -372,7 +376,7 @@ "type": "float" } ], - "ref": "6ad0bd56-fe4a-4746-bb70-95031c01fa68", + "ref": "c1d21358-84af-4dfd-9d74-caa6c4d616a1", "rows": [ [ "count", @@ -517,7 +521,7 @@ "max 71.964000 177.447800 5.000000" ] }, - "execution_count": 25, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } @@ -536,7 +540,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 41, "id": "b9c56857", "metadata": {}, "outputs": [ @@ -570,15 +574,24 @@ } ], "source": [ - "from nightingale.data_pipeline.audio_preprocessor import AudioPreprocessor\n", + "data_input_root = \"../data/birdclef-2024/train_audio\"\n", + "data_output_root = \"../data/birdclef-2024/train_audio_16\"\n", "\n", + "from nightingale.data_pipeline.audio_preprocessor import AudioPreprocessor\n", "# convert data if necessary\n", "preprocessor = AudioPreprocessor()\n", - "# Read train meta data. Convert to yamnet compatible format. Skip if file already exists.\n", + "\n", + "## Batch convert a complete dataset and store\n", + "# Read train meta data. Convert to yamnet compatible format. Skip if file already exists. Reproduce folder structure.\n", "preprocessor.process_folder(\n", - " input_root=\"../data/birdclef-2024/train_audio\",\n", - " output_root=\"../data/birdclef-2024/train_audio_16\",\n", - ")" + " input_root= data_input_root,\n", + " output_root= data_output_root,\n", + ")\n", + "\n", + "## Load single file\n", + "# input_audio_path = \"../data/birdclef-2024/train_audio/cohcuc1/XC19645.wav\"\n", + "# output_audio_path = \"../XC19645.wav\"\n", + "# audio_tensor = preprocessor.process_file(input_audio_path, output_audio_path)\n" ] }, { @@ -591,7 +604,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 42, "id": "6ef7c047", "metadata": {}, "outputs": [ @@ -623,15 +636,76 @@ }, { "cell_type": "code", - "execution_count": 28, - "id": "62a4886f", + "execution_count": 43, + "id": "0fb6207d", "metadata": {}, "outputs": [], "source": [ - "from nightingale.data_pipeline.audio_dataset_splitter import AudioDatasetSplitter\n", + "# Step 1: Split the data into training (60%), validation (20%) and test (20%) sets\n", + "train_df_idx, temp_df_idx = train_test_split(filtered_bird_df.index, test_size=0.4, random_state=42, stratify=filtered_bird_df['target'])\n", + "val_df_idx, test_df_idx = train_test_split(temp_df_idx, test_size=0.5, random_state=42, stratify=filtered_bird_df.loc[temp_df_idx, 'target'])\n", "\n", - "data_split = AudioDatasetSplitter()\n", - "train_ds, val_ds, test_ds = data_split.build(filtered_bird_df)" + "# Step 2: Create 'fold' column in original filtered_bird_df\n", + "filtered_bird_df['fold'] = '' # initialize empty\n", + "filtered_bird_df.loc[train_df_idx, 'fold'] = 1\n", + "filtered_bird_df.loc[val_df_idx, 'fold'] = 2\n", + "filtered_bird_df.loc[test_df_idx, 'fold'] = 3\n", + "\n", + "# filtered_bird_df.head(10)\n", + "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 1]['target'], bins=len(bird_classes), alpha=0.7, label='Train')\n", + "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 2]['target'], bins=len(bird_classes), alpha=0.7, label='Val')\n", + "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 3]['target'], bins=len(bird_classes), alpha=0.7, label='Test')\n", + "# plt.xlabel('Bird Classes')\n", + "# plt.ylabel('Count')\n", + "# plt.title('Distribution of Bird Classes in Train, Val, and Test Sets')\n", + "# plt.legend()\n", + "# plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "8433d3f5", + "metadata": {}, + "outputs": [], + "source": [ + "filenames_train = filtered_bird_df[filtered_bird_df['fold'] == 1]['filename']\n", + "targets_train = filtered_bird_df[filtered_bird_df['fold'] == 1]['target']\n", + "\n", + "filenames_val = filtered_bird_df[filtered_bird_df['fold'] == 2]['filename']\n", + "targets_val = filtered_bird_df[filtered_bird_df['fold'] == 2]['target']\n", + "\n", + "filenames_test = filtered_bird_df[filtered_bird_df['fold'] == 3]['filename']\n", + "targets_test = filtered_bird_df[filtered_bird_df['fold'] == 3]['target']\n", + "\n", + "\n", + "train_ds = tf.data.Dataset.from_tensor_slices((filenames_train, targets_train))\n", + "val_ds = tf.data.Dataset.from_tensor_slices((filenames_val, targets_val))\n", + "test_ds = tf.data.Dataset.from_tensor_slices((filenames_test, targets_test))\n", + "\n", + "def load_wav_for_map(filename, label):\n", + " \"\"\"\n", + " Read and decode a WAV file into a mono waveform tensor.\n", + "\n", + " Uses tf.io.read_file + tf.audio.decode_wav to load the file, squeezes the\n", + " channel dimension so the returned tensor has shape [num_samples].\n", + "\n", + " Args:\n", + " filename: path to the audio file (string tensor).\n", + " label: associated label.\n", + "\n", + " Returns:\n", + " (wav, label): tuple where wav is a 1-D float32 tensor and label is unchanged.\n", + " \"\"\"\n", + " audio = tf.io.read_file(filename)\n", + " wav, sr = tf.audio.decode_wav(audio, desired_channels=1)\n", + " # Remove the trailing channel dimension -> shape [num_samples]\n", + " wav = tf.squeeze(wav, axis=-1)\n", + " return wav, label\n", + "\n", + "train_ds = train_ds.map(load_wav_for_map)\n", + "val_ds = val_ds.map(load_wav_for_map)\n", + "test_ds = test_ds.map(load_wav_for_map)" ] }, { @@ -644,27 +718,30 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 45, "id": "5aca4873", "metadata": {}, "outputs": [], "source": [ - "from nightingale.model.yamnet_base import YamnetEmbedding\n", - "\n", - "#object of the yamnet Model\n", - "yam = YamnetEmbedding()" + "model = hub.load('https://tfhub.dev/google/yamnet/1')\n", + "def extract_embedding(wav_data, label):\n", + " ''' run YAMNet to extract embedding from the wav data '''\n", + " scores, embeddings, spectrogram = model(wav_data)\n", + " num_embeddings = tf.shape(embeddings)[0]\n", + " return (embeddings,\n", + " tf.repeat(label, num_embeddings))" ] }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 46, "id": "1852e16e", "metadata": {}, "outputs": [], "source": [ - "train_ds = train_ds.map(yam).unbatch()\n", - "val_ds = val_ds.map(yam).unbatch()\n", - "test_ds = test_ds.map(yam).unbatch()\n", + "train_ds = train_ds.map(extract_embedding).unbatch()\n", + "val_ds = val_ds.map(extract_embedding).unbatch()\n", + "test_ds = test_ds.map(extract_embedding).unbatch()\n", "train_ds.element_spec\n", "\n", "train_ds = train_ds.cache().shuffle(1000).batch(32).prefetch(tf.data.AUTOTUNE)\n", @@ -682,18 +759,18 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 47, "id": "c1b433b4", "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
Model: \"classifier_head_1\"\n",
+       "
Model: \"classifier_head\"\n",
        "
\n" ], "text/plain": [ - "\u001b[1mModel: \"classifier_head_1\"\u001b[0m\n" + "\u001b[1mModel: \"classifier_head\"\u001b[0m\n" ] }, "metadata": {}, @@ -705,9 +782,9 @@ "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
        "┃ Layer (type)                     Output Shape                  Param # ┃\n",
        "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
-       "│ dense_2 (Dense)                 │ ?                      │   0 (unbuilt) │\n",
+       "│ dense (Dense)                   │ ?                      │   0 (unbuilt) │\n",
        "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
-       "│ dense_3 (Dense)                 │ ?                      │   0 (unbuilt) │\n",
+       "│ dense_1 (Dense)                 │ ?                      │   0 (unbuilt) │\n",
        "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
        "
\n" ], @@ -715,9 +792,9 @@ "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n", "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n", "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n", - "│ dense_2 (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", + "│ dense (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", - "│ dense_3 (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", + "│ dense_1 (\u001b[38;5;33mDense\u001b[0m) │ ? │ \u001b[38;5;34m0\u001b[0m (unbuilt) │\n", "└─────────────────────────────────┴────────────────────────┴───────────────┘\n" ] }, @@ -774,7 +851,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 48, "id": "3c380b83", "metadata": {}, "outputs": [], @@ -806,7 +883,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 49, "id": "5256d5fc", "metadata": {}, "outputs": [ @@ -829,13 +906,15 @@ "name": "stdout", "output_type": "stream", "text": [ - " 18/Unknown \u001b[1m3s\u001b[0m 3ms/step - accuracy: 0.7579 - loss: 0.6477" + " 14/Unknown \u001b[1m2s\u001b[0m 4ms/step - accuracy: 0.6383 - loss: 0.7548" ] }, { "name": "stderr", "output_type": "stream", "text": [ + "2025-11-25 12:36:22.157308: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n", "/workspaces/nightingale/.venv/lib/python3.11/site-packages/keras/src/trainers/epoch_iterator.py:164: UserWarning: Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least `steps_per_epoch * epochs` batches. You may need to use the `.repeat()` function when building your dataset.\n", " self._interrupted_warning()\n" ] @@ -844,24 +923,34 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 34ms/step - accuracy: 0.8949 - loss: 0.3456 - val_accuracy: 0.9346 - val_loss: 0.2245\n", + "\u001b[1m25/25\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 61ms/step - accuracy: 0.8582 - loss: 0.3638 - val_accuracy: 0.9267 - val_loss: 0.2084\n", "Epoch 2/5\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9660 - loss: 0.1097 - val_accuracy: 0.9085 - val_loss: 0.1891\n", + "\u001b[1m25/25\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 3ms/step - accuracy: 0.9699 - loss: 0.1017 - val_accuracy: 0.9400 - val_loss: 0.1792\n", "Epoch 3/5\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9766 - loss: 0.0792 - val_accuracy: 0.9314 - val_loss: 0.1977\n", + "\u001b[1m25/25\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9812 - loss: 0.0634 - val_accuracy: 0.9444 - val_loss: 0.1663\n", "Epoch 4/5\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9915 - loss: 0.0442 - val_accuracy: 0.9346 - val_loss: 0.1977\n", - "Epoch 5/5\n", - "\u001b[1m30/30\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9904 - loss: 0.0359 - val_accuracy: 0.9314 - val_loss: 0.1988\n" + "\u001b[1m25/25\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.9862 - loss: 0.0449 - val_accuracy: 0.9222 - val_loss: 0.1945\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "2025-11-25 09:16:11.687201: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "2025-11-25 12:36:23.534349: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n", + "2025-11-25 12:36:23.617490: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", + "\t [[{{node IteratorGetNext}}]]\n", + "2025-11-25 12:36:23.734711: I tensorflow/core/framework/local_rendezvous.cc:407] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n", "\t [[{{node IteratorGetNext}}]]\n" ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 5/5\n", + "\u001b[1m25/25\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 4ms/step - accuracy: 0.9912 - loss: 0.0343 - val_accuracy: 0.9378 - val_loss: 0.1777\n" + ] } ], "source": [ @@ -881,7 +970,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 50, "id": "bd931dfe", "metadata": {}, "outputs": [ @@ -889,9 +978,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "\u001b[1m17/17\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 66ms/step - accuracy: 0.8694 - loss: 0.3808\n", - "Loss: 0.38082048296928406\n", - "Accuracy: 0.8693957328796387\n" + "\u001b[1m17/17\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 63ms/step - accuracy: 0.8969 - loss: 0.3787\n", + "Loss: 0.3786546289920807\n", + "Accuracy: 0.8968871831893921\n" ] } ], @@ -912,7 +1001,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 51, "id": "ba9a394a", "metadata": {}, "outputs": [], From a1342f8f7f42651220394bc368cb94f1126edd60 Mon Sep 17 00:00:00 2001 From: David Pellhammer Date: Tue, 25 Nov 2025 12:37:51 +0000 Subject: [PATCH 10/11] adjusted notebook --- notebooks/train_nightingale.ipynb | 61 +++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/notebooks/train_nightingale.ipynb b/notebooks/train_nightingale.ipynb index c5b5a8d..abfa933 100644 --- a/notebooks/train_nightingale.ipynb +++ b/notebooks/train_nightingale.ipynb @@ -478,15 +478,68 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "9a647265", "metadata": {}, "outputs": [], "source": [ - "from nightingale.data_pipeline.audio_dataset_splitter import AudioDatasetSplitter\n", + "# Step 1: Split the data into training (60%), validation (20%) and test (20%) sets\n", + "train_df_idx, temp_df_idx = train_test_split(filtered_bird_df.index, test_size=0.4, random_state=42, stratify=filtered_bird_df['target'])\n", + "val_df_idx, test_df_idx = train_test_split(temp_df_idx, test_size=0.5, random_state=42, stratify=filtered_bird_df.loc[temp_df_idx, 'target'])\n", + "\n", + "# Step 2: Create 'fold' column in original filtered_bird_df\n", + "filtered_bird_df['fold'] = '' # initialize empty\n", + "filtered_bird_df.loc[train_df_idx, 'fold'] = 1\n", + "filtered_bird_df.loc[val_df_idx, 'fold'] = 2\n", + "filtered_bird_df.loc[test_df_idx, 'fold'] = 3\n", + "\n", + "# filtered_bird_df.head(10)\n", + "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 1]['target'], bins=len(bird_classes), alpha=0.7, label='Train')\n", + "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 2]['target'], bins=len(bird_classes), alpha=0.7, label='Val')\n", + "# plt.hist(filtered_bird_df[filtered_bird_df['fold'] == 3]['target'], bins=len(bird_classes), alpha=0.7, label='Test')\n", + "# plt.xlabel('Bird Classes')\n", + "# plt.ylabel('Count')\n", + "# plt.title('Distribution of Bird Classes in Train, Val, and Test Sets')\n", + "# plt.legend()\n", + "# plt.show()\n", + "\n", + "filenames_train = filtered_bird_df[filtered_bird_df['fold'] == 1]['filename']\n", + "targets_train = filtered_bird_df[filtered_bird_df['fold'] == 1]['target']\n", + "\n", + "filenames_val = filtered_bird_df[filtered_bird_df['fold'] == 2]['filename']\n", + "targets_val = filtered_bird_df[filtered_bird_df['fold'] == 2]['target']\n", + "\n", + "filenames_test = filtered_bird_df[filtered_bird_df['fold'] == 3]['filename']\n", + "targets_test = filtered_bird_df[filtered_bird_df['fold'] == 3]['target']\n", + "\n", + "\n", + "train_ds = tf.data.Dataset.from_tensor_slices((filenames_train, targets_train))\n", + "val_ds = tf.data.Dataset.from_tensor_slices((filenames_val, targets_val))\n", + "test_ds = tf.data.Dataset.from_tensor_slices((filenames_test, targets_test))\n", + "\n", + "def load_wav_for_map(filename, label):\n", + " \"\"\"\n", + " Read and decode a WAV file into a mono waveform tensor.\n", + "\n", + " Uses tf.io.read_file + tf.audio.decode_wav to load the file, squeezes the\n", + " channel dimension so the returned tensor has shape [num_samples].\n", + "\n", + " Args:\n", + " filename: path to the audio file (string tensor).\n", + " label: associated label.\n", + "\n", + " Returns:\n", + " (wav, label): tuple where wav is a 1-D float32 tensor and label is unchanged.\n", + " \"\"\"\n", + " audio = tf.io.read_file(filename)\n", + " wav, sr = tf.audio.decode_wav(audio, desired_channels=1)\n", + " # Remove the trailing channel dimension -> shape [num_samples]\n", + " wav = tf.squeeze(wav, axis=-1)\n", + " return wav, label\n", "\n", - "data_split = AudioDatasetSplitter()\n", - "train_ds, val_ds, test_ds = data_split.build(filtered_bird_df)" + "train_ds = train_ds.map(load_wav_for_map)\n", + "val_ds = val_ds.map(load_wav_for_map)\n", + "test_ds = test_ds.map(load_wav_for_map)" ] }, { From 19a98c744d5de7b041492bdde378e5602f2b4494 Mon Sep 17 00:00:00 2001 From: David Pellhammer Date: Tue, 25 Nov 2025 14:20:59 +0000 Subject: [PATCH 11/11] adjusted wav loader --- notebooks/load_birdclallclassifier.ipynb | 45 ++++++++++++++++++------ 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/notebooks/load_birdclallclassifier.ipynb b/notebooks/load_birdclallclassifier.ipynb index dccdefc..fb1888a 100644 --- a/notebooks/load_birdclallclassifier.ipynb +++ b/notebooks/load_birdclallclassifier.ipynb @@ -2,31 +2,33 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "148505fc", "metadata": {}, "outputs": [], "source": [ "import tensorflow as tf\n", "from nightingale.model.bird_call_classifier import BirdCallClassifier\n", - "from nightingale.data_pipeline.wav_loader import load_wav_16k_mono" + "from nightingale.data_pipeline.audio_preprocessor import AudioPreprocessor\n", + "# convert data if necessary\n" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "594d6080", "metadata": {}, "outputs": [], "source": [ - "wav1 = load_wav_16k_mono(\"../data/birdclef-2024/train_audio_16/cohcuc1/XC19645.wav\")\n", - "wav2 = load_wav_16k_mono(\"../data/birdclef-2024/train_audio_16/integr/XC810654.wav\")\n", - "wav3 = load_wav_16k_mono(\"../data/birdclef-2024/train_audio_16/tilwar1/XC191454.wav\")" + "preprocessor = AudioPreprocessor()\n", + "wav1,sr1 = preprocessor.load_audio(\"../data/birdclef-2024/train_audio_16/cohcuc1/XC19645.wav\")\n", + "wav2,sr2 = preprocessor.load_audio(\"../data/birdclef-2024/train_audio_16/integr/XC810654.wav\")\n", + "wav3,sr3 = preprocessor.load_audio(\"../data/birdclef-2024/train_audio_16/tilwar1/XC191454.wav\")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "0855a68f", "metadata": {}, "outputs": [], @@ -36,10 +38,31 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "047543cf", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2025-11-25 14:19:39.536124: W external/local_xla/xla/tsl/framework/cpu_allocator_impl.cc:84] Allocation of 22413312 exceeds 10% of free system memory.\n", + "2025-11-25 14:19:39.539009: W external/local_xla/xla/tsl/framework/cpu_allocator_impl.cc:84] Allocation of 22413312 exceeds 10% of free system memory.\n", + "2025-11-25 14:19:39.615155: W external/local_xla/xla/tsl/framework/cpu_allocator_impl.cc:84] Allocation of 21037056 exceeds 10% of free system memory.\n", + "2025-11-25 14:19:39.618458: W external/local_xla/xla/tsl/framework/cpu_allocator_impl.cc:84] Allocation of 21037056 exceeds 10% of free system memory.\n", + "2025-11-25 14:19:39.623203: W external/local_xla/xla/tsl/framework/cpu_allocator_impl.cc:84] Allocation of 21037056 exceeds 10% of free system memory.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Common Hawk-Cuckoo\n", + "Common Hawk-Cuckoo\n", + "Common Hawk-Cuckoo\n" + ] + } + ], "source": [ "print(model.predict(wav1))\n", "print(model.predict(wav2))\n", @@ -49,7 +72,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "nightingale", "language": "python", "name": "python3" }, @@ -63,7 +86,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.12" + "version": "3.11.14" } }, "nbformat": 4,