{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport os\nimport json\nimport tensorflow as tf\nimport tensorflow.keras.layers as ls\nfrom tensorflow.contrib.framework.python.ops import audio_ops as audio\nfrom sklearn.preprocessing import MultiLabelBinarizer","execution_count":1,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"os.listdir('../input')","execution_count":2,"outputs":[{"output_type":"execute_result","execution_count":2,"data":{"text/plain":"['freesound-audio-tagging-2019', 'cnnfat2019']"},"metadata":{}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"do_run=False","execution_count":3,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if not do_run:\n    print(os.listdir('../input/cnnfat2019'))\n    train_curated_csv = '../input/freesound-audio-tagging-2019/train_curated.csv'\n    train_noisy_csv = '../input/freesound-audio-tagging-2019/train_noisy.csv'\n    test_csv = '../input/freesound-audio-tagging-2019/test.csv'\n    train_curated_path = '../input/freesound-audio-tagging-2019/train_curated/'\n    train_noisy_path = '../input/freesound-audio-tagging-2019/train_noisy/'\nelse:\n    train_curated_csv = '../input/train_curated.csv'\n    train_noisy_csv = '../input/train_noisy.csv'\n    test_csv = '../input/test.csv'\n    train_curated_path = '../input/train_curated/'\n    train_noisy_path = '../input/train_noisy/'","execution_count":4,"outputs":[{"output_type":"stream","text":"['model.ckpt-29700.index', 'model.ckpt-29600.data-00000-of-00001', 'events.out.tfevents.1559275568.8820e0a5f4f9', 'model.ckpt-29800.meta', 'events.out.tfevents.1559275567.8820e0a5f4f9', 'model.ckpt-29600.index', 'model.ckpt-29900.meta', 'model.ckpt-29600.meta', 'model.ckpt-30000.data-00000-of-00001', 'model.ckpt-29900.data-00000-of-00001', 'checkpoint', 'model.ckpt-29900.index', 'model.ckpt-29700.meta', 'model.ckpt-30000.meta', 'model.ckpt-29700.data-00000-of-00001', 'model.ckpt-29800.data-00000-of-00001', 'model.ckpt-30000.index', 'model.ckpt-29800.index']\n","name":"stdout"}]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"# Read train files\ntrain_curated_df = pd.read_csv(train_curated_csv)\ntrain_noisy_df = pd.read_csv(train_noisy_csv)\n\n# Append path to train files\ntrain_curated_df['fname'] = train_curated_path + train_curated_df['fname']\ntrain_noisy_df['fname'] = train_noisy_path + train_noisy_df['fname']\n\n# Generate labels dict\nlabels = np.concatenate(train_curated_df['labels'].str.split(','))\nunique_labels = np.unique(labels)\nlabels_dict = {label:i for i, label in enumerate(unique_labels)}\n\n# Generate Val curated df\nsplit = int(0.2 * train_curated_df.shape[0])\nindices = np.random.permutation(train_curated_df.shape[0])\nval_indices = indices[:split]\ntrain_indices = indices[split:]\nval_curated_df = train_curated_df[train_curated_df.index.isin(val_indices)]\ntrain_curated_df = train_curated_df[train_curated_df.index.isin(train_indices)]\n\n# Generate Train df\ntrain_df = pd.concat([train_curated_df, train_noisy_df])\n\n# Remove unwanted labels from noisy data\nnoisy_labels = train_noisy_df['labels'].str.split(',')\nnew_noisy_labels = []\nfor labels in noisy_labels:\n    new_noisy_labels.append(','.join([label for label in labels if label in labels_dict]))\ntrain_noisy_df['labels'] = new_noisy_labels\n\n# Saving files\nif not os.path.isdir('./preprocessed'):\n    os.makedirs('./preprocessed')\ntrain_curated_df.to_csv('./preprocessed/train_curated.csv', index=False)\ntrain_noisy_df.to_csv('./preprocessed/train_noisy.csv', index=False)\nval_curated_df.to_csv('./preprocessed/val_curated.csv', index=False)\ntrain_df.to_csv('./preprocessed/train.csv', index=False)\n\nwith open('./preprocessed/labels_dict.json', 'w+') as fp:\n    json.dump(labels_dict, fp)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del train_curated_df\ndel train_df\ndel train_noisy_df\ndel train_indices\ndel labels_dict\nimport gc; gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def random_rolls(audio):\n    random_num = tf.random.uniform((1,), 0, 10)[0]\n    cond = random_num >= 5\n    roll_amount = tf.random.uniform((1,), 1200, 2000)[0]\n    new_audio = tf.cond(\n        cond, lambda: tf.manip.roll(audio, tf.cast(roll_amount, tf.int32), 0),\n        lambda: audio)\n    return new_audio\n\ndef random_speedx(audio):\n    def get_audio():\n        factor = tf.random.uniform((1,), 0.7, 1.7)[0]\n        indices = tf.round(tf.range(0, tf.shape(audio)[0], factor))\n        indices = tf.boolean_mask(indices, indices < tf.cast(tf.shape(audio)[0], tf.float32))\n        sound = tf.gather(audio, tf.cast(indices, tf.int32))\n        return sound\n\n    random_num = tf.random.uniform((1,), 0, 10)[0]\n    cond = random_num >= 5\n    return tf.cond(cond, get_audio, lambda: audio)\n\ndef wav_to_spectogram(wav_filename, random_perturbs=False):\n    wav_bytes = tf.read_file(wav_filename)\n    wav_decoder = audio.decode_wav(wav_bytes, 1)\n    if random_perturbs:\n        sound = random_speedx(random_rolls(wav_decoder.audio))\n    else:\n        sound = wav_decoder.audio\n    spectogram = audio.audio_spectrogram(\n        sound, window_size=1024, stride=64)\n    \n    minimum =  tf.minimum(spectogram, 255.)\n    expand_dims = tf.expand_dims(minimum, -1)\n    resize = tf.image.resize_bilinear(expand_dims, [300, 300])\n    squeeze = tf.squeeze(resize, 0)\n\n    return squeeze\n\ndef csv_pipe(csv, labels_dict):\n    df = pd.read_csv(csv)\n    df = df.sample(frac=1).reset_index(drop=True)\n    \n    files = df['fname']\n    labels = df['labels'].str.split(',')\n\n    binarizer = MultiLabelBinarizer(list(labels_dict.keys()))\n    labels_1hot = binarizer.fit_transform(labels).astype(np.int32)\n    return files, labels_1hot\n\ndef wav_data_generators(csv, labels_dict, batch_size=32, shuffle=False, repeat=True):\n    files, labels = csv_pipe(csv, labels_dict)\n\n    wav_to_spectogram_applier = lambda file, label: (wav_to_spectogram(file, random_perturbs=shuffle), label)\n\n    dataset = tf.data.Dataset.from_tensor_slices((files, labels))\n    dataset = dataset.map(wav_to_spectogram_applier)\n\n    if shuffle:\n        dataset = dataset.shuffle(800)\n\n    dataset = dataset.batch(batch_size).prefetch(10)\n\n    if repeat:\n        dataset = dataset.repeat()\n\n    return dataset","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def conv_relu_bn(filters, kernels, strides, padding='valid', in_shape=None):\n    if in_shape is not None:\n        conv = ls.Conv2D(filters, kernels, strides, padding=padding, input_shape=in_shape)\n    else:\n        conv = ls.Conv2D(filters, kernels, strides, padding=padding)\n    return tf.keras.models.Sequential([\n        conv,\n        ls.ReLU(),\n        ls.BatchNormalization()\n    ])\n    \n\nclass Model(tf.keras.Model):\n    def __init__(self, in_shape, n_classes=80):\n        super(Model, self).__init__()\n        self.conv_relu_bn1 = conv_relu_bn(64, 3, 1, padding='same', in_shape=in_shape)\n        self.conv_relu_bn2 = conv_relu_bn(64, 3, 2)\n        self.conv_relu_bn3 = conv_relu_bn(128, 3, 1, padding='same')\n        self.conv_relu_bn4 = conv_relu_bn(128, 3, 2)\n        self.conv_relu_bn5 = conv_relu_bn(256, 3, 1, padding='same')\n        self.conv_relu_bn6 = conv_relu_bn(256, 3, 2)\n        self.conv_relu_bn7 = conv_relu_bn(512, 3, 1, padding='same')\n        self.conv_relu_bn8 = conv_relu_bn(512, 3, 2)\n        self.gpool = ls.GlobalAveragePooling2D()\n        self.classifier = ls.Dense(n_classes)\n\n    def call(self, inputs):\n        conv_relu_bn1 = self.conv_relu_bn1(inputs)\n        conv_relu_bn2 = self.conv_relu_bn2(conv_relu_bn1)\n        conv_relu_bn3 = self.conv_relu_bn3(conv_relu_bn2)\n        conv_relu_bn4 = self.conv_relu_bn4(conv_relu_bn3)\n        conv_relu_bn5 = self.conv_relu_bn5(conv_relu_bn4)\n        conv_relu_bn6 = self.conv_relu_bn6(conv_relu_bn5)\n        conv_relu_bn7 = self.conv_relu_bn7(conv_relu_bn6)\n        conv_relu_bn8 = self.conv_relu_bn8(conv_relu_bn7)\n        pooled = self.gpool(conv_relu_bn8)\n        return self.classifier(pooled)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class Trainor:\n    def __init__(self,\n                 train_csv,\n                 val_csv,\n                 labels_dict,\n                 lr=1e-3,\n                 batch_size=8,\n                 shuffle=True,\n                 model_dir='ds2'):\n        if not os.path.isdir(model_dir):\n            os.makedirs(model_dir)\n        self.model_dir = model_dir\n        self.model = Model(in_shape=(300, 300, 1))\n        self._define_dataset_iterators(\n            train_csv, val_csv, labels_dict, batch_size, shuffle)\n\n        logits = self.model(self.features)\n        self.probas = tf.nn.sigmoid(logits)\n        preds = self.probas > 0.5\n\n        self.loss = tf.losses.sigmoid_cross_entropy(self.labels, logits)\n        self.accuracy = tf.reduce_mean(tf.cast(\n            tf.equal(tf.cast(preds, tf.int32), self.labels), tf.float32))\n        optimizer = tf.train.RMSPropOptimizer(lr)\n        self.global_step = tf.train.get_or_create_global_step()\n        self.train_op = optimizer.minimize(self.loss, global_step=self.global_step)\n        \n        self.sess = tf.Session()\n        self._define_summaries()\n        self.sess.run(tf.global_variables_initializer())\n        self.saver = tf.train.Saver()\n        self._may_be_load_model()\n\n    def _define_summaries(self):\n        tf.summary.scalar('loss', self.loss)\n        tf.summary.scalar('accuracy', self.accuracy)\n        flip = tf.image.flip_left_right(self.features)\n        transpose = tf.image.transpose_image(flip)\n        tf.summary.image('spectogram', transpose)\n        self.merged = tf.summary.merge_all()\n        self.summary_writer = tf.summary.FileWriter(self.model_dir, self.sess.graph)\n\n    def _define_dataset_iterators(self, train_csv, val_csv, labels_dict, batch_size, shuffle):\n        train_dataset = wav_data_generators(\n            train_csv, labels_dict, batch_size, shuffle)\n        val_dataset = wav_data_generators(\n            val_csv, labels_dict, batch_size, shuffle)\n        iter = tf.data.Iterator.from_structure(\n            train_dataset.output_types, train_dataset.output_shapes)\n\n        self.features, self.labels = iter.get_next()\n        self.train_init_op = iter.make_initializer(train_dataset)\n        self.val_init_op = iter.make_initializer(val_dataset)\n\n    def _may_be_load_model(self):\n        #if os.path.isdir(self.model_dir):\n        if os.path.isdir('../input/cnnfat2019'):\n            #files = os.listdir(self.model_dir)\n            files = os.listdir('../input/cnnfat2019')\n            steps = [int(file.split('-')[-1].split('.')[0]) for file in files if 'model' in file]\n            if len(steps) > 0:\n                #self._load_model(os.path.join(self.model_dir, 'model.ckpt'), max(steps))\n                self._load_model(os.path.join('../input/cnnfat2019', 'model.ckpt'), max(steps))\n\n    def _save_model(self):\n        return self.saver.save(\n            self.sess, os.path.join(self.model_dir, 'model.ckpt'),\n            global_step=self.global_step)\n\n    def _load_model(self, ckpt_path, step):\n        self.saver.restore(self.sess, ckpt_path + '-{}'.format(step))\n\n    def train(self, steps=500, ckpt_every_n_steps=100, log_every_n_steps=1500, log_val_n_steps=5):\n        writer = tf.summary.FileWriter(self.model_dir, self.sess.graph)\n        self.sess.run(self.train_init_op)\n        for step in range(1, steps+1):\n            \n            summary, _ = self.sess.run([self.merged, self.train_op])\n            self.summary_writer.add_summary(summary, step)\n\n            if step % log_every_n_steps == 0:\n                self.sess.run(self.val_init_op)\n                val_losses, val_accs = [], []\n                for _ in range(log_val_n_steps):\n                    l, a = self.sess.run([self.loss, self.accuracy])\n                    val_losses.append(l)\n                    val_accs.append(a)\n                print('STEP: {}, Loss: {:.4f}, Acc: {:.4f}'.format(\n                    step, np.mean(val_losses), np.mean(val_accs)))\n                self.sess.run(self.train_init_op)\n\n            if step % ckpt_every_n_steps == 0:\n                path = self._save_model()\n                print('STEP: {}, Model saved at: {}'.format(step, path))\n        path = self._save_model()\n        print('Final Model saved at: {}'.format(step, path))\n\n    def __del__(self):\n        self.sess.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with open('./preprocessed/labels_dict.json') as fp:\n    labels_dict = json.load(fp)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# if do_run:\ntrainor = Trainor(\n    './preprocessed/train.csv',\n    './preprocessed/val_curated.csv',\nlabels_dict)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# if do_run:\ntrainor.train(3000)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# if not do_run:\n#     trainor = Trainor(\n#         './preprocessed/val_curated.csv',\n#         './preprocessed/train.csv',\n#         labels_dict)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# if not do_run:\n#     trainor.train(700)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class Predictor:\n    def __init__(self,\n                 files,\n                 lr=1e-3,\n                 batch_size=16,\n                 model_dir='ds2'):\n        self.model_dir = model_dir\n        self.model = Model((300, 300, 1))\n        self._define_dataset_iterator(\n            files, batch_size)\n\n        logits = self.model(self.features)\n        self.probas = tf.nn.sigmoid(logits)\n        \n        self.sess = tf.Session()\n        self.sess.run(tf.global_variables_initializer())\n        self.saver = tf.train.Saver()\n        self._load_model()\n\n    def _define_dataset_iterator(self, files, batch_size):\n        dataset = tf.data.Dataset.from_tensor_slices((files,))\n        dataset = dataset.map(wav_to_spectogram)\n\n        dataset = dataset.batch(batch_size).prefetch(10)\n\n        dataset = dataset.repeat(1)\n        self.features = dataset.make_one_shot_iterator().get_next()\n\n    def _load_model(self):\n        files = os.listdir(self.model_dir)\n        steps = [int(file.split('-')[-1].split('.')[0]) for file in files if 'model' in file]\n        ckpt_path = os.path.join(self.model_dir, 'model.ckpt')\n        self.saver.restore(self.sess, ckpt_path + '-{}'.format(max(steps)))\n\n    def pred_generator(self):\n        try:\n            while True:\n                yield self.sess.run(self.probas)\n        except:\n            print('Prediction over')\n\n    def __del__(self):\n        self.sess.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tf.reset_default_graph()\nif do_run:\n    orig_files = os.listdir('../input/test')\n    files = [os.path.join('../input/test', file) for file in orig_files]\n    predictor = Predictor(files)\nelse:\n    orig_files = os.listdir('../input/freesound-audio-tagging-2019/test')\n    files = [os.path.join('../input/freesound-audio-tagging-2019/test', file) for file in orig_files]\n    predictor = Predictor(files)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred_gen = predictor.pred_generator()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred_dict = {}\nfor label in labels_dict:\n    pred_dict[label] = []\n\nfor probs in pred_gen:\n    for label in labels_dict:\n        pred_dict[label].extend(list(probs[:, labels_dict[label]]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred_dict['fname'] = orig_files\ndf = pd.DataFrame(pred_dict, columns=['fname'].extend(list(labels_dict.keys())))\ndf.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}