{"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":"# Prepare Environment","metadata":{}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nimport pandas as pd\nimport math\nimport cv2\nimport librosa \nimport librosa.display\nimport IPython.display as ipd \nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.model_selection import train_test_split\n\nos.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' \nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Sequential, load_model\nfrom tensorflow.keras.layers import *\nfrom tensorflow.keras import backend as K","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-03-18T20:58:47.861763Z","iopub.execute_input":"2022-03-18T20:58:47.862033Z","iopub.status.idle":"2022-03-18T20:58:47.868971Z","shell.execute_reply.started":"2022-03-18T20:58:47.862003Z","shell.execute_reply":"2022-03-18T20:58:47.867852Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def merge_history(hlist):\n    history = {}\n    for k in hlist[0].history.keys():\n        history[k] = sum([h.history[k] for h in hlist], [])\n    return history","metadata":{"execution":{"iopub.status.busy":"2022-03-18T20:56:28.311914Z","iopub.execute_input":"2022-03-18T20:56:28.312158Z","iopub.status.idle":"2022-03-18T20:56:28.316545Z","shell.execute_reply.started":"2022-03-18T20:56:28.312127Z","shell.execute_reply":"2022-03-18T20:56:28.315857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def vis_training(h, start=1):\n    epoch_range = range(start, len(h['loss'])+1)\n    s = slice(start-1, None)\n\n    plt.figure(figsize=[14,4])\n\n    n = int(len(h.keys()) / 2)\n\n    for i in range(n):\n        k = list(h.keys())[i]\n        plt.subplot(1,n,i+1)\n        plt.plot(epoch_range, h[k][s], label='Training')\n        plt.plot(epoch_range, h['val_' + k][s], label='Validation')\n        plt.xlabel('Epoch'); plt.ylabel(k); plt.title(k)\n        plt.grid()\n        plt.legend()\n\n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-18T20:56:28.317686Z","iopub.execute_input":"2022-03-18T20:56:28.318030Z","iopub.status.idle":"2022-03-18T20:56:28.335801Z","shell.execute_reply.started":"2022-03-18T20:56:28.317989Z","shell.execute_reply":"2022-03-18T20:56:28.335058Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load Data","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv('../input/freesound-audio-tagging/train.csv')\nprint(train.shape, '\\n')\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-18T20:56:28.337414Z","iopub.execute_input":"2022-03-18T20:56:28.337670Z","iopub.status.idle":"2022-03-18T20:56:28.377939Z","shell.execute_reply.started":"2022-03-18T20:56:28.337637Z","shell.execute_reply":"2022-03-18T20:56:28.377271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Explore Sample","metadata":{}},{"cell_type":"code","source":"harmonica = '../input/freesound-audio-tagging/audio_train/86881793.wav'\nipd.Audio(harmonica)","metadata":{"execution":{"iopub.status.busy":"2022-03-18T20:57:16.667674Z","iopub.execute_input":"2022-03-18T20:57:16.668313Z","iopub.status.idle":"2022-03-18T20:57:16.709031Z","shell.execute_reply.started":"2022-03-18T20:57:16.668275Z","shell.execute_reply":"2022-03-18T20:57:16.708435Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"signal, sr = librosa.load(harmonica)\nprint(type(signal))\nprint(type(sr))","metadata":{"execution":{"iopub.status.busy":"2022-03-18T20:57:21.050785Z","iopub.execute_input":"2022-03-18T20:57:21.051048Z","iopub.status.idle":"2022-03-18T20:57:22.042699Z","shell.execute_reply.started":"2022-03-18T20:57:21.051021Z","shell.execute_reply":"2022-03-18T20:57:22.040991Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(signal.shape)\nprint(sr)\nprint(len(signal) / sr)","metadata":{"execution":{"iopub.status.busy":"2022-03-18T20:57:24.117194Z","iopub.execute_input":"2022-03-18T20:57:24.117802Z","iopub.status.idle":"2022-03-18T20:57:24.122301Z","shell.execute_reply.started":"2022-03-18T20:57:24.117762Z","shell.execute_reply":"2022-03-18T20:57:24.121598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize = [12,3])\nplt.subplot(2,1,1)\nplt.plot(signal)\nplt.subplot(2,1,2)\ninterval = range(2000, 3000)\nplt.plot(interval, signal[interval])\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-18T20:57:26.977699Z","iopub.execute_input":"2022-03-18T20:57:26.978279Z","iopub.status.idle":"2022-03-18T20:57:27.318351Z","shell.execute_reply.started":"2022-03-18T20:57:26.978240Z","shell.execute_reply":"2022-03-18T20:57:27.317637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x1 = librosa.feature.melspectrogram(y=signal, sr=22050)   \nx2 = librosa.power_to_db(x1, ref=np.max)   \n\nprint(x2.shape)\n\nlibrosa.display.specshow(x2, sr=22050, x_axis='time', y_axis='hz')\nplt.colorbar()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-18T20:57:29.275968Z","iopub.execute_input":"2022-03-18T20:57:29.276830Z","iopub.status.idle":"2022-03-18T20:57:29.554171Z","shell.execute_reply.started":"2022-03-18T20:57:29.276783Z","shell.execute_reply":"2022-03-18T20:57:29.553495Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Label Encoder","metadata":{}},{"cell_type":"code","source":"labels = np.unique(train.label.values)\nlabel_encoder = {label:i for i, label in enumerate(labels)}\nprint(label_encoder['Bark'])\nprint(label_encoder['Knock'])","metadata":{"execution":{"iopub.status.busy":"2022-03-18T20:57:32.574899Z","iopub.execute_input":"2022-03-18T20:57:32.575200Z","iopub.status.idle":"2022-03-18T20:57:32.594705Z","shell.execute_reply.started":"2022-03-18T20:57:32.575165Z","shell.execute_reply":"2022-03-18T20:57:32.593934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Generators","metadata":{}},{"cell_type":"code","source":"SPEC_PATH = '../input/freesound-mel-spectrograms-128-512/spectrograms'\nIMG_SIZE = (128,32)\n\nclass DataGenerator(keras.utils.Sequence):\n    \n    def __init__(self, df, batch_size=32, shuffle=True, is_train=True):\n        self.df = df\n        self.n = len(df)\n        self.batch_size = batch_size\n        self.shuffle = shuffle\n        self.is_train = is_train\n        self.on_epoch_end()\n        \n    def on_epoch_end(self):\n        self.indices = np.arange(self.n)\n        if self.shuffle == True:\n            np.random.shuffle(self.indices)   \n    \n    def __len__(self):\n        \n        return math.ceil( self.n / self.batch_size )\n    \n    def __getitem__(self, batch_index):\n        \n        start = batch_index * self.batch_size\n        end = (batch_index + 1) * self.batch_size\n        \n        indices = self.indices[start:end]\n        \n        return self.__data_generation(indices)\n    \n    def __data_generation(self, batch_indices):\n        batch_size = len(batch_indices)\n        \n        X = np.zeros(shape=(batch_size, IMG_SIZE[0], IMG_SIZE[1], 1))\n        y = np.zeros(batch_size)\n        \n        for i, idx in enumerate(batch_indices):\n            FILE = self.df.fname.values[idx]\n            LABEL = self.df.label.values[idx]\n            \n            SET = 'train_spec' if self.is_train else 'test_spec'\n            path = f'{SPEC_PATH}/{SET}/{FILE[:-4]}.npy'\n\n            try:\n                data_array = np.load(path)\n                resized = cv2.resize(data_array, (IMG_SIZE[1], IMG_SIZE[0]))\n                X[i,:,:,0] = resized                \n            except:\n                print('skipped')\n\n            if self.is_train:\n                y[i] = label_encoder[LABEL]\n\n        if self.is_train:    \n            return X, y\n        return X\n\n    \nGENERATOR_TEST = True\n\nif GENERATOR_TEST:\n    temp_gen = DataGenerator(train, batch_size=8, shuffle=False)\n    X,y = temp_gen.__getitem__(0)\n\n    print(X.shape)\n    print(y)\n    \n    librosa.display.specshow(X[0, :, :, 0])","metadata":{"execution":{"iopub.status.busy":"2022-03-18T21:06:15.278862Z","iopub.execute_input":"2022-03-18T21:06:15.279139Z","iopub.status.idle":"2022-03-18T21:06:15.364989Z","shell.execute_reply.started":"2022-03-18T21:06:15.279107Z","shell.execute_reply":"2022-03-18T21:06:15.364202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df, valid_df = train_test_split(train, test_size=0.2, random_state=1, stratify=train.label)\n\nprint(train_df.shape)\nprint(valid_df.shape)","metadata":{"execution":{"iopub.status.busy":"2022-03-18T21:06:17.890659Z","iopub.execute_input":"2022-03-18T21:06:17.891362Z","iopub.status.idle":"2022-03-18T21:06:17.913768Z","shell.execute_reply.started":"2022-03-18T21:06:17.891325Z","shell.execute_reply":"2022-03-18T21:06:17.913107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_loader = DataGenerator(train_df, batch_size=64, shuffle=True)\nvalid_loader = DataGenerator(valid_df, batch_size=64, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2022-03-18T21:06:19.555014Z","iopub.execute_input":"2022-03-18T21:06:19.555590Z","iopub.status.idle":"2022-03-18T21:06:19.559830Z","shell.execute_reply.started":"2022-03-18T21:06:19.555557Z","shell.execute_reply":"2022-03-18T21:06:19.558880Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Build CNN","metadata":{}},{"cell_type":"code","source":"np.random.seed(1)\n\ncnn = Sequential()\n\ncnn.add(Conv2D(16, (3,3), activation = 'relu', padding = 'same', input_shape=(128,32,1)))\ncnn.add(Conv2D(16, (3,3), activation = 'relu', padding = 'same'))\ncnn.add(MaxPooling2D(2,2))\ncnn.add(Dropout(0.50))\ncnn.add(BatchNormalization())\n\ncnn.add(Conv2D(32, (3,3), activation = 'relu', padding = 'same'))\ncnn.add(Conv2D(32, (3,3), activation = 'relu', padding = 'same'))\ncnn.add(MaxPooling2D(2,2))\ncnn.add(Dropout(0.50))\ncnn.add(BatchNormalization())\n\n\ncnn.add(Flatten())\n\ncnn.add(Dense(128, activation='relu'))\ncnn.add(Dropout(0.5))\ncnn.add(BatchNormalization())\n\ncnn.add(Dense(64, activation='relu'))\ncnn.add(Dropout(0.50))\ncnn.add(BatchNormalization())\n\ncnn.add(Dense(41, activation='softmax'))\n\ncnn.summary()","metadata":{"execution":{"iopub.status.busy":"2022-03-18T21:06:20.943345Z","iopub.execute_input":"2022-03-18T21:06:20.944101Z","iopub.status.idle":"2022-03-18T21:06:21.071261Z","shell.execute_reply.started":"2022-03-18T21:06:20.944034Z","shell.execute_reply":"2022-03-18T21:06:21.070572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train Network","metadata":{}},{"cell_type":"code","source":"%%time\n\nopt = tf.keras.optimizers.Adam(0.001)\ncnn.compile(loss='sparse_categorical_crossentropy', optimizer=opt, metrics=['accuracy'])\n\nh1 = cnn.fit(train_loader, epochs=10, validation_data=valid_loader, verbose=1)","metadata":{"execution":{"iopub.status.busy":"2022-03-18T21:06:23.476455Z","iopub.execute_input":"2022-03-18T21:06:23.477317Z","iopub.status.idle":"2022-03-18T21:08:33.802595Z","shell.execute_reply.started":"2022-03-18T21:06:23.477270Z","shell.execute_reply":"2022-03-18T21:08:33.801066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = merge_history([h1])\nvis_training(history)","metadata":{"execution":{"iopub.status.busy":"2022-03-18T21:08:33.804715Z","iopub.execute_input":"2022-03-18T21:08:33.804964Z","iopub.status.idle":"2022-03-18T21:08:34.172535Z","shell.execute_reply.started":"2022-03-18T21:08:33.804929Z","shell.execute_reply":"2022-03-18T21:08:34.171852Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Save Model\n","metadata":{}},{"cell_type":"code","source":"cnn.save(f'my_model_v01.h5')","metadata":{"execution":{"iopub.status.busy":"2022-03-18T21:08:34.173747Z","iopub.execute_input":"2022-03-18T21:08:34.174145Z","iopub.status.idle":"2022-03-18T21:08:34.258006Z","shell.execute_reply.started":"2022-03-18T21:08:34.174105Z","shell.execute_reply":"2022-03-18T21:08:34.257352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Test Predictions","metadata":{}},{"cell_type":"code","source":"test = pd.read_csv('../input/freesound-audio-tagging/sample_submission.csv')\n\ntest_loader = DataGenerator(test, batch_size=64, shuffle=False, is_train=False)\n\nprobs = cnn.predict(test_loader)\nprint(probs.shape)","metadata":{"execution":{"iopub.status.busy":"2022-03-18T21:09:15.455255Z","iopub.execute_input":"2022-03-18T21:09:15.455548Z","iopub.status.idle":"2022-03-18T21:09:56.355882Z","shell.execute_reply.started":"2022-03-18T21:09:15.455518Z","shell.execute_reply":"2022-03-18T21:09:56.355137Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(probs[0, :].round(2))\n","metadata":{"execution":{"iopub.status.busy":"2022-03-18T21:10:54.991991Z","iopub.execute_input":"2022-03-18T21:10:54.992351Z","iopub.status.idle":"2022-03-18T21:10:55.003882Z","shell.execute_reply.started":"2022-03-18T21:10:54.992314Z","shell.execute_reply":"2022-03-18T21:10:55.003148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Submit Top 1 Prediction","metadata":{}},{"cell_type":"code","source":"submission_top1 = test.copy()\n\nN = len(test)\nfor i in range(N):\n    p = probs[i, :]\n    idx = np.argmax(p)\n    submission_top1.label[i] = labels[idx]\n\nsubmission_top1.to_csv('submission_top1.csv', index=False, header=True)\n\nsubmission_top1.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-18T21:11:53.551915Z","iopub.execute_input":"2022-03-18T21:11:53.552468Z","iopub.status.idle":"2022-03-18T21:11:54.265617Z","shell.execute_reply.started":"2022-03-18T21:11:53.552429Z","shell.execute_reply":"2022-03-18T21:11:54.264927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Submit Top 3 Predictions","metadata":{}},{"cell_type":"code","source":"submission_top3 = test.copy()\n\nN = len(test)\nfor i in range(N):\n    p = probs[i, :]\n    idx = np.argsort(-p)[:3]\n    top3 = labels[idx]\n    submission_top3.label[i] = ' '.join(top3)\n\nsubmission_top3.to_csv('submission_top3.csv', index=False, header=True)\nsubmission_top3.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-18T21:12:33.748353Z","iopub.execute_input":"2022-03-18T21:12:33.748722Z","iopub.status.idle":"2022-03-18T21:12:34.876625Z","shell.execute_reply.started":"2022-03-18T21:12:33.748681Z","shell.execute_reply":"2022-03-18T21:12:34.875944Z"},"trusted":true},"execution_count":null,"outputs":[]}]}