{"cells":[{"metadata":{},"cell_type":"markdown","source":"## **Imports**","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport csv\nimport wave\nfrom scipy.io import wavfile\nimport os\nfrom sklearn.utils import shuffle\nimport sklearn\nfrom tqdm import tqdm\nfrom tensorflow import keras\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras import layers\nfrom tensorflow.keras import Input\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping\nfrom tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras.layers import Dense, Flatten, Dropout, Activation, LSTM, SimpleRNN\n\nimport librosa\nimport warnings\nwarnings.filterwarnings('ignore')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sequence_length = 50","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"class Preprocessing():\n    def load_data(self,file_path):\n        df = pd.read_csv(file_path,usecols = ['ebird_code','filename'])\n        print(df.head())\n        birds = df[\"ebird_code\"].unique()\n        self.id_to_bird = {k:v for k,v in enumerate(birds)}\n        self.bird_to_id = {v:k for k,v in enumerate(birds)}\n        df = shuffle(df)\n        return df\n    \n    def get_features_(self,df,file_path):   \n        to_append = f'bird chroma_stft rmse spec_cent spec_bw rolloff zcr mfcc'\n        for i, item in df.iterrows():\n            bird = self.bird_to_id[item['ebird_code']]\n            audio_file = os.path.join(file_path,item['ebird_code'],item['filename'])\n            print(audio_file)\n            y, sr = librosa.load(audio_file)\n            chroma_stft = librosa.feature.chroma_stft(y=y, sr=sr)\n            rmse = librosa.feature.rms(y=y)\n            spec_cent = librosa.feature.spectral_centroid(y=y, sr=sr)\n            spec_bw = librosa.feature.spectral_bandwidth(y=y, sr=sr)\n            rolloff = librosa.feature.spectral_rolloff(y=y, sr=sr)\n            zcr = librosa.feature.zero_crossing_rate(y)\n            mfcc = librosa.feature.mfcc(y=y, sr=sr)\n           \n            to_append += f'{bird} {np.mean(chroma_stft)} {np.mean(rmse)} {np.mean(spec_cent)} {np.mean(spec_bw)} {np.mean(rolloff)} {np.mean(zcr)}'    \n            for e in mfcc:\n                to_append += f' {np.mean(e)}'\n            file = open('data.csv', 'a', newline='')\n            with file:\n                writer = csv.writer(file)\n                writer.writerow(to_append.split())\n\n    def get_feature(self,df,file_path):\n        bird_list = list()\n        audio_data = list()\n        for i, item in df.iterrows():\n            bird = self.bird_to_id[item['ebird_code']]\n            audio_file = os.path.join(file_path,item['ebird_code'],item['filename'])\n            \n            wave_data, wave_rate = librosa.load(audio_file)\n            data_point_per_second = 10\n            prepared_sample = wave_data[0::int(wave_rate/data_point_per_second)]\n            normalized_sample = sklearn.preprocessing.minmax_scale(prepared_sample, axis=0)\n\n            song_sample = []\n            sample_length = 5*data_point_per_second\n            for idx in range(0,len(normalized_sample),sample_length): \n                song_sample = normalized_sample[idx:idx+sample_length]\n                if len(song_sample)>=sample_length:\n                    audio_data.append(np.asarray(song_sample).astype(np.float32))\n                    bird_list.append(bird)\n        data = pd.DataFrame({\"audio_data\":audio_data,\"bird\":bird})\n        return data\n    \n    def get_data(self,df):\n        train,valid = sklearn.model_selection.train_test_split(df,test_size=0.2, random_state=42)\n        x_train = np.asarray(np.reshape(np.asarray([np.asarray(x) for x in train[\"audio_data\"]]),(train.shape[0],1,sequence_length))).astype(np.float32)\n        groundtruth = np.asarray([np.asarray(x) for x in train[\"bird\"]]).astype(np.float32)\n        y_train = to_categorical(groundtruth, num_classes=len(self.bird_to_id.keys()), dtype='float32')\n\n        x_valid = np.asarray(np.reshape(np.asarray([np.asarray(x) for x in valid[\"audio_data\"]]),(valid.shape[0],1,sequence_length))).astype(np.float32)\n        validation_groundtruth = np.asarray([np.asarray(x) for x in valid[\"bird\"]]).astype(np.float32)\n        y_valid = to_categorical(validation_groundtruth, num_classes=len(self.bird_to_id.keys()), dtype='float32')\n        return x_train,y_train,x_valid,y_valid","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"prp_obj = Preprocessing()\ntrain_df = prp_obj.load_data('/kaggle/input/birdsong-recognition/train.csv')\ntrain_audio_path = '/kaggle/input/birdsong-recognition/train_audio/'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data = prp_obj.get_feature(train_df,train_audio_path)\ndata.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_train,y_train,x_valid,y_valid = prp_obj.get_data(data)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird2id = prp_obj.bird_to_id\nid2bird = prp_obj.id_to_bird\nnum_class = len(bird2id.keys())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CreateModel():\n    def build_model(self):\n        self.model = Sequential()\n        self.model.add(LSTM(32, return_sequences=True, recurrent_dropout=0.2,input_shape=(None, sequence_length)))\n        self.model.add(LSTM(32,recurrent_dropout=0.2))\n        self.model.add(Dense(128,activation = 'relu'))\n        self.model.add(Dropout(0.3))\n        self.model.add(Dense(128,activation = 'relu'))\n        self.model.add(Dropout(0.3))\n        self.model.add(Dense(num_class, activation=\"softmax\"))\n        self.model.summary()\n        self.model.compile(loss=\"categorical_crossentropy\", optimizer='adam',metrics=['acc'])\n        \n    def run(self):\n        callbacks = [ReduceLROnPlateau(monitor='val_loss', patience=2, verbose=1, factor=0.7),\n                     EarlyStopping(monitor='val_loss', patience=10),\n                     ModelCheckpoint(filepath='model.h5', monitor='val_loss', save_best_only=True)]\n        self.history = self.model.fit(x_train, y_train, \n                                      epochs = 100, \n                                      batch_size = 32,\n                                      validation_data=(x_valid, y_valid), \n                                      callbacks=callbacks)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_obj = CreateModel()\nmodel_obj.build_model()\nmodel_obj.run()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class Prediction():\n    def __init__(self):\n        self.model = keras.models.load_model(\"model.h5\")\n        test_file_path = \"/kaggle/input/birdsong-recognition/example_test_audio\"\n        test_df = pd.read_csv(\"/kaggle/input/birdsong-recognition/example_test_audio_summary.csv\")\n        test_df[\"audio_id\"] = [ \"BLKFR-10-CPL_20190611_093000.pt540\" if filename==\"BLKFR-10-CPL\" else \"ORANGE-7-CAP_20190606_093000.pt623\" for filename in test_df[\"filename\"]]\n\n    def predict_submission(self, df, audio_file_path):\n        \n        loaded_audio_sample = []\n        previous_filename = \"\"\n        data_point_per_second = 10\n        sample_length = 5*data_point_per_second\n        wave_data = []\n        wave_rate = None\n\n        for idx,row in df.iterrows():\n            try:\n                if previous_filename == \"\" or previous_filename!=row.audio_id:\n                    filename = '{}/{}.mp3'.format(audio_file_path, row.audio_id)\n                    wave_data, wave_rate = librosa.load(filename)\n                    prepared_sample = wave_data[0::int(wave_rate/data_point_per_second)]\n                    sample = sklearn.preprocessing.minmax_scale(prepared_sample, axis=0)\n                previous_filename = row.audio_id\n\n                #basically allows to check if we are running the examples or the test set.\n                if \"site\" in df.columns:\n                    if row.site==\"site_1\" or row.site==\"site_2\":\n                        song_sample = np.array(sample[int(row.seconds-5)*data_point_per_second:int(row.seconds)*data_point_per_second])\n                    elif row.site==\"site_3\":\n                        song_sample = np.array(sample[0:sample_length])\n                else:\n                    song_sample = np.array(sample[int(row.seconds-5)*data_point_per_second:int(row.seconds)*data_point_per_second])\n\n                input_data = np.reshape(np.asarray([song_sample]),(1,sequence_length)).astype(np.float32)\n                prediction = model.predict(np.array([input_data]))\n\n                if any(prediction[0]>0.5):\n                    predicted_bird = id2bird[np.argmax(prediction)]\n                    df.at[idx,\"birds\"] = predicted_bird\n                else:\n                    df.at[idx,\"birds\"] = \"nocall\"\n            except:\n                df.at[idx,\"birds\"] = \"nocall\"\n        return df\n    \n    def make_submission(self):\n        test_file_path = \"/kaggle/input/birdsong-recognition/test_audio\"\n        test_df = pd.read_csv(\"/kaggle/input/birdsong-recognition/test.csv\")\n        submission_df = pd.read_csv(\"/kaggle/input/birdsong-recognition/sample_submission.csv\")\n        submission_df = self.predict_submission(test_df, test_file_path)\n\n        submission_df[[\"row_id\",\"birds\"]].to_csv('submission.csv', index=False)\n        submission_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred_obj = Prediction()\npred_obj.make_submission()","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}