{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import json\nimport numpy as np\nfrom sklearn.model_selection import train_test_split\nimport tensorflow.keras as keras\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint\nimport tensorflow as tf\nfrom tensorflow.keras import callbacks\nfrom tensorflow.keras.layers import Dropout, Flatten, Dense, LSTM\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.applications import VGG16\nfrom tensorflow.keras.datasets import cifar10\nfrom tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras import Model\nfrom tensorflow.keras.initializers import Constant\nimport pandas as pd\nimport os\nfrom pathlib import Path\nfrom tensorflow.keras.callbacks import Callback\n\nimport numpy as np\nimport pandas as pd\nimport numpy as np\nimport librosa.display\nfrom scipy import signal\nimport scipy.io.wavfile\nimport IPython.display as ipd\nimport matplotlib.pyplot as plt\nimport os\n\nimport math\nfrom scipy.io.wavfile import write\nfrom tensorflow.keras import activations\nfrom keras.models import model_from_json\nfrom keras.regularizers import l2\n\nfrom math import pi\nfrom math import cos\nfrom math import floor\nfrom keras import backend","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def dataretreival(filename1,filename2,filename3):\n    # Data1\n\n    with open(\"../input/data-full/\"+str(filename1), \"r\") as read_it: \n         data1 = json.load(read_it) \n    X1=np.array(data1[\"features\"])\n    y1=np.array(data1[\"classes\"])\n\n    # Data2\n    with open(\"../input/data-full/\"+str(filename2), \"r\") as read_it: \n         data2 = json.load(read_it) \n    X2=np.array(data2[\"features\"])\n    y2=np.array(data2[\"classes\"])\n\n    '''\n    # Data2\n    with open(\"../input/data-full/\"+str(filename3), \"r\") as read_it: \n         data3 = json.load(read_it) \n    X2=np.array(data3[\"features\"])\n    y2=np.array(data3[\"classes\"])\n    '''\n\n    \n    X=np.concatenate((X1,X2),axis=0)\n    y=np.concatenate((y1,y2),axis=0)\n    print(X.shape)\n    print(y.shape)\n    return X,y\n\n\ndef prepare_data(test_size,model_type=\"base\"):\n    \n    # Load the data\n    X,y=dataretreival(\"data.json\",\"data_2.json\",\"data_3.json\")\n    \n    #print(np.max(y))\n\n    # Create train/Test Split \n    X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=test_size)\n    \n    plt.figure()    \n    plt.hist(y_train,bins=100)\n    plt.show()\n    \n    y_train=to_categorical(y_train)\n    y_test=to_categorical(y_test)\n    \n    #print(y_test.shape)\n    # Currently 3D array for each sample (N, S1, S2)--> 4D Array (N, S1, S2,Depth)\n    if model_type==\"base\":\n        X_train=X_train[...,np.newaxis] # 4D Array \n        X_test=X_test[...,np.newaxis]\n        return X_train,X_test, y_train, y_test, np.max(y)\n    elif model_type==\"vgg\":\n        inp_shape=(48,48,3)\n        X_train=np.repeat(X_train[..., np.newaxis], 3, -1)\n        X_test=np.repeat(X_train[..., np.newaxis], 3, -1)\n        X_train_resize=[]\n        X_test_resize=[]\n        for img in X_train:\n            X_train_resize.append(np.resize(img,inp_shape))\n        X_train_resize=np.array(X_train_resize)\n        for img in X_test:\n            X_test_resize.append(np.resize(img,inp_shape))\n        X_test_resize=np.array(X_test_resize)\n        return X_train_resize,X_test_resize, y_train, y_test, np.max(y)\n    else:\n        return X_train,X_test, y_train, y_test, np.max(y)\n    \n\ndef build_model_cnn(input_shape,class_labels):\n    \n    # Create Model\n    model=keras.Sequential()\n    \n    # 1st Conv Layer\n    model.add(keras.layers.Conv2D(16,(7,7),padding='same',\\\n                                  input_shape=input_shape))\n    model.add(keras.layers.BatchNormalization())\n    model.add(keras.layers.Activation(activations.relu))\n    model.add(keras.layers.MaxPool2D((3,3),strides=(2,2),padding=\"same\"))\n    \n    # 2nd Conv Layer\n    model.add(keras.layers.Conv2D(32,(5,5),padding='same'))\n    model.add(keras.layers.BatchNormalization())\n    model.add(keras.layers.Activation(activations.relu))\n    model.add(keras.layers.MaxPool2D((3,3),strides=(2,2),padding=\"same\"))\n    \n    # 3rd Conv Layer\n    model.add(keras.layers.Conv2D(32,(3,3),padding='same'))\n    model.add(keras.layers.BatchNormalization())\n    model.add(keras.layers.Activation(activations.relu))\n    model.add(keras.layers.MaxPool2D((3,3),strides=(2,2),padding=\"same\"))\n    \n    # 4th Conv Layer\n    model.add(keras.layers.Conv2D(64,(3,3),padding='same'))\n    model.add(keras.layers.BatchNormalization())\n    model.add(keras.layers.Activation(activations.relu))\n    model.add(keras.layers.MaxPool2D((3,3),strides=(2,2),padding=\"same\"))\n    \n    # 5th Conv Layer\n    model.add(keras.layers.Conv2D(64,(3,3),padding='same'))\n    model.add(keras.layers.BatchNormalization())\n    model.add(keras.layers.Activation(activations.relu))\n    model.add(keras.layers.MaxPool2D((3,3),strides=(2,2),padding=\"same\"))\n    \n    # 6th Conv Layer\n    model.add(keras.layers.Conv2D(128,(3,3),padding='same'))\n    model.add(keras.layers.BatchNormalization())\n    model.add(keras.layers.Activation(activations.relu))\n    model.add(keras.layers.MaxPool2D((3,3),strides=(2,2),padding=\"same\"))  \n\n   \n    # Flatten\n    model.add(keras.layers.Flatten())\n    model.add(keras.layers.Dense(1028))\n    model.add(keras.layers.BatchNormalization())\n    model.add(keras.layers.Activation(activations.relu))\n    model.add(keras.layers.Dropout(0.5))\n    \n  \n    # Output\n    model.add(keras.layers.Dense(class_labels,activation='softmax'))    \n    return model\n\ndef rnn(input_shape,class_labels):\n    \n    # Create Model\n    model=keras.Sequential()\n    \n    model.add(keras.layers.LSTM(64,input_shape,return_sequences=True))\n    model.add(keras.layers.LSTM(64))\n    model.add(keras.layers.Dense(64,activation='relu'))\n    model.add(keras.layers.Dropout(0.5))  \n    \n    # Output\n    model.add(keras.layers.Dense(class_labels,activation='softmax'))    \n    return model\n\n\n\ndef vgg_model(input_shape,class_labels):\n    base_model=VGG16(weights='imagenet',include_top=False,input_shape=input_shape)\n    \n    for layer in base_model.layers:\n        if layer.name ==  'block5_conv1':\n            break\n        layer.trainable=False\n        print('Layer '+layer.name+'frozen.')\n    last=base_model.layers[-1].output\n    x=Flatten()(last)\n    x=Dense(1000,activation='relu',name='fc1')(x)\n    x=Dropout(0.3)(x)\n    x=Dense(class_labels,activation='softmax',name='predictions')(x)\n    model=Model(base_model.input,x)\n    return model\n\n\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# IF CNN, type=\"base\" & RNN, type=\"rnn\"\n# Split the data into train & test \nmodel_type=\"rnn\"\nX_train,X_test, y_train, y_test,label_size=prepare_data(test_size=0.2,model_type=model_type)\nlabel_size=label_size+1\nprint(X_train.shape,X_test.shape,label_size)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Cosine Annealing for CNN only","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"\nclass CosineAnnealingLearningrateschedule(Callback):\n    def __init__(self,n_epochs,n_cycles,lrate_max,verbose=0):\n        self.epochs=n_epochs\n        self.cycles=n_cycles\n        self.lr_max=lrate_max\n        self.lrates=list()\n        \n    # calculate learning rate for each epoch\n    def cosineannealing(self,epoch,n_epochs,n_cycles,lrate_max):\n        epochs_per_cycle=floor(n_epochs/n_cycles)\n        cos_inner=(pi*(epoch%epochs_per_cycle))/epochs_per_cycle\n        return lrate_max/2*(cos(cos_inner)+1)\n    \n    # calculate and set learning rate at the start of the epoch\n    def on_epoch_begin(self,epoch,logs=None):\n        # calculate learning rate\n        lr=self.cosineannealing(epoch,self.epochs,self.cycles,self.lr_max)\n        # set learningrate\n        backend.set_value(self.model.optimizer.lr,lr)\n        # log value\n        self.lrates.append(lr)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# CNN - RNN","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow.keras as keras\n#print(X_test.shape,y_test.shape,np.max(X_test[0]))\n\n\n# Build the CNN \nif ((model_type == \"base\") or (model_type==\"vgg\")):\n    input_shape=(X_train.shape[1],X_train.shape[2],X_train.shape[3])\n    model=build_model_cnn(input_shape,label_size) # Model from scratch\nelse:\n    input_shape=(X_train.shape[1],X_train.shape[2])\n    model=rnn(input_shape,label_size) # Model from scratch\n\n#model=vgg_model(input_shape,label_size)\n\nmodel.summary()\n\n'''\n# Compile the model \noptimizer=keras.optimizers.Adam(learning_rate=0.001)\nmodel.compile(optimizer=optimizer,loss=\"categorical_crossentropy\",metrics=[\"accuracy\"])\n#model.load_weights(\"../input/model-best/weights-improvement-177-0.57.hdf5\")\n\n# Network Parameters\nn_epochs=500\nbatch_Size=128\nepochs_per_cycle=50\n\n# Callbacks defintion\nfilepath=\"weights-improvement-{epoch:02d}-{val_accuracy:.2f}.hdf5\"\ncheckpointer=ModelCheckpoint(filepath,monitor='val_accuracy',verbose=1,\n                             save_best_only=True,mode='max')\n\nn_cycles=n_epochs/epochs_per_cycle\nca=CosineAnnealingLearningrateschedule(n_epochs,n_cycles,0.01)\ncallbacks_list=[ca,checkpointer]\n\n# Train the model\nhistory=model.fit(X_train,y_train,validation_data=(X_test,y_test),batch_size=batch_Size,\\\n                  epochs=n_epochs,callbacks=callbacks_list,verbose=2) \n\n\n# Generate generalization metrics\nscore = model.evaluate(X_test, y_test, verbose=0)\nprint(f'Test loss: {score[0]} / Test accuracy: {score[1]}')\n\n# Saving the model\nmodel_json = model.to_json()\nwith open(\"model.json\", \"w\") as json_file:\n    json_file.write(model_json)\n#print(\"Saved model to disk\")\n\n# Visualize history\n# Plot history: Loss\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('loss history')\nplt.ylabel('Loss value')\nplt.xlabel('No. epoch')\nplt.show()\n\n# Plot history: Accuracy\nplt.plot(history.history['accuracy'])\nplt.plot(history.history['val_accuracy'])\nplt.title('accuracy history')\nplt.ylabel('Accuracy value (%)')\nplt.xlabel('No. epoch')\nplt.show()\n'''","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# RNN","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow.keras as keras\n#print(X_test.shape,y_test.shape,np.max(X_test[0]))\n\n\n# Build the CNN \ninput_shape=(X_train.shape[1],X_train.shape[2])\nmodel=rnn_cnn(input_shape,label_size) # Model from scratch\n\nmodel.summary()\n\n\n# Compile the model \noptimizer=keras.optimizers.Adam(learning_rate=0.001)\nmodel.compile(optimizer=optimizer,loss=\"categorical_crossentropy\",metrics=[\"accuracy\"])\n\n# Network Parameters\nn_epochs=500\nbatch_Size=128\nepochs_per_cycle=50\n\n# Callbacks defintion\nfilepath=\"weights-improvement-{epoch:02d}-{val_accuracy:.2f}.hdf5\"\ncheckpointer=ModelCheckpoint(filepath,monitor='val_accuracy',verbose=1,\n                             save_best_only=True,mode='max')\n\nn_cycles=n_epochs/epochs_per_cycle\nca=CosineAnnealingLearningrateschedule(n_epochs,n_cycles,0.01)\ncallbacks_list=[ca,checkpointer]\n\n# Train the model\nhistory=model.fit(X_train,y_train,validation_data=(X_test,y_test),batch_size=batch_Size,\\\n                  epochs=n_epochs,callbacks=callbacks_list,verbose=2) \n\n\n# Generate generalization metrics\nscore = model.evaluate(X_test, y_test, verbose=0)\nprint(f'Test loss: {score[0]} / Test accuracy: {score[1]}')\n\n# Saving the model\nmodel_json = model.to_json()\nwith open(\"model.json\", \"w\") as json_file:\n    json_file.write(model_json)\n#print(\"Saved model to disk\")\n\n# Visualize history\n# Plot history: Loss\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('loss history')\nplt.ylabel('Loss value')\nplt.xlabel('No. epoch')\nplt.show()\n\n# Plot history: Accuracy\nplt.plot(history.history['accuracy'])\nplt.plot(history.history['val_accuracy'])\nplt.title('accuracy history')\nplt.ylabel('Accuracy value (%)')\nplt.xlabel('No. epoch')\nplt.show()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n#optimizer=keras.optimizers.Adam(learning_rate=0.001)\n#model.compile(optimizer=optimizer,loss=\"categorical_crossentropy\",metrics=[\"accuracy\"])\n#model.load_weights(\"weights-improvement-177-0.57.hdf5\")\nscore = model.evaluate(X_test,y_test, verbose=0)\nprint(score)\ny_pred=model.predict(X_test).argmax(axis=1)\ny_test1=y_test.argmax(axis=1)\nprint(y_pred,y_test1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\narray=confusion_matrix(y_test1, y_pred)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import classification_report\nprint (classification_report(y_test1, y_pred))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import seaborn as sn\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\nfor k in range(0,91,10):\n    df_cm = pd.DataFrame(array[k:k+10,k:k+10], index = [i for i in range(k,k+10)],\n                      columns = [i for i in range(k,k+10)])\n    plt.figure(figsize = (8,3))\n    sn.heatmap(df_cm, annot=True)\n    plt.title(f'Confusion ratio for classes {k}-{k+10}')\n    plt.show()\n    plt.close()\n    \n\n\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# submission sample","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Laoding & Compiling the model \nmodel.load_weights(\"weights-improvement-47-0.95.hdf5\")\noptimizer=keras.optimizers.Adam(learning_rate=0.001)\nmodel.compile(optimizer=optimizer,loss=\"categorical_crossentropy\",metrics=[\"accuracy\"])\n\n# Loading the Sample test data \nBASE_TEST_DIR = '../input/birdsong-recognition' if os.path.exists('../input/birdsong-recognition/test_audio') else '../input/birdcall-check'\ndf_test = pd.read_csv(f'{BASE_TEST_DIR}/test.csv')\nsub_test_12 = df_test[df_test.site.isin(['site_1', 'site_2'])]\nsub_test_3 = df_test[df_test.site.isin(['site_3'])]\nTEST_FOLDER = f'{BASE_TEST_DIR}/test_audio'\n\n# Defining the files for predictions\nX_Valid=[]\nsubmission = {'row_id': [], 'birds': []}\nbirds_all={'amepip':0, 'blkpho':1,'comgra':2,'comred':3,'comter':4,\\\n           'gockin':5,'herthr':6,'logshr':7, 'mouchi':8, 'rebwoo':9}\n\n# getting respective bird names from the predictions\ndef get_key(val): \n    for key, value in birds_all.items(): \n         if val == value: \n             return key  \n    return \"key doesn't exist\"\n\ndef predchec(arr):\n    # Should store array value\n    for ind in len(arr):\n        if np.max(arr[ind]) > 0.80:\n            return np.argwhere(arr[ind]>0.80)\n        elif np.max(arr[] < 0.80 & np.max(arr[] > 0.5)):\n            return top two\n        else:\n            return 99\n            \n            \n# Looping through Site1/site2 & Site3 for predictions\n# For Site1 & Site2 (with duration data)\nfor index, row in sub_test_12.iterrows():\n    # Get test row information\n    site = row['site']\n    start_time = row['seconds'] - 5\n    end_time=row['seconds']\n    row_id = row['row_id']\n    audio_id = row['audio_id']\n    DURATION=end_time-start_time\n    #print(DURATION)\n\n    # Parameters for MFCC\n    hop_length=512\n    n_fft=2048\n    n_mfcc=13\n    #expected_no_mfccvec_per_segment=700\n\n    # Getting the file\n    librosa_audio, librosa_sample_rate = librosa.load(f'{TEST_FOLDER}/{audio_id}.mp3')\n    SAMPLE_RATE=librosa_sample_rate\n    DURATION=DURATION\n    SAMPLES_PER_SIGNAL=SAMPLE_RATE*DURATION # Varies as a function of duration if sample rate is fixed\n    segment_duration=5 # seconds\n    total_samples_reqd_segment=SAMPLE_RATE*segment_duration # Total samples for 5 secs\n    #print(SAMPLES_PER_SIGNAL,total_samples_reqd_segment)\n    num_samples_per_segment=total_samples_reqd_segment # Should be based on the train set\n    expected_no_mfccvec_per_segment=math.ceil(num_samples_per_segment/hop_length)\n    #print(expected_no_mfccvec_per_segment)\n    num_segments=math.ceil(int(SAMPLES_PER_SIGNAL)/num_samples_per_segment)\n\n    # Get MFCC Features for each of the data\n    start_sample_indx=int(start_time*SAMPLE_RATE)\n    end_sample_indx=int(start_sample_indx+SAMPLES_PER_SIGNAL)\n    mfcc=librosa.feature.mfcc(librosa_audio[start_sample_indx:end_sample_indx],hop_length=hop_length,n_fft=n_fft,n_mfcc=n_mfcc) # Analyzing a slice of a signal \n    mfcc=mfcc.T\n\n    #librosa.display.specshow(mfcc,sr=SAMPLE_RATE,hop_length=hop_length)\n    #print(mfcc.shape)\n    X_Check=mfcc\n    X_Ch=X_Check[...,np.newaxis]\n    X_Ch_mod=np.reshape(X_Ch,(-1,X_Ch.shape[0],X_Ch.shape[1],X_Ch.shape[2]))\n    y_pred=model.predict(X_Ch_mod)\n    \n    \n    y_pred_max=np.argmax(y_pred,axis=1)\n    submission['row_id'].append(row_id)\n    submission['birds'].append(get_key(y_pred_max))\n    \n\n\n# For Site3 (No duration data)\nfor index, row in sub_test_3.iterrows():\n    # Get test row information\n    site = row['site']\n    start_time = 0#row['seconds'] - 5\n    end_time=5#row['seconds']\n    row_id = row['row_id']\n    audio_id = row['audio_id']\n    DURATION=end_time-start_time\n    #print(DURATION)\n\n    # Parameters for MFCC\n    hop_length=512\n    n_fft=2048\n    n_mfcc=13\n    #expected_no_mfccvec_per_segment=700\n\n    # Getting the file\n    librosa_audio, librosa_sample_rate = librosa.load(f'{TEST_FOLDER}/{audio_id}.mp3')\n    SAMPLE_RATE=librosa_sample_rate\n    DURATION=DURATION\n    SAMPLES_PER_SIGNAL=SAMPLE_RATE*DURATION # Varies as a function of duration if sample rate is fixed\n    segment_duration=5 # seconds\n    total_samples_reqd_segment=SAMPLE_RATE*segment_duration # Total samples for 5 secs\n    #print(SAMPLES_PER_SIGNAL,total_samples_reqd_segment)\n    num_samples_per_segment=total_samples_reqd_segment # Should be based on the train set\n    expected_no_mfccvec_per_segment=math.ceil(num_samples_per_segment/hop_length)\n    #print(expected_no_mfccvec_per_segment)\n    num_segments=math.ceil(int(SAMPLES_PER_SIGNAL)/num_samples_per_segment)\n\n    # Get MFCC Features for each of the data\n    start_sample_indx=int(start_time*SAMPLE_RATE)\n    end_sample_indx=int(start_sample_indx+SAMPLES_PER_SIGNAL)\n    mfcc=librosa.feature.mfcc(librosa_audio[start_sample_indx:end_sample_indx],hop_length=hop_length,n_fft=n_fft,n_mfcc=n_mfcc) # Analyzing a slice of a signal \n    mfcc=mfcc.T\n    \n    #librosa.display.specshow(mfcc,sr=SAMPLE_RATE,hop_length=hop_length)\n    X_Check=mfcc\n    X_Ch=X_Check[...,np.newaxis]\n    X_Ch_mod=np.reshape(X_Ch,(-1,X_Ch.shape[0],X_Ch.shape[1],X_Ch.shape[2]))\n    y_pred=model.predict(X_Ch_mod)\n    y_pred_max=np.argmax(y_pred,axis=1)\n    submission['row_id'].append(row_id)\n    submission['birds'].append(get_key(y_pred_max))\n    \nsubmission=pd.DataFrame(submission)\nsubmission.head()\nsubmission.to_csv('submission.csv', index=False)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}