{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"pip install audiomentations","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Useful resources:\n**Notebooks :**\n[ https://www.kaggle.com/stegzz/readable-keras-resnet50-model ]\n[ https://www.kaggle.com/alkahapur/birdspicies-prediction-using-tensorflow-and-cnn ]\n[ https://www.kaggle.com/dimitreoliveira/rainforest-audio-classification-tf-improved ]\n\n**Papers**\n[ http://ceur-ws.org/Vol-1866/paper_143.pdf ]\n[ https://arxiv.org/pdf/1706.07156.pdf%5D ]"},{"metadata":{},"cell_type":"markdown","source":"# Importing Libraries"},{"metadata":{"trusted":true},"cell_type":"code","source":"import os ,time,gc\nimport glob,math\nimport pandas as pd  \nimport numpy as np\n# import cupy as cp\nimport matplotlib.pyplot as plt \nimport seaborn as sns \nfrom IPython.display import Audio\nfrom tqdm import tqdm\nfrom skimage.transform import resize\n\nimport librosa\nimport librosa.display as ld \nimport soundfile as sf\nfrom audiomentations import Compose,AddGaussianSNR,Shift,TimeStretch,TimeMask,FrequencyMask,PolarityInversion\n\n\nimport tensorflow as tf \nfrom tensorflow import keras \nfrom keras import regularizers\nfrom keras import layers\nfrom sklearn.preprocessing import StandardScaler\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Loading Data**"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_fp=pd.read_csv('../input/rfcx-species-audio-detection/train_fp.csv') #false positives \ntrain_tp=pd.read_csv('../input/rfcx-species-audio-detection/train_tp.csv')  #true positives \n\n#training path \ntrain_path='../input/rfcx-species-audio-detection/train/'\ntest_path='../input/rfcx-species-audio-detection/test/'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(f'Number of True positives = {len(train_tp)} \\n Number of false positives = {len(train_fp)}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Parameters:\n# n_mfcc=30\nn_fft=2048\nhop_len=512\n# sr=int(train_tp.f_max.max()*1.5)  #setting the sample rate according to the max value of frequency\nsr=44200\nshape_1=(256,512)\n\nmin_freq=int(train_tp['f_min'].min() * 0.75)       #a buffer around min and max freq values.\nmax_freq=int(train_tp['f_max'].max() * 1.25)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data overview:"},{"metadata":{},"cell_type":"markdown","source":"**Columns**\n\n    recording_id - unique identifier for recording\n    species_id - unique identifier for species\n    songtype_id - unique identifier for songtype\n    t_min - start second of annotated signal\n    f_min - lower frequency of annotated signal\n    t_max - end second of annotated signal\n    f_max- upper frequency of annotated signal\n    is_tp- [tfrecords only] an indicator of whether the label is from the train_tp (1) or train_fp (0) file.\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"#True positive Class balance \nplt.figure(figsize=(16,8))\nsns.countplot(train_tp.species_id)\nplt.title('train_true_positives')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#False Positives\nplt.figure(figsize=(16,8))\nsns.countplot(train_fp.species_id)\nplt.title('train_false_positives')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Lets see (I mean hear.) a sample audio recording from the data .**"},{"metadata":{"trusted":true},"cell_type":"code","source":"file_path=train_path + '/' +'006ab765f.flac'\nAudio(file_path)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Waveplot and Power spectrum**"},{"metadata":{"trusted":true},"cell_type":"code","source":"#loading file\nsignal,sr=librosa.load(file_path,sr=sr)\n\nplt.figure(figsize=(16,8))\n\n#waveplot:\nplt.subplot(2,1,1)\nld.waveplot(signal,sr)\nplt.ylabel('Magnitude')\nplt.title('Waveplot')\n\n#fast fourier transform:\n\nfft=np.fft.fft(signal)\nmag=np.abs(fft)\nfreq=np.linspace(0,sr,len(mag))\nplt.subplot(2,1,2)\nplt.plot(freq,mag)\nplt.xlabel('Frequency')\nplt.ylabel('Magnitude')\nplt.title('Power Spectrum')\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**SHORT TIME FOURIER TRANSFORM(STFT)**"},{"metadata":{"trusted":true},"cell_type":"code","source":"#short time fourier transform:\nstft=librosa.core.stft(signal,hop_length=hop_len,n_fft=n_fft)\nspectrogram=librosa.amplitude_to_db(np.abs(stft),ref=np.max)\n\n#display_spectrogram:\nplt.figure(figsize=(16,10))\n\nax=plt.subplot(2,1,1)\nimg=ld.specshow(spectrogram,sr=sr,hop_length=hop_len,ax=ax,x_axis='time',y_axis='log')\nplt.xlabel('Time')\nplt.ylabel('Freq')\nplt.colorbar(img)\nplt.title('STFT')\nplt.show()\n\n\nax=plt.subplot(2,1,2)\nM = librosa.feature.melspectrogram(y=signal, sr=sr)\nM_db = librosa.power_to_db(M, ref=np.max)\nimg = ld.specshow(M_db, y_axis='mel', x_axis='time', ax=ax)\nplt.colorbar(img)\nax.set(title='Mel spectrogram display')\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**MEL Frequency Cepstral Coefficients (MFCC)**"},{"metadata":{"trusted":true},"cell_type":"code","source":"#MFCC:\n\nmfcc=librosa.feature.mfcc(signal,n_fft=n_fft,hop_length=hop_len,n_mfcc=30)\n\nfig,ax=plt.subplots(figsize=(16,8))\nimg=ld.specshow(mfcc,sr=sr,hop_length=hop_len,ax=ax,cmap='gray')\nplt.title('mfcc')\nplt.colorbar(img)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**lets see patterns in STFT spectrograms**"},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_stft(df,trainpath,n_fft=2048,hop_len=512,sr=sr):\n    plt.subplots(25,1,figsize=(16,8*25))\n    for i,row in df.iterrows():\n        rec_id=row['recording_id']\n        start=int(row['t_min']*0.75)\n        end=int(row['t_max']*1.25)\n        idx=row['species_id']\n        \n        #loading files\n        fpath=os.path.join(trainpath +'/'+f'{rec_id}.flac')\n        sig,sr=librosa.load(fpath,sr=sr)\n        sig=sig[sr*start:sr*end]     #limiting signal to around  t_min and t_max\n        \n        \n        \n        #plotting stft:\n        stft=librosa.core.stft(sig,hop_length=hop_len,n_fft=n_fft)\n        spectrogram=librosa.amplitude_to_db(np.abs(stft),ref=np.max)\n        ax=plt.subplot(25,1,i+1)\n        \n        img=ld.specshow(spectrogram,sr=sr,hop_length=hop_len,ax=ax,x_axis='time',y_axis='log')\n        plt.xlabel('Time')\n        plt.ylabel('Freq')\n        plt.colorbar(img)\n        plt.title(f'Species Id {idx}')\n    plt.show()\n\n# plot_stft(df=train_tp[:25],trainpath=train_path,n_fft=2048,hop_len=512,sr=sr)\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Audio Augmentation.\nSimilar to the approach used for image classification, Audio Augmentation is also a useful approach to increase the robustness of the model and have more examples for the model to train upon. This is especially important because I have not figured out a approach to use False positive data for training."},{"metadata":{"trusted":true},"cell_type":"code","source":"#Audio Augmentation:\naugmentations = Compose([\n            TimeMask(min_band_part=0.005, max_band_part=0.10, p=0.5),\n            FrequencyMask(min_frequency_band=0.005, max_frequency_band=0.10, p=0.5),\n            TimeStretch(min_rate=0.8,max_rate=1.25,p=0.5),\n            AddGaussianSNR(min_SNR=0.001, max_SNR=.75, p=0.5),\n            PolarityInversion(p=0.5),\n            Shift(min_fraction=-0.25,max_fraction=0.25,p=0.5)])\n\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**I would not be using MFCCs because the model has not been performing all that well on MFCCs. This belief is reinforced in this paper [ https://arxiv.org/pdf/1706.07156.pdf ] which claims STFT spectrograms do a better job than baseline MFCCs. **"},{"metadata":{"trusted":true},"cell_type":"code","source":"# def save_mfccs(path=train_path,df=train_tp,n_mfcc=n_mfcc,hop_len=hop_len,sr=sr,n_fft=n_fft):\n#     data={'mfcc':[],'label':[]}\n#     mfccs,labels=[],[]\n    \n#     #loading audio files:\n#     for i,row in df.iterrows():\n#         rec_id=row['recording_id']\n#         filepath=os.path.join(path +'/' +f'{rec_id}.flac')\n#         start,end=math.floor(row['t_min']),math.ceil(row['t_max']) #taking signal slice around t_min and t_max \n        \n#         #loading files:\n#         signal,sr=librosa.load(filepath,sr=sr)\n#         signal=signal[start:end]\n        \n#         signal=augmentations(signal,sample_rate=sr)\n        \n#         #extracting mfccs:\n#         mfcc= librosa.feature.mfcc(signal,sr=sr,n_mfcc=n_mfcc,hop_length=hop_len,n_fft=2048)\n        \n#         #appending to list:\n#         mfccs.append(mfcc)\n#         labels.append(row['species_id'])\n#     data['mfcc']=mfccs\n#     data['label']=labels\n#     print('MFCCs extracted')\n#     return data \n\n# mfcc=save_mfccs()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Extracting mel-scaled-STFT "},{"metadata":{"trusted":true},"cell_type":"code","source":"def save_stft(df=train_tp,path=train_path,sr=sr,augment=True,power=1.5,shape=shape_1,expand_dim=True):\n    #dict to store values: \n    data={'mel-stft':[] ,'label':[]}\n    stfts,labels=[],[]\n    \n    #loading audio files:\n    for i,row in df.iterrows():\n        try:\n    \n            rec_id=row['recording_id']\n            label=row['species_id']\n            filepath=os.path.join(path +'/' +f'{rec_id}.flac')\n\n            #the starting and end of species sound provided in dataframe.\n            start,end=row['t_min'],row['t_max'] \n\n            #taking signal slice around t_min and t_max \n            buffer1=np.random.uniform(2,6)\n            buffer2=np.random.uniform(2,6)\n            #buffer around start\n            if start<6:\n                start=0\n            else:\n                start=math.floor(start-buffer1) * sr\n\n            #buffer around end\n\n            if end > 54:\n                end = 60\n            else:\n                end=math.ceil(end + buffer2) * sr\n\n             #loading files:\n           \n            signal,sr=librosa.load(filepath,sr=sr)\n            signal=signal[start:end]\n\n            #augmenting data\n            if augment==True:\n                signal=augmentations(signal,sample_rate=sr)\n\n            #spectrogram\n            stft = librosa.feature.melspectrogram(signal, sr=sr,n_mels=shape[0],power=power,\n                                                 fmin=min_freq,fmax=max_freq)\n            stft_db=librosa.core.amplitude_to_db(np.abs(stft))\n\n            #reshape:\n            stft_db= resize(stft_db,shape)\n\n            #expand_dims\n            if expand_dim==True:\n                stft_db=np.stack((stft_db,stft_db,stft_db))\n\n            #appending labels and stfts to lists :\n            stfts.append(stft_db)\n            labels.append(label)\n        except:\n            pass\n    #assign lists to data :\n    data['mel-stft']=stfts\n    data['label']=labels\n    print('STFTs extracted')    \n    return data\n\n%time\nData=save_stft(df=train_tp,path=train_path,sr=sr,augment=False,power=2)\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Normalizing the data**"},{"metadata":{"trusted":true},"cell_type":"code","source":"X=np.array(Data['mel-stft'])\ny=np.array(Data['label'])\n# X=np.expand_dims(X,axis=-1)\ny=keras.utils.to_categorical(y,num_classes=24)\nshape=X.shape\n\n#Normalizing:\nfrom sklearn.preprocessing import MinMaxScaler\n\nX=MinMaxScaler().fit_transform(X.reshape(-1,X.shape[-1])).reshape(shape)\nX=X.reshape(X.shape[0],X.shape[2],X.shape[3],X.shape[1])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Evaluation metric:\n**Function from this notebook:** [ https://www.kaggle.com/stegzz/readable-keras-resnet50-model ]"},{"metadata":{"trusted":true},"cell_type":"code","source":"@tf.function\ndef _one_sample_positive_class_precisions(example):\n    y_true, y_pred = example\n\n    retrieved_classes = tf.argsort(y_pred, direction='DESCENDING')\n    class_rankings = tf.argsort(retrieved_classes)\n    retrieved_class_true = tf.gather(y_true, retrieved_classes)\n    retrieved_cumulative_hits = tf.math.cumsum(tf.cast(retrieved_class_true, tf.float32))\n\n    idx = tf.where(y_true)[:, 0]\n    i = tf.boolean_mask(class_rankings, y_true)\n    r = tf.gather(retrieved_cumulative_hits, i)\n    c = 1 + tf.cast(i, tf.float32)\n    precisions = r / c\n\n    dense = tf.scatter_nd(idx[:, None], precisions, [y_pred.shape[0]])\n    return dense\n\n\nclass LWLRAP(tf.keras.metrics.Metric):\n    def __init__(self, num_classes, name='lwlrap'):\n        super().__init__(name=name)\n\n        self._precisions = self.add_weight(\n            name='per_class_cumulative_precision',\n            shape=[num_classes],\n            initializer='zeros',\n        )\n\n        self._counts = self.add_weight(\n            name='per_class_cumulative_count',\n            shape=[num_classes],\n            initializer='zeros',\n        )\n\n    def update_state(self, y_true, y_pred, sample_weight=None):\n        precisions = tf.map_fn(\n            fn=_one_sample_positive_class_precisions,\n            elems=(y_true, y_pred),\n            dtype=(tf.float32),\n        )\n\n        increments = tf.cast(precisions > 0, tf.float32)\n        total_increments = tf.reduce_sum(increments, axis=0)\n        total_precisions = tf.reduce_sum(precisions, axis=0)\n\n        self._precisions.assign_add(total_precisions)\n        self._counts.assign_add(total_increments)        \n\n    def result(self):\n        per_class_lwlrap = self._precisions / tf.maximum(self._counts, 1.0)\n        per_class_weight = self._counts / tf.reduce_sum(self._counts)\n        overall_lwlrap = tf.reduce_sum(per_class_lwlrap * per_class_weight)\n        return overall_lwlrap\n\n    def reset_states(self):\n        self._precisions.assign(self._precisions * 0)\n        self._counts.assign(self._counts * 0)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Building Models:"},{"metadata":{"trusted":true},"cell_type":"code","source":"#Custom CNN Model:\ndef build_model():\n    inp=layers.Input(shape=(X.shape[1:]))\n    \n    x=layers.Conv2D(32, strides=1,kernel_size=(7,7),padding='same')(inp)    \n    x=layers.MaxPooling2D(pool_size=(2,2))(x)\n    \n        \n    for i in range(len(filters)):\n        x=layers.Conv2D(filters[i], strides=stride[i],kernel_size=kernel[i],padding='same')(x)     \n        x=layers.MaxPooling2D(pool_size=pool[i])(x)\n        x=layers.Activation('relu')(x)\n        x=layers.BatchNormalization()(x)\n        \n    x=layers.Flatten()(x)\n    \n    for i in range(len(dense)):\n        x=layers.BatchNormalization()(x)\n        x=layers.Dense(dense[i],kernel_regularizer=l2)(x)\n        x=layers.Dropout(rate=drop[i])(x)\n    \n    x=layers.BatchNormalization()(x)\n    output=layers.Dense(24,activation='softmax')(x)\n    \n    model=keras.Model(inputs=inp,outputs=output)\n    \n    return model\n\n\n#DenseNet base model.\ndef DenseNet():\n    #base layer\n    base=keras.applications.DenseNet121(include_top=False, weights='imagenet')\n    \n    model= keras.Sequential([\n    #input\n    layers.Input(shape=X.shape[1:]),\n    \n    #Desnenet 121 base:    \n    base,\n    \n        \n    layers.GlobalAveragePooling2D(),\n    layers.BatchNormalization(),\n    \n    layers.Flatten(),\n    #dense1\n    layers.Dense(256,activation='relu'),\n    layers.BatchNormalization(),\n    layers.Dropout(rate=0.8),\n    \n        \n    layers.Dense(128,activation='relu'),\n    layers.BatchNormalization(),\n    layers.Dropout(rate=0.7),\n    \n    layers.Dense(64,activation='relu'),\n    layers.BatchNormalization(),\n    layers.Dropout(rate=0.5),\n    \n    #output\n    layers.Dense(24,activation='softmax')        \n    ])\n    return model\n    \n#model 3\ndef ResNet():\n    #base layer\n    base=keras.applications.ResNet50(weights='imagenet', include_top=False)\n    \n    \n    model= keras.Sequential([\n    #input\n    layers.Input(shape=X.shape[1:]),\n    \n    #Resnet50 base:    \n    base,\n    \n        \n    layers.GlobalAveragePooling2D(),\n    layers.BatchNormalization(),\n     \n    layers.Flatten(),\n    \n    #dense1\n    layers.Dense(512,activation='relu'),\n    layers.BatchNormalization(),\n    layers.Dropout(rate=0.6),\n    \n    layers.Dense(128,activation='relu'),\n    layers.BatchNormalization(),\n    layers.Dropout(rate=0.5),\n    \n        \n    #dense2\n    layers.Dense(64,activation='relu'),\n    layers.BatchNormalization(),\n    layers.Dropout(rate=0.5),\n    \n    #output\n    layers.Dense(24,activation='softmax')        \n    ])\n    return model\n\n    \n    \n#plotting history:\ndef plot_history(history):\n    his=pd.DataFrame(history.history)\n    plt.subplots(1,2,figsize=(16,8))\n    \n    #loss:\n    plt.subplot(1,2,1)\n    plt.plot(range(len(his)),his['loss'],color='g',label='training')\n    plt.plot(range(len(his)),his['val_loss'],color='r',label='validation')\n    plt.legend()\n    plt.title('Loss')\n    \n    plt.subplot(1,2,2)\n    plt.plot(range(len(his)),his['lwlrap'],color='g',label='training')\n    plt.plot(range(len(his)),his['val_lwlrap'],color='r',label='validation')\n    plt.legend()\n    plt.title('accuracy')\n    \n    plt.show()                ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model1 : Custom CNN"},{"metadata":{"trusted":true},"cell_type":"code","source":"#model_architecture:\nl2=keras.regularizers.l2(1e-3)\nfilters=[128,256,512,1024]        #conv filters\nkernel=[(5,5),(3,3),(3,3),(3,3)]  #kernel size\nstride=[1,1,1,1]                  #stride length \npool=[(2,2),(2,2),(2,2),(2,2)]    # max-pooling size\ndense=[512,128,64]                # dense layers 256,64\ndrop=[0.6,0.5,0.5]                #dropout probabilities\n\n\n#params:\nEpochs1=100\nbatch_size1=32\nfilepath1 = \"CustomCNN.hdf5\"\n\nmodel1=build_model()\n\n#compiling model\nmodel1.compile(optimizer = tf.keras.optimizers.Nadam(learning_rate=0.01)\n               ,loss='categorical_crossentropy',metrics=[LWLRAP(24)])\n\n#callbacks:\n#reduce_lr\nreduce_lr=keras.callbacks.ReduceLROnPlateau(patience=3,factor=0.75,monitor='val_loss',verbose=0,min_lr=1e-8)\n\n#early stopping\nearly_stopping=keras.callbacks.EarlyStopping(patience=30,min_delta=1e-3,monitor='val_loss')\n\n#save model :\n# checkpoint1 =keras.callbacks.ModelCheckpoint(filepath1, monitor='val_lwlrap', verbose=1,\n#                                                 save_best_only=True, mode='max')    \n\ngc.collect()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Training model1:\n\nhistory1=model1.fit(X,y,validation_split=0.05,callbacks=[reduce_lr],verbose=1,\n                   epochs=Epochs1,batch_size=batch_size1,shuffle=True)\n\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_history(history1)\ngc.collect()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model 2 : Densenet 121 base model."},{"metadata":{"trusted":true},"cell_type":"code","source":"#Model 2\n\n#params:\nEpochs2=100\nbatch_size2=32\nfilepath2='DenseNet_model.hdf5'\n\n#model2\nmodel2=DenseNet()\n\nmodel2.compile(optimizer=keras.optimizers.Nadam(lr=1e-2),loss='categorical_crossentropy',\n              metrics=[LWLRAP(24)])\n#callbacks:\n\n#reduce_lr\nreduce_lr=keras.callbacks.ReduceLROnPlateau(patience=3,factor=0.75,min_delta=1e-2,monitor='val_loss',verbose=0,min_lr=1e-8)\n\n#early stopping\n# early_stopping=keras.callbacks.EarlyStopping(patience=25,min_delta=1e-3,monitor='val_lwlrap',restore_best_weights=True)\n\n#save model:\n# checkpoint2 = keras.callbacks.ModelCheckpoint(filepath2, monitor='val_lwlrap', verbose=1,\n#                                                 save_best_only=True, mode='max')    \ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#training model2:\n\nhistory2=model2.fit(X,y,validation_split=0.05,callbacks=[reduce_lr],\n                   epochs=Epochs2,batch_size=batch_size2,shuffle=True,verbose=1)\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_history(history2)\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Inference:\nThe test code is almost entirely from this notebook: [ https://www.kaggle.com/stegzz/readable-keras-resnet50-model ]"},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_test_spec(audio, shape, sr=44200, power=2.0, third_dim=True):\n    '''\n    docstring here\n    '''\n    \n    # initialize list \n    final_list = []\n    # break audio into 10 seconds sub arrays\n    audio = np.split(audio, 10)\n\n    # loop through sub arrays\n    for sub_array in audio:\n\n        stft = librosa.feature.melspectrogram(sub_array, sr=sr, power=power, fmin=min_freq, fmax=max_freq, n_mels=shape_1[0])\n        stft_to_db = librosa.core.amplitude_to_db(np.abs(stft))\n\n        # resize array\n        stft_to_db = resize(stft_to_db, shape)\n\n        # normalize \n        stft_to_db = stft_to_db - np.min(stft_to_db)\n        stft_to_db = stft_to_db / np.max(stft_to_db)\n    \n    \n        if third_dim == True:\n            stft_to_db = np.stack((stft_to_db,stft_to_db,stft_to_db))\n        \n        # reshape output\n        stft_to_db = stft_to_db.reshape(stft_to_db.shape[1], stft_to_db.shape[2], stft_to_db.shape[0])\n        \n        # append stft_to_db to list\n        final_list.append(stft_to_db)\n    \n\n\n    return(final_list)\n\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Predicting:"},{"metadata":{"trusted":true},"cell_type":"code","source":"\n# get test headers from sample_submission.csv\ntemp = pd.read_csv('../input/rfcx-species-audio-detection/sample_submission.csv')\ncols = temp.columns.tolist()\n\n# initialize list\nprediction_list = []\n\n# loop through test files\ntest_path = '../input/rfcx-species-audio-detection/test'\n\nfor root, dirs, files in os.walk(test_path):\n    \n    # get total number of files for progress report\n    total = len(files)\n    \n    # loop through files \n    for file in files:\n        \n        # load in audio\n        loaded_audio, sample_rate = librosa.load(test_path+'/'+file, sr=None)\n        \n        # pass loaded_audio to create_test_spec function\n        test_list = create_test_spec(loaded_audio, shape=shape_1, power=2)\n        \n        # get predictions\n        preds =(0.5 * model1.predict(np.array(test_list)))+(0.5 * model2.predict(np.array(test_list)))         \n        \n        # get mean prediction probabilities\n        mean_preds = np.mean(preds, axis=0)\n        \n        # append mean probs to list\n        prediction_list.append(mean_preds) \n        \n# convert final list to dataframe --> this is messy and needs to be cleaned up\nsub_df = pd.DataFrame({cols[0]:files})\ncols2 = cols[1:]\ntemp_df= pd.DataFrame(prediction_list, columns=cols2)\ntemp_df['recording_id']=files\nsub_df = temp_df[cols]\n\n# eliminate file extension\nsub_df['recording_id'] = sub_df['recording_id'].str.replace(r'.flac$','')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# create submission .csv\nsub_df.to_csv('./submission.csv',index=False)","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}