{"nbformat": 4, "nbformat_minor": 1, "metadata": {"language_info": {"file_extension": ".py", "codemirror_mode": {"name": "ipython", "version": 3}, "name": "python", "version": "3.6.3", "nbconvert_exporter": "python", "mimetype": "text/x-python", "pygments_lexer": "ipython3"}, "kernelspec": {"language": "python", "name": "python3", "display_name": "Python 3"}}, "cells": [{"source": ["In this kernel I present an end-to-end solution using the custom Keras Directory Iterator and a small training/validation subset that I 've compiled. You can find my training data as well as the whole test dataset here https://www.kaggle.com/voglinio/speechtest. Once loaded, this dataset will give you access to the following folders\n", "* train_path='../input/part1/part1/train/'\n", "* val_path ='../input/part1/part1/val/'\n", "* test_path ='../input/test/test/'\n", "\n", "This kernel ends with a submission file, that scores 0.72 on the LB. I have used limited number of epochs because of the 1 hour running time limit imposed by the kernel.\n", "## Some statistics about the files"], "metadata": {"_cell_guid": "b6c77e2e-db2d-400f-bd35-8379ee4a0447", "_uuid": "7d802ef3da2bcddb3e9826adf5216368e93a1ec3"}, "cell_type": "markdown"}, {"source": ["import numpy as np\n", "from keras import backend as K\n", "from keras.preprocessing.image import Iterator\n", "from keras.preprocessing.image import img_to_array\n", "\n", "import librosa\n", "import os\n", "import multiprocessing.pool\n", "from functools import partial\n", "from random import getrandbits\n", "\n", "train_path='../input/part1/part1/train/'\n", "val_path ='../input/part1/part1/val/'\n", "test_path ='../input/test/test/'\n", "\n", "classnames=os.listdir(train_path)\n", "train_count_dict = {}\n", "for d in classnames:\n", "    train_count_dict[d] = len(os.listdir(os.path.join(train_path, d)))\n", "print('train freq')\n", "for k, v in train_count_dict.items():\n", "    print ( '%7s  %i' % (k, v))\n", "val_count_dict = {}\n", "for d in classnames:\n", "    val_count_dict[d] = len(os.listdir(os.path.join(val_path, d)))\n", "print('\\nval freq')\n", "for k, v in val_count_dict.items():\n", "    print ( '%7s  %i' % (k, v))\n", "print ('')\n", "print ('test files', len(os.listdir(test_path+'/audio')))"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "d8e1e7b2-53be-4108-91e3-eb6ded71747a", "_uuid": "328c0912632783eb30d43bb1f762ea62cb685e72", "collapsed": true}, "cell_type": "code"}, {"source": ["## Directory Iterator definition"], "metadata": {"_cell_guid": "35e55907-ddd7-40cc-9336-6077fc4403e5", "_uuid": "d83d3b05950cc92c63c4566f94a22acb70598422"}, "cell_type": "markdown"}, {"source": ["def spect_loader(path, window_size, window_stride, window, normalize, max_len=101, \n", "                 augment=False, allow_speedandpitch=False, allow_pitch=False,\n", "                 allow_speed=False, allow_dyn=False, allow_noise=False,\n", "                allow_timeshift=False ):\n", "    y, sr = librosa.load(path, sr=None)\n", "    # n_fft = 4096\n", "    n_fft = int(sr * window_size)\n", "    win_length = n_fft\n", "    hop_length = int(sr * window_stride)\n", "\n", "    # STFT\n", "    D = librosa.stft(y, n_fft=n_fft, hop_length=hop_length,\n", "                     win_length=win_length, window=window)\n", "    spect, phase = librosa.magphase(D)\n", "\n", "    # S = log(S+1)\n", "    spect = np.log1p(spect)\n", "\n", "    # make all spects with the same dims\n", "    # TODO: change that in the future\n", "    if spect.shape[1] < max_len:\n", "        pad = np.zeros((spect.shape[0], max_len - spect.shape[1]))\n", "        spect = np.hstack((spect, pad))\n", "    elif spect.shape[1] > max_len:\n", "        spect = spect[:max_len, ]\n", "    spect = np.resize(spect, (1, spect.shape[0], spect.shape[1]))\n", "    #spect = torch.FloatTensor(spect)\n", "\n", "    # z-score normalization\n", "    if normalize:\n", "        mean = np.mean(np.ravel(spect))\n", "        std = np.std(np.ravel(spect))\n", "        if std != 0:\n", "            spect = spect -mean\n", "            spect = spect / std\n", "\n", "    return spect\n", "\n", "def _count_valid_files_in_directory(directory, white_list_formats, follow_links):\n", "    \"\"\"Count files with extension in `white_list_formats` contained in a directory.\n", "    # Arguments\n", "        directory: absolute path to the directory containing files to be counted\n", "        white_list_formats: set of strings containing allowed extensions for\n", "            the files to be counted.\n", "    # Returns\n", "        the count of files with extension in `white_list_formats` contained in\n", "        the directory.\n", "    \"\"\"\n", "    def _recursive_list(subpath):\n", "        return sorted(os.walk(subpath, followlinks=follow_links), key=lambda tpl: tpl[0])\n", "\n", "    samples = 0\n", "    for root, _, files in _recursive_list(directory):\n", "        for fname in files:\n", "            is_valid = False\n", "            for extension in white_list_formats:\n", "                if fname.lower().endswith('.' + extension):\n", "                    is_valid = True\n", "                    break\n", "            if is_valid:\n", "                samples += 1\n", "    return samples\n", "\n", "def _list_valid_filenames_in_directory(directory, white_list_formats,\n", "                                       class_indices, follow_links):\n", "    \"\"\"List paths of files in `subdir` relative from `directory` whose extensions are in `white_list_formats`.\n", "    # Arguments\n", "        directory: absolute path to a directory containing the files to list.\n", "            The directory name is used as class label and must be a key of `class_indices`.\n", "        white_list_formats: set of strings containing allowed extensions for\n", "            the files to be counted.\n", "        class_indices: dictionary mapping a class name to its index.\n", "    # Returns\n", "        classes: a list of class indices\n", "        filenames: the path of valid files in `directory`, relative from\n", "            `directory`'s parent (e.g., if `directory` is \"dataset/class1\",\n", "            the filenames will be [\"class1/file1.jpg\", \"class1/file2.jpg\", ...]).\n", "    \"\"\"\n", "    def _recursive_list(subpath):\n", "        return sorted(os.walk(subpath, followlinks=follow_links), key=lambda tpl: tpl[0])\n", "\n", "    classes = []\n", "    filenames = []\n", "    subdir = os.path.basename(directory)\n", "    basedir = os.path.dirname(directory)\n", "    for root, _, files in _recursive_list(directory):\n", "        for fname in sorted(files):\n", "            is_valid = False\n", "            for extension in white_list_formats:\n", "                if fname.lower().endswith('.' + extension):\n", "                    is_valid = True\n", "                    break\n", "            if is_valid:\n", "                classes.append(class_indices[subdir])\n", "                # add filename relative to directory\n", "                absolute_path = os.path.join(root, fname)\n", "                filenames.append(os.path.relpath(absolute_path, basedir))\n", "    return classes, filenames\n", "\n", "class SpeechDirectoryIterator(Iterator):\n", "    \"\"\"Iterator capable of reading images from a directory on disk.\n", "    # Arguments\n", "       \n", "    \"\"\"\n", "\n", "    def __init__(self, directory, window_size, window_stride, \n", "                 window_type, normalize, max_len=101,\n", "                 target_size=(256, 256), color_mode='grayscale',\n", "                 classes=None, class_mode='categorical',\n", "                 batch_size=32, shuffle=True, seed=None,\n", "                 data_format=None, save_to_dir=None,\n", "                 save_prefix='', save_format='png',\n", "                 follow_links=False, interpolation='nearest', augment=False,\n", "                allow_speedandpitch = False, allow_pitch = False,\n", "                allow_speed = False, allow_dyn = False, allow_noise = False, allow_timeshift=False ):\n", "        if data_format is None:\n", "            data_format = K.image_data_format()\n", "        self.window_size = window_size\n", "        self.window_stride = window_stride\n", "        self.window_type = window_type\n", "        self.normalize = normalize\n", "        self.max_len = max_len\n", "        self.directory = directory\n", "        self.allow_speedandpitch = allow_speedandpitch\n", "        self.allow_pitch = allow_pitch\n", "        self.allow_speed = allow_speed \n", "        self.allow_dyn = allow_dyn\n", "        self.allow_noise = allow_noise\n", "        self.allow_timeshift = allow_timeshift \n", "        self.augment = augment\n", "#        self.image_data_generator = image_data_generator\n", "        self.target_size = tuple(target_size)\n", "        if color_mode not in {'rgb', 'grayscale'}:\n", "            raise ValueError('Invalid color mode:', color_mode,\n", "                             '; expected \"rgb\" or \"grayscale\".')\n", "        self.color_mode = color_mode\n", "        self.data_format = data_format\n", "        if self.color_mode == 'rgb':\n", "            if self.data_format == 'channels_last':\n", "                self.image_shape = self.target_size + (3,)\n", "            else:\n", "                self.image_shape = (3,) + self.target_size\n", "        else:\n", "            if self.data_format == 'channels_last':\n", "                self.image_shape = self.target_size + (1,)\n", "            else:\n", "                self.image_shape = (1,) + self.target_size\n", "        self.classes = classes\n", "        if class_mode not in {'categorical', 'binary', 'sparse',\n", "                              'input', None}:\n", "            raise ValueError('Invalid class_mode:', class_mode,\n", "                             '; expected one of \"categorical\", '\n", "                             '\"binary\", \"sparse\", \"input\"'\n", "                             ' or None.')\n", "        self.class_mode = class_mode\n", "        self.save_to_dir = save_to_dir\n", "        self.save_prefix = save_prefix\n", "        self.save_format = save_format\n", "        self.interpolation = interpolation\n", "\n", "        white_list_formats = {'png', 'jpg', 'jpeg', 'bmp', 'ppm', 'wav'}\n", "\n", "        # first, count the number of samples and classes\n", "        self.samples = 0\n", "\n", "        if not classes:\n", "            classes = []\n", "            for subdir in sorted(os.listdir(directory)):\n", "                if os.path.isdir(os.path.join(directory, subdir)):\n", "                    classes.append(subdir)\n", "        self.num_classes = len(classes)\n", "        self.class_indices = dict(zip(classes, range(len(classes))))\n", "\n", "        pool = multiprocessing.pool.ThreadPool()\n", "        function_partial = partial(_count_valid_files_in_directory,\n", "                                   white_list_formats=white_list_formats,\n", "                                   follow_links=follow_links)\n", "        self.samples = sum(pool.map(function_partial,\n", "                                    (os.path.join(directory, subdir)\n", "                                     for subdir in classes)))\n", "\n", "        print('Found %d images belonging to %d classes.' % (self.samples, self.num_classes))\n", "\n", "        # second, build an index of the images in the different class subfolders\n", "        results = []\n", "\n", "        self.filenames = []\n", "        self.classes = np.zeros((self.samples,), dtype='int32')\n", "        i = 0\n", "        for dirpath in (os.path.join(directory, subdir) for subdir in classes):\n", "            results.append(pool.apply_async(_list_valid_filenames_in_directory,\n", "                                            (dirpath, white_list_formats,\n", "                                             self.class_indices, follow_links)))\n", "            \n", "        \n", "        for res in results:\n", "            classes, filenames = res.get()\n", "            self.classes[i:i + len(classes)] = classes\n", "            self.filenames += filenames\n", "            if i==0:\n", "                img = spect_loader(os.path.join(self.directory, filenames[0]), \n", "                               self.window_size, \n", "                               self.window_stride, \n", "                               self.window_type, \n", "                               self.normalize, \n", "                               self.max_len, \n", "                               self.augment,\n", "                               self.allow_speedandpitch,\n", "                               self.allow_pitch,\n", "                               self.allow_speed, \n", "                               self.allow_dyn,\n", "                               self.allow_noise,\n", "                               self.allow_timeshift ) \n", "                img=np.swapaxes(img, 0, 2)\n", "                self.target_size = tuple((img.shape[0], img.shape[1]))\n", "                print(self.target_size)\n", "                if self.color_mode == 'rgb':\n", "                    if self.data_format == 'channels_last':\n", "                        self.image_shape = self.target_size + (3,)\n", "                    else:\n", "                        self.image_shape = (3,) + self.target_size\n", "                else:\n", "                    if self.data_format == 'channels_last':\n", "                        self.image_shape = self.target_size + (1,)\n", "                    else:\n", "                        self.image_shape = (1,) + self.target_size\n", "                        \n", "            i += len(classes)\n", "        pool.close()\n", "        pool.join()\n", "        super(SpeechDirectoryIterator, self).__init__(self.samples, batch_size, shuffle, seed)\n", "    \n", "\n", "    \n", "    \n", "    def _get_batches_of_transformed_samples(self, index_array):\n", "        batch_x = np.zeros((len(index_array),) + self.image_shape, dtype=K.floatx())\n", "        batch_f = []\n", "        grayscale = self.color_mode == 'grayscale'\n", "        # build batch of image data\n", "        #print(index_array)\n", "        for i, j in enumerate(index_array):\n", "            #print(i, j, self.filenames[j])\n", "            fname = self.filenames[j]\n", "            #img = load_img(os.path.join(self.directory, fname),\n", "            #               grayscale=grayscale,\n", "            #               target_size=self.target_size,\n", "            #               interpolation=self.interpolation)\n", "            img = spect_loader(os.path.join(self.directory, fname), \n", "                               self.window_size, \n", "                               self.window_stride, \n", "                               self.window_type, \n", "                               self.normalize, \n", "                               self.max_len, \n", "                                )\n", "            img=np.swapaxes(img, 0, 2)\n", "            \n", "            x = img_to_array(img, data_format=self.data_format)\n", "            #x = self.image_data_generator.random_transform(x)\n", "            #x = self.image_data_generator.standardize(x)\n", "            batch_x[i] = x\n", "            batch_f.append(fname)\n", "        # optionally save augmented images to disk for debugging purposes\n", "        if self.save_to_dir:\n", "            for i, j in enumerate(index_array):\n", "                img = array_to_img(batch_x[i], self.data_format, scale=True)\n", "                fname = '{prefix}_{index}_{hash}.{format}'.format(prefix=self.save_prefix,\n", "                                                                  index=j,\n", "                                                                  hash=np.random.randint(1e7),\n", "                                                                  format=self.save_format)\n", "                img.save(os.path.join(self.save_to_dir, fname))\n", "        # build batch of labels\n", "        if self.class_mode == 'input':\n", "            batch_y = batch_x.copy()\n", "        elif self.class_mode == 'sparse':\n", "            batch_y = self.classes[index_array]\n", "        elif self.class_mode == 'binary':\n", "            batch_y = self.classes[index_array].astype(K.floatx())\n", "        elif self.class_mode == 'categorical':\n", "            batch_y = np.zeros((len(batch_x), self.num_classes), dtype=K.floatx())\n", "            for i, label in enumerate(self.classes[index_array]):\n", "                batch_y[i, label] = 1.\n", "        else:\n", "            return batch_x\n", "        return batch_x, batch_y\n", "\n", "    def next(self):\n", "        \"\"\"For python 2.x.\n", "        # Returns\n", "            The next batch.\n", "        \"\"\"\n", "        with self.lock:\n", "            index_array = next(self.index_generator)[0]\n", "        # The transformation of images is not under thread lock\n", "        # so it can be done in parallel\n", "        return self._get_batches_of_transformed_samples(index_array)"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "01295a0b-a688-4baa-b9c3-c9c685cc0d7f", "_uuid": "08cd6805a5eb4e6e3629ddef1b53c83f4a185076", "collapsed": true}, "cell_type": "code"}, {"source": ["window_size=.02\n", "window_stride=.01\n", "window_type='hamming'\n", "normalize=True\n", "max_len=101\n", "batch_size = 64\n", "train_iterator = SpeechDirectoryIterator(directory=train_path, \n", "                                   batch_size=batch_size, \n", "                                   window_size=window_size, \n", "                                   window_stride=window_stride, \n", "                                   window_type=window_type,\n", "                                   normalize=normalize, \n", "                                   max_len=max_len)"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "9c3fa96c-6ffa-44fc-bdcc-b10a7c95a8c2", "_uuid": "c118d4a8ba97128d09b44cc096334f5b4cf8a4a2", "collapsed": true}, "cell_type": "code"}, {"source": ["val_iterator = SpeechDirectoryIterator(directory=val_path, \n", "                                   batch_size=batch_size, \n", "                                   window_size=window_size, \n", "                                   window_stride=window_stride, \n", "                                   window_type=window_type,\n", "                                   normalize=normalize, \n", "                                   max_len=max_len)"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "80f4870d-cfd7-495c-8d32-e19202bb473a", "_uuid": "6e58e13aaf1f31420977b8453afa3c83720fc013", "collapsed": true}, "cell_type": "code"}, {"source": ["##  Model definition"], "metadata": {"_cell_guid": "c32d8004-c555-466d-9cf3-0eab7f199e48", "_uuid": "a14082b43c280319fac81e8b62c08782bfd3972a"}, "cell_type": "markdown"}, {"source": ["from keras.models import Sequential\n", "from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout\n", "model = Sequential()\n", "model.add(Conv2D(12, (5, 5), activation = 'relu', input_shape=train_iterator.image_shape))\n", "\n", "model.add(MaxPooling2D(pool_size=(2, 2)))\n", "\n", "model.add(Conv2D(25, (5, 5), activation = 'relu'))\n", "\n", "model.add(MaxPooling2D(pool_size=(2, 2)))\n", "\n", "model.add(Flatten())\n", "model.add(Dense(180, activation = 'relu'))\n", "model.add(Dropout(0.5))\n", "model.add(Dense(100, activation = 'relu'))\n", "model.add(Dropout(0.5))\n", "model.add(Dense(len(classnames), activation = 'softmax')) #Last layer with one output per class\n", "\n", "model.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=[\"accuracy\"])\n", "model.summary()"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "b4f38662-ef55-469d-aba4-02907077ef45", "_uuid": "eaffab2905a6274171619018b25e289cb5b1baa3", "collapsed": true}, "cell_type": "code"}, {"source": ["## Training and callbacks"], "metadata": {"_cell_guid": "e30248d4-a53c-4b84-a891-8254a6b94ece", "_uuid": "31db35a9110519df16260a7ac6a39733840a58d0"}, "cell_type": "markdown"}, {"source": ["from keras.callbacks import EarlyStopping, ReduceLROnPlateau\n", "\n", "early = EarlyStopping(monitor='val_loss', min_delta=0, patience=5, verbose=1, mode='auto')\n", "reduce = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=3, verbose=1, mode='auto', min_lr=0.00001)\n", "model.fit_generator(train_iterator,\n", "        steps_per_epoch=int(np.ceil(train_iterator.n / batch_size)),\n", "        epochs=5,\n", "        validation_data=val_iterator,\n", "        validation_steps=int(np.ceil(val_iterator.n / batch_size)),\n", "        verbose=1, callbacks=[early, reduce])\n"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "5f37d705-6623-44e9-9d81-0c431f80b199", "_uuid": "f4df4a820885f240e7a33026028eb0f24413e244", "collapsed": true}, "cell_type": "code"}, {"source": ["## Prediction on test set\n", "I use the `keras.util.Sequence` class to iterate through test images. It is a thread safe way to predict on a series of test files."], "metadata": {"_cell_guid": "270049f1-08e5-4059-8b89-0edf779290d3", "_uuid": "169956908ca4fa3480b6529f8960dd40bb501176"}, "cell_type": "markdown"}, {"source": ["test_path_audio=os.path.join(test_path, 'audio')\n", "test_filenames = os.listdir(test_path_audio) \n", "test_filenames[:10]"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "75e84968-f137-4ce8-8a28-20d3d2dc3a04", "_uuid": "e3dfd5343f8d459d005d2d16831c602f43f82a30", "collapsed": true}, "cell_type": "code"}, {"source": ["import math\n", "from keras.utils import Sequence\n", "from keras.preprocessing.image import img_to_array\n", "\n", "def loadAndSpect(fname,  window_size, window_stride, window_type, normalize, max_len):\n", "    img = spect_loader(os.path.join(test_path_audio, fname), \n", "                       window_size, \n", "                       window_stride, \n", "                       window_type, \n", "                       normalize, \n", "                       max_len)\n", "    img=np.swapaxes(img, 0, 2)\n", "\n", "    x = img_to_array(img, data_format='channels_last')\n", "    return x\n", "            \n", "class WavSequence(Sequence):\n", "\n", "    def __init__(self, x_set, batch_size=64, window_size=0.02, window_stride=0.01, window_type='hamming', normalize=True, max_len=101):\n", "        self.x = x_set\n", "        self.batch_size = batch_size\n", "        self.window_size = window_size\n", "        self.window_stride = window_stride\n", "        self.window_type = window_type\n", "        self.normalize = normalize\n", "        self.max_len = max_len\n", "\n", "    def __len__(self):\n", "        return math.ceil(len(self.x) / self.batch_size)\n", "\n", "    def __getitem__(self, idx):\n", "        batch_x = self.x[idx * self.batch_size:(idx + 1) * self.batch_size]\n", "\n", "        return np.array([\n", "            loadAndSpect(file_name, window_size, window_stride, window_type, normalize, max_len)\n", "               for file_name in batch_x])"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "f11b931d-0720-4422-bd59-807f8b15b27d", "_uuid": "b095d9e1122b4bbbe7848745c5104ad8a809dac4", "collapsed": true}, "cell_type": "code"}, {"source": ["Here we define the `WavSequence` using the list of test file names and the same batch size."], "metadata": {"_cell_guid": "9deac6b1-d4f2-4c54-885c-de614929c33e", "_uuid": "a9972a11eabf9cfaea51558409549461980a9b2b"}, "cell_type": "markdown"}, {"source": ["seq = WavSequence(test_filenames, batch_size=batch_size)"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "06bdb318-dd8a-41f7-bb3f-22769b62a8ee", "_uuid": "7afe21d60a5feacae49bf797ef509dd1b1e772bc", "collapsed": true}, "cell_type": "code"}, {"source": ["preds = model.predict_generator(generator=seq, \n", "                        steps=len(seq), \n", "                        workers=1, \n", "                        use_multiprocessing=False, \n", "                        verbose=1)"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "17ad3234-2cfb-4cf6-aaba-a1820b73a328", "_uuid": "766ba877d4385f7a187a380fbf7e204606da3229", "collapsed": true}, "cell_type": "code"}, {"source": ["Let us create a submission file (and hope that the files are evaluated in order)."], "metadata": {"_cell_guid": "863bc32b-5742-4b3d-856a-d56f6081800c", "_uuid": "e1ff31571d28d22a1a3e51339058cd0c65ddc5ae"}, "cell_type": "markdown"}, {"source": ["inv_map = {v: k for k, v in train_iterator.class_indices.items()}\n", "print(inv_map)\n", "classes = np.argmax(preds, axis=1)\n", "probes = np.max(preds, axis=1)\n", "print (classes[:10])\n", "print (probes[:10])\n", "\n", "unique_elements, counts_elements = np.unique(classes, return_counts=True)\n", "print(np.asarray((unique_elements, counts_elements)))\n", "\n", "res = []\n", "for cl in classes:\n", "    res.append(inv_map[cl])\n", "\n", "\n", "import pandas as pd\n", "df = pd.DataFrame(np.transpose(np.vstack((np.array(test_filenames), res))), columns=['fname', 'label'])\n", "df.to_csv('submission.csv', header=True, quoting=0, index=False)"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "5cdcfa1b-0bc8-443b-b453-355e4801055f", "_uuid": "63dd489c9ecfb66f0dad82ccac9d340ddaa36edc", "collapsed": true}, "cell_type": "code"}, {"source": ["df.head(n=20)"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "62984c56-1f76-4b06-add1-faf56d4b6f9c", "_uuid": "4df8083146e06b2c0d1ccc6d1cfc415ca0e5b19d", "collapsed": true}, "cell_type": "code"}, {"source": ["import IPython.display as ipd\n", "ipd.Audio(test_path_audio+'/'+'clip_5d6b88af5.wav')"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "b5055527-06a4-46c2-8688-e88e5ae9ade1", "_uuid": "e487eac60f1f60fdfa7dd547472677732c6e12a9", "collapsed": true}, "cell_type": "code"}, {"source": ["ipd.Audio(test_path_audio+'/'+'clip_6eb57dec2.wav')"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "558f6c9b-fa2a-4a6b-91d9-099841a181b5", "_uuid": "140d2867b81a24d300b5be3feccf5eb6f820e749", "collapsed": true}, "cell_type": "code"}, {"source": ["ipd.Audio(test_path_audio+'/'+'clip_2570d8e83.wav')"], "outputs": [], "execution_count": null, "metadata": {"_cell_guid": "ca7f4444-0775-460d-8591-375f470b1153", "_uuid": "c22f452d368bb6958770f6f65ee1af78905b56af", "collapsed": true}, "cell_type": "code"}]}