{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":70203,"databundleVersionId":8068726,"sourceType":"competition"},{"sourceId":41115,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":27205},{"sourceId":47155,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":26264}],"dockerImageVersionId":30673,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Code modified from [STEFAN KAHL](https://www.kaggle.com/stefankahl)'s [How to submit to BirdCLEF 2023](https://www.kaggle.com/code/stefankahl/how-to-submit-to-birdclef-2023). ","metadata":{}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport librosa\nimport tensorflow as tf\nimport shutil\nimport pathlib\nimport time\nimport pywt\n\nimport matplotlib.cm as cm\nfrom PIL import Image, ImageOps\nimport keras\n\nimage_size = 224\n# First, load list of audio files by parsing the test_soundscape folder.\ntest_audio_dir = '/kaggle/input/birdclef-2024/test_soundscapes/'\n\nrootdir = pathlib.Path(test_audio_dir)\nfile_list = list(rootdir.rglob('*.ogg'))\nif len(file_list) == 0:\n    print('Cant find test audio, using unlabel data.')\n    rootdir = pathlib.Path('/kaggle/input/birdclef-2024/unlabeled_soundscapes')\n    file_list = list(rootdir.rglob('*.ogg'))[-5:]\nprint('Number of test soundscapes:', len(file_list))","metadata":{"execution":{"iopub.status.busy":"2024-04-26T07:41:00.922278Z","iopub.execute_input":"2024-04-26T07:41:00.922790Z","iopub.status.idle":"2024-04-26T07:41:06.709409Z","shell.execute_reply.started":"2024-04-26T07:41:00.922755Z","shell.execute_reply":"2024-04-26T07:41:06.707245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#load model effnet pretrain model:\n#start_time = time.time()\n#source_dir = '/kaggle/input/effnet/keras/effinet/2/effinet.keras'\n#dest_dir = \"/kaggle/working/effinet.keras\"\n#shutil.copyfile(source_dir, dest_dir)\n#model = tf.keras.models.load_model('/kaggle/working/effinet.keras')\n#end_time = time.time()\n#print(\"load model used: {:.2f} seconds\".format(end_time - start_time))\n#CNN model\nsource_dir = '/kaggle/input/birdclef2024-cnn/keras/test1/2/BirdClef24 mycnn.keras'\ndest_dir = \"/kaggle/working/cnn.keras\"\nshutil.copyfile(source_dir, dest_dir)\nmodel = tf.keras.models.load_model('/kaggle/working/cnn.keras')","metadata":{"execution":{"iopub.status.busy":"2024-04-24T22:55:03.912995Z","iopub.execute_input":"2024-04-24T22:55:03.914240Z","iopub.status.idle":"2024-04-24T22:55:13.976613Z","shell.execute_reply.started":"2024-04-24T22:55:03.914197Z","shell.execute_reply":"2024-04-24T22:55:13.975524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def wavelet_filter(y, thresh=0.1, wavelet=\"db4\", level=None):\n    thresh = thresh * np.nanmax(y)\n    coeffs = pywt.wavedec(y, wavelet, level=level, mode=\"per\")\n    coeffs = [pywt.threshold(c, value=thresh, mode=\"soft\") for c in coeffs]\n    reconstructed_signal = pywt.waverec(coeffs, wavelet, mode=\"per\")\n    return reconstructed_signal","metadata":{"execution":{"iopub.status.busy":"2024-04-24T22:55:13.982402Z","iopub.execute_input":"2024-04-24T22:55:13.982704Z","iopub.status.idle":"2024-04-24T22:55:13.990627Z","shell.execute_reply.started":"2024-04-24T22:55:13.982678Z","shell.execute_reply":"2024-04-24T22:55:13.989350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n    \n# This is where we will store our results\npred = {'row_id': []}\ntrain_audio_dir = '../input/birdclef-2024/train_audio/'\nspecies_list = sorted(os.listdir(train_audio_dir))\nfor species_code in species_list:\n    pred[species_code] = []\n    \n#input_data = np.empty(shape= [0, 224,224,3])\nrst = []\n# Process audio files and make predictions\n#start_time = time.time()\nfile_count = 0\nfor afile in file_list:\n    input_data = []\n    rowid = []\n    #file_start = time.time()\n    file_count +=1\n    # Complete file path\n    path = str(afile)\n    \n    # Open file with librosa and split signal into 5-second chunks\n    raw_audio_data, rate = librosa.load(path, sr=32000)\n    sig = wavelet_filter(raw_audio_data)\n    # ...\n    total_duration = 240 #librosa.get_duration(path= path)\n    #if total_duration >240:\n    #    total_duration = 240\n    num_chunks= int(total_duration // 5.0)\n    #chunks = [[] for i in range(num_chunks)]\n    \n    # Construct predict input data of all chunks\n    for i in range(num_chunks): #len(chunks)): \n        #t_start = time.time()\n        chunk_start_time = i * 5\n        chunk_end_time = (i + 1) * 5\n        \n        # Assign the row_id which we need to do for each chunk\n        row_id = afile.stem + '_' + str(chunk_end_time)\n        #pred['row_id'].append(row_id)\n        rowid.append(row_id)\n        \n        segment_data = sig[chunk_start_time:chunk_end_time]\n        S = librosa.feature.melspectrogram(y=segment_data, sr=rate, n_mels=128)\n        S_db = librosa.amplitude_to_db(S, ref=np.max)\n        #convert spectrogram data into directly into image (much faster than matplotlib)\n        normalized_array = (S_db - np.min(S_db)) / (np.max(S_db) - np.min(S_db))\n        \n        #set color mapping \n        spectrogram_image = cm.magma(normalized_array)[:, :, :3]\n        spectrogram_image = (spectrogram_image * 255).astype(np.uint8)\n        spectrogram_image = Image.fromarray(spectrogram_image)\n        \n        #resize and flip (so consistent with original dataset)\n        spectrogram_image = spectrogram_image.resize((image_size, image_size), Image.ANTIALIAS)\n        spectrogram_image = ImageOps.flip(spectrogram_image)\n        #print(f' process file chunks , used {(time.time()-t_start)} seconds ')\n        #d_start = time.time()\n        input_arr = keras.utils.img_to_array(spectrogram_image)\n        input_arr = np.array([input_arr])  # Convert single image to a batch.\n        input_data.append(input_arr)\n        #input_data = np.append(input_data,input_arr, axis = 0)\n        #print(f' process file chunks , generate dataset used {(time.time()-d_start)} seconds ')\n    #file_end = time.time()\n    #print(f' process file {file_count}, used {(file_end-file_start)} seconds ')\n\n    #input_data = np.array(input_data)\n    pre_data = np.concatenate(input_data)\n    #end_time = time.time()\n    #print(\"process files used: {:.2f} seconds\".format(end_time - start_time))\n    #predict all chunks of all files\n    #start_time = time.time()\n\n    #pre = model.predict(pre_data, batch_size = 48)\n    pre = model(pre_data, training = False)\n\n    #end_time = time.time()\n    #print(\"predict used: {:.2f} seconds\".format(end_time - start_time))\n    #write to the output\n    #rst = np.concatenate((rowid, pre), axis= 1)\n    rows = np.array(rowid)\n    rows = rows[:, np.newaxis]\n    rst_tmp = np.concatenate((rows, pre), axis= 1)\n    rst.append(rst_tmp)\n    '''\n    s = time.time()\n    for bird in species_list:\n        pre_len = len(pre)\n        for idx in range(pre_len):\n            score = pre[idx, species_list.index( bird)].numpy().astype(np.float32)\n            # Put the result into our prediction dict            \n            pred[bird].append(score)\n    print(\"predict used: {:.2f} seconds\".format(time.time() - s))\n    '''","metadata":{"execution":{"iopub.status.busy":"2024-04-24T22:55:13.992477Z","iopub.execute_input":"2024-04-24T22:55:13.993360Z","iopub.status.idle":"2024-04-24T22:55:49.177970Z","shell.execute_reply.started":"2024-04-24T22:55:13.993315Z","shell.execute_reply":"2024-04-24T22:55:49.177018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# Make a new data frame and look at some results        \nresults = pd.DataFrame(np.concatenate(rst, axis = 0), columns = ['row_id'] + species_list)\n#rst1 = pd.DataFrame(pred, columns = ['row_id'] + species_list)\n\n# Quick sanity check\nprint(results.head())\n#print(rst1.head()) \n\n    \n# Convert our results to csv\nresults.to_csv(\"submission.csv\", index=False)\n#rst1.to_csv(\"submission1.csv\", index=False)\n","metadata":{"execution":{"iopub.status.busy":"2024-04-24T22:55:49.181661Z","iopub.execute_input":"2024-04-24T22:55:49.183324Z","iopub.status.idle":"2024-04-24T22:55:49.232225Z","shell.execute_reply.started":"2024-04-24T22:55:49.183259Z","shell.execute_reply":"2024-04-24T22:55:49.230999Z"},"trusted":true},"execution_count":null,"outputs":[]}]}