{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# may thanks to Awsaf for the baseline [here](https://www.kaggle.com/code/awsaf49/birdclef23-pretraining-is-all-you-need-infer)","metadata":{}},{"cell_type":"markdown","source":"# BirdCLEF 2023 🐦\n> Identify bird calls in soundscapes\n\n<img src=\"https://storage.googleapis.com/kaggle-competitions/kaggle/44224/logos/header.png?t=2023-03-06-18-30-53\">","metadata":{}},{"cell_type":"markdown","source":"# Methodology  🎯\n* This notebook will demonstrate **Bird Call Identification** with `TensorFlow`. Specifically, this notebook shows inference for [BirdCLEF23: Pretraining is All you Need [Train]](https://www.kaggle.com/awsaf49/birdclef23-pretraining-is-all-you-need-infer), where mdoel is initially **pretrained** on BirdCLEF 2021 & 2022 dataset, and then **fine-tuned** in BirdCLEF 2023 dataset.\n* This notebook differs from previous [notebook](https://www.kaggle.com/awsaf49/birdclef23-effnet-fsr-cutmixup-train/) as unlike previous notebook where model is fed with spectrogram, current notebook feds  raw audio to model.\n* Raw audio is processed using pre-processing layers from [tensorflow-extra](github.com/awsaf49/tensorflow_extra) library.\n* This notebook will use `5sec` audio recording as per requirements. But training is done on much more larger size recording. Dynamic shape is utilize to infer on a different resolution.\n* This notebook will consider one recording as one batch which will speed up the processing.","metadata":{}},{"cell_type":"markdown","source":"# Notebooks 📓\n\n* Pretraining is All you Need\n    * Train: [BirdCLEF23: Pretraining is All you Need [Train]](https://www.kaggle.com/awsaf49/birdclef23-pretraining-is-all-you-need-train/)\n    * Infer: [BirdCLEF23: Pretraining is All you Need [Infer]](https://www.kaggle.com/awsaf49/birdclef23-pretraining-is-all-you-need-infer/)\n    \n    \n* EffNet + FSR + CutMixUp\n    * Train: [BirdCLEF23: EffNet + FSR + CutMixUp [Train]](https://www.kaggle.com/awsaf49/birdclef23-effnet-fsr-cutmixup-train/)\n    * Infer: [BirdCLEF23: EffNet + FSR + CutMixUp [Infer]](https://www.kaggle.com/awsaf49/birdclef23-effnet-fsr-cutmixup-infer/)\n","metadata":{}},{"cell_type":"markdown","source":"# Update 🆕\n* `v4`:\n    * BirdCLEF 2020 & Xeno-Canto Extend Dataset added","metadata":{}},{"cell_type":"markdown","source":"# Install Libraries 🛠","metadata":{"papermill":{"duration":0.062037,"end_time":"2022-03-08T03:15:20.082763","exception":false,"start_time":"2022-03-08T03:15:20.020726","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import sys, os\nsys.path.append('/kaggle/input/efficientnet-keras-dataset/efficientnet_kaggle')\n!pip install -q /kaggle/input/tensorflow-extra-lib-ds/tensorflow_extra-1.0.2-py3-none-any.whl --no-deps","metadata":{"execution":{"iopub.status.busy":"2023-03-31T19:40:17.44896Z","iopub.execute_input":"2023-03-31T19:40:17.449441Z","iopub.status.idle":"2023-03-31T19:40:40.003275Z","shell.execute_reply.started":"2023-03-31T19:40:17.449406Z","shell.execute_reply":"2023-03-31T19:40:40.001335Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Import Libraries 📚","metadata":{"papermill":{"duration":0.065343,"end_time":"2022-03-08T03:18:11.885586","exception":false,"start_time":"2022-03-08T03:18:11.820243","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import tensorflow as tf\ntf.get_logger().setLevel('ERROR')\ntf.autograph.set_verbosity(0)\nimport os\nimport pandas as pd\nimport numpy as np\nimport random\nfrom glob import glob\nfrom tqdm import tqdm\ntqdm.pandas()\nimport gc\nimport librosa\nimport sklearn\nimport time\n\nimport matplotlib as mpl\nimport matplotlib.pyplot as plt\nimport librosa.display as lid\nimport IPython.display as ipd\n\nimport tensorflow as tf\ntf.config.optimizer.set_jit(True) # enable xla for speed up\nimport tensorflow_io as tfio\nimport tensorflow.keras.backend as K\n\nimport efficientnet.tfkeras as efn\nimport tensorflow_extra as tfe","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":2.632068,"end_time":"2022-03-08T03:18:14.585094","exception":false,"start_time":"2022-03-08T03:18:11.953026","status":"completed"},"tags":[],"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-03-31T19:40:40.007439Z","iopub.execute_input":"2023-03-31T19:40:40.007933Z","iopub.status.idle":"2023-03-31T19:40:40.023517Z","shell.execute_reply.started":"2023-03-31T19:40:40.007892Z","shell.execute_reply":"2023-03-31T19:40:40.021805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Library Version","metadata":{"papermill":{"duration":0.065649,"end_time":"2022-03-08T03:18:14.717311","exception":false,"start_time":"2022-03-08T03:18:14.651662","status":"completed"},"tags":[]}},{"cell_type":"code","source":"print('np:', np.__version__)\nprint('pd:', pd.__version__)\nprint('sklearn:', sklearn.__version__)\nprint('librosa:', librosa.__version__)\nprint('tf:', tf.__version__)\nprint('tfio:', tfio.__version__)","metadata":{"papermill":{"duration":0.155095,"end_time":"2022-03-08T03:18:14.939054","exception":false,"start_time":"2022-03-08T03:18:14.783959","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-31T19:40:40.025472Z","iopub.execute_input":"2023-03-31T19:40:40.025906Z","iopub.status.idle":"2023-03-31T19:40:40.045481Z","shell.execute_reply.started":"2023-03-31T19:40:40.025864Z","shell.execute_reply":"2023-03-31T19:40:40.043773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Configuration ⚙️","metadata":{"papermill":{"duration":0.066353,"end_time":"2022-03-08T03:18:18.099835","exception":false,"start_time":"2022-03-08T03:18:18.033482","status":"completed"},"tags":[]}},{"cell_type":"code","source":"class CFG:\n    debug = False\n    verbose = 0\n    \n    device = 'CPU'\n    seed = 42\n    \n    # Input image size and batch size\n    img_size = [128, 384]\n    batch_size = 16\n    infer_bs = 2\n    tta = 1\n    drop_remainder = True\n    \n    # STFT parameters\n    duration = 5 # duration for test\n    train_duration = 10\n    sample_rate = 32000\n    downsample = 1\n    audio_len = duration*sample_rate\n    nfft = 2028\n    window = 2048\n    hop_length = train_duration*32000 // (img_size[1] - 1)\n    fmin = 20\n    fmax = 16000\n    normalize = True\n\n    # Data Preprocessing Settings\n    class_names = sorted(os.listdir('/kaggle/input/birdclef-2023/train_audio/'))\n    num_classes = len(class_names)\n    class_labels = list(range(num_classes))\n    label2name = dict(zip(class_labels, class_names))\n    name2label = {v:k for k,v in label2name.items()}\n    \n    target_col = ['target']\n    tab_cols = ['filename','common_name','rate']","metadata":{"papermill":{"duration":0.156464,"end_time":"2022-03-08T03:18:18.322809","exception":false,"start_time":"2022-03-08T03:18:18.166345","status":"completed"},"tags":[],"_kg_hide-input":false,"execution":{"iopub.status.busy":"2023-03-31T19:40:40.047761Z","iopub.execute_input":"2023-03-31T19:40:40.048338Z","iopub.status.idle":"2023-03-31T19:40:40.063889Z","shell.execute_reply.started":"2023-03-31T19:40:40.048298Z","shell.execute_reply":"2023-03-31T19:40:40.062314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Reproducibility ♻️\nSets value for random seed to produce similar result in each run.","metadata":{"papermill":{"duration":0.070351,"end_time":"2022-03-08T03:18:18.46058","exception":false,"start_time":"2022-03-08T03:18:18.390229","status":"completed"},"tags":[]}},{"cell_type":"code","source":"tf.keras.utils.set_random_seed(CFG.seed)","metadata":{"papermill":{"duration":0.153451,"end_time":"2022-03-08T03:18:18.685056","exception":false,"start_time":"2022-03-08T03:18:18.531605","status":"completed"},"tags":[],"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-03-31T19:40:40.069395Z","iopub.execute_input":"2023-03-31T19:40:40.069837Z","iopub.status.idle":"2023-03-31T19:40:40.129742Z","shell.execute_reply.started":"2023-03-31T19:40:40.069798Z","shell.execute_reply":"2023-03-31T19:40:40.12798Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Set Up Device  📱\nFollowing codes automatically detects hardware(tpu or tpu-vm or gpu). ","metadata":{"papermill":{"duration":0.065779,"end_time":"2022-03-08T03:18:18.817867","exception":false,"start_time":"2022-03-08T03:18:18.752088","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def get_device():\n    \"Detect and intializes GPU/TPU automatically\"\n    # Check TPU category\n    tpu = 'local' if CFG.device=='TPU-VM' else None\n    try:\n        # Connect to TPU\n        tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect(tpu=tpu) \n        # Set TPU strategy\n        strategy = tf.distribute.TPUStrategy(tpu)\n        print(f'> Running on {CFG.device} ', tpu.master(), end=' | ')\n        print('Num of TPUs: ', strategy.num_replicas_in_sync)\n        device=CFG.device\n    except:\n        # If TPU is not available, detect GPUs\n        gpus = tf.config.list_logical_devices('GPU')\n        ngpu = len(gpus)\n         # Check number of GPUs\n        if ngpu:\n            # Set GPU strategy\n            strategy = tf.distribute.MirroredStrategy(gpus) # single-GPU or multi-GPU\n            # Print GPU details\n            print(\"> Running on GPU\", end=' | ')\n            print(\"Num of GPUs: \", ngpu)\n            device='GPU'\n        else:\n            # If no GPUs are available, use CPU\n            print(\"> Running on CPU\")\n            strategy = tf.distribute.get_strategy()\n            device='CPU'\n    return strategy, device, tpu","metadata":{"_kg_hide-input":true,"papermill":{"duration":7.941725,"end_time":"2022-03-08T03:18:26.826553","exception":false,"start_time":"2022-03-08T03:18:18.884828","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-31T19:40:40.135258Z","iopub.execute_input":"2023-03-31T19:40:40.135769Z","iopub.status.idle":"2023-03-31T19:40:40.148573Z","shell.execute_reply.started":"2023-03-31T19:40:40.135725Z","shell.execute_reply":"2023-03-31T19:40:40.146795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Initialize GPU/TPU/TPU-VM\nstrategy, CFG.device, tpu = get_device()\nCFG.replicas = strategy.num_replicas_in_sync","metadata":{"execution":{"iopub.status.busy":"2023-03-31T19:40:40.150699Z","iopub.execute_input":"2023-03-31T19:40:40.151113Z","iopub.status.idle":"2023-03-31T19:40:40.171126Z","shell.execute_reply.started":"2023-03-31T19:40:40.151078Z","shell.execute_reply":"2023-03-31T19:40:40.169601Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset Path 📁","metadata":{}},{"cell_type":"code","source":"BASE_PATH = '/kaggle/input/birdclef-2023'\nGCS_PATH = BASE_PATH","metadata":{"execution":{"iopub.status.busy":"2023-03-31T19:40:40.172989Z","iopub.execute_input":"2023-03-31T19:40:40.17338Z","iopub.status.idle":"2023-03-31T19:40:40.182224Z","shell.execute_reply.started":"2023-03-31T19:40:40.173347Z","shell.execute_reply":"2023-03-31T19:40:40.181141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Meta Data 📖\n* **test_soundscapes/** - directory contains $~200$ recordings to be used for scoring when a notebook is submitted. Without submission only $1$ recording is accessible.  All recordings are $10$ minutes long and in `.ogg` audio format.\n* **sample_submission.csv** - is the valid sample submission.\n    * `row_id`: A slug of [soundscape_id]_[end_time] for the prediction.\n    * `[bird_id]`: There are $264$ bird ID columns. The probability of the presence of each bird for each row needs to be predicted.","metadata":{"papermill":{"duration":0.067107,"end_time":"2022-03-08T03:18:26.962626","exception":false,"start_time":"2022-03-08T03:18:26.895519","status":"completed"},"tags":[]}},{"cell_type":"code","source":"test_paths = glob('/kaggle/input/birdclef-2023/test_soundscapes/*ogg')\ntest_df = pd.DataFrame(test_paths, columns=['filepath'])\ntest_df['filename'] = test_df.filepath.map(lambda x: x.split('/')[-1].replace('.ogg',''))\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-03-31T19:40:40.18349Z","iopub.execute_input":"2023-03-31T19:40:40.183899Z","iopub.status.idle":"2023-03-31T19:40:40.209784Z","shell.execute_reply.started":"2023-03-31T19:40:40.183863Z","shell.execute_reply":"2023-03-31T19:40:40.206785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.io.gfile.exists(test_df.filepath.iloc[0])","metadata":{"papermill":{"duration":0.244976,"end_time":"2022-03-08T03:18:33.994955","exception":false,"start_time":"2022-03-08T03:18:33.749979","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-31T19:40:40.211549Z","iopub.execute_input":"2023-03-31T19:40:40.212416Z","iopub.status.idle":"2023-03-31T19:40:40.223951Z","shell.execute_reply.started":"2023-03-31T19:40:40.212377Z","shell.execute_reply":"2023-03-31T19:40:40.22232Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Loader 🍚","metadata":{"papermill":{"duration":0.077969,"end_time":"2022-03-08T03:18:36.503797","exception":false,"start_time":"2022-03-08T03:18:36.425828","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def load_audio(filepath, sr=32000, normalize=True):\n    audio, orig_sr = librosa.load(filepath, sr=None)\n    if sr!=orig_sr:\n        audio = librosa.resample(y, orig_sr, sr)\n    audio = audio.astype('float32').ravel()\n    audio = tf.convert_to_tensor(audio)\n    return audio\n\n@tf.function(jit_compile=True)\ndef MakeFrame(audio, duration=5, sr=32000):\n    frame_length = int(duration * sr)\n    frame_step = int(duration * sr)\n    chunks = tf.signal.frame(audio, frame_length, frame_step, pad_end=True)\n    return chunks","metadata":{"_kg_hide-input":true,"papermill":{"duration":0.251393,"end_time":"2022-03-08T03:18:36.833376","exception":false,"start_time":"2022-03-08T03:18:36.581983","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-31T19:40:40.22617Z","iopub.execute_input":"2023-03-31T19:40:40.227183Z","iopub.status.idle":"2023-03-31T19:40:40.240805Z","shell.execute_reply.started":"2023-03-31T19:40:40.227137Z","shell.execute_reply":"2023-03-31T19:40:40.239008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# EDA 🎨","metadata":{"papermill":{"duration":0.091062,"end_time":"2022-03-08T03:18:37.019504","exception":false,"start_time":"2022-03-08T03:18:36.928442","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"## Utility","metadata":{}},{"cell_type":"code","source":"def display_audio(row):\n    # Caption for viz\n    caption = f'Id: {row.filename}'\n    # Read audio file\n    audio = load_audio(row.filepath)\n    # Keep fixed length audio\n    audio = audio[:CFG.audio_len]\n    # Display audio\n    print(\"# Audio:\")\n    display(ipd.Audio(audio.numpy(), rate=CFG.sample_rate))\n    print('# Visualization:')\n    plt.figure(figsize=(12, 3))\n    plt.title(caption)\n    # Waveplot\n    lid.waveshow(audio.numpy(),\n                 sr=CFG.sample_rate,)\n                 \n    plt.xlabel('');\n    plt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-03-31T19:40:40.243505Z","iopub.execute_input":"2023-03-31T19:40:40.243919Z","iopub.status.idle":"2023-03-31T19:40:40.25816Z","shell.execute_reply.started":"2023-03-31T19:40:40.243881Z","shell.execute_reply":"2023-03-31T19:40:40.256913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Check","metadata":{}},{"cell_type":"code","source":"display_audio(test_df.iloc[0])","metadata":{"execution":{"iopub.status.busy":"2023-03-31T19:40:40.25949Z","iopub.execute_input":"2023-03-31T19:40:40.260112Z","iopub.status.idle":"2023-03-31T19:40:41.47974Z","shell.execute_reply.started":"2023-03-31T19:40:40.260071Z","shell.execute_reply":"2023-03-31T19:40:41.477659Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Inference Configs 🔧","metadata":{}},{"cell_type":"code","source":"# Directory of checkpoint\nCKPT_DIR = '/kaggle/input/birdclef23-pretraining-is-all-you-need-train-ds'\n# Get file paths of all trained models in the directory\nCKPT_PATHS = sorted([x for x in glob(f'{CKPT_DIR}/fold-*h5')])\nprint(\"Checkpoints: \", CKPT_PATHS)\n# Load all the models in memory to speed up\nCKPTS = [tf.keras.models.load_model(x, compile=False) for x in tqdm(CKPT_PATHS, desc=\"Loading ckpts \")]\n# Num of ckpt to use\nNUM_CKPTS = 1\n\n# Submit or Interactive mode\nSUBMIT = pd.read_csv('/kaggle/input/birdclef-2023/sample_submission.csv').shape[0] != 3","metadata":{"execution":{"iopub.status.busy":"2023-03-31T19:40:41.486699Z","iopub.execute_input":"2023-03-31T19:40:41.488159Z","iopub.status.idle":"2023-03-31T19:40:48.042486Z","shell.execute_reply.started":"2023-03-31T19:40:41.488096Z","shell.execute_reply":"2023-03-31T19:40:48.041056Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Inference 🧪","metadata":{"papermill":{"duration":0.151237,"end_time":"2022-03-08T03:18:47.959873","exception":false,"start_time":"2022-03-08T03:18:47.808636","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# Start stopwatch\ntick = time.time()\n\n# Initialize empty list to store ids\nids = []\n# Initialize empty array to store predictions\npreds = np.empty(shape=(0, 264), dtype='float32')\n\n# Iterate over each audio file in the test dataset\nfor filepath in tqdm(test_df.filepath.tolist(), 'test '):\n    # Extract the filename without the extension\n    filename = filepath.split('/')[-1].replace('.ogg','')\n    \n    # Load audio from file and create audio frames, each recording will be a batch input\n    audio = load_audio(filepath)\n    chunks = MakeFrame(audio)\n    \n    # Predict bird species for all frames in a recording using all trained models\n    chunk_preds = np.zeros(shape=(len(chunks), 264), dtype=np.float32)\n    for model in CKPTS[:NUM_CKPTS]:\n        # Get the model's predictions for the current audio frames\n        rec_preds = model(chunks, training=False).numpy()\n        # Ensemble all prediction with average\n        chunk_preds += rec_preds/len(CKPTS)\n    \n    # Create a ID for each frame in a recording using the filename and frame number\n    rec_ids = [f'{filename}_{(frame_id+1)*5}' for frame_id in range(len(chunks))]\n    \n    # Concatenate the ids\n    ids += rec_ids\n    # Concatenate the predictions\n    preds = np.concatenate([preds, chunk_preds], axis=0)\n    \n# Stop stopwatch\ntock = time.time()","metadata":{"execution":{"iopub.status.busy":"2023-03-31T19:40:48.04467Z","iopub.execute_input":"2023-03-31T19:40:48.04555Z","iopub.status.idle":"2023-03-31T19:41:22.093515Z","shell.execute_reply.started":"2023-03-31T19:40:48.045504Z","shell.execute_reply":"2023-03-31T19:41:22.09207Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# remove lowest predictions","metadata":{}},{"cell_type":"code","source":"for i in range(len(preds)):\n    for j in range(len(preds[i])):\n        if preds[i][j] > 0.00015: # arbitrary value\n            pass\n        else:\n            preds[i][j] = 0.0            \n    \n        if preds[i][j] < 0.99985: # arbitrary value\n            pass\n        else:\n            preds[i][j] = 0.0            \n","metadata":{"execution":{"iopub.status.busy":"2023-03-31T19:43:57.683316Z","iopub.execute_input":"2023-03-31T19:43:57.683828Z","iopub.status.idle":"2023-03-31T19:43:57.854216Z","shell.execute_reply.started":"2023-03-31T19:43:57.683788Z","shell.execute_reply":"2023-03-31T19:43:57.852517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submission 📮","metadata":{}},{"cell_type":"code","source":"# Submit prediction\npred_df = pd.DataFrame(ids, columns=['row_id'])\npred_df.loc[:, CFG.class_names] = preds\npred_df.to_csv('submission.csv',index=False)\npred_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-03-31T19:44:04.951407Z","iopub.execute_input":"2023-03-31T19:44:04.951902Z","iopub.status.idle":"2023-03-31T19:44:05.058475Z","shell.execute_reply.started":"2023-03-31T19:44:04.95186Z","shell.execute_reply":"2023-03-31T19:44:05.05684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Check Submission","metadata":{}},{"cell_type":"code","source":"if not SUBMIT:\n    pred_labels = pred_df[pred_df.columns[1:]].values.argmax(axis=1)\n    pred_classes = list(map(lambda x: CFG.label2name[x], pred_labels))\n    print(pred_classes)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-03-31T19:41:22.339679Z","iopub.status.idle":"2023-03-31T19:41:22.340166Z","shell.execute_reply.started":"2023-03-31T19:41:22.339951Z","shell.execute_reply":"2023-03-31T19:41:22.339976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submission Time ⏰\nEstimated time to complete the submission.\n> **Note**: There are nearly ~$200$ recordings on the test data.","metadata":{}},{"cell_type":"code","source":"sub_time = (tock-tick)*200 # ~200 recording on the test data\nsub_time = time.gmtime(sub_time)\nsub_time = time.strftime(\"%H hr: %M min : %S sec\", sub_time)\nprint(f\">> Time for submission: ~ {sub_time}\")","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-03-31T19:41:22.342279Z","iopub.status.idle":"2023-03-31T19:41:22.342872Z","shell.execute_reply.started":"2023-03-31T19:41:22.342608Z","shell.execute_reply":"2023-03-31T19:41:22.342641Z"},"trusted":true},"execution_count":null,"outputs":[]}]}