{"cells": [{"source": ["# WavCeption V1: just a 1-D Inception approach "], "cell_type": "markdown", "metadata": {"_uuid": "b531642dd4c3a53e20e5f6b9076bf17e9418e1e4", "_cell_guid": "58ef1a47-96bc-416d-a016-938a494fb1c3"}}, {"source": ["I just wanted to share a little toy I have been playing with and gave me **amazing results**. As I currently don't have time, I would like to share it to see how people plays with it :-D. The **WavCeption V1** network seems to produce impressive results compared to a regular convolutional neural network, but in this competition it seems that there is a hard-work on the pre-processing and unknown tracks management. It is based on the Google's inception network, the same idea. \n", "\n", " I wrote some weeks ago a module implementing it so that it is easy to build an 1D-inception network by connecting lots of these modules in cascade (as you will see below).\n", " \n", " Unfortunately and due to several Kaggle constraints, it won't run in the kernel machine, so I encourage you to download it and run it in your own machine.\n", " \n", " By running the model for 12h without struggling too much I achieved 0.76 in the leaderboard (with 0.84 in local test). Some other trials in the same line gave me 0.89 in local, so there is a huge improvement in how you deal with the unknown clips :-D"], "cell_type": "markdown", "metadata": {"_uuid": "f597ce3d9e1e9fe818cf0a8e51f6da2404ba5b43", "_cell_guid": "e68a3daa-14d7-46d7-a0db-9f80380b9d0f"}}, {"source": ["## Load modules and libraries"], "cell_type": "markdown", "metadata": {"_uuid": "f924854d4d258cd9a7db10eb5566e0bdff085574", "_cell_guid": "dd3e1543-18e2-4be6-b511-5c1e734d2c60"}}, {"source": ["%matplotlib inline\n", "import numpy as np \n", "import pandas as pd \n", "import os\n", "import shutil\n", "import glob\n", "import random\n", "from tqdm import tqdm\n", "from collections import Counter\n", "from sklearn.preprocessing import LabelEncoder\n", "import IPython\n", "from numpy.fft import rfft, irfft\n", "import numpy as np\n", "import random\n", "import itertools\n", "\n", "from scipy.io import wavfile\n", "import IPython.display as ipd\n", "import matplotlib.pyplot as plt\n", "import scipy as sp\n", "import tensorflow as tf"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "9d73d1472e8ea2c21b0c70b5f537a74a9c562708", "collapsed": true, "_cell_guid": "cb0f537e-1932-4c45-a4d0-59e7d2caac6b"}}, {"source": ["## Noise generation functions "], "cell_type": "markdown", "metadata": {"_uuid": "89ca39590c40bc3e332bab39fcedc7f2670b0f99", "_cell_guid": "e8220812-116f-4f9b-a855-4b836f7411fc"}}, {"source": ["The code in this section has been borrowed and adapted from: \n", "https://github.com/python-acoustics/python-acoustics/blob/master/acoustics/generator.py"], "cell_type": "markdown", "metadata": {"_uuid": "d2d4594b05edbaf2eb450959812b741b8cfed6dc", "_cell_guid": "890ea515-323c-46ae-884f-9cc71cf19d08"}}, {"source": ["def ms(x):\n", "    \"\"\"Mean value of signal `x` squared.\n", "    :param x: Dynamic quantity.\n", "    :returns: Mean squared of `x`.\n", "    \"\"\"\n", "    return (np.abs(x)**2.0).mean()\n", "\n", "def normalize(y, x=None):\n", "    \"\"\"normalize power in y to a (standard normal) white noise signal.\n", "    Optionally normalize to power in signal `x`.\n", "    #The mean power of a Gaussian with :math:`\\\\mu=0` and :math:`\\\\sigma=1` is 1.\n", "    \"\"\"\n", "    #return y * np.sqrt( (np.abs(x)**2.0).mean() / (np.abs(y)**2.0).mean() )\n", "    if x is not None:\n", "        x = ms(x)\n", "    else:\n", "        x = 1.0\n", "    return y * np.sqrt( x / ms(y) )\n", "    #return y * np.sqrt( 1.0 / (np.abs(y)**2.0).mean() )\n", "\n", "def white_noise(N, state=None):\n", "    state = np.random.RandomState() if state is None else state\n", "    return state.randn(N)\n", "\n", "def pink_noise(N, state=None):\n", "\n", "    state = np.random.RandomState() if state is None else state\n", "    uneven = N%2\n", "    X = state.randn(N//2+1+uneven) + 1j * state.randn(N//2+1+uneven)\n", "    S = np.sqrt(np.arange(len(X))+1.) # +1 to avoid divide by zero\n", "    y = (irfft(X/S)).real\n", "    if uneven:\n", "        y = y[:-1]\n", "    return normalize(y)\n", "\n", "def blue_noise(N, state=None):\n", "    \"\"\"\n", "    Blue noise. \n", "    \n", "    :param N: Amount of samples.\n", "    :param state: State of PRNG.\n", "    :type state: :class:`np.random.RandomState`\n", "    \n", "    Power increases with 6 dB per octave.\n", "    Power density increases with 3 dB per octave. \n", "    \n", "    \"\"\"\n", "    state = np.random.RandomState() if state is None else state\n", "    uneven = N%2\n", "    X = state.randn(N//2+1+uneven) + 1j * state.randn(N//2+1+uneven)\n", "    S = np.sqrt(np.arange(len(X)))# Filter\n", "    y = (irfft(X*S)).real\n", "    if uneven:\n", "        y = y[:-1]\n", "    return normalize(y)\n", "\n", "def brown_noise(N, state=None):\n", "    \"\"\"\n", "    Violet noise.\n", "    \n", "    :param N: Amount of samples.\n", "    :param state: State of PRNG.\n", "    :type state: :class:`np.random.RandomState`\n", "    \n", "    Power decreases with -3 dB per octave.\n", "    Power density decreases with 6 dB per octave. \n", "    \"\"\"\n", "    state = np.random.RandomState() if state is None else state\n", "    uneven = N%2\n", "    X = state.randn(N//2+1+uneven) + 1j * state.randn(N//2+1+uneven)\n", "    S = (np.arange(len(X))+1)# Filter\n", "    y = (irfft(X/S)).real\n", "    if uneven:\n", "        y = y[:-1]\n", "    return normalize(y)\n", "\n", "def violet_noise(N, state=None):\n", "    \"\"\"\n", "    Violet noise. Power increases with 6 dB per octave. \n", "    \n", "    :param N: Amount of samples.\n", "    :param state: State of PRNG.\n", "    :type state: :class:`np.random.RandomState`\n", "    \n", "    Power increases with +9 dB per octave.\n", "    Power density increases with +6 dB per octave. \n", "    \n", "    \"\"\"\n", "    state = np.random.RandomState() if state is None else state\n", "    uneven = N%2\n", "    X = state.randn(N//2+1+uneven) + 1j * state.randn(N//2+1+uneven)\n", "    S = (np.arange(len(X)))# Filter\n", "    y = (irfft(X*S)).real\n", "    if uneven:\n", "        y = y[:-1]\n", "    return normalize(y)"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "df4bdf2dc7234238c43e495a393ea824ae5e6e82", "collapsed": true, "_cell_guid": "a401d022-6475-4155-8282-94acd8c81fd7"}}, {"source": ["## Tensorflow utilities"], "cell_type": "markdown", "metadata": {"_uuid": "a0c5d5315f8f420ba504c26f4ef0ed6d97a4aa57", "_cell_guid": "f08a3dd0-fb34-4415-a24d-795c2a475b3f"}}, {"source": ["Utilities to modularize tensorflow common actions"], "cell_type": "markdown", "metadata": {"_uuid": "ea75d0aee8fe1d444af7201364c62bc358ba38ab", "_cell_guid": "f7c51859-aedb-4da5-87e2-8ecf0d41425e"}}, {"source": ["# Tf Utils\n", "def get_tensorflow_configuration(device=\"0\", memory_fraction=1):\n", "    \"\"\"\n", "    Function for selecting the GPU to use and the amount of memory the process is allowed to use\n", "    :param device: which device should be used (str)\n", "    :param memory_fraction: which proportion of memory must be allocated (float)\n", "    :return: config to be passed to the session (tf object)\n", "    \"\"\"\n", "    device = str(device)\n", "    config = tf.ConfigProto()\n", "    config.allow_soft_placement = True\n", "    config.gpu_options.per_process_gpu_memory_fraction = memory_fraction\n", "    config.gpu_options.visible_device_list = device\n", "    return(config)\n", "\n", "\n", "def start_tensorflow_session(device=\"0\", memory_fraction=1):\n", "    \"\"\"\n", "    Starts a tensorflow session taking care of what GPU device is going to be used and\n", "    which is the fraction of memory that is going to be pre-allocated.\n", "    :device: string with the device number (str)\n", "    :memory_fraction: fraction of memory that is going to be pre-allocated in the specified\n", "    device (float [0, 1])\n", "    :return: configured tf.Session\n", "    \"\"\"\n", "    return(tf.Session(config=get_tensorflow_configuration(device=device, memory_fraction=memory_fraction)))\n", "\n", "\n", "def get_summary_writer(session, logs_path, project_id, version_id):\n", "    \"\"\"\n", "    For Tensorboard reporting\n", "    :param session: opened tensorflow session (tf.Session)\n", "    :param logs_path: path where tensorboard is looking for logs (str)\n", "    :param project_id: name of the project for reporting purposes (str)\n", "    :param version_id: name of the version for reporting purposes (str)\n", "    :return summary_writer: the tensorboard writer\n", "    \"\"\"\n", "    path = os.path.join(logs_path,\"{}_{}\".format(project_id, version_id)) \n", "    if os.path.exists(path):\n", "        shutil.rmtree(path)\n", "    summary_writer = tf.summary.FileWriter(path, graph_def=session.graph_def)\n", "    return(summary_writer)\n"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "7a782f5e128b8c429c9df8489276c8147ed365f2", "collapsed": true, "_cell_guid": "93fe476d-5f7b-40b1-a074-1a0e9d50ce11"}}, {"source": ["## Paths management module"], "cell_type": "markdown", "metadata": {"_uuid": "233bef658d360ebf7c9c6f623925615c56ec727b", "_cell_guid": "7dadd066-bd8e-4902-939d-300993467c67"}}, {"source": ["Modules to deal with the paths"], "cell_type": "markdown", "metadata": {"_uuid": "3bba8797dc146f2a51bc6887aa3d60831745425d", "_cell_guid": "db84f1ec-e69d-47b6-9bc2-6916a224e905"}}, {"source": ["# Common paths\n", "def _norm_path(path):\n", "    \"\"\"\n", "    Decorator function intended for using it to normalize a the output of a path retrieval function. Useful for\n", "    fixing the slash/backslash windows cases.\n", "    \"\"\"\n", "    def normalize_path(*args, **kwargs):\n", "        return os.path.normpath(path(*args, **kwargs))\n", "    return normalize_path\n", "\n", "\n", "def _assure_path_exists(path):\n", "    \"\"\"\n", "    Decorator function intended for checking the existence of a the output of a path retrieval function. Useful for\n", "    fixing the slash/backslash windows cases.\n", "    \"\"\"\n", "    def assure_exists(*args, **kwargs):\n", "        p=path(*args, **kwargs)\n", "        assert os.path.exists(p), \"the following path does not exist: '{}'\".format(p)\n", "        return p\n", "    return assure_exists\n", "\n", "\n", "def _is_output_path(path):\n", "    \"\"\"\n", "    Decorator function intended for grouping the functions which are applied over the output of an output path retrieval\n", "    function\n", "    \"\"\"\n", "    @_norm_path\n", "    @_assure_path_exists\n", "    def check_existence_or_create_it(*args, **kwargs):\n", "        if not os.path.exists(path(*args, **kwargs)):\n", "            \"Path does not exist... creating it: {}\".format(path(*args, **kwargs))\n", "            os.makedirs(path(*args, **kwargs))\n", "        return path(*args, **kwargs)\n", "    return check_existence_or_create_it\n", "\n", "\n", "def _is_input_path(path):\n", "    \"\"\"\n", "    Decorator function intended for grouping the functions which are applied over the output of an input path retrieval\n", "    function\n", "    \"\"\"\n", "    @_norm_path\n", "    @_assure_path_exists\n", "    def check_existence(*args, **kwargs):\n", "        return path(*args, **kwargs)\n", "    return check_existence\n", "\n", "@_is_input_path\n", "def get_train_path():\n", "    path = \"../input/train\"\n", "    return path\n", "\n", "@_is_input_path\n", "def get_test_path():\n", "    path = \"../input/test\"\n", "    return path\n", "\n", "@_is_input_path\n", "def get_train_audio_path():\n", "    path = os.path.join(get_train_path(), \"audio\")\n", "    return path\n", "\n", "@_is_input_path\n", "def get_scoring_audio_path():\n", "    path = os.path.join(get_test_path(), \"audio\")\n", "    return path\n", "\n", "@_is_output_path\n", "def get_submissions_path():\n", "    path = \"../working/output\"\n", "    return path\n", "\n", "@_is_output_path\n", "def get_silence_path():\n", "    path = \"../working/silence\"\n", "    return path"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "ac2c7e2219c90972ed163a2ce50c2af3c634f8be", "collapsed": true, "_cell_guid": "98e21f2b-673c-44d3-a156-56278ebe0054"}}, {"source": ["## Utilities"], "cell_type": "markdown", "metadata": {"_uuid": "fb0647c5bf761a85cfbfc98017dfc428cad260f4", "_cell_guid": "ee43ab62-3c4a-40dc-9f18-efb0c114505d"}}, {"source": ["Common general-purpose utilities"], "cell_type": "markdown", "metadata": {"_uuid": "46742e27457bae13221a6dd2983aeb05c59b7aaa", "_cell_guid": "7001ab0b-20f0-44ad-abc9-54c855232c53"}}, {"source": ["# Utilities\n", "flatten = lambda l: [item for sublist in l for item in sublist]\n", "\n", "def batching(iterable, n=1):\n", "    l = len(iterable)\n", "    for ndx in range(0, l, n):\n", "        yield iterable[ndx:min(ndx + n, l)]"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "ca100ad49d05f067cd4c96636a687563581f73d8", "collapsed": true, "_cell_guid": "c38d1870-b7c4-453e-bf94-1d6226fbe8b8"}}, {"source": ["## Data Tools"], "cell_type": "markdown", "metadata": {"_uuid": "2d0cb1612507e8edcf3752cb3411b4836f6ec800", "_cell_guid": "4cf6e246-a187-456d-9b32-4885babd562f"}}, {"source": ["Data handling tools"], "cell_type": "markdown", "metadata": {"_uuid": "666ca8a8a9f96b9284d8efa3b5d0f5617661c399", "_cell_guid": "0d5b73ee-5261-4ada-8ca1-3bf5a31af487"}}, {"source": ["# Data tools\n", "def read_wav(filepath, pad=True):\n", "    \"\"\"\n", "    Given the filepath of a wav file, this function reads it, normalizes it and pads\n", "    it to assure it has 16k samples.\n", "    :param filepath: existing filepath of a wav file (str)\n", "    :param pad: is padding required? (bool)\n", "    :returns: the sample and the target variable (tuple of (np.array, str))\n", "    \"\"\"\n", "    sample_rate, x = wavfile.read(filepath)\n", "    target = os.path.split(os.path.split(filepath)[0])[1]\n", "    assert sample_rate==16000\n", "    if pad:\n", "        return np.pad(x, (0, 16000-len(x)), mode=\"constant\")/32768, target\n", "    else:\n", "        return x/32768, target\n", "\n", "def get_batcher(list_of_paths, batch_size, label_encoder=None, scoring=False):\n", "    \"\"\"\n", "    Builds a batch generator given a list of batches\n", "    :param list_of_paths: list of tuples with elements of format (filepath, target) (list)\n", "    :param batch_size: size of the batch (int)\n", "    :param label_encoder: fitted LabelEncoder (sklearn.LabelEncoder|optional)\n", "    :param scoring: should the target be considered? (bool)\n", "    :returns: batch generator\n", "    \"\"\"\n", "    for filepaths in batching(list_of_paths, batch_size):\n", "        wavs, targets = zip(*list(map(read_wav, filepaths)))\n", "        if scoring:\n", "            yield np.expand_dims(np.row_stack(wavs), 2), filepaths\n", "        else:\n", "            if label_encoder is None:\n", "                yield np.expand_dims(np.row_stack(wavs), 2), np.row_stack(targets)\n", "            else:\n", "                yield np.expand_dims(np.row_stack(wavs), 2), np.expand_dims(label_encoder.transform(np.squeeze(targets)),1)\n"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "87488aa067d32f457072b5816b8f96a45e1add11", "collapsed": true, "_cell_guid": "99da70b7-1f49-41f5-bd6b-268429c2d401"}}, {"source": ["## Architecture building blocks"], "cell_type": "markdown", "metadata": {"_uuid": "167d8606f98b87258078ef99d89bf7cc1d84c724", "_cell_guid": "d1472be2-c57a-41be-bf61-c5dea64e9c0c"}}, {"source": ["Inception-1D (a.k.a wavception) is a module I designed some weeks ago for this problem. It substantially enhances the performance of a regular convolutional neural net."], "cell_type": "markdown", "metadata": {"_uuid": "fa4997b17d264980689f988e1a50519206d13246", "_cell_guid": "a299b242-fd42-4cbf-8181-2bdbd9fa7c3a"}}, {"source": ["class BatchNorm(object):\n", "    def __init__(self, epsilon=1e-5, momentum=0.999, name=\"batch_norm\"):\n", "        with tf.variable_scope(name):\n", "            self.epsilon = epsilon\n", "            self.momentum = momentum\n", "            self.name = name\n", "\n", "    def __call__(self, x, train=True):\n", "        return tf.contrib.layers.batch_norm(x,\n", "                                            decay=self.momentum,\n", "                                            updates_collections=None,\n", "                                            epsilon=self.epsilon,\n", "                                            scale=True,\n", "                                            is_training=train,\n", "                                            scope=self.name)\n", "    \n", "    \n", "\n", "def inception_1d(x, is_train, depth, norm_function, activ_function, name):\n", "    \"\"\"\n", "    Inception 1D module implementation. \n", "    :param x: input to the current module (4D tensor with channels-last)\n", "    :param is_train: it is intented to be a boolean placeholder for controling the BatchNormalization behavior (0D tensor)\n", "    :param depth: linearly controls the depth of the network (int)\n", "    :param norm_function: normalization class (same format as the BatchNorm class above)\n", "    :param activ_function: tensorflow activation function (e.g. tf.nn.relu) \n", "    :param name: name of the variable scope (str)\n", "    \"\"\"\n", "    with tf.variable_scope(name):\n", "        x_norm = norm_function(name=\"norm_input\")(x, train=is_train)\n", "\n", "        # Branch 1: 64 x conv 1x1 \n", "        branch_conv_1_1 = tf.layers.conv1d(inputs=x_norm, filters=16*depth, kernel_size=1,\n", "                                           kernel_initializer=tf.contrib.layers.xavier_initializer(),\n", "                                           padding=\"same\", name=\"conv_1_1\")\n", "        branch_conv_1_1 = norm_function(name=\"norm_conv_1_1\")(branch_conv_1_1, train=is_train)\n", "        branch_conv_1_1 = activ_function(branch_conv_1_1, \"activation_1_1\")\n", "\n", "        # Branch 2: 128 x conv 3x3 \n", "        branch_conv_3_3 = tf.layers.conv1d(inputs=x_norm, filters=16, kernel_size=1, \n", "                                           kernel_initializer=tf.contrib.layers.xavier_initializer(),\n", "                                           padding=\"same\", name=\"conv_3_3_1\")\n", "        branch_conv_3_3 = norm_function(name=\"norm_conv_3_3_1\")(branch_conv_3_3, train=is_train)\n", "        branch_conv_3_3 = activ_function(branch_conv_3_3, \"activation_3_3_1\")\n", "\n", "        branch_conv_3_3 = tf.layers.conv1d(inputs=branch_conv_3_3, filters=32*depth, kernel_size=3, \n", "                                           kernel_initializer=tf.contrib.layers.xavier_initializer(),\n", "                                           padding=\"same\", name=\"conv_3_3_2\")\n", "        branch_conv_3_3 = norm_function(name=\"norm_conv_3_3_2\")(branch_conv_3_3, train=is_train)\n", "        branch_conv_3_3 = activ_function(branch_conv_3_3, \"activation_3_3_2\")\n", "\n", "        # Branch 3: 128 x conv 5x5 \n", "        branch_conv_5_5 = tf.layers.conv1d(inputs=x_norm, filters=16, kernel_size=1, \n", "                                           kernel_initializer=tf.contrib.layers.xavier_initializer(),\n", "                                           padding=\"same\", name=\"conv_5_5_1\")\n", "        branch_conv_5_5 = norm_function(name=\"norm_conv_5_5_1\")(branch_conv_5_5, train=is_train)\n", "        branch_conv_5_5 = activ_function(branch_conv_5_5, \"activation_5_5_1\")\n", "\n", "        branch_conv_5_5 = tf.layers.conv1d(inputs=branch_conv_5_5, filters=32*depth, kernel_size=5, \n", "                                           kernel_initializer=tf.contrib.layers.xavier_initializer(),\n", "                                           padding=\"same\", name=\"conv_5_5_2\")\n", "        branch_conv_5_5 = norm_function(name=\"norm_conv_5_5_2\")(branch_conv_5_5, train=is_train)\n", "        branch_conv_5_5 = activ_function(branch_conv_5_5, \"activation_5_5_2\")\n", "\n", "        # Branch 4: 128 x conv 7x7\n", "        branch_conv_7_7 = tf.layers.conv1d(inputs=x_norm, filters=16, kernel_size=1, \n", "                                           kernel_initializer=tf.contrib.layers.xavier_initializer(),\n", "                                           padding=\"same\", name=\"conv_7_7_1\")\n", "        branch_conv_7_7 = norm_function(name=\"norm_conv_7_7_1\")(branch_conv_7_7, train=is_train)\n", "        branch_conv_7_7 = activ_function(branch_conv_7_7, \"activation_7_7_1\")\n", "\n", "        branch_conv_7_7 = tf.layers.conv1d(inputs=branch_conv_7_7, filters=32*depth, kernel_size=5, \n", "                                           kernel_initializer=tf.contrib.layers.xavier_initializer(),\n", "                                           padding=\"same\", name=\"conv_7_7_2\")\n", "        branch_conv_7_7 = norm_function(name=\"norm_conv_7_7_2\")(branch_conv_7_7, train=is_train)\n", "        branch_conv_7_7 = activ_function(branch_conv_7_7, \"activation_7_7_2\")\n", "\n", "        # Branch 5: 16 x (max_pool 3x3 + conv 1x1)\n", "        branch_maxpool_3_3 = tf.layers.max_pooling1d(inputs=x_norm, pool_size=3, strides=1, padding=\"same\", name=\"maxpool_3\")\n", "        branch_maxpool_3_3 = norm_function(name=\"norm_maxpool_3_3\")(branch_maxpool_3_3, train=is_train)\n", "        branch_maxpool_3_3 = tf.layers.conv1d(inputs=branch_maxpool_3_3, filters=16, kernel_size=1, \n", "                                              kernel_initializer=tf.contrib.layers.xavier_initializer(),\n", "                                              padding=\"same\", name=\"conv_maxpool_3\")\n", "\n", "        # Branch 6: 16 x (max_pool 5x5 + conv 1x1)\n", "        branch_maxpool_5_5 = tf.layers.max_pooling1d(inputs=x_norm, pool_size=5, strides=1, padding=\"same\", name=\"maxpool_5\")\n", "        branch_maxpool_5_5 = norm_function(name=\"norm_maxpool_5_5\")(branch_maxpool_5_5, train=is_train)\n", "        branch_maxpool_5_5 = tf.layers.conv1d(inputs=branch_maxpool_5_5, filters=16, kernel_size=1, \n", "                                              kernel_initializer=tf.contrib.layers.xavier_initializer(),\n", "                                              padding=\"same\", name=\"conv_maxpool_5\")\n", "\n", "        # Branch 7: 16 x (avg_pool 3x3 + conv 1x1)\n", "        branch_avgpool_3_3 = tf.layers.average_pooling1d(inputs=x_norm, pool_size=3, strides=1, padding=\"same\", name=\"avgpool_3\")\n", "        branch_avgpool_3_3 = norm_function(name=\"norm_avgpool_3_3\")(branch_avgpool_3_3, train=is_train)\n", "        branch_avgpool_3_3 = tf.layers.conv1d(inputs=branch_avgpool_3_3, filters=16, kernel_size=1,\n", "                                              kernel_initializer=tf.contrib.layers.xavier_initializer(),\n", "                                              padding=\"same\", name=\"conv_avgpool_3\")\n", "\n", "        # Branch 8: 16 x (avg_pool 5x5 + conv 1x1)\n", "        branch_avgpool_5_5 = tf.layers.average_pooling1d(inputs=x_norm, pool_size=5, strides=1, padding=\"same\", name=\"avgpool_5\")\n", "        branch_avgpool_5_5 = norm_function(name=\"norm_avgpool_5_5\")(branch_avgpool_5_5, train=is_train)\n", "        branch_avgpool_5_5 = tf.layers.conv1d(inputs=branch_avgpool_5_5, filters=16, kernel_size=1, \n", "                                              kernel_initializer=tf.contrib.layers.xavier_initializer(),\n", "                                              padding=\"same\", name=\"conv_avgpool_5\")\n", "\n", "        # Concatenate\n", "        output = tf.concat([branch_conv_1_1, branch_conv_3_3, branch_conv_5_5, branch_conv_7_7, branch_maxpool_3_3, \n", "                           branch_maxpool_5_5, branch_avgpool_3_3, branch_avgpool_5_5], axis=-1)\n", "        return output\n"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "b2e0ccb28bc9a730958a11c6ad35da321ff33db9", "collapsed": true, "_cell_guid": "5f9d3b17-e5b8-4801-a91b-bf9fce956b84"}}, {"source": ["## Load and prepare Data"], "cell_type": "markdown", "metadata": {"_uuid": "87e5f1456e46cc5295acb535e761ba0f4cdc60cd", "_cell_guid": "a0210bf0-d88f-4bbd-8be8-11013fcc4b32"}}, {"source": ["# Synthetic and provided noise addition\n", "filepaths_noise = glob.glob(os.path.join(get_train_audio_path(), \"_background_noise_\", \"*.wav\"))\n", "\n", "noise = np.concatenate(list(map(lambda x: read_wav(x, False)[0], filepaths_noise)))\n", "noise = np.concatenate([noise, noise[::-1]])\n", "synthetic_noise = np.concatenate([white_noise(N=16000*30, state=np.random.RandomState(655321)), \n", "                                  blue_noise(N=16000*30, state=np.random.RandomState(655321)),\n", "                                  pink_noise(N=16000*30, state=np.random.RandomState(655321)),\n", "                                  brown_noise(N=16000*30, state=np.random.RandomState(655321)),\n", "                                  violet_noise(N=16000*30, state=np.random.RandomState(655321)),\n", "                                  np.zeros(16000*60)])\n", "synthetic_noise /= np.max(np.abs(synthetic_noise))\n", "synthetic_noise = np.concatenate([synthetic_noise, (synthetic_noise+synthetic_noise[::-1])/2])\n", "all_noise = np.concatenate([noise, synthetic_noise])"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "b779ec62114e4036225b2f62ea3a9bcab013e143", "collapsed": true, "_cell_guid": "aeec049b-d435-44d9-9c5f-ef57b2a6c1b3"}}, {"source": ["np.random.seed(655321)\n", "random.seed(655321)\n", "\n", "path = get_silence_path()\n", "\n", "if not os.path.exists(path):\n", "    os.makedirs(path) # It fails in kaggle kernel due to the read-only filesystem\n", "\n", "for noise_clip_no in tqdm(range(8000)):\n", "    if noise_clip_no<=4000:\n", "        idx = np.random.randint(0, len(noise)-16000)\n", "        clip = noise[idx:(idx+16000)]\n", "    else:\n", "        idx = np.random.randint(0, len(synthetic_noise)-16000)\n", "        clip = synthetic_noise[idx:(idx+16000)]\n", "    wavfile.write(os.path.join(path, \"{0:04d}.wav\".format(noise_clip_no)), 16000, \n", "                               ((32767*clip/np.max(np.abs(clip))).astype(np.int16)))\n", "    "], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "022d18f46ce8415e3a4f3e66a86b3f55f41d3860", "collapsed": true, "_cell_guid": "f579e3ad-a7ee-4e0c-a677-1a96fea8b71e"}}, {"source": ["filepaths = glob.glob(os.path.join(get_train_audio_path(), \"**/*.wav\"), recursive=True)\n", "filepaths += glob.glob(os.path.join(get_silence_path(), \"**/*.wav\"), recursive=True)\n", "filepaths = list(filter(lambda fp: \"_background_noise_\" not in fp, filepaths))\n", "validation_list = open(os.path.join(get_train_path(), \"validation_list.txt\")).readlines()\n", "test_list = open(os.path.join(get_train_path(), \"testing_list.txt\")).readlines()\n", "validation_list = list(map(lambda fn: os.path.join(get_train_audio_path(), fn.strip()), validation_list))\n", "testing_list = list(map(lambda fn: os.path.join(get_train_audio_path(), fn.strip()), test_list))\n", "training_list = np.setdiff1d(filepaths, validation_list+testing_list).tolist()"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "5b367716f0abfbca6d05ed7aea096b9e82df0b53", "collapsed": true, "scrolled": true, "_cell_guid": "c4f36041-b721-44cc-81ed-0a8b39bd9eed"}}, {"source": ["random.seed(655321)\n", "random.shuffle(filepaths)\n", "random.shuffle(validation_list)\n", "random.shuffle(testing_list)\n", "random.shuffle(training_list)"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "9b036b76d0e7e4d24b749846f4aec42a213aa505", "collapsed": true, "_cell_guid": "0840a4b4-2103-4ed0-8046-d6ebf91a8fe9"}}, {"source": ["# Quick Unit-Tests\n", "# Test number of files and their consistencies\n", "assert all(map(lambda fp: os.path.splitext(fp)[1]==\".wav\", filepaths))\n", "assert len(filepaths)==64727 - 6 + 8000\n", "assert len(training_list) == len(filepaths) - 6798 - 6835 \n", "assert len(validation_list) == 6798\n", "assert len(testing_list) == 6835\n", "\n", "# Test file existence\n", "assert all(map(lambda fn: os.path.exists(os.path.join(fn)), validation_list))\n", "assert all(map(lambda fn: os.path.exists(os.path.join(fn)), testing_list))\n", "assert all(map(lambda fn: os.path.exists(os.path.join(fn)), training_list))\n", "assert set(validation_list + testing_list + training_list) == set(filepaths)\n", "\n", "# Test non-overlap among sets\n", "assert len(np.intersect1d(validation_list, testing_list))==0\n", "assert len(np.intersect1d(training_list, testing_list))==0\n", "assert len(np.intersect1d(training_list, validation_list))==0"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "c8b9d3d50116c18af5d3c5d50ad76f2dd0612078", "collapsed": true, "scrolled": true, "_cell_guid": "a35f7c09-1ebf-4d84-adf8-5ad3d118f0fb"}}, {"source": ["# Classes processing\n", "cardinal_classes = list(set(map(lambda fp:os.path.split(os.path.split(fp)[0])[1], filepaths)))\n", "le_classes = LabelEncoder().fit(cardinal_classes)\n", "Counter(map(lambda fp:os.path.split(os.path.split(fp)[0])[1], filepaths))"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "3852dcc9ef44bc2841eecf65361d7b6f95e43b5f", "collapsed": true, "_cell_guid": "5c17af42-214c-4dab-b066-d7a0c6acac13"}}, {"source": ["# Quick Unit-Tests\n", "# Test data preparation\n", "_gen_test = get_batcher(filepaths, 1000)\n", "batch_a_wav, batch_a_target = next(_gen_test)\n", "batch_b_wav, batch_b_target = next(_gen_test)\n", "_gen_test_le = get_batcher(filepaths, 1000, label_encoder=le_classes)\n", "batch_le_wav, batch_le_target = next(_gen_test_le)\n", "\n", "# Test batch matrix shape coherences\n", "assert batch_a_wav.shape == (1000, 16000, 1)\n", "assert batch_le_wav.shape == (1000, 16000, 1)\n", "assert batch_a_wav.shape == batch_b_wav.shape == batch_le_wav.shape\n", "\n", "# Test batch reproducibility\n", "assert np.sum(np.abs(batch_a_wav-batch_b_wav)) != 0\n", "assert len(batch_a_target) == len(batch_b_target) == len(batch_le_target)\n", "assert any(batch_a_target != batch_b_target)\n", "\n", "# Test classes label encoder\n", "assert all(batch_le_target == np.expand_dims(le_classes.transform(np.squeeze(batch_a_target)),1))"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "791fd120463dd67b4255de43eb64a0af75655256", "collapsed": true, "_cell_guid": "9553bb5e-fb15-4a37-9876-8f4685b3076f"}}, {"source": ["## Architecture design"], "cell_type": "markdown", "metadata": {"_uuid": "671cb5ffa15b6fd8e549df8e0a6dcdb5b21a64f8", "_cell_guid": "ed02eca4-76ee-4b40-89a4-a853ddd74143"}}, {"source": ["Here it comes, WavCeption design"], "cell_type": "markdown", "metadata": {"_uuid": "24889480a844029116c9c9880611bc3fafd7d9bf", "_cell_guid": "5c67ad8f-80e3-43f9-a358-d352b17e8dbf"}}, {"source": ["class NameSpacer:\n", "    def __init__(self, **kwargs):\n", "        self.__dict__.update(kwargs)\n", "\n", "class Architecture:\n", "    def __init__(self, class_cardinality, seq_len=16000, name=\"architecture\"):\n", "        self.seq_len = seq_len\n", "        self.class_cardinality = class_cardinality\n", "        self.optimizer = tf.train.AdamOptimizer(learning_rate=0.0001)\n", "        self.name=name\n", "        self.define_computation_graph()\n", "        \n", "        #Aliases\n", "        self.ph = self.placeholders\n", "        self.op = self.optimizers\n", "        self.summ = self.summaries\n", "\n", "    def define_computation_graph(self):\n", "        # Reset graph\n", "        tf.reset_default_graph()\n", "        self.placeholders = NameSpacer(**self.define_placeholders())\n", "        self.core_model = NameSpacer(**self.define_core_model())\n", "        self.losses = NameSpacer(**self.define_losses())\n", "        self.optimizers = NameSpacer(**self.define_optimizers())\n", "        self.summaries = NameSpacer(**self.define_summaries())\n", "\n", "    def define_placeholders(self):\n", "        with tf.variable_scope(\"Placeholders\"):\n", "            wav_in = tf.placeholder(dtype=tf.float32, shape=(None, self.seq_len, 1), name=\"wav_in\")\n", "            is_train = tf.placeholder(dtype=tf.bool, shape=None, name=\"is_train\")\n", "            target = tf.placeholder(dtype=tf.int32, shape=(None, 1), name=\"target\")\n", "            acc_dev = tf.placeholder(dtype=tf.float32, shape=None, name=\"acc_dev\")\n", "            loss_dev = tf.placeholder(dtype=tf.float32, shape=None, name=\"loss_dev\")\n", "            return({\"wav_in\": wav_in, \"target\": target, \"is_train\": is_train, \"acc_dev\": \n", "                    acc_dev, \"loss_dev\": loss_dev})\n", "        \n", "    def define_core_model(self):\n", "        with tf.variable_scope(\"Core_Model\"):\n", "            x = inception_1d(x=self.placeholders.wav_in, is_train=self.placeholders.is_train, \n", "                             norm_function=BatchNorm, activ_function=tf.nn.relu, depth=1,\n", "                             name=\"Inception_1_1\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=1, name=\"Inception_1_2\")\n", "            x = tf.layers.max_pooling1d(x, 2, 2, name=\"maxpool_1\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=1, name=\"Inception_2_1\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=1, name=\"Inception_2_3\")\n", "            x = tf.layers.max_pooling1d(x, 2, 2, name=\"maxpool_2\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=2, name=\"Inception_3_1\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=2, name=\"Inception_3_2\")\n", "            x = tf.layers.max_pooling1d(x, 2, 2, name=\"maxpool_3\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=2, name=\"Inception_4_1\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=2, name=\"Inception_4_2\")\n", "            x = tf.layers.max_pooling1d(x, 2, 2, name=\"maxpool_4\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=3, name=\"Inception_5_1\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=3, name=\"Inception_5_2\")\n", "            x = tf.layers.max_pooling1d(x, 2, 2, name=\"maxpool_5\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=3, name=\"Inception_6_1\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=3, name=\"Inception_6_2\")\n", "            x = tf.layers.max_pooling1d(x, 2, 2, name=\"maxpool_6\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=4, name=\"Inception_7_1\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=4, name=\"Inception_7_2\")\n", "            x = tf.layers.max_pooling1d(x, 2, 2, name=\"maxpool_7\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=4, name=\"Inception_8_1\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=4, name=\"Inception_8_2\")\n", "            x = tf.layers.max_pooling1d(x, 2, 2, name=\"maxpool_8\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=4, name=\"Inception_9_1\")\n", "            x = inception_1d(x=x, is_train=self.placeholders.is_train, norm_function=BatchNorm, \n", "                             activ_function=tf.nn.relu, depth=4, name=\"Inception_9_2\")\n", "            x = tf.layers.max_pooling1d(x, 2, 2, name=\"maxpool_9\")\n", "            x = tf.contrib.layers.flatten(x)\n", "            x = tf.layers.dense(BatchNorm(name=\"bn_dense_1\")(x,train=self.placeholders.is_train),\n", "                                128, activation=tf.nn.relu, kernel_initializer=tf.contrib.layers.xavier_initializer(),\n", "                                name=\"dense_1\")\n", "            output = tf.layers.dense(BatchNorm(name=\"bn_dense_2\")(x,train=self.placeholders.is_train),\n", "                                self.class_cardinality, activation=None, kernel_initializer=tf.contrib.layers.xavier_initializer(),\n", "                                name=\"output\")\n", "            return({\"output\": output})\n", "        \n", "    def define_losses(self):\n", "        with tf.variable_scope(\"Losses\"):\n", "            softmax_ce = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=tf.squeeze(self.placeholders.target), \n", "                                                                        logits=self.core_model.output,\n", "                                                                        name=\"softmax\")\n", "            return({\"softmax\": softmax_ce})\n", "\n", "    def define_optimizers(self):\n", "        with tf.variable_scope(\"Optimization\"):\n", "            op = self.optimizer.minimize(self.losses.softmax)\n", "            return({\"op\": op})\n", "\n", "    def define_summaries(self):\n", "        with tf.variable_scope(\"Summaries\"):\n", "            ind_max = tf.squeeze(tf.cast(tf.argmax(self.core_model.output, axis=1), tf.int32))\n", "            target = tf.squeeze(self.placeholders.target)\n", "            acc= tf.reduce_mean(tf.cast(tf.equal(ind_max, target), tf.float32))\n", "            loss = tf.reduce_mean(self.losses.softmax)\n", "            train_scalar_probes = {\"accuracy\": acc, \n", "                                   \"loss\": loss}\n", "            train_performance_scalar = [tf.summary.scalar(k, tf.reduce_mean(v), family=self.name) \n", "                                        for k, v in train_scalar_probes.items()]\n", "            train_performance_scalar = tf.summary.merge(train_performance_scalar)\n", "\n", "            dev_scalar_probes = {\"acc_dev\": self.placeholders.acc_dev, \n", "                                 \"loss_dev\": self.placeholders.loss_dev}\n", "            dev_performance_scalar = [tf.summary.scalar(k, v, family=self.name) for k, v in dev_scalar_probes.items()]\n", "            dev_performance_scalar = tf.summary.merge(dev_performance_scalar)\n", "            return({\"accuracy\": acc, \"loss\": loss, \"s_tr\": train_performance_scalar, \"s_de\": dev_performance_scalar})\n"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "53e3de8a3ad9a1bd08746065d4d8bb6fab648615", "collapsed": true, "_cell_guid": "6ab30f80-6bff-43bd-9280-8aaa50326283"}}, {"source": ["## Run model "], "cell_type": "markdown", "metadata": {"_uuid": "e8dec0fa842ab5f693daf729900f461145a8355f", "_cell_guid": "b390b59e-0a78-4ff7-9b7d-fc0b48c7b3dd"}}, {"source": ["You should use a GPU to run the model if you don't want it to take forever... In addition, you should decide when to stop the network to make the prediction. It took me 12h in a Titan X Pascal."], "cell_type": "markdown", "metadata": {"_uuid": "9d79ca62dd150ac46a471492ce6156b265e9ef07", "_cell_guid": "1d586dc1-2f02-4669-8aca-5010ed9d2a1a"}}, {"source": ["net = Architecture(class_cardinality=len(cardinal_classes), name=\"wavception\")"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "bd4220c1d4ba2b9c20e0f51c226387217109b692", "collapsed": true, "_cell_guid": "a226088d-ecd9-4070-8893-de1ecc90938f"}}, {"source": ["sess = start_tensorflow_session(device=\"1\")\n", "sw = get_summary_writer(sess, \"~/.logs_tensorboard/\", \"wavception\", \"V1\") # Adjust your tensorboard logs path here\n", "c=0"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "dea3a0c128e64b3e8680b51ae0486c4ce0031e79", "collapsed": true, "_cell_guid": "ef8b85d6-271c-434a-b886-447e6d57c1b6"}}, {"source": ["sess.run(tf.global_variables_initializer())"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "4f0503ed3dffd436ff81caeefeac880b95167396", "collapsed": true, "_cell_guid": "2575da3e-f8b4-4a83-beba-f4683cf09cb1"}}, {"source": ["np.random.seed(655321)\n", "random.seed(655321)"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "ee203cc482466c4f133ff83161bcd871c626bc5c", "collapsed": true, "_cell_guid": "c4198ebd-bfbf-4c37-8370-95a37f73f5fa"}}, {"source": ["for epoch in range(50000):\n", "    random.shuffle(training_list)\n", "    batcher = get_batcher(training_list, 16, le_classes)\n", "    for i, (batch_x, batch_y) in enumerate(batcher):\n", "        _, loss, acc, s = sess.run([net.op.op, net.losses.softmax, net.summ.accuracy, net.summ.s_tr],\n", "                                 feed_dict={net.ph.wav_in: batch_x, net.ph.target: batch_y, \n", "                                            net.ph.is_train: True})\n", "        print(\"[{0:04d}|{1:04d}] Accuracy train: {2:.2f}%\".format(epoch, i, acc*100))\n", "        sw.add_summary(s, c)\n", "        \n", "        if c%1000==0: # Validation\n", "            accuracies_dev=[]\n", "            losses_dev=[]\n", "            batcher = get_batcher(validation_list, 16, le_classes)\n", "            for i, (batch_x, batch_y) in enumerate(batcher):\n", "                acc, loss= sess.run([net.summ.accuracy, net.summ.loss], \n", "                               feed_dict={net.ph.wav_in: batch_x, net.ph.target: batch_y, \n", "                                          net.ph.is_train: False})\n", "                accuracies_dev.append(acc)\n", "                losses_dev.append(loss)\n", "            s = sess.run(net.summ.s_de, feed_dict={net.ph.acc_dev: np.mean(accuracies_dev),\n", "                                                        net.ph.loss_dev: np.mean(losses_dev)})\n", "            sw.add_summary(s, c)\n", "        c += 1"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "34ba4ec269007f8102fe6dff142763e10d29902f", "collapsed": true, "scrolled": false, "_cell_guid": "7872b624-0a21-45e6-b5d1-47323a69e8d3"}}, {"source": ["Test accuracy"], "cell_type": "markdown", "metadata": {"_uuid": "cbf30b73e48e0f832ce07358ae4aa5a1e6b2bf22", "_cell_guid": "a499d252-39d4-4262-9d3e-b0a5de05e44b"}}, {"source": ["accuracies=[]\n", "batcher = get_batcher(testing_list, 64, le_classes)\n", "for i, (batch_x, batch_y) in tqdm(enumerate(batcher)):\n", "    acc= sess.run(net.summ.accuracy, feed_dict={net.ph.wav_in: batch_x, net.ph.target: batch_y, \n", "                                                     net.ph.is_train: False})\n", "    accuracies.append(acc)\n", "        "], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "df013bec21566ca6df051b649fa9ad2af886c3fd", "collapsed": true, "_cell_guid": "e4679982-80ae-4906-b9ed-820b5050d6ce"}}, {"source": ["## Prediction and submission building"], "cell_type": "markdown", "metadata": {"_uuid": "5c38203a647bb0b93fd29174eb81a2e3cb4f16ed", "_cell_guid": "7f13d203-8631-41ad-8db2-c3fb0da16938"}}, {"source": ["scoring_list = glob.glob(os.path.join(get_scoring_audio_path(), \"*.wav\"), recursive=True)"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "e2266973295bc652913ad078e14c35ef44e9c702", "collapsed": true, "_cell_guid": "c6a67202-a658-46da-9934-555b355f24e9"}}, {"source": ["batcher = get_batcher(scoring_list, 80, le_classes, scoring=True)"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "14e7aec6a0c2200191904c1f2f65013d71620813", "collapsed": true, "_cell_guid": "91bce141-2bb6-46eb-bff5-9578260a307e"}}, {"source": ["fns = []\n", "prds = []\n", "for i, (batch_x, filepaths) in tqdm(enumerate(batcher)):\n", "    pred = sess.run(net.core_model.output, feed_dict={net.ph.wav_in: batch_x, net.ph.is_train: False})\n", "    fns.extend(map(lambda f:os.path.split(f)[1], filepaths))\n", "    prds.extend(map(lambda f:np.argmax(pred, axis=1).tolist(), pred))"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "dd967dd2c93fd7dbc867c505b1ba66a108db7805", "collapsed": true, "_cell_guid": "11015ffb-878c-4451-9688-3f3dbbd5114d"}}, {"source": ["Note: I implemented here a quick & dirty way of solving the unknown clips problem. It still performs well (~76 LB) but there are much more smart ways to do it ;-)."], "cell_type": "markdown", "metadata": {"_uuid": "666fb81cce7b16f1f229d2936ef877105f1446a3", "_cell_guid": "f188097c-6eb7-40e6-add6-24a3dc4b3cb7"}}, {"source": ["# Submission storage\n", "df=pd.DataFrame({\"fname\":fns, \"label\": prds})\n", "df.label = le_classes.inverse_transform(df.label)\n", "df.loc[~df.label.isin([\"yes\", \"no\", \"up\", \"down\", \"left\", \"right\", \"on\", \"off\", \"stop\", \"go\", \"silence\"]), \"label\"]=\"unknown\"\n", "df.to_csv(os.path.join(get_submissions_path(), \"submission.csv\"), index=False)"], "execution_count": null, "cell_type": "code", "outputs": [], "metadata": {"_uuid": "04c064866c203f7e29c0a43347b7ff29bfe33443", "collapsed": true, "_cell_guid": "bafc416e-9bcf-46cc-8b7a-ef627dda8220"}}], "nbformat": 4, "metadata": {"language_info": {"nbconvert_exporter": "python", "name": "python", "pygments_lexer": "ipython3", "mimetype": "text/x-python", "file_extension": ".py", "version": "3.6.3", "codemirror_mode": {"name": "ipython", "version": 3}}, "kernelspec": {"name": "python3", "language": "python", "display_name": "Python 3"}}, "nbformat_minor": 1}