{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "sb_auto_header", "tags": [ "sb_auto_header" ] }, "source": [ "\n", "\n", "\n", "[\"Open](https://colab.research.google.com/github/speechbrain/speechbrain/blob/develop/docs/tutorials/basics/data-loading-pipeline.ipynb)\n", "to execute or view/download this notebook on\n", "[GitHub](https://github.com/speechbrain/speechbrain/tree/develop/docs/tutorials/basics/data-loading-pipeline.ipynb)" ] }, { "cell_type": "markdown", "metadata": { "id": "5ZZTjoafZw49" }, "source": [ "# Data Loading\n", "\n", "Handling data consumes 90% of the active work time in many machine learning projects.\n", "\n", "SpeechBrain complements standard PyTorch data loading in handling variable-length sequences, large datasets, and complex data transformation pipelines. These are typical challenges when working with speech, but SpeechBrain tries not to make assumptions about your data." ] }, { "cell_type": "markdown", "metadata": { "id": "EnirXev8XUyt" }, "source": [ "## Install dependencies\n" ] }, { "cell_type": "code", "execution_count": 71, "metadata": { "id": "5spDEaL1yddy" }, "outputs": [], "source": [ "%%capture\n", "# Installing SpeechBrain via pip\n", "BRANCH = 'speechllm_librispeech'\n", "!python -m pip install git+https://github.com/speechbrain/speechbrain.git@$BRANCH" ] }, { "cell_type": "code", "execution_count": 72, "metadata": { "id": "DPX-4BBbX5L9" }, "outputs": [], "source": [ "import speechbrain\n", "import torch" ] }, { "cell_type": "markdown", "metadata": { "id": "HL_oCiDyoP8Y" }, "source": [ "In this tutorial we will use MiniLibriSpeech from https://www.openslr.org/resources/31: we download the validation set in the following two cells as well as images and scripts." ] }, { "cell_type": "code", "execution_count": 73, "metadata": { "id": "vtSWx0KAX5L9" }, "outputs": [], "source": [ "%%capture\n", "# downloading mini_librispeech dev data\n", "!wget https://www.openslr.org/resources/31/dev-clean-2.tar.gz\n", "!tar -xvzf dev-clean-2.tar.gz" ] }, { "cell_type": "markdown", "metadata": { "id": "HBlTW2Mq5S35" }, "source": [ "## Preface: PyTorch data loading pipeline\n", "\n", "SpeechBrain data-IO follows and extends [PyTorch data loading](https://pytorch.org/docs/stable/data.html). This preface section recaps PyTorch data loading and does not yet consider the SpeechBrain data loading extensions.\n", "\n", "### Overview\n", "PyTorch data loading can run in many configurations,\n", "but a typical approach has these basic elements:\n", "- a [Dataset](https://pytorch.org/docs/stable/data.html#torch.utils.data.Dataset), which loads data points one-at-a-time.\n", "- a [collation function](https://pytorch.org/docs/stable/data.html#dataloader-collate-fn), or ``collate_fn`` for short, which takes a list of data points and forms a batch.\n", "- a [Sampler](https://pytorch.org/docs/stable/data.html#data-loading-order-and-sampler), which determines the order in which the Dataset is iterated.\n", "- a [DataLoader](https://pytorch.org/docs/stable/data.html#torch.utils.data.DataLoader), which combines the elements above (and has defaults for ``collate_fn`` and Sampler), and orchestrates the whole pipeline.\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "qHNJPq6PfInp" }, "source": [ "### Dataset\n", "The role of the Dataset is to produce single data points. Typically they are loaded off the disk, but they could also come from some more complex source or in some cases just from RAM. You can write your own Dataset subclass or sometimes you can use a standardized class. The training, validation, and test subsets get their own Dataset instances.\n", "\n", "The Dataset interface is simple; it implements\n", "`__getitem__` and usually also `__len__`. Usually, \"map-style\" Datasets are used, but it's worth noting that PyTorch also has a notion of [IterableDataset](https://pytorch.org/docs/stable/data.html#iterable-style-datasets)s.\n", "\n", "`__getitem__` can return _anything_ because data can look like _anything_. Often, though, a data point consists of multiple associated things (e.g. an image and a label, or a speech waveform and its transcription). The Dataset should return all of these associated things.\n", "\n", "It is also relatively common for the Dataset to somehow transform the data on the fly, on the CPU.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "huVMufrKo9uf" }, "source": [ "### Collation function\n", "\n", "The ``collate_fn`` just converts a list of examples into a PyTorch tensor batch. If the data has variable-length sequences, ``collate_fn`` usually needs to implement padding." ] }, { "cell_type": "markdown", "metadata": { "id": "ZmGerYfHpBxu" }, "source": [ "### Sampler\n", "Typically users don't need to create their own sampler; the two default options are to iterate in the original Dataset order or to iterate in random order.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "fpuhtBUEpECO" }, "source": [ "### DataLoader\n", "\n", "The DataLoader takes the other elements above and many other arguments such as batch size. The DataLoader has basic defaults for all arguments (except the Dataset, of course), but it's worthwhile to understand the [args](https://pytorch.org/docs/stable/data.html#torch.utils.data.DataLoader).\n", "\n", "The DataLoader object is iterated in the training loop, and every Dataset instance (e.g. training, validation, test) gets its own DataLoader.\n", "```python\n", "train_loader = DataLoader(train_data, collate_fn=PaddedBatch, batch_size=32, num_workers=2)\n", "for batch in train_loader:\n", " pred = model(batch.signal)\n", " ...\n", "```\n", "\n", "The iterator that DataLoader returns can either load batches in the same process that it is created in (`num_workers=0`), or it can start a new process (`num_workers=1`) or multiple new processes (`num_workers>1`). Because of the Global Interpreter Lock, Python cannot work on two tasks at the same time in a single process. Using at least one background worker process to load data while simultaneously running training is often essential for taking full advantage of GPU compute resources." ] }, { "cell_type": "markdown", "metadata": { "id": "4rXqNQYb_Taw" }, "source": [ "## SpeechBrain Basic dataIO\n", "\n", "The basic dataIO pipeline is organized around three \"key\" blocks: **DynamicItemDataset**, **Dynamic Items Pipelines (DIPs)** and **CategoricalEncoder** which are tightly connected.\n", "\n", "**DynamicItemDataset** inherits from `torch.utils.data.Dataset` and has been built to work together with **Dynamic Items Pipelines** to provide a straightforward and flexible way to fetch and transform data and labels from the raw dataset stored in your disk.\n", "\n", "**DIPs** consists of user-defined functions in which the user specifies operations applied to metadata and data contained in the dataset. E.g. reading and augmenting an audio file or encoding a sequence of words using SentencePiece tokenizer.\n", "These functions are called inside **DynamicItemDataset** `__getitem__` method and are run in parallel on the CPU.\n", "\n", "The **CategoricalEncoder** is a convenient abstraction we provide for multi-class classification problems and it is sub-classed into **TextEncoder** and **CTCTextEncoder** which instead can be used for sequence-to-sequence applications related to text, such as ASR.\n", "\n", "\n", "Thanks to these abstractions, most of the work necessary to set up the data IO pipeline is parsing the dataset into suitable annotation supported by **DynamicItemDataset** (SpeechBrain supports both CSV and JSON formats).\n", "\n", "\n", "Once this annotation is ready, a flexible and efficient pipeline can be created in few lines of code, as SpeechBrain will take care under the hood of padding and other operations." ] }, { "cell_type": "markdown", "metadata": { "id": "kOmWMuv_XDg4" }, "source": [ "In the following tutorial, we will explain in detail how these blocks work.\n", "We will start from the required CSV or JSON annotation whose purpose is to represent and describe the information contained in the dataset.\n", "For example:\n", "\n", "* Paths to audio files, pre-extracted features et cetera.\n", "* Metadata such as words spoken in the audio files, Signal-to-Noise-Ratio, sound event tags, speaker identities et cetera.\n", "\n", "Basically any information required to train your algorithm." ] }, { "cell_type": "markdown", "metadata": { "id": "T9VSd39Cmqxm" }, "source": [ "### Dataset Annotation\n", "\n", "SpeechBrain offers native support for JSON and CSV formats for **describing a dataset** and, in fact, in official recipes (such as LibriSpeech ASR recipes) we provide parsing scripts to obtain such formats. " ] }, { "cell_type": "markdown", "metadata": { "id": "ZFaNums8qj1J" }, "source": [ "We can take a glimpse to how these files can be structured using the downloaded Mini-LibriSpeech example.\n", "\n", "Each file in Mini-LibriSpeech is an utterance from a single speaker, thus either JSON and CSV formats can be used to contain the absolute path to that file, the speaker identity and the words the speaker utters. This is enough to build an Automatic Speech Recognition (ASR) system.\n", "\n", "Creating those files should be rather easy for most datasets as Python offers many tools for manipulating CSV and JSON files (such as [pandas](https://pandas.pydata.org/)). In fact parsing the data to JSON, for example, can be done in few lines of codes:" ] }, { "cell_type": "code", "execution_count": 74, "metadata": { "id": "nzgmi6IyNWMb" }, "outputs": [], "source": [ "%%capture\n", "!pip install soundfile" ] }, { "cell_type": "code", "execution_count": 75, "metadata": { "id": "N-UPJi6v93w_", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "b03f60e3-62da-4c9a-a6c8-a98b30cfce73" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Number of flac audio files 1089\n", "Number of transcriptions 1089\n" ] } ], "source": [ "import soundfile\n", "from pathlib import Path\n", "\n", "# Load all the audio files into one list\n", "dev_clean_root = Path(\"./LibriSpeech/dev-clean-2\")\n", "flac_files = list(dev_clean_root.glob(\"**/*.flac\"))\n", "print(\"Number of flac audio files {}\".format(len(flac_files)))\n", "\n", "# we build a dictionary to map utterance id to words for each utterance\n", "# each row in the text file is simply:\n", "# \n", "text_files = dev_clean_root.glob(\"**/*.txt\")\n", "text_contents = [line.split(maxsplit=1) for file in text_files for line in open(file, encoding=\"utf8\")]\n", "words_dict = {utt_id: words.strip() for utt_id, words in text_contents}\n", "print(\"Number of transcriptions {}\".format(len(words_dict)))\n", "\n", "# Our dictionary has four keys, including annotation of transcript and speaker identity,\n", "# making this manifest suitable for automatic transcription or speaker identification\n", "examples = {\n", " path.stem: {\n", " \"file_path\": str(path),\n", " \"words\": words_dict[path.stem],\n", " \"spkID\": int(path.stem.split(\"-\")[0]),\n", " \"length\": soundfile.info(path).frames / soundfile.info(path).samplerate,\n", " }\n", " for path in flac_files\n", "}" ] }, { "cell_type": "markdown", "metadata": { "id": "lhaZEuQBNWMb" }, "source": [ "Both JSON and CSV formats are briefly illustrated here:" ] }, { "cell_type": "code", "execution_count": 76, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "OVXbuTX-NWMc", "outputId": "9d5feb59-4b5f-405f-8448-a9534dc04cf1" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "{\n", " \"3576-138058-0019\": {\n", " \"file_path\": \"LibriSpeech/dev-clean-2/3576/138058/3576-138058-0019.flac\",\n", " \"words\": \"GIVE ME MY HORSE AND ARMS AND WAIT FOR ME HERE I WILL GO IN QUEST OF THIS KNIGHT AND DEAD OR ALIVE I WILL MAKE HIM KEEP HIS WORD PLIGHTED TO SO GREAT BEAUTY\",\n", " \"spkID\": 3576,\n", " \"length\": 9.935\n", " },\n", " \"3576-138058-0021\": {\n", " \"file_path\": \"LibriSpeech/dev-clean-2/3576/138058/3576-138058-0021.flac\",\n", " \"words\": \"THEY MADE HASTE TO OVERTAKE THEM WHICH AS THE PARTY MOVED SLOWLY THEY WERE ABLE TO DO WITH EASE\",\n" ] } ], "source": [ "import json\n", "\n", "with open(\"data.json\", \"w\") as f:\n", " json.dump(examples, f, indent=4)\n", "\n", "!head data.json" ] }, { "cell_type": "code", "execution_count": 77, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "sM6h9p7FNWMc", "outputId": "0defa3f6-7af2-4578-e4d4-8c0c0500ec1b" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "id,file_path,words,spkID,length\r\n", "3576-138058-0019,LibriSpeech/dev-clean-2/3576/138058/3576-138058-0019.flac,GIVE ME MY HORSE AND ARMS AND WAIT FOR ME HERE I WILL GO IN QUEST OF THIS KNIGHT AND DEAD OR ALIVE I WILL MAKE HIM KEEP HIS WORD PLIGHTED TO SO GREAT BEAUTY,3576,9.935\r\n", "3576-138058-0021,LibriSpeech/dev-clean-2/3576/138058/3576-138058-0021.flac,THEY MADE HASTE TO OVERTAKE THEM WHICH AS THE PARTY MOVED SLOWLY THEY WERE ABLE TO DO WITH EASE,3576,6.18\r\n", "3576-138058-0028,LibriSpeech/dev-clean-2/3576/138058/3576-138058-0028.flac,CLAUDIA TOLD HIM SHE MEANT TO GO TO A MONASTERY OF WHICH AN AUNT OF HERS WAS ABBESS WHERE SHE INTENDED TO PASS HER LIFE WITH A BETTER AND EVERLASTING SPOUSE,3576,10.46\r\n", "3576-138058-0014,LibriSpeech/dev-clean-2/3576/138058/3576-138058-0014.flac,DON QUIXOTE WAS ON FOOT WITH HIS HORSE UNBRIDLED AND HIS LANCE LEANING AGAINST A TREE AND IN SHORT COMPLETELY DEFENCELESS HE THOUGHT IT BEST THEREFORE TO FOLD HIS ARMS AND BOW HIS HEAD AND RESERVE HIMSELF FOR A MORE FAVOURABLE OCCASION AND OPPORTUNITY,3576,18.13\r\n", "3576-138058-0000,LibriSpeech/dev-clean-2/3576/138058/3576-138058-0000.flac,MASTER AND MAN DISMOUNTED FROM THEIR BEASTS AND AS SOON AS THEY HAD SETTLED THEMSELVES AT THE FOOT OF THE TREES SANCHO WHO HAD HAD A GOOD NOONTIDE MEAL THAT DAY LET HIMSELF WITHOUT MORE ADO PASS THE GATES OF SLEEP,3576,14.14\r\n", "3576-138058-0010,LibriSpeech/dev-clean-2/3576/138058/3576-138058-0010.flac,SANCHO ROSE AND REMOVED SOME DISTANCE FROM THE SPOT BUT AS HE WAS ABOUT TO PLACE HIMSELF LEANING AGAINST ANOTHER TREE HE FELT SOMETHING TOUCH HIS HEAD AND PUTTING UP HIS HANDS ENCOUNTERED SOMEBODY'S TWO FEET WITH SHOES AND STOCKINGS ON THEM,3576,15.735\r\n", "3576-138058-0022,LibriSpeech/dev-clean-2/3576/138058/3576-138058-0022.flac,THE WOUNDED GENTLEMAN OPENED HIS ALL BUT CLOSED EYES AND RECOGNISING CLAUDIA SAID I SEE CLEARLY FAIR AND MISTAKEN LADY THAT IT IS THOU THAT HAST SLAIN ME A PUNISHMENT NOT MERITED OR DESERVED BY MY FEELINGS TOWARDS THEE FOR NEVER DID I MEAN TO NOR COULD I WRONG THEE IN THOUGHT OR DEED,3576,26.9\r\n", "3576-138058-0005,LibriSpeech/dev-clean-2/3576/138058/3576-138058-0005.flac,SEEING THIS SANCHO GOT UP AND GRAPPLING WITH HIS MASTER HE GRIPPED HIM WITH ALL HIS MIGHT IN HIS ARMS GIVING HIM A TRIP WITH THE HEEL STRETCHED HIM ON THE GROUND ON HIS BACK AND PRESSING HIS RIGHT KNEE ON HIS CHEST HELD HIS HANDS IN HIS OWN SO THAT HE COULD NEITHER MOVE NOR BREATHE,3576,16.655\r\n", "3576-138058-0017,LibriSpeech/dev-clean-2/3576/138058/3576-138058-0017.flac,HE SAW ME HE PAID COURT TO ME I LISTENED TO HIM AND UNKNOWN TO MY FATHER I LOVED HIM FOR THERE IS NO WOMAN HOWEVER SECLUDED SHE MAY LIVE OR CLOSE SHE MAY BE KEPT WHO WILL NOT HAVE OPPORTUNITIES AND TO SPARE FOR FOLLOWING HER HEADLONG IMPULSES,3576,17.325\r\n" ] } ], "source": [ "import csv\n", "\n", "# CSV is flat list with special \"id\" column\n", "csv_examples = [{\"id\": key, **values} for key, values in examples.items()]\n", "with open(\"data.csv\", \"w\") as f:\n", " writer = csv.DictWriter(f, fieldnames=csv_examples[0].keys())\n", " writer.writeheader()\n", " writer.writerows(csv_examples)\n", "\n", "!head data.csv" ] }, { "cell_type": "markdown", "metadata": { "id": "P9YLGDk0XdG-" }, "source": [ "Unlike other toolkits which have a rather strict requirements on how a dataset must be specified to be able to process it **we do not impose any restriction on JSON and CSV syntax except the requirement for a different unique ID string for every single example**.\n", "\n", "This means that the JSON file must contain a dictionary whose keys are the example ids and each entry of the dictionary contains metadata for that example. Instead, CSV files, must have at least one column called id.\n", "\n", "These are the only strict requirements to guarantee that the JSON and CSV dataset description files will work with SpeechBrain data IO pipeline.\n", "\n", "Users are given great flexibility in how to represent their datasets in the JSON and CSV files as their goals and applications could be different: speech separation, enhancement, ASR, diarization, VAD et cetera.\n", "\n", "This because in SpeechBrain we aim at many different tasks and datasets.\n", "\n", "- **Every Dataset is unique**, it can be single channel or multichannel, it can provide different metadata such as speaker IDs, or speaker positions or even\n", "multi-modal data such as audio and video.\n", "\n", "- **Every task is unique**, the annotation used in this example is suitable for applications like ASR and Speaker Recognition. But for diarization, for example, the user would like to have also the start and stop (in seconds, frames whatever !) of each uttererance too.\n", "\n", "This also allows to keep the annotation very simple and focused to the particular task with only the necessary information for the current application, instead of having a cumbersone do-it-all annotation.\n", "\n", "\n", "**TIP**\n", "\n", "It is useful, when building the parsing script, to have a `length` or `duration` for each example containing the length of the example in seconds or samples or even frames. This allows for subsequent operations such as filtering examples that are too long (to avoid OOM issues) or sorting them for faster training. Regarding CSV files if a `duration` column is specified it is automatically cast to float when a DynamicItemDataset is built from the CSV.\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "frGoZYqCrb3A" }, "source": [ "Hereafter we show how the **DynamicItemDataset**, **DIPs** and **CategoricalEncoder** can be used to build a data pipeline for Speaker Recognition.\n", "\n", "In particular we have to:\n", "\n", "- read the audio\n", "- read the speaker ID from annotation and encode it to integer\n", "- cache filterbank features once and reuse them across epochs\n" ] }, { "cell_type": "markdown", "metadata": { "id": "fIHCwY-BunQ1" }, "source": [ "### DynamicItemDataset\n", "\n", "**DynamicItemDataset** is at the heart of SpeechBrain data pipeline and is built on top of `torch.utils.data.Dataset`.\n", "\n", "As the name implies it allows the **dynamical creation of new \"objects\"** from the entries specified in the JSON (or CSV) dataset annotation." ] }, { "cell_type": "code", "execution_count": 78, "metadata": { "id": "QOjqauY9i6Ll" }, "outputs": [], "source": [ "#`creating a DynamiItemDataset instance from JSON or CSV annotation is immediate\n", "from speechbrain.dataio.dataset import DynamicItemDataset\n", "\n", "dataset = DynamicItemDataset.from_json(\"data.json\") # or equivalently, DynamicItemDataset.from_csv(\"data.csv\")" ] }, { "cell_type": "markdown", "metadata": { "id": "340CyO9Pj965" }, "source": [ "What does it mean dynamical creation of \"objects\" from the entries specified in the data.json annotation ?" ] }, { "cell_type": "code", "execution_count": 79, "metadata": { "id": "epqTBMW6j4SB", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "86afee0a-8b8d-4658-92e7-da7d0ddbaffb" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{}" ] }, "metadata": {}, "execution_count": 79 } ], "source": [ "dataset[0]" ] }, { "cell_type": "markdown", "metadata": { "id": "Na1uMIKokMXs" }, "source": [ "As it is now, this `Dataset` object does not return anything.\n", "\n", "Dynamical creation means exactly that, **items the user wants to be returned must be specified** in some way by the user. These items can depend on the entries specified in the data.json examples:" ] }, { "cell_type": "code", "execution_count": 80, "metadata": { "id": "5RPpu88_k_b2", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "f15aeeb1-9edf-49da-fa16-18ca0d840880" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "dict_keys(['file_path', 'words', 'spkID', 'length'])\n" ] } ], "source": [ "print(next(iter(examples.values())).keys())" ] }, { "cell_type": "markdown", "metadata": { "id": "CETiI0IglI3L" }, "source": [ "Namely from `['file_path', 'words', 'spkID', 'length']`.\n", "\n", "For example one \"dynamic item\" could be the audio signal which will depend on the `'file_path'` key. Another one could be the `spkID` encoded to an integer value if one wishes to perform speaker recognition or, for ASR, it could be the words encoded by a tokenizer.\n", "\n", "To obtain these \"items\" one should specify in some way a function which, when applied to the corresponding key, will provide the new item.\n", "\n", "E.g. a function which reads the audio when applied to `'file_path'` key. in order to make the `Dataset` class return, for each example. the audio signal.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "UMXJkQi5usJg" }, "source": [ "### Dynamic Item Pipelines (DIPs)\n", "\n", "This task is handled by specifying **Dynamic Item Pipelines** for each dynamic item the user wants to get from the dataset. The user can specify an arbitrary number of pipelines.\n", "\n", "For example, regarding the audio signal:" ] }, { "cell_type": "code", "execution_count": 81, "metadata": { "id": "IuEewb4yoB-g" }, "outputs": [], "source": [ "@speechbrain.utils.data_pipeline.takes(\"file_path\")\n", "@speechbrain.utils.data_pipeline.provides(\"signal\")\n", "def audio_pipeline(file_path):\n", " sig = speechbrain.dataio.dataio.read_audio(file_path)\n", " return sig" ] }, { "cell_type": "markdown", "metadata": { "id": "sYELrX1GocuG" }, "source": [ "We specify a function that takes the `file_path` for each example and provides a new item called `sig` which is a tensor containing the audio.\n", "\n", "\n", "We use here some pre-built function in `speechbrain.dataio.dataio` for reading audio. But the user can also use its own.\n", "\n", "Once specified, the pipeline must be added to the `DynamicItemDataset` object and, following, the outputs requested by the user should be specified with the `set_output_keys` method.\n", "We request two items in the output: a new one `sig` and also `file_path` which is in the JSON annotation." ] }, { "cell_type": "code", "execution_count": 82, "metadata": { "id": "IjfzuoFxowKF", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "4afeb4f3-60d8-46ba-a3da-12f4fde9e8e4" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'signal': tensor([ 0.0020, 0.0006, 0.0004, ..., -0.0033, -0.0034, -0.0029]),\n", " 'file_path': 'LibriSpeech/dev-clean-2/3576/138058/3576-138058-0019.flac'}" ] }, "metadata": {}, "execution_count": 82 } ], "source": [ "dataset.add_dynamic_item(audio_pipeline)\n", "dataset.set_output_keys([\"signal\", \"file_path\"])\n", "dataset[0]" ] }, { "cell_type": "markdown", "metadata": { "id": "1_qZ_CYHQMdt" }, "source": [ "Note that a more compact syntax can be used for applying a simple function like reading the audio file." ] }, { "cell_type": "code", "execution_count": 83, "metadata": { "id": "d3ACymf1JQsP", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "98107a04-0fc8-45cc-b81d-588a03cc3d5c" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'id': '3576-138058-0019',\n", " 'signal': tensor([ 0.0020, 0.0006, 0.0004, ..., -0.0033, -0.0034, -0.0029]),\n", " 'words': 'GIVE ME MY HORSE AND ARMS AND WAIT FOR ME HERE I WILL GO IN QUEST OF THIS KNIGHT AND DEAD OR ALIVE I WILL MAKE HIM KEEP HIS WORD PLIGHTED TO SO GREAT BEAUTY'}" ] }, "metadata": {}, "execution_count": 83 } ], "source": [ "dataset.add_dynamic_item(speechbrain.dataio.dataio.read_audio, takes=\"file_path\", provides=\"signal\")\n", "dataset.set_output_keys([\"id\", \"signal\", \"words\"])\n", "dataset[0]" ] }, { "cell_type": "markdown", "metadata": { "id": "ngjASy73p4Pc" }, "source": [ "Now the dataset object will return this new specified item \"sig\" as well as the `file_path` as specified in the JSON. To show that its really loading the signal, let's plot the waveform." ] }, { "cell_type": "code", "execution_count": 84, "metadata": { "id": "2nnvmJ_xqArq", "colab": { "base_uri": "https://localhost:8080/", "height": 452 }, "outputId": "108e3ed3-0f5d-4aae-d1c8-2d9d153db8b2" }, "outputs": [ { "output_type": "display_data", "data": { "text/plain": [ "
" ], "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjYAAAGzCAYAAAA8I13DAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAbD9JREFUeJzt3Xd0FGXbBvBr00NIIaSRkBB66J0YQECIgiA2VFAURMQG0hQFC+hrARVRX16UDxWxgGBBbIh0FIiE3nuNQBIgJqGm7Xx/YJZssmV2d/pev3NyDmxmZ+7Z7M7e85T7MQmCIICIiIjIAHzUDoCIiIhIKkxsiIiIyDCY2BAREZFhMLEhIiIiw2BiQ0RERIbBxIaIiIgMg4kNERERGQYTGyIiIjIMJjZERERkGExsiEgWycnJePjhhyXb3yuvvAKTySTZ/ojImJjYEJFLdu3ahXvuuQd16tRBUFAQEhIScPPNN2PGjBmKx/Lmm29i8eLFih+XiLTLxLWiiEisDRs24KabbkJSUhKGDBmCuLg4ZGVl4a+//sKRI0dw+PBhy7ZFRUXw8fGBv7+/JMcuLS1FaWkpgoKCLI9Vr14d99xzD+bOnSvJMYhI//zUDoCI9OONN95AeHg4Nm3ahIiICKvf5ebmWv0/MDBQ0mP7+fnBz4+XLCJyjF1RRCTakSNH0KxZsypJDQDExMRY/d/WGJudO3eiW7duCA4ORu3atfH666/js88+g8lkwvHjxx0eu/IYG5PJhEuXLuHzzz+HyWSCyWSyOt6pU6fwyCOPIDY2FoGBgWjWrBnmzJljtc81a9bAZDLhm2++wauvvoqEhASEhobinnvuQUFBAYqKijBmzBjExMSgevXqGDp0KIqKikS9VkSkDt7+EJFoderUQUZGBnbv3o3mzZu79NxTp07hpptugslkwsSJExESEoJPPvnE7ZadL7/8Eo8++ig6duyIxx57DABQv359AEBOTg5uuOEGmEwmjBw5EtHR0fjtt98wbNgwFBYWYsyYMVb7mjJlCoKDgzFhwgQcPnwYM2bMgL+/P3x8fPDPP//glVdewV9//YW5c+eibt26mDRpklsxE5ECBCIikZYtWyb4+voKvr6+QlpamvDcc88Jv//+u1BcXFxl2zp16ghDhgyx/P/pp58WTCaTsG3bNstj58+fFyIjIwUAwrFjxxwee/LkyULlS1ZISIjVMcoNGzZMqFWrlnDu3DmrxwcOHCiEh4cLly9fFgRBEFavXi0AEJo3b251Dvfff79gMpmEW2+91er5aWlpQp06dRzGSUTqYlcUEYl28803IyMjA7fffjt27NiBt99+G7169UJCQgJ++uknh89dunQp0tLS0Lp1a8tjkZGRGDRokKQxCoKA77//Hv369YMgCDh37pzlp1evXigoKMDWrVutnjN48GCrQc6pqakQBAGPPPKI1XapqanIyspCaWmppDETkXSY2BCRSzp06IBFixbhn3/+QWZmJiZOnIgLFy7gnnvuwd69e+0+78SJE2jQoEGVx2095omzZ88iPz8fs2fPRnR0tNXP0KFDAVQd6JyUlGT1//DwcABAYmJilcfNZjMKCgokjZmIpMMxNkTkloCAAHTo0AEdOnRAo0aNMHToUHz77beYPHmyqnGZzWYAwIMPPoghQ4bY3KZly5ZW//f19bW5nb3HBVbJINIsJjZE5LH27dsDAM6cOWN3mzp16ljVuSln6zGxbFUijo6ORmhoKMrKypCenu72volIn9gVRUSirV692mZrxZIlSwAAjRs3tvvcXr16ISMjA9u3b7c8lpeXh3nz5rkdT0hICPLz860e8/X1Rf/+/fH9999j9+7dVZ5z9uxZt49HRNrHFhsiEu3pp5/G5cuXcddddyElJQXFxcXYsGEDFi5ciOTkZMsYFluee+45fPXVV7j55pvx9NNPW6Z7JyUlIS8vz611oNq1a4cVK1Zg+vTpiI+PR926dZGamoqpU6di9erVSE1NxfDhw9G0aVPk5eVh69atWLFiBfLy8jx5GYhIw5jYEJFo06ZNw7fffoslS5Zg9uzZKC4uRlJSEp566im89NJLNgv3lUtMTMTq1asxatQovPnmm4iOjsaIESMQEhKCUaNGWS2VINb06dPx2GOP4aWXXsKVK1cwZMgQpKamIjY2FpmZmfjPf/6DRYsW4cMPP0TNmjXRrFkzvPXWWx68AkSkdVwriohUNWbMGPzf//0fLl68aHewLhGRWBxjQ0SKuXLlitX/z58/jy+//BJdunRhUkNEkmBXFBEpJi0tDd27d0eTJk2Qk5ODTz/9FIWFhXj55ZfVDo2IDIKJDREppk+fPvjuu+8we/ZsmEwmtG3bFp9++im6du2qdmhEZBAcY0NERESGwTE2REREZBhMbIiIiMgwDDfGxmw24/Tp0wgNDXWr4BcREREpTxAEXLhwAfHx8fDxcb/dxXCJzenTp6usyEtERET6kJWVhdq1a7v9fMMlNqGhoQCuvTBhYWEqR0NERERiFBYWIjEx0fI97i7DJTbl3U9hYWFMbIiIiHTG02EkHDxMREREhsHEhoiIiAyDiQ0REREZBhMbIiIiMgwmNkRERGQYTGyIiIjIMJjYEBERkWEwsSEiIiLDYGJDREREhsHEhoiIiAyDiQ0REREZBhMbIiIiMgwmNkRE/1q6OxtLd59ROwwi8oDhVvcmInLH5eJSPPHVFgDArlduQWiQv8oREZE72GJDRATgaonZ8u8rJWUqRkJEnmBiQ0RERIbBxIaIiIgMg4kNERERGQYTGyIiIjIMJjZERJWcvVCkdghE5CYmNkRElSzZxVo2RHqlSGIzc+ZMJCcnIygoCKmpqcjMzHS4fX5+PkaMGIFatWohMDAQjRo1wpIlS5QIlYiIiHRM9gJ9CxcuxLhx4zBr1iykpqbi/fffR69evXDgwAHExMRU2b64uBg333wzYmJi8N133yEhIQEnTpxARESE3KESERGRzsme2EyfPh3Dhw/H0KFDAQCzZs3Cr7/+ijlz5mDChAlVtp8zZw7y8vKwYcMG+Ptfq/yZnJwsd5ikMxeuliAkwA8+Pia1QyEiIg2RtSuquLgYW7ZsQXp6+vUD+vggPT0dGRkZNp/z008/IS0tDSNGjEBsbCyaN2+ON998E2VltiuBFhUVobCw0OqHjG3D4XNo8coy9J2xTu1QiIhIY2RNbM6dO4eysjLExsZaPR4bG4vs7Gybzzl69Ci+++47lJWVYcmSJXj55Zfx7rvv4vXXX7e5/ZQpUxAeHm75SUxMlPw8SFse+GQjAGDfGSaxJJ3MY+fVDoGIJKC5WVFmsxkxMTGYPXs22rVrhwEDBuDFF1/ErFmzbG4/ceJEFBQUWH6ysrIUjpiIjOBgzkW1QyAiCcg6xiYqKgq+vr7IycmxejwnJwdxcXE2n1OrVi34+/vD19fX8liTJk2QnZ2N4uJiBAQEWG0fGBiIwMBA6YMnIiIi3ZG1xSYgIADt2rXDypUrLY+ZzWasXLkSaWlpNp/TuXNnHD58GGbz9ZV2Dx48iFq1alVJaoiIiIgqkr0raty4cfj444/x+eefY9++fXjyySdx6dIlyyypwYMHY+LEiZbtn3zySeTl5WH06NE4ePAgfv31V7z55psYMWKE3KESERGRzsk+3XvAgAE4e/YsJk2ahOzsbLRu3RpLly61DCg+efIkfHyu51eJiYn4/fffMXbsWLRs2RIJCQkYPXo0nn/+eblDJSIiIp2TPbEBgJEjR2LkyJE2f7dmzZoqj6WlpeGvv/6SOSoiIiIyGs3NiiIiIiJyFxMbIqJKjp+/rHYIhpZbeBUr9+XAbBbUDoUMiIkNERGAiotz/LqTq3vLqds7azDs881YtO2U2qGQATGxISIiRV0pubZEztqDZ1WOhIyIiQ0REalCENgVRdJjYiOz/dmFSJuyEt9s4lIPREREcmNiI7NnvtmBMwVX8dz3O9UOhYhIU9heQ3JgYiOz0jJ+dImIiJTCxIaICIDJ5HwbItI+JjZERERkGExsiIiIyDCY2BCR1yu8WoJpyw6qHYb34RBEkgETG9K1kjKz2iGQAcxee1TtEIhIIkxsSNeW781ROwQygItFpWqH4J04YJtkwMSGdI0tNqSEnMKr6DdjHRZuOql2KMbCriiSARMbIiInpv62H7tOFeD573epHQoROcHERmYHci6oHQJpRP7lYizdfQbFpWxl0ptLBuuqKikz48UfdmHpbq5iTsbDxMaLGHHBuZ93nFY7BNEGzv4LT3y1FR+s5OwbUtfCTVmYt/Eknvhqq9qhEEmOiY2XKC0zo+9/12H4F5vVDkVSK/blqh2CaPuzr7XezVx9ROVIyNvlXihSOwQi2TCx8RLbsvKx90whZxER2ZBdcFXtEFxypuAK3l12ADmF+oqbSAl+agdAyliQmaV2CESatXRPtsPfHz9/SaFIxBn8aSYO5V7EmgNn8fPTXdQOh0hT2GLjJQ7nchAzkbsO5ly0/PvYOfWTnEO51+LZdapA5UiItIeJjRcy4iBiIqWcyb+idghE5AATGy+0+cQ/aodApFuz/+TyC0RaxsRGQWazNlpKCi6XqB0CkW5dKS5TOwTPsdWWDIyJjYLYUkJERCQvJjYK4rpGRPqXd6lY7RAMQ+BiUSQDJjZEKrhcbKwS/d6kfEYSEWkTExsiFaw9cFbtEIhUZ4JJ7RDIgJjYeAmNjFsmIrJYvjfHcAuMkvqY2HgJoxTyunCVM7qIjKK4zIxRX29TOwwyGCY2XsBIg5YrVoAlIv1buV8/C9mSPjCx8QIbjpy3+v+BHC6vQOTN2DNNRsbExguYKxXjeuf3A9h2kjV1iIjIeJjYeIG//6m6ts2iradUiITK8Y6Z9OZw7kU8/fU2HGSLL2kcExsvMH3ZgSqPffnXCRUioYqyC67ixR924RC/KEhhOYVXLf8Wu0TEg59sxM87TuOejzbIFRaRJJjYEKlkxPytmLfxJG6bsU7tUMjLlJZdbzMUW/03+99kqPAqp2eTtjGxURBLUVFF5VPwi0qNM2uNSKtO5V/BiHlbsYVr9hkeExsiIi+28VgeTudXHYdnNGMXbMevu86gP7vSDM9P7QCIiEhZFTufhn62CQBwfGpfdYJRyIm8S2qHQApRpMVm5syZSE5ORlBQEFJTU5GZmSnqeQsWLIDJZMKdd94pb4BEChMEcGqUjnEZAP3hulTeQ/bEZuHChRg3bhwmT56MrVu3olWrVujVqxdycx1Xmzx+/DieffZZ3HjjjXKHSKQKsYM2SXsyKhW9JCLtkD2xmT59OoYPH46hQ4eiadOmmDVrFqpVq4Y5c+bYfU5ZWRkGDRqEV199FfXq1ZM7RMUUGWhpAy05pdPxASVlTGz06rfd2fhpx2m1w7A4U3AFJ86L72qx1XYhCMZ+P2ZXmOJOxiZrYlNcXIwtW7YgPT39+gF9fJCeno6MjAy7z/vPf/6DmJgYDBs2zOkxioqKUFhYaPWjVWaNLbGtxwuZrZobZUwQSGHfb/0bo77ehoLL6i/KKggC0qasQrd31oheJNbWJ4Zf/GQUsiY2586dQ1lZGWJjY60ej42NRXZ2ts3nrFu3Dp9++ik+/vhjUceYMmUKwsPDLT+JiYkexy2XUo0lNhoLR5TZfx5VOwRJ5F8pVjsEksClYm2NtcnxIDn5bZftazKR3mhquveFCxfw0EMP4eOPP0ZUVJSo50ycOBEFBQWWn6ysLJmjdN+XGepU+9Vh/mJX3qUitUOQxKs/7VU7BCIr+86o19q9dHc2yvR4p0WaJOt076ioKPj6+iInJ8fq8ZycHMTFxVXZ/siRIzh+/Dj69etnecxsvjYuxc/PDwcOHED9+vWtnhMYGIjAwEAZopfeusPn1A6BNKKY460M4UqJuOUItEZr3dBPfLUFr93RDA+lJasdChmArC02AQEBaNeuHVauXGl5zGw2Y+XKlUhLS6uyfUpKCnbt2oXt27dbfm6//XbcdNNN2L59u6a7mbRMY9cwl1S+ANs6lw1HmDCSOhZu0m4LsavUvkysOXBW5QjIKGTviho3bhw+/vhjfP7559i3bx+efPJJXLp0CUOHDgUADB48GBMnTgQABAUFoXnz5lY/ERERCA0NRfPmzREQECB3uF7lqsbvNq8Ul+GmaWsw7pvtlsdsJTaZx/OUC4q8zkUHNWu0/hlyxZkCdWcXrtyfi7nrj6kaAxmD7InNgAEDMG3aNEyaNAmtW7fG9u3bsXTpUsuA4pMnT+LMmTNyh0E2/LhdO9NVK/tozRE0mbQUx89fxqKtpxxuu/PvgiqPbTh8DjNXH9Zckzvpx5d/nUDyhF/xwqJdaofikFRrja0/rH5tnld+5tgz8pwiSyqMHDkSI0eOtPm7NWvWOHzu3LlzpQ+IAABlZu2O83hr6X6bj1+2MQvlcO7FKo898MlGAEDdqBD0aVFL2uDIK7y8eDcAaKpejS3fb/1b7RCINEVTs6KInDl+/rJL22flubY9kSu2Z+WrHYJXLu/w684zqs7iIm1jYiOjQzkX1A7BMRPXTiHyhK1uUDVtOv6PqO303EH719HzGDF/K2794E+1QyGNYmIjI0eDDomIpDZvozq1spS0ny015AQTG2/mZQNrOZCYiMj4mNiQV1i09W+kvrkSuzTWdeCJsxeK8MIPu7BDA+M8iNTAmxWyhYmNFyi4YmdhPC8aYzPumx3IvVCEkV9vVTsUyTz//U7M33gSd8xcj82s5UNe6IDWxzGSKpjYyIj3EuqouOJy3mXrxSZPuDirSssqjjWYILLWSplZwOu/7MXKfTnON/YStlaMJ30olqiGDxkLExvSHE+n0JZWqM9jtrGw3oWrdlqwvMD3W//GJ+uOYdjnm9UORTO0tkK3J3afEjew9uJV7Z7z2QvGWOiW1MPExot9ptHy5bmFV2Xd/7yNJ2Xdv1JOF7j+OmW78RzStivFrrdarNyfK0Mk0lh7UPyaUSv35bJWFVXBxMaLHT17Se0QZJdr4+5v6m+2qxrrmTcWaZOK3sefvrfioNohqOaDlYdw49ur1Q6DNIaJDVkpvFqC4+eMk/BoeT0sKZ1hSwx5CS1UeyZtY2IjIz3eCbZ/bQW6T1uDI2errr9E2uHuNFfvmQfn3U7lX8HwLzbjh23GW0dqsZfcrJD7mNiQleKya/31G46ot9KvycY09NP5V1SIRFnzNp7A/bP/ElWxWuwgUXJOMOD8xc5TV2H53hyMXbgDe04bp3YTkRhMbEgXjp933D1mhGmfL/6wGxlHz6Ptf5Y73baolFOUJSNDXnOpqFQzrZ4bj+qrxhFbFclTTGy8nFEKuz333Q61Q5BMcZkZf//DmR56ccpGa2K3d9ag57trNVEVunID6OFcbSRcRHJhYuPlftudrXYIkqi4qnHlG/CrJfpr3WDROP04YaM18dzFa7PxVmigEGLeJesilbkXtD3Q3J0GtJIy/bfYknSY2Hi5T9dpr5aNraZokwcN1O+vOOR+MGR4co6wmbHqsIx7t63ywPLKMRzMNt4yBCed1LLR480NuY+Jjaz0NSjx1Z/3qB0CANu1ZzyReUy9gdCkjNzCq/hx+ym37tylnr2o9S/RV37eq3YIimOLjnfxUzsA0o7P1h9XOwQAwPK9nnWPVW7b2Xoy36P9aUWZWYCvD4dW2tLnv3/i3MVinDh/GaN6NlQ1lmKVv0T1WGaiIjne4Tp/SchFbLEhquDPQ2ex+5T602MrD/jcc7oATSYtxczVnnVtGPUCf+7itXEk7iwVYMTp3nJzt46SWnQWLnmIiY2BzFx9GEt2nXH5eV9kHJc+GInZKG1jxdbMFFdl5V3GQ59m4rYZ6zB/40lNdSlM/nEPikvNeOf3Ax7tp+IFXky9HHJOa9OpHX2HS1UW4eedrl9n5FRmY7FbK0xsvAoTG1kp122w5UQe3vn9AJ6at9Xl577+yz4ZIpKWsz7y8GB/j49RcQDiCz/swttLPUsitC67wPhFD5WwSGPVfX/Zab8yb5abZQQqt9AcytHWAOTPNxx3+Hu2ynkXJjayUu7DdNaDAbdqjwkQ46FPM2F2cFcWUc3zxKaytQe1uwKyu7Zn/eN8I3JJVp62EsRDOfbr1Lzl5gKwlT96Whvptc3JODp2RXkXJjYGIfUHV80Ll71TuVhsv+tEini1dbG2H03BlRK39lhaZsbqA2fdDciw5P7SU7oCsaNu22V7HdfV2XfG9lId5kovUqmzrh8iFTGxkdFSBYrfnc6/gue+24F9FWpTnDzv3VVrxVxytV6krLKK59Tq1WXY5cYAZ2/4MnInOZX6VcmotM5az3fX4rKDpFxLztjpnvz7H221SrnK+O98qojTvWX0dWaW7McYMX9rlWbYgzkXkFSzmuzHVpqjrihX7TtzATGhQZLtT2rOBku/6oW1SPRiy4mq3X2bj/+Dro2iFTm+rbdO3qViRIYEOH2uvdYrZ2NY1Obs86K3WVzkGbbY6JytvmWjfoQXbT0ly34FQcCkH3fjo7VHZNm/Oypfp4+dc7wIqDtW72e3FKDMl97gOZnKLVxq41ve0/dP5ddIa9cYZ4kNeRcmNjLiXYK0HDWHmzy4su09U4gvMk7gz0Pn3N6H3Cqv9yOFN5ZoYzaclC1x7pDqY2o2Czh5/rLdz/3lInXLB2Q5WXYAsP9a6L0XU+fhk4uY2MiIHyb32Lu4ynVXxgUn1bMjKx8tX12maldH5YGx7nr2ux3o+s5qLNhkuwu6fGFMtXyz2f2u8crTpeVsILE3gNkTvMf0LkxsZKTnD5MWQ/9hm7iuKLZK68cz3+7AxaJSTP5JmnXKTrtRqFGqz2l5V+mFq7YHCntaNVqs7Vn5VR4rvFIiakFOey+Fki02n7ixMO/uU46TIXfq2AiCwFZ3nWJiIyO1ikKV6qAujTuk7I4pM2vrNap8AfWka01PpD5LqRdQFUtMRV+lZqUV2aiY/baEFasBz1pPVbk+ufjSm80C7v5oAx76NJPJjQ4xsZGRVOXLXfWkG9WHbTly9iLunLkeK/c5rn2hR3PWHbf8295F+shZ6Qfs2nPrB39a/d/etFvSJqm6s6RgKxKx3TtKfIl/nnFClv0u2mq/ArSrZ5X1z2VsO5mPdYfP4YqGllYhcZjYyEjNAXfOliBwpqikDD3fXYvtWfkY9vlmiaKSj6s3kH8dPe98IwXtz7YuUf/qT94xnftQrrLF67yCB9cdJdYPW39YnkH6477ZgT2nbdd3spWvCYKAXX8X4JKNc/7n8vUimJdUHvRNrmNio2NSLPxoz+u/qjdjRjv3vuqR4wvGle6DgislVnfvx89dwrC5m2zWaCFx43SU6l70pPVo3Dc7RG3nScOOnK1CB7Jtr2Fla1jAzzvPoN//1uHuDzdU+V3NCjV/qgX4ShcgKYKJjY4ddVCq/Q0VExNPeXrhc+XZV0vKsPe09LMwPHUq/wq2npQ2iRD7sm45kYdWry7D2IXbLY89/uUWrNyfi/4fVf0S0Dspvmbzr4gb/7Xz73zZWizKaf3GQM74XBmEXt51dUBjC3qS55jYGNRcjVcKldpVF/vBywdyDpj9F17+UZoZOVKzdScpRuXWFld9uPpaocLF26+vEv23m6tCewsxi9AKgoDb/7cegz7ZiOwC+Zb0UGK8jydTsuUMz96MNNtdUeL26SXj+A2FiY2OyVGNVq9Ou/lFscPG1NiKNhzRbtE+W3afKkCrV5fhia+2qB2KbkjRNTKmQuuWGEt2nfH4mPYoMbbPkxmKarQo2Tqm1lu2yH1MbBR2WMLBkm86qRwrptJoOVdbPLzF7wosZCqlOeuv1QD5fU/VmWy885TPUREz6Cp+kf7nl73YKNcAdg3N0AKA8xeLMHHRTpv1ddTEadzGxcRGYe5O4z17oajKB/FqieOZT9OWia9dsVhk8TvSOJmu1fwK8NzaA9Zrc83+46gsx9Ha8geTftyDrzOzcOfM9arF4CyJ+WnHaYe/J31hYqMDM1cfRoc3VrhcZMuVG3QtDaBzp3osUbkfttmvZ2KLUnlA5ZluK/fn4rgM3cm7Ttme8uwZ9xfBrNxKrUZLibNDjvp6mzKBkCIUSWxmzpyJ5ORkBAUFITU1FZmZmXa3/fjjj3HjjTeiRo0aqFGjBtLT0x1u7w3e+Teh+WiNfKtPf7b+uMPfe1oXxxWeFsZztFimq+QqJiYXR9dvsd8nGrvhd9nYheKmLJdTs0dit526K1ojZnC03rAnyrhkT2wWLlyIcePGYfLkydi6dStatWqFXr16ITc31+b2a9aswf3334/Vq1cjIyMDiYmJuOWWW3DqFLtK1DTHjfVb1LLKgJWSxZLrbljJxNbbXSkuw4/bT6GgQpE4ta3YZ3293vm3+IRMC2O7bH0sikW+p8u01rdHTsme2EyfPh3Dhw/H0KFD0bRpU8yaNQvVqlXDnDlzbG4/b948PPXUU2jdujVSUlLwySefwGw2Y+XKlXKHajhSFgT7n0IL+CnJqGtqeepQbtVuyZIyfV3c/7vykNohuO3Vn/dg9ILtGDrXmC3VarSU2CrQJ2bANwDM23hS6nBIZrImNsXFxdiyZQvS09OvH9DHB+np6cjIyBC1j8uXL6OkpASRkZE2f19UVITCwkKrH7pGyrt3e/UhtEjsWY8VWWVVT6T4i2fl6X+M0/TlB13YWr2kzWRjJFz5KvZbT+YrHI1rnFWhPp1/BbtlGe/jOtuNLuL+7qv32+5dIO2SNbE5d+4cysrKEBsba/V4bGwssrPFTaN9/vnnER8fb5UcVTRlyhSEh4dbfhITEz2OW0s8aVVwpbnYSMTmcz8bbCbEuYtFLtc2MuLYiXJiE3s1x1pooZvGXf0/2oAVe+13+3aaugq3zVhXZR00W60ncrNVtFDs333jsTzNTVV3ZOW+HI8KKBqBpmdFTZ06FQsWLMAPP/yAoKAgm9tMnDgRBQUFlp+srCyFo3SNrTs0Rz7xYGxLKfuGvUr711dYJbNFpc5rEz01z/VCfpeL9dN6JwY/Je579AvtL5AL2E5yK9fucjSO7F0XSmeoafepAgz7fDNu/eBPtUNRlayJTVRUFHx9fZGTY53V5+TkIC4uzuFzp02bhqlTp2LZsmVo2bKl3e0CAwMRFhZm9WMkU3/bb/PxgyKmZ+v5bpCu8aQ7sfCK8wRk03HX16Pq+e5au7/be7oQ6w7pq1qz2LEWcvDGj6gqY2wqHXPdoXO4VGyd2FScTanXGVNivhe8gayJTUBAANq1a2c18Ld8IHBaWprd57399tt47bXXsHTpUrRv317OEBUnVTPsLe/9Icl+xArw03TjnmFpcdDuGQfLV/T575948NONstRnkYu9FaGVVlpmxqn8K4a/IVFn8LC1Bz/dqHwQCtDTWEg5+cl9gHHjxmHIkCFo3749OnbsiPfffx+XLl3C0KFDAQCDBw9GQkICpkyZAgB46623MGnSJMyfPx/JycmWsTjVq1dH9erV5Q7XUKS8PhaX2m6mLS4140pJGcKD/SU8mrYIgiDpDDNXmEzXVoTWmxN5l5EcFaJ2GKKoMeajXMW31UOfZiJDrmUWvJyrC4PqNbl0ZXVzI5P9NnzAgAGYNm0aJk2ahNatW2P79u1YunSpZUDxyZMncebM9QXhPvroIxQXF+Oee+5BrVq1LD/Tpk2TO1RFuDrGRksuXL1eV+NKcRlO51/BTdPWoNWry3DuonEHoapJEIDb/6deKXp7hszJxKr91l3MBVe0U3cF0Ed3wur915ZZOHexiEmNjMwi5mBUvDJXfu+odWPjiorXZ8C718KSvcUGAEaOHImRI0fa/N2aNWus/n/8+HH5A9KI4lIzBAgI9PNVOxRRtp7MR7dG0QCAru+stppRk3HkPPq1ilcrNCs6uAbp3tqDZ7H24Fkcn9rX8tinf15f+0hPF1U1Q124OQtv3dMSk37crV4QCtPKrCi5Hc69iNd+2YtRPRuiXZ0ash/v/RXWtZs+WHkIY9IbyX5cLeLACZWYzQI6vLEC7V5bYXNKtyAINheNGzl/q+hjnLtYLNt0XiNPE65sTaXFC/VC6QSvqML7+OM/5VngUQ5qp2BbTuRhyS59rSLvCS0MHrZlW5b9gfTuJOqPzN2EtQfPov9HG1x+rjv+OGh9naqc6HgTJjYqKbhSgoIrJbhYVIoHPtlY5YNzuuCqzdoJv+w8I3q67cWiUnR4Y4UU4eqK1BfOoXM3wazDqfOV8xp7r8uGI+fwxJdbnBZcc8X6w+p3q+SL7RpTuXWp/0fiipUahRqvtpgWm4prjEnRqvT3P5fdfm5JmRmHcy+4lFAdqrTYqDdjYqOSim/XzGN5+OtontXv/7lUbPe5an3HOmoAMHr3zz+X7f89tErsuIAHPt6IpXuyFbuzVErb15bj5ulrcaZA/5WUyTOeXjLdGWPjyTEf+2Iz0qf/ge+2uLZSPV3DxEYllTPxi0WllX5v/7kdXlenFeYLBytd/7jdWFV8yQ0abNQ6lHsRaVNWqR0GqUyNMV8VD3n7/9a59NzV/3Z/f7b+uIQReQ8mNiqp3OriU+mGoPCq/Wb0KyXOK8rKYYWDVbOXOyitTuoweCOaZDSYjxmbBy+4vbITzqjdk7zz7wLRLYfZFepEXTJYlW+lMLGRibMxGZX7cCu2dF4tKcOgT7RZQEqPNVW8lVoJsBY5Kkegowlcqliy64zzjVzgyfiV33a7F4unLTZS3CTkXxY35mvGquuDfk+cd3+cDqCv2YlSYmIjk43H8hz+PrtS9dZ9Z65XP5VyEKfUtFhTpTI1C65pyYdrDlv935tfl/1n7FcX9ubXRYyn5jmeialklekrxe4l62q32ACAj8hxOpVbpdw9ZwBeWxuJiY1MnC1A+EGlqXgV1yl5f8VBWWIi/fHkS7fie8rbHT3HGSPuEHPHn+nkJk5KJW5mKK7Wsam8uRR5kdjxx6crdVl5sujs5SLvbLVlYqOSymt6fJ150vLviis0k+u8qcaOI0qMsckptL9ulJa84qDUvJe21osix2vjyT5P57uXrIs95vPf7bQ5vlGKLp3K4yhtyS286rB1kcRhYiOTRVtP2Xz8YtG1D03mcft3OVq/zmq93/Z0vj6+bOUmtunbE6lvrnS+kQZooStCj8S8bI4WRXV3n/ZkHHGva0XsNWvh5ixMX1a1xfxPkSvWHzl7Ed9t+dvmGMuLTlpPCq+WoOObK3G+UqkPvnVdx8RGJj/tsD39ecpv++0+Jyvv34FiGn8na71FyUg1dTzJIaVY30brSSzJS8zf/z0Fu87dXRrhrAtr2c3dcNztS3DPd9fi2W93YPH2qje2tirJV3TinGcDhek6JjYKczTK/YUfdgHQ/mDGuRuOqx2CQ/wuvkbtBG9/dqFL2z/51RZ16o0ofkT9kOO18eRv7G5is/e0a+9FT207mS/ZvsrY3OgyJjYaUt7cWVKm7TfymgO5aofgkNYTQ1dsctBl6Sq5r4+Vd9/7/T9dev5vu7Nx5Kzyg3yZCFv76q/rhTjVem3sTb4Qs0q3La6ehqN7gh+3n8KwuZusxuIIgoA3ft3rPA43XlAxN5L7ziibuGkdExuN8WQEvFK88Q6iQOy6QxL7wc5YLXescKOIYuWK2I7kSjKQWPlmJiMlwlJ4e+l+5BRexZtL9uFknvRTucW82va+/8U819Yae66u9eZo69ELtmPl/lzMXHW9nMKe04X4+M9jTvf7j8haNhX9ecj5Irwb7Iw98tZ3NhMbGXzuQVfNe8u1P9W78Kr2ky+pvfP7AVWO627TO1B1FsbJPNf78D/+Q/wq3YtdXFZj/eGqAzL9fQ00QEqnBOFa7ZrZfxzFXR9Ku37Y1ZIyj4rOiWmZ+MXG+EY57sX+74+j+GHbtbWcKt8AXLJzQ+DOu/uSB1O2h3+x2e3n6hkTGxlMdjC11BkxWT85ZpLhrv+33dmqLKboyQV5b6UvAXdyJDmT2E/XVX2v+/mqcEny1ttaO8yCYCkSWrkshae++usE8hws8FuuuMzNPifY/nPK1SpXviJ45SrfZRL24R0TUQCRg/ytMbGR2OJt0nUdkLao0ZrmSYtNVp7+CvSp0WLDrwRrlzyodOuM2C7dLx0suOsOVz9GriYKQz/bZPV/qZehINcwsZHYmIXb1Q7B68l1d6bG0CK9f+m6OmbMk2Z3ko7aM+r+/kffU5+VngCybA8XIa6IiQ2RSKq09kp4THcSPjFdEY6+hOwVqgRsD0KXc92hUjvdG2zGr8rTvMbTgeRS/0naJEVIu8MKftkpfmyZlLMcy529UOSw4GvyhF9dLr2gd0xsyDBsDUbVO0+6oqRwMMd5effzF+2Pmag8YLmkzIxdfxfAbBaw9mDV2R4+YurOu2nFPt7ViuVpccdTdpY+UKIhaNepqgVEXT2fytV/HRk5f5vobR/7covd37nzkn/51wl0eGOF0+1cLb2gd0xsyDAGfbIRJ84rt9KwEtRObIAKFbEdOJxrOwGa/cdRqxaR8d/uQL//rcMHKw/Z3H71fvlqJOUU2q4+q4GXWHM8TUCkfkmLS82ib1xsLcrpaqvc1n8HT2vNhiPn8Pove3H138HKLy/erXJE2sTEhgzluAdTSbVIyi/dfDdqaAgQcP/HfznZBhgxz/5d68p915OV8inhH609YnPb33bLN+hy8k97UFzq/mwbb1Lq4YCywzmeFVpcsCnL6v+v/7oXgz7Z6Pb+XL1BkHJWk5Qe+HgjPll3DHPWc/asI35qB+CN9FCET8/kmO4NqFPIbZkbRfXscWcpDEEA/v7H8eyqn3ecRt5l+033j/5bS6NXs1jLY/b+Qn4+8t5rnb9UhFrhwVaPafMrTL8WZJ7EhEW7JN3nFx7Okgr2d+2rTmsJ8NaT/yA08Po5/L4nB091b6BiRNrGxEYFuXaaxPUuK+8yEiOrqR0G2WBv4Kwzl0VM/c08lieqqf/3CjM37G1d4kH9Endp9OZcl7Zn5UuW1GzPykeTWqH4fovnJTQaxlZ3aXt7lXzltPWk/e6vuysVStxho7oyXcfEhiRz0uCJjZzjP+QkCAJe/dn5Oja2iCkOZmuwprtyL8ib9NurCKt15y8W4cLVUiRHhagdikPOVrAuKjUjJS4U+7OdD0q/c+Z6NK0VVqXQpBJsJdiCIHg8qNresXb+XeD2Z1SslftyUKdmCBrEuJbk6RHH2JBkClVaT6mydTLNjnJnnRe1XSoqRY931+LLv6QteOYptcqkpE//o8pj8RFBKkTimnavr0D3aWuQXSDFelzqcXWsi7tJjaddSbZKEeyRaYXwST/uQf+PNsi+Bt+wzzcjffpaWY+hFUxsVPDN5iznG+mQ2kW9qKrDuRdFtbpoRZC//Jekyt1mtWtot5Wx8pfdPp3XI1Gq2+/Vn62XtXH1uLYG2l8tkad45NeZJ2XZrz33ztqA/606ZOj6TUxsVPDhGtszQvSPmY3eXbiqbqtUVPVA2Y+x+kDlLkXtXuC/2Zxl9QXko/O7B6XCn7fxJA6I6O6yx50FY/Vi0/F/MG3ZQavZikbDxIYk4ytjcTWxzsk8RkNvjrtY12e6yqvLD+yQKPsxzlZ6j2j5xnXZnmxkV6jie1mnY4TU8EXGcUn3p+G3iVtOq7Cor1KY2EhIrqZKvdBAXoNnvt2hdgiaMnrBdpe2P6lyHSA5Kw+Xq7yOj5a/sFYfOIuikuvjRWytiK4ncgy+tce6F8/zv7IGLm8kEhMbCf28Q/yaIUYkZl0hW577bgfu/nC921OSSTorFZr5VWRncKdZgZVGK7dKabnF5oHUJGyuUAV3s0Yr4h4SsfQGoPS6XNIeS6q9aWVsi1Yme8iBiY2ElF7RVWu+3/q3W8/7ZvPf2HoyH5uOa/OiXdFpO2vgkDSUyG3zXFgHSG1Bfr5qhyCK2OUOlPxON2v0PkmB3F2UacvU7XaWExMbkoynzcx6GBe5ZJd8Jf8JKFPh20iNitJimUzWXSBarUGiZBeTWGcvXh9LpZFGEgDaabExMiY2EtLyBVIJf9hYrdkVWhh87Iyna+iQY2qs0aOn75mQAG224IjNa5R8qVdJ3K0q1fvkIgeAy46JDUnKk5opepjKqvZ0aKNTY5iVlvOaRZW6d7X6pegNsxGlamn5YOUhbDv5jybGFD41bwsKDXhNY2JDknK11aZiTZEjuRc18WF3ZOZqo9Yg0gZXK9Ma3T+XS6xaQ46c1Waxxf+uOixqO7X+vFIcNvNYngR7AT5bfxx3fbgBby3dL8n+PLFkVzamLFE/DqkxsZGQXKtK60lENX+Xth/62SbLv1/6cbfbM6vIGOQuK2+L1sc8fKWx5TC81bsS13j6+E9tTN3/OvMkrohY7FZPmNhIyNvH2ABAQkSw6G3PVCoQ5en6LkrZdFyaOzeq6tN1x5A84VfdLlYph60n89UOQTK8RmqTGguNyomre0voaok+vpjl9P3Wv/Hdlr9xuuAq1h8+h4yJPVBcaobJZMLm43mWgnExoYE2V3LWwTAb3DsrAw93SsYrtzdTOxTDajb5dxyf2hcf/3EUEdX8cW97aSsSX7hagtAg11oXyTFbK2JX9tn64/IHYoPGG+VU9/qve/HDU53VDkMyTGw8VFJmhp+PCSaTCe/8bry+Sld9nWm9wGfHN1ba3M5WUgPopztv7obj6NUsDmn1a6odimHd/eF6S2tFcIAvbmsZL9m+31t+CJP6NQWgv/pTO//OVzsEm/afcX9tJnKdlN1H207m480l+/BCnyYoKTNje1Y+WidGwN9Xn506JkHrHcwuKiwsRHh4OAoKChAWFib5/jcfz8PU3/ZXqQAaVT0Q5y4af2aA3G5sGIU/D4kr9qUFa8d3R52aIaK2TZ7wq8zRGNuWl9JRs8IimWVmAf1mrEPHupGYu+G4W/usGRKA8zoq2Eeu6ZBcA98+0QkHsi+g1/t/eLy/9RN6oPPUVRJEds0f429C13dWu/XcxMhgZOXJVzC0bVIEFj3VGfmXixEa5I/iUjPeXXYA97SvjZQ46b9bAem+vxVJbGbOnIl33nkH2dnZaNWqFWbMmIGOHTva3f7bb7/Fyy+/jOPHj6Nhw4Z466230KdPH1HHkjOx+XZzFsZ/t1PSfZL+fTa0A1rXjkBENX+YTCas3p+LX3edwfO9UyzrhyVGVmNiI4G/JvbEuYtFaFIrDPVfWKJ2OKQDjWNDUVJmxlEPSlF4u9aJEdielW/5f8va4fhpZBfJj6ObxGbhwoUYPHgwZs2ahdTUVLz//vv49ttvceDAAcTExFTZfsOGDejatSumTJmC2267DfPnz8dbb72FrVu3onnz5k6PJ1dic7WkDCkvL5Vsf0RERHo1vldjjLipgaT71E1ik5qaig4dOuB///sfAMBsNiMxMRFPP/00JkyYUGX7AQMG4NKlS/jll18sj91www1o3bo1Zs2aVWX7oqIiFBVd7wIqLCxEYmKi5InNj9tPubxSMhERkVEdn9pX0v1JldjIOjKouLgYW7ZsQXp6+vUD+vggPT0dGRkZNp+TkZFhtT0A9OrVy+72U6ZMQXh4uOUnMVHa2RPl6kdrc40WIiIiuk7WxObcuXMoKytDbGys1eOxsbHIzs62+Zzs7GyXtp84cSIKCgosP1lZWTa381SzeHkGSxEREZF0dD/dOzAwEIGBgc439JAWV68lIiJSw2Nd66kdgl2yJjZRUVHw9fVFTk6O1eM5OTmIi4uz+Zy4uDiXtlfS/z3UDo9/uUXtMEhjDr9xK7L+uYLkmtUcJsCcFeWZyv35nr6eU+5ugYmLdnm0D9K+JrXCsM9glXWBa7MxKy5JI7eEiGCcyr82vTwyJAAv9Gmi2LFdJWtXVEBAANq1a4eVK68XaTObzVi5ciXS0tJsPictLc1qewBYvny53e2V1KtZHOY83L7K460TI5D5Qk90TI5UISpSS4CvD45P7Qs/Xx/UjQphq57CVj/bHZP7NcXwG+u6/NwHb0jC/R2TsPXlm2WITF5H3hRX+kJpu1/tpXYIVWx+KR2/jb4Rr/xbjNFTo3pIOwvo2BT3/5Y3Na46q1gK43s1xtIxN+LYlD74/slOAICwID/8/HQXzHs0FZkv9sTGF3rKcmypyN4VNW7cOAwZMgTt27dHx44d8f777+PSpUsYOnQoAGDw4MFISEjAlClTAACjR49Gt27d8O6776Jv375YsGABNm/ejNmzZ8sdqig9UmJxfGpfnLtYhE3H8rDj7wI816sxfHxM0EnRXMX0bhaHpXuujY0K8vcRteTEinFdkT7d80JaShjYUZ6B6lSVrS+UulEhqBt1LalxdUHBO1snALh25zkoNQnzNp70PEiF+Ppo80JTPVB7IxvCg6VdNuPmpnGiVzIXQ0s3Q091r4/xvRpbxdSuTg38NvpGxEcEIzzYH50bRKkYoXiyvxMHDBiAs2fPYtKkScjOzkbr1q2xdOlSywDhkydPwsfnesNRp06dMH/+fLz00kt44YUX0LBhQyxevFhUDRslRVUPxK0tauHWFrUsj2nnLaqe6fe1wrhvdgAAZj3UDleKy7Bsbza6NIjCyn25eO57ZwUO9fMqNq3FAeVyKV8n6o0l+/Bwp2SMvbmRpPtvX6F1NTpU/jF6pI7yJQGkSiB89LnCgCiPda1n83VqosPrnCIp9siRIzFy5Eibv1uzZk2Vx+69917ce++9MkclvQdSk7DxmHev/Hx329q4oV5N1KgWAODaGj93/Ht3fG/72kioEYxBn2wEANSLDsHRs/qrBjomvSF2nyrE3W1rqx2KIQX6Xfv2GN61Hh7pUlf2FgpXVqRXw20ta+GXnWfUDoMA0cuniBEapJ0WrswXeyLi32u2EWjnlTWAFgnhaoegCfF2vihMJhM6N4jCklE34sM1h/HMLY0RGRKAVq8uA6CtD7ojT3VvgAA/A9+6qayo9HqXpVa7XZSkh4UIpe7y0Sopu9v8NPLejgwJQExokNphSEr7nxgd0VJ/qZY1jQ/D/x5oi7pRIQgP9seSUTeiR0oMvnk8DXp4CfWU1Ghx3AO5pk7NapZ/P9e7sYqR2PfsLdJ2FXqDxMhqzjdSwDiJu3m1QD9XaDKspvFhmPNwB1305Y7q2VDtEFzSI0WemRNGouUbkujQQHRrFG35/xNd66sYjX03N1W/HIfefPRgO7VDAAAMSk1SOwTJMbEhckF6E30lChr+ziYRvnsizSrx8tFI90VlYt9nag241+LnQAtju+oZtEwFExsJGe/tQZWZdPZXlneJW3l0ql9T1v0naaQLQAw9jK9xxY8jO6sdgiaEBPiqHQIAQIeXB1GM9alRmVHfJErSetqgt5sbAddmn+lJr2bydmvoaaCrXt5vYsNUMlHT8tiR2YOrFnpVQ6nZeW0xPWJiQ2RggiAgRmd1Wgan1ZF1/5WTBS3nDrppIdRgmC1qa3eWqlYK3T3aRbvrPXmCiY2ENPjZ9jpPdZd3cKVe7qDL1Y0KwTv3tFI7DFEeSE3C8al9Ze/zv71VvKz7J23Q2UdVFfd3NN7AYYCJDRlMZIi8RaZ0cwf9r6e6N0BiZDX0ahardihOmc3KdOb2bVnL+UYaIuhgoJQWPxcVrwU6eAkVt+3lm3VVusIVxjwrUsUN9Yy/CKjeSqoHa2SQopZEVddP15xeWggDNDjIuWXtCEn3585iq2KotXhyDZlvAtWkvXejjunlIiSXN+5qoXYIsndjaPHOVAw93LEu2JSlyHH0NNPIBG3X2SkXXk2eAdlaKjA58dYmkuyn8oz9uY90wLdPpIl6bmyYfpJyNennE06aV1OCOwBPL+JyfwVUrAKrJ1yaQL/00BWldVK8hlLVEJpxf1ur/1cL8EMHhVttHu0iT+uTVjCxIclIsYhaoMb7fIP89dm1I3bBzqd7NKjy2Fv91W+JI2VpqaXEaOLC3V+XSYphaLteuQUv3dbU8x1pmLa/RXTGkzcsXWNvAU3yjNiKyaNtLBlRN6q61OGo5ueRXdQOwTUqNbTpvYXvvvbiEnm9kaLlKTRIP3Wc3MXERkKBfuLu5m19eZA0tFy7Qk0mk0lUYTpbXYEdkms4fE7j2FC341LSbS1r8f0hkqeJjVQtPt0bRzvfyIZa4dY3SJ6mA6FB2mjB0uIgbS3iq6QCvd8NaVlLfnF5xNZb09m4pw51HSc+WvHsLbZXxtbB2FzFeXqN8vf1/EV9pV9TvHl3C7eWH3hE4jEkWkkoatfQ5xg/pWnjr0UkgdfuaCa61YxsU2oGzuPdlK94qpW7bleoNQvPTwM3Xw93rouwIH+XW1tCA/10tWyGK+5skwAAaBR7rXu4Twuuqm6L/j7pRHY8lJasdghea/ukm9H6P8tFbz+hdwr+b+1RGSMyBrVak4I9HCTvcdePB11ZL91WdVq2p0NTtDIvbWCHRDSIqY4mta51/4YHi5uw0a5ODSTXDMH9HRPlDE8z2GKjAvXvhYikE109CBHVAtAiQXw3oB5qs2iFGi1N0we0RoKKA/mrBV5PrFxNSsJUHhz7nzuaybZvHx8TOtaNtAwAfvYWcQt9pjeJxbv3tUJ7lYoBKo2JDZGXkKseyvCu18YzCJq5r3WN1nOsBjGhGNWjgaxfmJWlxIVi/YQebj9fyq4sLRSlc+WzMzgtGX+Mv0nS4/dvWxtzHq66InjN6oGiVjFvnRghaTxax8RGYb+O0tl0UyInqgW416LQPCFM4kiMpzw9GHdLYwzWQVfrewNaITo0EDMfaOt8YweaxV9v/ft4cNUvdEdsDXxWOuVOclDIMzzY9c/Lu/e1Qo8U2+u9PdbV8Xi1V/o1RVr9mi4fU8+Y2Cis4geW9CUuzNh1ip7oJu/K6JXNe/QGRY9H4rm77MRdbWoj84WeaOVhC8Hb97S0/LthbCiiQ8W32tyUIq5mkyucJUautFA1iJG2PIKzoqEPdzZ2lWFbmNioQOtN32SbXrtaxFK6yd+oM1ekpNZYJE+me0sRc+WFSl/sI36dJjXWAnuyu7I3BeQYExsiAuD5oHZfkV9oRq0KS/Kp5uEq9XKvt8XlvLSFiY3E+otck4f0R68re3vClS6AAR2SZIxEPlr+u2o3Mu+i9cRl4q0paoegKUxsJCamed3dwZZEckqOCqnymCsVV0MCxd1VS10VlqS17eWb1Q5B0/7voXZWy4iMuEn9bqhbmrFQX0VMbCQ24qb6SIlzPDjsgVR93tmS8sTWqRDD2U1n01rKzFJKieNsKC2rESKu6JuSOjeI8uj5ntbkKbhSYvl3r2Zx+H1sV8v/XanfJJe6Nm5KvBkTG4nVrB6IpWO6OtzG2Sh20iY1xnF6OrukIntrJUmFRfekZ8SX1J1p/iEeLqrZS8YWDUEA4iUoZnhn63gJoiGAiQ2RpplgwuePdJRkX4mR8laSlXuApqfsRWfE5EEqcsyUe+FW8TOcpOLj4iwvV8ZKCrg2IP7RLnXx2dAOLkZ23dT+LZ1vRKIwsSESSY3vPwECujWKlmRfWh4kq4SaGuxicUbtRV1/eKqz9DvVwduwcrJb3UmLkZ+vD166rSluaux+DR05WvIHtPeOtaEqY2Ijkxn3t1E7BEXc3zEJSZHVMPXuFmqHQk44q8Oj7fYWz+mxqyzYw2nOnpKii8UIbLVGtk2KgK+PCV0aejb+R06uzGo0Ek7PkUm/VvF4+uttaochu7pR1TDlbmnXRdEqNWYeeHsrC1G5YH9fXCkpk/04jWKri9ruuyc6objMrOkxkzrM5SXBFhuDW/RUJ7VDMIynNDCtk0gPHH2hupuse1INWaw/n7sJPz8tbj0/Hx+TppMab8YWG4Nrm1RD7RAMw5WaLlLR8h1Xo9jqmNxPuRWnieSWGGl/8Uo96t5YmvF5esPEhkjDfCTMbG6o53iFX1uTmhwdftnYbh5GREbl5yP9TUDL2uHYcOS85PsVQ6/jz9rViVQ7BFWwK4pIwzrWle7C5E7Fa1dmcLerw9ZBukaObqOnezSUfJ9kTExsiDRMiXEF7hjfq2qxv9o1jNWMT/JwtxGSiTOJxcRGJY9yvRzSMTFrotniaWl7OehxGrg3CvDzzq+rx7vVUzsE3eEYG5XEhQepHQKR7BIignEq/woAYMOEHojUYZE8IjWLaqdK2B3tLbwzBSZyg9Frysh9RxwfEczpsTo084G2aoegOmfFLcX6zx2cRagEWa9keXl5GDRoEMLCwhAREYFhw4bh4sWLDrd/+umn0bhxYwQHByMpKQmjRo1CQUGBnGGSB7T4Zc+eBde81LcJnu+dIktryqAbrq1kn+ZkRhYAjEnn4FAt6tuylqT70+PHU6oWm/rR4or/SWHWg+0UO5bWyJrYDBo0CHv27MHy5cvxyy+/4I8//sBjjz1md/vTp0/j9OnTmDZtGnbv3o25c+di6dKlGDZsmJxhkos+GNha7RAc0vhajJrz6I318GR314oPik0eH+9aH988noY5DztfHDA0yL1xO57S4xctGVN6E/fXmuqYbN1l1bu58pXStUK2xGbfvn1YunQpPvnkE6SmpqJLly6YMWMGFixYgNOnT9t8TvPmzfH999+jX79+qF+/Pnr06IE33ngDP//8M0pLS+UKlVx0R+sEtUMghXja+uXrY0LHupGi1jxigkFG52zQva0bDLGt4l8/doPl3+lNYl0LzGBkS2wyMjIQERGB9u3bWx5LT0+Hj48PNm7cKHo/BQUFCAsLg5+f7XHORUVFKCwstPrRg5a1I9QOwS33ta+tdgikAXK0iuVfKZF+p0RuiAuTZ3JH84Rwh7/3ZIZexdIQj97o3bNuZUtssrOzERNj3azm5+eHyMhIZGdni9rHuXPn8NprrznsvpoyZQrCw8MtP4mJ+lim3V7htZS4UIUjES82LBBv39NK7TDIoOauP6bKcasHcnKokpx9ebdw8uWvBFe7ZsUQU5IquWaIRMfy7vZPlxObCRMmwGQyOfzZv3+/x4EVFhaib9++aNq0KV555RW7202cOBEFBQWWn6ysLI+PrZa+LWrhi0c6qh2GXXoZuyLXZzos2HhfgCEiuoiUotbbq1sj71xPR6v8fNX/Ug6plOwq9d5kOQRpuHylfuaZZ/Dwww873KZevXqIi4tDbm6u1eOlpaXIy8tDXJzjQU0XLlxA7969ERoaih9++AH+/vb7JQMDAxEYGCg6fi0b2aMBYmRqAiXPGbGQm7NzUjKZVevV9dFodWe9aO9iRWBBL3dIEvvI3VlKfHu6zOXEJjo6GtHRzu9w0tLSkJ+fjy1btqBdu2t/0FWrVsFsNiM1NdXu8woLC9GrVy8EBgbip59+QlCQ93zR6/F7M9Bfe6WQ7muXiIWb9dtypyRnXzKv3m677oaY92qr2s67FEKD/HDhaum/+9ThB4Ak1yw+TO0QqvIgF2tXpwa+Hn6D11ZOVoNsr3STJk3Qu3dvDB8+HJmZmVi/fj1GjhyJgQMHIj4+HgBw6tQppKSkIDMzE8C1pOaWW27BpUuX8Omnn6KwsBDZ2dnIzs5GWVmZXKGSSBW/d8b3aoyOyZG4r732xjT19GDKJFlrEON+3Y0BHZKcbrPpxXS390/65CyBDfTTRveolIkIkxplyfpqz5s3DykpKejZsyf69OmDLl26YPbs2Zbfl5SU4MCBA7h8+TIAYOvWrdi4cSN27dqFBg0aoFatWpYfPY+dsWfLS+5d1AN81f+QjLipAb55Io2VZMkjFd8/BZwVZSWimjp1fVylZMdSbJhyww6aV2g5GntzI5efX56/2ZsoIid/DYxTUpOsoyEjIyMxf/58u79PTk62agrv3r27V/W/1qxu/SFtFCNuRtTrdzXHc9/tdLrdqB4N3IqLlJdcsxqOn78s6T7jJViPTMlPoxZmw2jJ72O6qh2CLJxd47XylVyxZalfK9erL695tjtW78/FwI7OWy4rCvTzQVGp2fJ/Vz4XT3avj6y8y2idGOHSMY1G/Vt/AgD4+ZhED2KsJfILq3Li5KnIEGMM0jaqjwa1Rc0Ksyom2xkfI4X4cOlX6dZLC4VSYnUykUAriYjUKp6XO/fbdWqG4OHOdV1u1Z7Ur6nV/6NcuI4/3zsF/3ugrdePV2NiQ6L974E2aodgWFK0jKTWq4mMiT0t/68p49TR7o2lnyLdRsa7zOhQJuVa4cmXrqKz9FTKDbQw1EDv+ArqkNgPt9QfTCUXcNOSqOoBWDGum9phOGWC9SDFOBEte87eSvbeQva+nO5u6/5yGzVkTMSekqHgGrnHm4YbkDqY2KhsSFodANdmGZE2jU5v5NHsIDGkzEEXj+iMuUM7oHaNapLt8/U7m4varl6U+5VT5fy+8+6GeXnd2kLa1b8dvQ06N4iS9FgVaaUrlGmf54xXSlVnXrm9GR7pUhdJkeK/hLy8+5SckGPg4A315J/ZYZYxs+nWmCUA5NIzRbnX9sEb6uCHbadk2XeNatYthmxY0i+22KjMZDKhTs0QWQZ78YPpXeRIeJV8C4lZAdxddT1oSVLDzU3dX525Uay+u4wdvY39ZKwSXXnPFQf9ip2wIQletz3GxEaDbpJhYKY38ffSYlh6TWQn3dYU3RtH45528qwc/1jXerLsV07P905x+7lKJ3FSJ9RaaZGuGIcfB/TqCv9aGvTWPS0l2Y9WLhBKu1HGfnhvJWfS9EiXupg7tKNsFWfHprteXE1tnhSi02uCK4ac17Rxt+jvfUK2MbHRoEBfxxf4hiIL+XkrsXdX7evUwPzhqbitpbSDH92hVt0JsV+CFTfTU3n49wa0krWLSy6hQdoYyKoGR+9JOZO221rGy7dzUpR+rlBeRHDSySpmGi+J06l+FNLq11Q7DEmmwLqTGzl7r9nSv608XUZyuKOV+9PP9cpbW2qJyjGxIa9VfifftSHHNLlCT1+cYqt5a0lKnGctsiaFJ7d7c+uSHNy52SBrTGzIa43q2RAAkOjCVHtvkxDh/tIJMaz265aQQH1V4Yh0sbAiv7YdM/IYKaUwsdEgqd7YPRSsL6FHrl6QtU6OO/Xy8TQV35Nij9KzCd9/auAdP3k7JjYGJmXl2ftdXKGW9EH84OHrG4rtivL2hfjc9fJtTZ1vpBGtaru+Iruzd8UtzeLcC4boX/pq8yTVdGvEcShGxHt77UiJC8XPT3eBv45qpriThDl7z3WsK3+VazI2/XyCiEg1FVt2qgfqY7DoBwNbqx2Cy/SU1DzSuS7aJyubhDSKZakLck4/nyIvUj3IeUOar8KzPTok11D0eKRdT3azv1J2/3+rB2uhenZyTX0to6A3k/op32Wmx5pErtJTcqtVfAU1SMwb+xWFLyo1q3OGC10TFmw/8a4VHoz9r/XGnIc7KBgRadF/72+j+DEf76a/5TMqu62V+gVD9Y6JjU4l1HB/Gi65pkY1fXS9yMlqVpSTQcFB/r4cOEy4vVU8BqfVUfSYwf7Stejc9O+K8KEKT7+vuLSI0sc2Cr5qOsVaB8q5tblO7qCYS+ja0z0aqh2CaCEiu4Re6dcMX2SckDkaeQxOq4O48CC0r6N8N/zvY7rig5UHMaF3E8WPbQRMbEg3gvx9cLXErPhxlR7PpCg3pnvrRfME16ciqyHAzwd/jL9JV0ulJItcQVyPlZ/L+fn6oE8LdW5qGseF4sNB7VQ5thGwK0qnvLGlPy5MPxd+V2mp6+b2VsZYDFAvCakJxl7/rXzcS18FkgS2ZBPAFhsiw5AqNwq1MSuPXxjeLcDXB8Vl7rWWjr+lMW5uEosWbhTzI3IHW2yIvJjYLqbypRXIO4UFWw+gdyXR9fP1QfvkSKtBsURyYouNzrzdv6XaIahG6u6aGtWMtVaUr4zdWQ1jquOO1vGI4rR/ItI4JjY6Y7SFG10hSNwfYrTXUs5VoU0mEz4YqHxdEnKdHIuh6oWGhqqRiti+TKQBtpK2xiwfT5rBQVakH0xsiDSquwaWJSD90frUfA5EJ7kxsZGRnF0dztbBqVOzmmzH9iZiC5ERuat8fS05NYyp7tHz5ezmJJIaExsZpdaVb+XbetGeXaj0SI1aL487WPBRSomRniWiz/VuLFEkpLRJt8m/7punCys2j5duqjbHwZDcmNgQaUADW3fULnwBSLlGDikrSA9/OwmTEXZFkdyY2BABWPDYDWqH4BF3v3f4JeMdeqTEqB2CIhrGcMA9MbGRVd6lYtWO3bJ2hGrH1oP+ba3HNdxQr6bN7YxemM5sI7O5reW1JRVqcwV5t/j7aq+vpa7ItZ3E0mp3Up8WcWqHQBpg7Ku2yi4Wlap27Ee71JVsX0kejv9Qwvhero0xaVsnQtR2D91Qx41olBcf4V4SYqvBJq1+TawY1w3Lxnb1LCgvNfVu7y2iqTYtrblG6mFiY1CeDhasaGSPBpLtSy5yLZCp1GyQm5vGqvr8yhrEVEe1AM6EIduYP5CWMbGRkScf/se61pMuEA9ppWm9a8MoyfYVXmntG7V1TPZsBh3vVLXDG4Yt6X1s1mt3Nlc7BJIRExuNGpSa5HSb6FDvWrfnzjYJku3r1ua1JNsXGU+tcHlaALXuhnrylajQkhtkLMVB6mNiIyNP7mrqOCnABwDfPJ7m/gF0yMdBq4SPi+9kXx+2cJB9Rnt3sEHPWkMuV2JoTGx0zFHtkprVxVc9fucex4Md9bConhwtMBHVtNVdRcoa2CHRrecZcTZZbTcHpxOpgYmNQcW6MJj23vbuXcC1JNCA07LvbC1d1xu5rlmCe9V27ZUO0LOnezaUbF9aX8uK9E/Wb4O8vDwMGjQIYWFhiIiIwLBhw3Dx4kVRzxUEAbfeeitMJhMWL14sZ5i6VSNEuhYFPYzXcdQKpffBjLY0qRWmdgikQ560sNp7bvVKswNZJ4u0TNbEZtCgQdizZw+WL1+OX375BX/88Qcee+wxUc99//33OdPDiUA/6UqxN3Cw9pRW/gy1a2i/no67DJiXkUo8aRER+1xP6jvpoWub9E22xGbfvn1YunQpPvnkE6SmpqJLly6YMWMGFixYgNOnTzt87vbt2/Huu+9izpw5coWnCDlW99bFujJEXmr1s93VDkHU8gmv3t7Mo2P4aaQEhCc8XfGctEu2xCYjIwMRERFo37695bH09HT4+Phg48aNdp93+fJlPPDAA5g5cybi4pyXxy4qKkJhYaHVj1Y8c4tnKy6XX6A+G9oB43s1Rr9W8ehUX57++zgvnd7q7YzYhacmqZcucEen+s7rPamZmGhljI2jWZakb7KVFs3OzkZMjPWdg5+fHyIjI5GdnW33eWPHjkWnTp1wxx13iDrOlClT8Oqrr3oUq1xiwzwbt/LJ4PY4d7EIMWFBuKmxvIvYPdm9Pn7YdkrWY+gNv/RJbvMeTZV0fyEB9lt0PxjYGqMXbMeUu1vYXCOMyChcbrGZMGECTCaTw5/9+/e7FcxPP/2EVatW4f333xf9nIkTJ6KgoMDyk5WV5daxtcjHx4QYmZYKqKyagwuiHrhy89W9cbR8gZAm3N4qXvFj/jb6Rpe2f6xrPXRuIF01bQBoYKc+S8vaEbijdQIOvN4b93d0XvxTj1onRqgdAmmEyy02zzzzDB5++GGH29SrVw9xcXHIzc21ery0tBR5eXl2u5hWrVqFI0eOICIiwurx/v3748Ybb8SaNWuqPCcwMBCBgdqf0SOXTS+mo8MbKzzej6N1gTrqoEqnKwPNZ9zfxubjzeLDsOe0droyyX0fDGzt0fMFiCsh0L5ODdSPro7mCWGansXW4N/xJFJNONBiJ87Qzslqh0Aa4XJiEx0djeho53e8aWlpyM/Px5YtW9CuXTsA1xIXs9mM1FTbza8TJkzAo48+avVYixYt8N5776Ffv36uhuoVpJqmbW+gc+YLPRVrNXLk4U7Jku0rNMj2NPmBHZPw8uLdkh1HSp8N7YChn21SOwzdkGJG5e2t4vH9lr+x8Vie3W3qR1fHW04KXKotwUZxPXszk1qIrN3DjizSMtkGDzdp0gS9e/fG8OHDkZmZifXr12PkyJEYOHAg4uOvNROfOnUKKSkpyMzMBADExcWhefPmVj8AkJSUhLp168oVqtfp3cz5oOxyWkhqAKBJLflLoGvxLrSc3GOsqKogf18sdLJsycCO2i9uOX+4+HE8d7AoJBmArHVs5s2bh5SUFPTs2RN9+vRBly5dMHv2bMvvS0pKcODAAVy+fFnOMKiSO9soP/5ADwJ8jVe9mORVo5r0JR2UYK9BS88zhTjGhsrJNisKACIjIzF//ny7v09OTobgZHS+s99rmVZD7+VCi41WKPFa3t46Hs99v9Py/0axytW50O/XifE93aMBZqw6bPN3yRqY3k3XiFk4uCKtTDsn6fEW1QvZG3/w0aC2CkeiLZWLHwaouP6UuwswkvS0PCjYaPQ+O5O0gYkNWTSsNFVUygG75Jqp/bU9INXojLioqhghgQokFg4aSnxV6gpLiZN/DB8pxzs/vSRKYqQx1mbSQjVYZ9gori0NvLTcvqvdOUbRJilC7RBIQkxsZKTjcXiG4u6MIq2NkQoNlHVIHFUg5m//joNp3uHBtksKEDigjGTHxIbs6pBcQ+0QqIJu/1ZMtlWXxF2hQUyW3HVve/vjoBwlPUqLCNbYzC2N3TCQ8TCxIbta1o5Q5bjP3NxI0v0ZpeXszbtb4OXbmuL7JztJts/Gdkrwk2cC/bUzCDa8GluPbEmsYYyudqqKiY2X8VdxVV+xbK00bpTkxBNhQf4Y1qUuV2JXgF4bFRrqfGzQf+0sdyKHsRLfQJF2MLExIEdjMfRcgMuezx/p6PD3xjtjUpLWxlo58nLfpoocR45ZY+8NaIWbUpSrsB3CMWuGxcTGgOIlHIOhB9V5gSJCv1bxinU7yTF7ys+HX0ckDb6TyKKGQfvidXTDTRJ4qnt9tUMQhXWitKM712IzFCY2BpRaL9Kt59WsLs1K4SS/V/op0+WgN3WjQvBc7xS1w3DqlqaxHrWsGnFdMz8f9zuNX+rbxKNjd2sU7dHzSVuM9+nQELX65ifcqv0Lu5QSI72r6w0AaoRobAqvwThbo87TBRef7tHQo+frmb1XNr1prNv7bOxh5WADDj30akxsDKhagP0xJ0b8AMeEip8lZMQ7XVLe3W0TPHq+v5/0H8TGCi7a6gl7OaM/P5skEb6TvJwW65jYuu6lxHEhQjnc1rKW2iHokhbvD+5uW1vtEEQxy9CU7c4NS5D/9eeYNPkXJXdxOomXE3QytLaVh03/7uiqYL+7J+ML3BEdGoj37muNtPo1FT2uUSj53hBLL6Uc5EhsOiS7Pq6wVngwxqY3QnCADwK8dNFTo2JiQ1RBxsQeOJJ7CecvFaFPC+VaM0wKfyklRASjS8MoRY9pJLFh+i6SqGYKJMetlI+bNwaj0713rJORMU01gP46aYJWU/mihK2drOJbK/zaF/4drRMU7/NXutWGvJeqjTseZjaTbuOMQHKMiY0XSK0rvpl26ZgbcXfbBPz53E0yRqS8xSM6Y/iNdfE/BUu2a5lOei006f6OiQjS0FpQeuNpV1RSJNd4IseY2BjAnW3iJdtXSlwYpt/XGokGu3jUjQrBi32bIkaDXQjxbqz91DaJK6/LqW9L+5+pKXdrZ+Vud6m5TIRZH8P6SMeY2Cjo2VvkWXSNM4b06827WuCHEZ0BAH3/naHUPMH539NoiafWtKwdbvPx0T2lGZPhK2OTmVy7Dg2SZkimsxpBRJ5iYqOg6FB5KvuGBbt+wRnWpS4A4xbzq1iZV8u9Lg+kJlkGor5xVwu83b8lvngkVeWoyJ5bmrlfRK6iBjKuwp2g8bXiPE1rEmp4dn5ibhxI35jYGECgn+v9/S/f1hQ7X7kFPVKkuVBrzUNpyZZ/62VKc/VAP9zXIRGRIqsK//J0F0RVD8Bvo290+Vi1a7DFR6zqErVUlBvfq7Gss+Bk27dEDS2ettg0qRWG6fe1wmQ3lxVpx25cw+N0by8WFmTMRS8BwNfHhF9HdcHe04XokWLMBe6aJ4Rj80s3u/Scr4ffgIWbTuJlziwR7cYG0k6LD/TymikNJSgKWl6MsF2dGojT4Lg5UhcTGxnVrM71fKTWLD4Me04Xitw2HM3ibY+V8FZp9WvqpgVLKyrWSBHb2NDEwdpFD6QmeRqSrtWPro4Fj92A6NBA9Hx3rUf7alk7wuXnhATya8/ovPvWQWbudBHJoV60PtaQEaOhjGMTiJwRO2g7JiwIq5/tXuXxFeO6OVzLzVvcUK8m6it8XXrzrhZIrRuJJ7rXV/S4pDwmNgbhaGDyve1ZwI/IE5teTMe652+yFHoUo25UCI6+2cfy//QmsdINGvZwGE2n+lW715x12b50WxMA1yce6M0DqUlY+Hiaobvg6RreOhhESlwozl4osvk7OaeWEhlR5S4nd2c0ulvq3ykbXWKurPtma2ZRGyfrsQ3okISbGsdIOrvzk8Ht8egXm/H7mK6S7ZOIiQ0RkQG4O4j2tTua4di5yxjetZ7TbaUucJneNBbHp/aVdJ9E7IoyiBQHgxWJyPjcneadVr8mJvVrymUiyDDYYmMQY9Ibwc/XB7c2j1M7FFnpfVVl8l71okPUDoHIK7DFxiBCAv3wfO8Ut6Y/at0ng9tb/u3tU2XJMS2OJvv2iTQ83ClZsuUYxLij9bW1rm5uaswCnESOsMWGNC+9wsW5Tk3e9ZL0Xr+zOV5avFuWfXdIjkSH5EhZ9m3PBwPb4I27WqA6a7aQF2KLjYLUWvut4iyGJ7s1UCcIIg178IY6aocgOUdJTcWWLdbVIaPhO9oLxFdYFK9JLQ4yJvJ2Pj4mvNW/BS5cLbW6PhAZARMbIqJKEiON/2U/oAPHq5ExsSvKy/j5anF4JZG26K17pqbIFeGJvIG+Pr06p2YB4KGdk7HndCG6NoxWLwgiktzqZ7sjRsJqwER6x8RGZiEBvrhUXKZ2GJjcr5naIUhmSFodfJ5xQu0wiDShbhRnChJVxK4o0p1nezW2/Pvedlzgk4iIrmNiQ5pTK1x8deHqQWx0JCKi62RLbPLy8jBo0CCEhYUhIiICw4YNw8WLF50+LyMjAz169EBISAjCwsLQtWtXXLlyRa4wSYO6NIhy+PuQCgM7Y0K5xAJJg106RMYg2+3uoEGDcObMGSxfvhwlJSUYOnQoHnvsMcyfP9/uczIyMtC7d29MnDgRM2bMgJ+fH3bs2AEfHzYseRNni/n5+Fz/vZ8PZ3mRNFaM64Zfdp5Ge4WrBBORtGRJbPbt24elS5di06ZNaN/+2jo/M2bMQJ8+fTBt2jTEx8fbfN7YsWMxatQoTJgwwfJY48aNbW5LRCQlXx8T7midoHYYROQhWZpCMjIyEBERYUlqACA9PR0+Pj7YuHGjzefk5uZi48aNiImJQadOnRAbG4tu3bph3bp1Do9VVFSEwsJCqx8iIiLyTrIkNtnZ2YiJibF6zM/PD5GRkcjOzrb5nKNHjwIAXnnlFQwfPhxLly5F27Zt0bNnTxw6dMjusaZMmYLw8HDLT2JionQnIgFn3SrkWEiAr9ohkA6E/rsu0g31a6ocCRGpzaXEZsKECTCZTA5/9u/f71YgZrMZAPD4449j6NChaNOmDd577z00btwYc+bMsfu8iRMnoqCgwPKTlZXl1vHl8kjnZLVD0LV372utdgikA0tG34iX+jbBi32aqB0KEanMpTE2zzzzDB5++GGH29SrVw9xcXHIzc21ery0tBR5eXmIi4uz+bxatWoBAJo2bWr1eJMmTXDy5Em7xwsMDERgoHarbnZpGI3/rjqsdhi61ToxQu0QSAcSI6vh0RvrqR0GEWmAS4lNdHQ0oqOdl+RPS0tDfn4+tmzZgnbt2gEAVq1aBbPZjNTUVJvPSU5ORnx8PA4cOGD1+MGDB3Hrrbe6EiYZwMYXeqLwSgni7NS0CQvyQ+HVUnRrrN8lIupHc3oxEZHUZJkV1aRJE/Tu3RvDhw/HrFmzUFJSgpEjR2LgwIGWGVGnTp1Cz5498cUXX6Bjx44wmUwYP348Jk+ejFatWqF169b4/PPPsX//fnz33XdyhEkaFhsWhNgw+zVqMib2xPmLxUiqWU3BqKT189Nd1A6BiMhwZKtjM2/ePIwcORI9e/aEj48P+vfvj//+97+W35eUlODAgQO4fPmy5bExY8bg6tWrGDt2LPLy8tCqVSssX74c9evXlytM0qmQQD+EBOq76rDeVpAmItID2a6skZGRDovxJScnQxCEKo9PmDDBqo4NERERkVgs6aug2jX0221CRESkB0xsZNYiIdzy706ssUFERCQrdvLLLDjAF/tf6w0/HxOL9REREcmMLTYKCPL3hZ8vX2pvN74X1z0jIpIbv22JFJIQEax2CEREhsfEhoiIiAyDiQ2RQnx9OMaKiEhuTGyIFHJLs1i1QyCDaBBTXe0QiDSLiQ2RQgL9fNUOgQzi/x5qhztbx+PXUVyWg6gyTvcmItKZxMhqeH9gG7XDINIkttgQKSi1biQAoB5X9iYikgVbbIgU9MmQ9li87RR6NY9TOxQiIkNiYkOkoNAgfzyUlqx2GEREhsWuKCIiIjIMJjZERERkGExsiIiIyDCY2BAREZFhMLEhIiIiw2BiQ0RERIbBxIaIiIgMg4kNERERGQYTGyIiIjIMJjZERERkGExsiIiIyDCY2BAREZFhMLEhIiIiwzDc6t6CIAAACgsLVY6EiIiIxCr/3i7/HneX4RKbCxcuAAASExNVjoSIiIhcdeHCBYSHh7v9fJPgaWqkMWazGadPn0ZoaChMJpOk+y4sLERiYiKysrIQFhYm6b61wujnaPTzA3iORmH0czT6+QE8R1cJgoALFy4gPj4ePj7uj5QxXIuNj48PateuLesxwsLCDPsmLWf0czT6+QE8R6Mw+jka/fwAnqMrPGmpKcfBw0RERGQYTGyIiIjIMJjYuCAwMBCTJ09GYGCg2qHIxujnaPTzA3iORmH0czT6+QE8R7UYbvAwEREReS+22BAREZFhMLEhIiIiw2BiQ0RERIbBxIaIiIgMg4kNERERGQYTG5FmzpyJ5ORkBAUFITU1FZmZmWqHBACYMmUKOnTogNDQUMTExODOO+/EgQMHrLa5evUqRowYgZo1a6J69ero378/cnJyrLY5efIk+vbti2rVqiEmJgbjx49HaWmp1TZr1qxB27ZtERgYiAYNGmDu3LlV4pH7dZo6dSpMJhPGjBljqPM7deoUHnzwQdSsWRPBwcFo0aIFNm/ebPm9IAiYNGkSatWqheDgYKSnp+PQoUNW+8jLy8OgQYMQFhaGiIgIDBs2DBcvXrTaZufOnbjxxhsRFBSExMREvP3221Vi+fbbb5GSkoKgoCC0aNECS5Ys8fj8ysrK8PLLL6Nu3boIDg5G/fr18dprr1ktdqe3c/zjjz/Qr18/xMfHw2QyYfHixVa/19L5iInF1XMsKSnB888/jxYtWiAkJATx8fEYPHgwTp8+rZtzdPY3rOiJJ56AyWTC+++/r5vzE3uO+/btw+23347w8HCEhISgQ4cOOHnypOX3urvGCuTUggULhICAAGHOnDnCnj17hOHDhwsRERFCTk6O2qEJvXr1Ej777DNh9+7dwvbt24U+ffoISUlJwsWLFy3bPPHEE0JiYqKwcuVKYfPmzcINN9wgdOrUyfL70tJSoXnz5kJ6erqwbds2YcmSJUJUVJQwceJEyzZHjx4VqlWrJowbN07Yu3evMGPGDMHX11dYunSpZRu5X6fMzEwhOTlZaNmypTB69GjDnF9eXp5Qp04d4eGHHxY2btwoHD16VPj999+Fw4cPW7aZOnWqEB4eLixevFjYsWOHcPvttwt169YVrly5Ytmmd+/eQqtWrYS//vpL+PPPP4UGDRoI999/v+X3BQUFQmxsrDBo0CBh9+7dwtdffy0EBwcL//d//2fZZv369YKvr6/w9ttvC3v37hVeeuklwd/fX9i1a5dH5/jGG28INWvWFH755Rfh2LFjwrfffitUr15d+OCDD3R7jkuWLBFefPFFYdGiRQIA4YcffrD6vZbOR0wsrp5jfn6+kJ6eLixcuFDYv3+/kJGRIXTs2FFo166d1T60fI7O/oblFi1aJLRq1UqIj48X3nvvPd2cn5hzPHz4sBAZGSmMHz9e2Lp1q3D48GHhxx9/tLqu6e0ay8RGhI4dOwojRoyw/L+srEyIj48XpkyZomJUtuXm5goAhLVr1wqCcO3i4+/vL3z77beWbfbt2ycAEDIyMgRBuPbG9/HxEbKzsy3bfPTRR0JYWJhQVFQkCIIgPPfcc0KzZs2sjjVgwAChV69elv/L+TpduHBBaNiwobB8+XKhW7dulsTGCOf3/PPPC126dLH7e7PZLMTFxQnvvPOO5bH8/HwhMDBQ+PrrrwVBEIS9e/cKAIRNmzZZtvntt98Ek8kknDp1ShAEQfjwww+FGjVqWM65/NiNGze2/P++++4T+vbta3X81NRU4fHHH/foHPv27Ss88sgjVo/dfffdwqBBgwxxjpW/MLR0PmJiceccbcnMzBQACCdOnNDdOdo7v7///ltISEgQdu/eLdSpU8cqsdHT+dk7xwEDBggPPvig3efo8RrLrigniouLsWXLFqSnp1se8/HxQXp6OjIyMlSMzLaCggIAQGRkJABgy5YtKCkpsYo/JSUFSUlJlvgzMjLQokULxMbGWrbp1asXCgsLsWfPHss2FfdRvk35PuR+nUaMGIG+fftWicEI5/fTTz+hffv2uPfeexETE4M2bdrg448/tvz+2LFjyM7Otjp2eHg4UlNTrc4xIiIC7du3t2yTnp4OHx8fbNy40bJN165dERAQYHWOBw4cwD///CPqdXBXp06dsHLlShw8eBAAsGPHDqxbtw633nqrYc6xIi2dj5hYpFJQUACTyYSIiAhDnKPZbMZDDz2E8ePHo1mzZlV+b4Tz+/XXX9GoUSP06tULMTExSE1Ntequ0uM1lomNE+fOnUNZWZnVHwwAYmNjkZ2drVJUtpnNZowZMwadO3dG8+bNAQDZ2dkICAiwXGjKVYw/Ozvb5vmV/87RNoWFhbhy5Yqsr9OCBQuwdetWTJkypcrvjHB+R48exUcffYSGDRvi999/x5NPPolRo0bh888/t4rR0bGzs7MRExNj9Xs/Pz9ERkZK8jp4eo4TJkzAwIEDkZKSAn9/f7Rp0wZjxozBoEGDDHOOFWnpfMTEIoWrV6/i+eefx/33329Z5Vnv5/jWW2/Bz88Po0aNsvl7vZ9fbm4uLl68iKlTp6J3795YtmwZ7rrrLtx9991Yu3at5dh6u8b6ubQ1adqIESOwe/durFu3Tu1QJJOVlYXRo0dj+fLlCAoKUjscWZjNZrRv3x5vvvkmAKBNmzbYvXs3Zs2ahSFDhqgcnTS++eYbzJs3D/Pnz0ezZs2wfft2jBkzBvHx8YY5R29WUlKC++67D4Ig4KOPPlI7HEls2bIFH3zwAbZu3QqTyaR2OLIwm80AgDvuuANjx44FALRu3RobNmzArFmz0K1bNzXDcxtbbJyIioqCr69vlRHgOTk5iIuLUymqqkaOHIlffvkFq1evRu3atS2Px8XFobi4GPn5+VbbV4w/Li7O5vmV/87RNmFhYQgODpbtddqyZQtyc3PRtm1b+Pn5wc/PD2vXrsV///tf+Pn5ITY2VtfnBwC1atVC06ZNrR5r0qSJZVZC+f4dHTsuLg65ublWvy8tLUVeXp4kr4On5zh+/HhLq02LFi3w0EMPYezYsZZWOCOcY0VaOh8xsXiiPKk5ceIEli9fbmmtKT+2Xs/xzz//RG5uLpKSkizXnhMnTuCZZ55BcnKy7s8PuPb95ufn5/T6o7drLBMbJwICAtCuXTusXLnS8pjZbMbKlSuRlpamYmTXCIKAkSNH4ocffsCqVatQt25dq9+3a9cO/v7+VvEfOHAAJ0+etMSflpaGXbt2WX1Ayy9Q5W/4tLQ0q32Ub1O+D7lep549e2LXrl3Yvn275ad9+/YYNGiQ5d96Pj8A6Ny5c5Up+gcPHkSdOnUAAHXr1kVcXJzVsQsLC7Fx40arc8zPz8eWLVss26xatQpmsxmpqamWbf744w+UlJRYnWPjxo1Ro0YNUa+Duy5fvgwfH+vLja+vr+WO0QjnWJGWzkdMLO4qT2oOHTqEFStWoGbNmla/1/M5PvTQQ9i5c6fVtSc+Ph7jx4/H77//rvvzA65d1zp06ODw+qPL7xCXhhp7qQULFgiBgYHC3Llzhb179wqPPfaYEBERYTUCXC1PPvmkEB4eLqxZs0Y4c+aM5efy5cuWbZ544gkhKSlJWLVqlbB582YhLS1NSEtLs/y+fKreLbfcImzfvl1YunSpEB0dbXOq3vjx44V9+/YJM2fOtDlVT4nXqeKsKCOcX2ZmpuDn5ye88cYbwqFDh4R58+YJ1apVE7766ivLNlOnThUiIiKEH3/8Udi5c6dwxx132Jw63KZNG2Hjxo3CunXrhIYNG1pNO83PzxdiY2OFhx56SNi9e7ewYMECoVq1alWmnfr5+QnTpk0T9u3bJ0yePFmS6d5DhgwREhISLNO9Fy1aJERFRQnPPfecbs/xwoULwrZt24Rt27YJAITp06cL27Zts8wI0tL5iInF1XMsLi4Wbr/9dqF27drC9u3bra4/FWcAafkcnf0NK6s8K0rr5yfmHBctWiT4+/sLs2fPFg4dOmSZhv3nn39a9qG3aywTG5FmzJghJCUlCQEBAULHjh2Fv/76S+2QBEG4Nn3P1s9nn31m2ebKlSvCU089JdSoUUOoVq2acNdddwlnzpyx2s/x48eFW2+9VQgODhaioqKEZ555RigpKbHaZvXq1ULr1q2FgIAAoV69elbHKKfE61Q5sTHC+f38889C8+bNhcDAQCElJUWYPXu21e/NZrPw8ssvC7GxsUJgYKDQs2dP4cCBA1bbnD9/Xrj//vuF6tWrC2FhYcLQoUOFCxcuWG2zY8cOoUuXLkJgYKCQkJAgTJ06tUos33zzjdCoUSMhICBAaNasmfDrr796fH6FhYXC6NGjhaSkJCEoKEioV6+e8OKLL1p9AertHFevXm3zszdkyBDNnY+YWFw9x2PHjtm9/qxevVoX5+jsb1iZrcRGy+cn9hw//fRToUGDBkJQUJDQqlUrYfHixVb70Ns11iQIFUp/EhEREekYx9gQERGRYTCxISIiIsNgYkNERESGwcSGiIiIDIOJDRERERkGExsiIiIyDCY2REREZBhMbIiIiMgwmNgQERGRYTCxISIiIsNgYkNERESG8f+P+J5GecbvJgAAAABJRU5ErkJggg==\n" }, "metadata": {} } ], "source": [ "import matplotlib.pyplot as plt\n", "plt.figure(1)\n", "plt.title(\"Sig item\")\n", "plt.plot(dataset[0][\"signal\"])\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "id": "oL0MnsAyqet_" }, "source": [ "It can be seen that the `DynamicItemDataset` object returns the two specified items from the JSON annotation.\n", "\n", "The `file_path` item, is taken directly, as it is, from the JSON annotation without further processing.\n", "The other one is instead a new item derived from `file_path` item with the pipeline we have defined before." ] }, { "cell_type": "markdown", "metadata": { "id": "vk3vEoWHroqE" }, "source": [ "There is no constraints in what can be done in the pipelines: as said the user can also use their own functions:" ] }, { "cell_type": "code", "execution_count": 85, "metadata": { "id": "EKIlpL3zrnac" }, "outputs": [], "source": [ "import soundfile as sf\n", "@speechbrain.utils.data_pipeline.takes(\"file_path\")\n", "@speechbrain.utils.data_pipeline.provides(\"sig_numpy\")\n", "def audio_pipeline_numpy(file_path):\n", " sig, _ = sf.read(file_path, dtype=\"float32\")\n", " return sig" ] }, { "cell_type": "code", "execution_count": 86, "metadata": { "id": "Q89JrIT2t4IQ", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "eb237467-c893-459b-a56c-ffffd7f5be06" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'signal': tensor([ 0.0020, 0.0006, 0.0004, ..., -0.0033, -0.0034, -0.0029]),\n", " 'file_path': 'LibriSpeech/dev-clean-2/3576/138058/3576-138058-0019.flac',\n", " 'sig_numpy': array([ 0.00201416, 0.00061035, 0.00036621, ..., -0.00332642,\n", " -0.00335693, -0.00292969], dtype=float32)}" ] }, "metadata": {}, "execution_count": 86 } ], "source": [ "speechbrain.dataio.dataset.add_dynamic_item([dataset], audio_pipeline_numpy)\n", "speechbrain.dataio.dataset.set_output_keys(\n", " [dataset], [\"signal\", \"file_path\", \"sig_numpy\"],\n", " )\n", "dataset[0]" ] }, { "cell_type": "markdown", "metadata": { "id": "PkBvDF3IuFG_" }, "source": [ "The dataset object now also returns the signal as read with the soundfile library instead of only the one with read with the built-in speechbrain function which is based on torchaudio." ] }, { "cell_type": "markdown", "metadata": { "id": "j9W6Jseaua_m" }, "source": [ "**Multiple outputs can be specified by one pipeline by using python generators syntax**.\n", "\n", "In the example below three outputs are specified, the last two depend directly from the first one (sig) and are transformed version of this latter: with a random gain factor `rand_gain_sig` and with a constant offset `offset_sig`." ] }, { "cell_type": "code", "execution_count": 87, "metadata": { "id": "uiA8ccBevMMC", "colab": { "base_uri": "https://localhost:8080/", "height": 452 }, "outputId": "7836dc9f-9478-4ad9-af3f-eb11a8912891" }, "outputs": [ { "output_type": "display_data", "data": { "text/plain": [ "
" ], "image/png": "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\n" }, "metadata": {} } ], "source": [ "import random\n", "@speechbrain.utils.data_pipeline.takes(\"file_path\")\n", "@speechbrain.utils.data_pipeline.provides(\"sig\", \"rand_gain_sig\", \"offset_sig\")\n", "def audio_pipeline(file_path):\n", " sig = speechbrain.dataio.dataio.read_audio(file_path)\n", " yield sig\n", " rand_gain_sig = random.random()*sig\n", " yield rand_gain_sig\n", " offset_sig = sig + 1\n", " yield offset_sig\n", "\n", "\n", "speechbrain.dataio.dataset.add_dynamic_item([dataset], audio_pipeline)\n", "speechbrain.dataio.dataset.set_output_keys(\n", " [dataset], [\"sig\", \"rand_gain_sig\", \"offset_sig\"],\n", " )\n", "\n", "plt.figure(1)\n", "plt.title(\"Sig item\")\n", "plt.plot(dataset[0][\"sig\"])\n", "\n", "plt.title(\"Sig item with random gain\")\n", "plt.plot(dataset[0][\"rand_gain_sig\"])\n", "\n", "plt.title(\"Sig item offset\")\n", "plt.plot(dataset[0][\"offset_sig\"])\n", "plt.legend([\"sig\", \"rand_gain_sig\", \"offset_sig\"])\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "id": "7tzJSmbT7kT_" }, "source": [ "This toy example demonstrates that multiple items can be fetched from the same pipeline and dynamically created items can depend on other dynamically created items (`offset_sig` depends on `sig`)." ] }, { "cell_type": "markdown", "metadata": { "id": "et85McvM9Lhu" }, "source": [ "But dynamic items can also depend on dynamically created items from another, pre-specified pipeline:\n" ] }, { "cell_type": "code", "execution_count": 88, "metadata": { "id": "f0EYYxh670AI", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "84f82610-9a72-4d4e-a73a-cfe57db57951" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[0.00201416015625,\n", " 0.0006103515625,\n", " 0.0003662109375,\n", " 0.001129150390625,\n", " 0.000946044921875,\n", " 0.0001220703125,\n", " -0.000732421875,\n", " 0.00164794921875,\n", " 0.002685546875,\n", " 0.000457763671875]" ] }, "metadata": {}, "execution_count": 88 } ], "source": [ "@speechbrain.utils.data_pipeline.takes(\"sig\")\n", "@speechbrain.utils.data_pipeline.provides(\"sig_as_python_list\")\n", "def to_list_pipeline(sig):\n", " yield sig.numpy().tolist()\n", "\n", "\n", "speechbrain.dataio.dataset.add_dynamic_item([dataset], to_list_pipeline)\n", "speechbrain.dataio.dataset.set_output_keys(\n", " [dataset], [\"sig_as_python_list\"],\n", " )\n", "dataset[0][\"sig_as_python_list\"][:10]" ] }, { "cell_type": "markdown", "metadata": { "id": "HcTAPOk_-mOP" }, "source": [ "In this example we have defined a new pipeline which takes `sig` and turns it from `torch.tensor` to a python list obtaining a new dynamic item `sig_as_python_list`.\n", "\n", "\n", "**NOTE**\n", "\n", "\n", "Since we are requesting in the output only `sig_as_python_list` which depends itself from `sig`, dynamic items `offset_sig` and `rand_gain_sig` are not computed at all. Only `sig` is computed implicitly as it is necessary to obtain `sig_as_python_list`.\n", "\n", "\n", "In fact under the hood `DynamicItemDataset` finds a suitable evaluation\n", "order for the requested items by constructing a **computational graph** defined by the **pipelines**.\n", "\n", "**An error is returned if any circular dependency is present between the pipelines**.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "eFLiGm6xh3tZ" }, "source": [ "A **DIP** can also take multiple items/annotation keys in input, the syntax is the same as for the output items:" ] }, { "cell_type": "code", "execution_count": 89, "metadata": { "id": "HH9WhV1ih28l", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "9acd2f96-aee4-4d7c-cfde-48a2e837dfaf" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'sig': tensor([ 0.0020, 0.0006, 0.0004, ..., -0.0033, -0.0034, -0.0029]),\n", " 'spkidstring': 3576}" ] }, "metadata": {}, "execution_count": 89 } ], "source": [ "@speechbrain.utils.data_pipeline.takes(\"file_path\", \"spkID\")\n", "@speechbrain.utils.data_pipeline.provides(\"sig\", \"spkidstring\")\n", "def multiple_dip(file_path, spkID):\n", " sig = speechbrain.dataio.dataio.read_audio(file_path)\n", " yield sig\n", " yield spkID\n", "\n", "speechbrain.dataio.dataset.add_dynamic_item([dataset], multiple_dip)\n", "speechbrain.dataio.dataset.set_output_keys(\n", " [dataset], [\"sig\", \"spkidstring\"],\n", " )\n", "dataset[0]" ] }, { "cell_type": "code", "execution_count": 90, "metadata": { "id": "YPN3AXaVjQka", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "0e6e9be7-d8dc-4e24-9906-30f0d8db62a4" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'sig_tuple': (tensor([ 0.0020, 0.0006, 0.0004, ..., -0.0033, -0.0034, -0.0029]),\n", " 3576)}" ] }, "metadata": {}, "execution_count": 90 } ], "source": [ "@speechbrain.utils.data_pipeline.takes(\"file_path\", \"spkID\")\n", "@speechbrain.utils.data_pipeline.provides(\"sig_tuple\")\n", "def multiple_dip(file_path, spkID):\n", " sig = speechbrain.dataio.dataio.read_audio(file_path)\n", " yield sig, spkID\n", "\n", "\n", "speechbrain.dataio.dataset.add_dynamic_item([dataset], multiple_dip)\n", "speechbrain.dataio.dataset.set_output_keys(\n", " [dataset], [\"sig_tuple\"],\n", " )\n", "dataset[0] # sig now is a tuple" ] }, { "cell_type": "markdown", "metadata": { "id": "uXKHONsvTDTs" }, "source": [ "And also the same **DIP** can be used in multiple datasets.\n", "E.g. you want usually the read audio **DIP** to be the same for validation, training and test:" ] }, { "cell_type": "code", "execution_count": 91, "metadata": { "id": "wGLev2Q1U534", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "36abdd93-2c15-4c80-ffd9-3c17c48d7711" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'id': '3576-138058-0019',\n", " 'signal': tensor([ 0.0020, 0.0006, 0.0004, ..., -0.0033, -0.0034, -0.0029]),\n", " 'words': 'GIVE ME MY HORSE AND ARMS AND WAIT FOR ME HERE I WILL GO IN QUEST OF THIS KNIGHT AND DEAD OR ALIVE I WILL MAKE HIM KEEP HIS WORD PLIGHTED TO SO GREAT BEAUTY'}" ] }, "metadata": {}, "execution_count": 91 } ], "source": [ "validation = DynamicItemDataset.from_json(\"data.json\")\n", "train = DynamicItemDataset.from_json(\"data.json\")\n", "\n", "speechbrain.dataio.dataset.add_dynamic_item([validation, train], speechbrain.dataio.dataio.read_audio, takes=\"file_path\", provides=\"signal\")\n", "speechbrain.dataio.dataset.set_output_keys([validation, train], [\"id\", \"signal\", \"words\"])\n", "validation[0]\n" ] }, { "cell_type": "code", "execution_count": 92, "metadata": { "id": "JVrWPCG1VZ_t", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "72000543-9158-4570-97d6-87402a6d388c" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'id': '3576-138058-0019',\n", " 'signal': tensor([ 0.0020, 0.0006, 0.0004, ..., -0.0033, -0.0034, -0.0029]),\n", " 'words': 'GIVE ME MY HORSE AND ARMS AND WAIT FOR ME HERE I WILL GO IN QUEST OF THIS KNIGHT AND DEAD OR ALIVE I WILL MAKE HIM KEEP HIS WORD PLIGHTED TO SO GREAT BEAUTY'}" ] }, "metadata": {}, "execution_count": 92 } ], "source": [ "train[0]" ] }, { "cell_type": "markdown", "metadata": { "id": "Ihy-XYoDNWMg" }, "source": [ "#### Cached pipeline\n", "One last thing you can do with pipelines is to cache the result if the computation is expensive and static. For example, if you are using frozen deep embeddings, these may be a good candidate for caching. Here, we simply cache the feature extraction, although it doesn't add much time to the overall pipeline." ] }, { "cell_type": "code", "execution_count": 93, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "IOCmOZTyNWMg", "outputId": "2b61f905-65c6-416a-8ea6-50ff1fcfe1f3" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "3576-138058-0019 torch.Size([994, 40])\n", "3576-138058-0021 torch.Size([619, 40])\n" ] } ], "source": [ "filterbank = speechbrain.lobes.features.Fbank()\n", "\n", "# Must take \"id\" for storing and retrieving from the cache\n", "@speechbrain.utils.data_pipeline.CachedDynamicItem.cache(\"feature_cache\")\n", "@speechbrain.utils.data_pipeline.takes(\"id\", \"sig\")\n", "@speechbrain.utils.data_pipeline.provides(\"feats\")\n", "def feature_pipeline(uid, sig):\n", " # Fake batch dimension -- data items are singular\n", " return filterbank(sig.unsqueeze(0)).squeeze(0)\n", "\n", "speechbrain.dataio.dataset.add_dynamic_item([dataset], feature_pipeline)\n", "speechbrain.dataio.dataset.set_output_keys([dataset], [\"id\", \"feats\"])\n", "print(dataset[0][\"id\"], dataset[0][\"feats\"].shape)\n", "print(dataset[1][\"id\"], dataset[1][\"feats\"].shape)" ] }, { "cell_type": "markdown", "metadata": { "id": "QLvUzBGtNWMg" }, "source": [ "The results of the dynamic items are stored in torch format, one file per uid:" ] }, { "cell_type": "code", "execution_count": 94, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "2y4-8bJLNWMg", "outputId": "8ca40891-98d9-4d31-e356-a64eeef19fb6" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "['5694-64038-0005.pt', '1988-24833-0004.pt', '6295-244435-0018.pt', '5895-34622-0014.pt', '3576-138058-0001.pt', '1988-24833-0025.pt', '5895-34629-0025.pt', '2803-154320-0005.pt', '5338-284437-0006.pt', '1462-170145-0019.pt', '6295-244435-0040.pt', '7850-281318-0007.pt', '5338-284437-0025.pt', '2803-161169-0005.pt', '5895-34629-0001.pt', '5895-34615-0014.pt', '777-126732-0019.pt', '8297-275156-0010.pt', '251-136532-0003.pt', '2412-153948-0013.pt', '5895-34622-0022.pt', '1462-170145-0016.pt', '1272-135031-0019.pt', '2803-154320-0013.pt', '5338-284437-0009.pt', '6319-57405-0012.pt', '8842-304647-0002.pt', '3752-4944-0054.pt', '3536-23268-0008.pt', '6241-61946-0019.pt', '7976-110523-0013.pt', '2803-154320-0000.pt', '7976-110523-0006.pt', '3752-4944-0011.pt', '3752-4944-0038.pt', '5338-284437-0004.pt', '777-126732-0057.pt', '3536-23268-0000.pt', '1462-170142-0028.pt', '3752-4944-0039.pt', '1988-147956-0007.pt', '1988-24833-0028.pt', '251-118436-0018.pt', '2428-83699-0028.pt', '3576-138058-0035.pt', '1988-24833-0008.pt', '5895-34629-0002.pt', '3536-23268-0022.pt', '2428-83699-0041.pt', '3000-15664-0035.pt', '2428-83699-0023.pt', '3000-15664-0024.pt', '6295-244435-0000.pt', '6241-61946-0021.pt', '2035-147961-0002.pt', '7850-281318-0011.pt', '2412-153948-0015.pt', '1272-135031-0001.pt', '777-126732-0039.pt', '1462-170145-0005.pt', '5895-34629-0019.pt', '2428-83699-0024.pt', '2035-152373-0007.pt', '777-126732-0066.pt', '7850-286674-0012.pt', '3752-4944-0006.pt', '777-126732-0073.pt', '1272-141231-0010.pt', '2035-147961-0021.pt', '84-121550-0032.pt', '7976-110523-0003.pt', '84-121550-0001.pt', '174-168635-0007.pt', '1272-141231-0022.pt', '2412-153948-0000.pt', '3536-23268-0023.pt', '8842-304647-0005.pt', '2803-161169-0009.pt', '5895-34629-0030.pt', '2035-147960-0001.pt', '6319-57405-0000.pt', '3000-15664-0023.pt', '2428-83699-0029.pt', '8297-275156-0009.pt', '777-126732-0058.pt', '7850-286674-0017.pt', '1272-135031-0009.pt', '5895-34622-0020.pt', '7976-110523-0018.pt', '3576-138058-0028.pt', '2428-83699-0042.pt', '3536-23268-0025.pt', '8297-275156-0006.pt', '777-126732-0063.pt', '1988-24833-0007.pt', '5338-24640-0001.pt', '777-126732-0023.pt', '1462-170142-0006.pt', '2428-83699-0001.pt', '6241-61946-0001.pt', '174-168635-0012.pt', '251-118436-0014.pt', '6295-244435-0033.pt', '3752-4944-0004.pt', '251-136532-0006.pt', '777-126732-0070.pt', '5895-34622-0017.pt', '1988-24833-0024.pt', '3576-138058-0014.pt', '1462-170142-0010.pt', '1993-147964-0004.pt', '2035-147960-0016.pt', '84-121550-0014.pt', '1988-147956-0018.pt', '2035-152373-0014.pt', '6241-61943-0005.pt', '1272-141231-0028.pt', '5895-34615-0015.pt', '3536-23268-0005.pt', '1462-170142-0041.pt', '777-126732-0022.pt', '3576-138058-0036.pt', '1462-170145-0010.pt', '6295-244435-0010.pt', '1462-170142-0011.pt', '3000-15664-0009.pt', '1462-170145-0021.pt', '7850-281318-0019.pt', '3000-15664-0014.pt', '3752-4944-0002.pt', '3576-138058-0022.pt', '5338-24640-0007.pt', '3576-138058-0017.pt', '3000-15664-0031.pt', '3752-4944-0040.pt', '777-126732-0055.pt', '6241-61946-0012.pt', '2803-161169-0002.pt', '7850-281318-0014.pt', '2035-152373-0002.pt', '5694-64038-0000.pt', '5694-64038-0002.pt', '6241-61946-0008.pt', '7850-286674-0007.pt', '84-121550-0012.pt', '1988-24833-0002.pt', '2803-154320-0011.pt', '5895-34622-0023.pt', '251-136532-0022.pt', '2428-83699-0010.pt', '5895-34622-0003.pt', '7850-286674-0003.pt', '5694-64038-0011.pt', '5694-64038-0016.pt', '3536-23268-0024.pt', '3576-138058-0024.pt', '6241-61943-0027.pt', '1462-170142-0005.pt', '6319-57405-0004.pt', '1988-147956-0004.pt', '5338-284437-0029.pt', '1988-147956-0006.pt', '1462-170142-0000.pt', '3000-15664-0029.pt', '84-121550-0003.pt', '777-126732-0048.pt', '1993-147964-0005.pt', '5895-34622-0004.pt', '5895-34629-0013.pt', '7850-281318-0016.pt', '777-126732-0021.pt', '3536-23268-0002.pt', '6295-244435-0034.pt', '8842-304647-0013.pt', '3752-4944-0059.pt', '5338-284437-0020.pt', '1462-170142-0001.pt', '1988-24833-0013.pt', '6295-244435-0012.pt', '1272-141231-0018.pt', '6241-61943-0002.pt', '3752-4944-0056.pt', '251-136532-0014.pt', '2428-83699-0005.pt', '7976-110523-0005.pt', '8297-275156-0007.pt', '1988-24833-0019.pt', '1462-170142-0026.pt', '3000-15664-0022.pt', '8842-304647-0012.pt', '7850-281318-0006.pt', '3752-4944-0013.pt', '1988-147956-0020.pt', '5338-284437-0010.pt', '1988-24833-0014.pt', '251-136532-0023.pt', '3000-15664-0034.pt', '84-121550-0018.pt', '6295-244435-0038.pt', '174-168635-0000.pt', '5895-34629-0024.pt', '2803-161169-0010.pt', '1272-135031-0008.pt', '7976-110523-0014.pt', '2803-154320-0006.pt', '1993-147964-0007.pt', '2035-147961-0010.pt', '3576-138058-0009.pt', '2035-147961-0014.pt', '6241-61943-0023.pt', '5895-34615-0021.pt', '251-136532-0005.pt', '1272-141231-0009.pt', '3536-23268-0009.pt', '2428-83699-0004.pt', '3576-138058-0016.pt', '7976-110523-0010.pt', '84-121550-0010.pt', '1462-170142-0025.pt', '1462-170142-0029.pt', '5694-64038-0021.pt', '2428-83699-0032.pt', '3752-4944-0025.pt', '2035-147961-0016.pt', '3752-4944-0010.pt', '251-136532-0018.pt', '251-136532-0013.pt', '5338-24640-0005.pt', '2803-154320-0001.pt', '1988-147956-0014.pt', '777-126732-0046.pt', '2803-154320-0007.pt', '1272-141231-0000.pt', '1993-147964-0006.pt', '3752-4944-0052.pt', '1462-170142-0018.pt', '3000-15664-0025.pt', '1993-147964-0009.pt', '5338-284437-0003.pt', '2035-147961-0039.pt', '3000-15664-0033.pt', '1272-135031-0021.pt', '1462-170142-0004.pt', '3752-4944-0036.pt', '5895-34629-0026.pt', '777-126732-0027.pt', '6241-61943-0007.pt', '3752-4944-0065.pt', '5338-284437-0014.pt', '3536-23268-0001.pt', '3752-4944-0050.pt', '3752-4944-0034.pt', '2035-147961-0007.pt', '3000-15664-0013.pt', '5895-34622-0000.pt', '1272-135031-0018.pt', '777-126732-0031.pt', '3000-15664-0045.pt', '1462-170145-0007.pt', '3576-138058-0007.pt', '2035-147961-0023.pt', '6295-244435-0011.pt', '5338-284437-0024.pt', '2803-154320-0004.pt', '3752-4944-0017.pt', '174-168635-0014.pt', '6241-61943-0011.pt', '5694-64038-0025.pt', '2803-161169-0004.pt', '6295-244435-0023.pt', '5895-34615-0001.pt', '1462-170142-0008.pt', '1993-147964-0010.pt', '3576-138058-0025.pt', '7976-110523-0001.pt', '7850-286674-0016.pt', '3576-138058-0015.pt', '5694-64038-0001.pt', '777-126732-0047.pt', '174-168635-0010.pt', '3752-4944-0005.pt', '1988-24833-0022.pt', '1462-170145-0011.pt', '5895-34629-0022.pt', '1272-141231-0019.pt', '5895-34615-0003.pt', '7850-286674-0006.pt', '7850-281318-0001.pt', '174-168635-0002.pt', '1462-170142-0022.pt', '8297-275156-0000.pt', '6241-61946-0000.pt', '3000-15664-0030.pt', '5895-34615-0004.pt', '2803-161169-0017.pt', '2428-83699-0036.pt', '777-126732-0061.pt', '2428-83699-0008.pt', '2412-153948-0012.pt', '2428-83699-0021.pt', '2035-152373-0016.pt', '5338-24640-0004.pt', '7850-281318-0023.pt', '2035-147961-0036.pt', '2412-153948-0002.pt', '7976-110523-0009.pt', '2803-161169-0013.pt', '2035-152373-0015.pt', '5694-64038-0003.pt', '2035-147961-0038.pt', '3576-138058-0018.pt', '1462-170145-0022.pt', '6241-61946-0011.pt', '251-118436-0023.pt', '777-126732-0081.pt', '2035-147960-0015.pt', '6241-61946-0007.pt', '2803-161169-0011.pt', '2035-152373-0000.pt', '777-126732-0005.pt', '251-136532-0017.pt', '777-126732-0053.pt', '174-168635-0011.pt', '777-126732-0051.pt', '3536-23268-0014.pt', '2035-147961-0027.pt', '5895-34629-0005.pt', '6295-244435-0026.pt', '3000-15664-0002.pt', '251-136532-0015.pt', '2428-83699-0006.pt', '3752-4944-0026.pt', '1272-141231-0027.pt', '7850-286674-0002.pt', '1272-135031-0005.pt', '5895-34629-0015.pt', '7850-286674-0005.pt', '2035-147960-0006.pt', '6295-244435-0013.pt', '3000-15664-0010.pt', '2035-152373-0001.pt', '5895-34629-0009.pt', '2035-147960-0000.pt', '7976-110523-0002.pt', '3576-138058-0012.pt', '1272-135031-0016.pt', '251-118436-0000.pt', '1462-170142-0017.pt', '8842-304647-0004.pt', '174-168635-0022.pt', '6241-61946-0010.pt', '5338-284437-0015.pt', '777-126732-0062.pt', '8842-304647-0010.pt', '1462-170142-0002.pt', '777-126732-0012.pt', '2428-83699-0009.pt', '2035-147960-0010.pt', '3752-4944-0001.pt', '2428-83699-0000.pt', '2803-154320-0012.pt', '2803-154320-0002.pt', '3576-138058-0003.pt', '3752-4944-0061.pt', '3000-15664-0038.pt', '1272-141231-0013.pt', '7976-110523-0004.pt', '1462-170145-0015.pt', '5338-284437-0011.pt', '5895-34629-0027.pt', '1462-170142-0032.pt', '2035-147961-0013.pt', '1462-170145-0018.pt', '777-126732-0052.pt', '8297-275156-0003.pt', '8842-304647-0001.pt', '6241-61943-0008.pt', '5338-284437-0018.pt', '84-121550-0004.pt', '3536-23268-0013.pt', '2803-161169-0015.pt', '3576-138058-0011.pt', '6295-244435-0002.pt', '6241-61943-0012.pt', '1462-170142-0033.pt', '2035-147960-0009.pt', '6295-244435-0039.pt', '6241-61946-0020.pt', '2035-147961-0015.pt', '3752-4944-0067.pt', '84-121550-0020.pt', '3576-138058-0010.pt', '174-168635-0020.pt', '6295-244435-0024.pt', '3536-23268-0029.pt', '3752-4944-0000.pt', '251-118436-0003.pt', '3752-4944-0043.pt', '174-168635-0018.pt', '6295-244435-0025.pt', '84-121550-0028.pt', '777-126732-0028.pt', '777-126732-0038.pt', '5338-284437-0012.pt', '5338-284437-0032.pt', '777-126732-0060.pt', '6295-244435-0019.pt', '3000-15664-0015.pt', '2035-152373-0003.pt', '6241-61943-0016.pt', '251-118436-0010.pt', '6295-244435-0016.pt', '2035-147961-0020.pt', '6295-244435-0005.pt', '2428-83699-0034.pt', '777-126732-0045.pt', '3536-23268-0018.pt', '1272-141231-0004.pt', '777-126732-0030.pt', '2035-152373-0005.pt', '5338-284437-0002.pt', '1272-135031-0013.pt', '1462-170142-0009.pt', '6241-61946-0004.pt', '2035-152373-0006.pt', '84-121550-0025.pt', '5895-34615-0007.pt', '1988-147956-0017.pt', '2428-83699-0035.pt', '777-126732-0068.pt', '2035-152373-0017.pt', '5338-24640-0009.pt', '1988-147956-0021.pt', '3752-4944-0069.pt', '174-168635-0009.pt', '6295-244435-0030.pt', '6319-57405-0007.pt', '251-136532-0020.pt', '5895-34629-0000.pt', '84-121550-0033.pt', '1988-24833-0020.pt', '3752-4944-0016.pt', '5694-64038-0012.pt', '2035-147960-0004.pt', '6241-61946-0005.pt', '2035-147961-0005.pt', '1462-170142-0016.pt', '84-121550-0026.pt', '7850-286674-0000.pt', '251-136532-0007.pt', '6295-244435-0009.pt', '1988-147956-0012.pt', '2428-83699-0019.pt', '2428-83699-0016.pt', '3576-138058-0020.pt', '5895-34615-0010.pt', '84-121550-0008.pt', '251-118436-0009.pt', '1462-170142-0040.pt', '2035-152373-0010.pt', '7976-110523-0008.pt', '251-118436-0013.pt', '251-118436-0017.pt', '174-168635-0019.pt', '1993-147964-0003.pt', '777-126732-0067.pt', '1988-147956-0015.pt', '6241-61946-0006.pt', '8842-304647-0003.pt', '251-118436-0011.pt', '5895-34629-0031.pt', '5694-64038-0004.pt', '5694-64038-0008.pt', '1462-170142-0031.pt', '1272-141231-0021.pt', '6241-61943-0006.pt', '5895-34615-0017.pt', '1272-135031-0000.pt', '6295-244435-0032.pt', '3000-15664-0018.pt', '6241-61943-0026.pt', '5338-284437-0000.pt', '5895-34622-0009.pt', '2035-147961-0011.pt', '1988-24833-0003.pt', '2412-153948-0003.pt', '1462-170142-0020.pt', '5895-34622-0006.pt', '5895-34622-0016.pt', '6241-61943-0025.pt', '1272-141231-0003.pt', '5895-34629-0006.pt', '3536-23268-0012.pt', '1988-24833-0011.pt', '6319-57405-0011.pt', '3536-23268-0010.pt', '777-126732-0026.pt', '5895-34629-0029.pt', '3576-138058-0027.pt', '1272-141231-0023.pt', '8842-304647-0007.pt', '6241-61943-0022.pt', '5895-34615-0006.pt', '251-118436-0004.pt', '251-136532-0000.pt', '6241-61946-0014.pt', '777-126732-0075.pt', '1272-141231-0017.pt', '5895-34615-0016.pt', '3576-138058-0019.pt', '2428-83699-0012.pt', '1462-170142-0012.pt', '3752-4944-0048.pt', '84-121550-0002.pt', '6241-61943-0015.pt', '3000-15664-0046.pt', '3752-4944-0062.pt', '2803-161169-0012.pt', '3000-15664-0008.pt', '251-118436-0021.pt', '777-126732-0059.pt', '8842-304647-0008.pt', '5895-34615-0002.pt', '6319-57405-0010.pt', '5895-34622-0002.pt', '1993-147964-0001.pt', '2412-153948-0014.pt', '3000-15664-0012.pt', '7976-110523-0015.pt', '2428-83699-0013.pt', '6241-61946-0018.pt', '6295-244435-0020.pt', '6295-244435-0035.pt', '5338-284437-0022.pt', '1462-170142-0023.pt', '251-136532-0012.pt', '777-126732-0037.pt', '1462-170142-0034.pt', '8297-275156-0004.pt', '777-126732-0016.pt', '6241-61943-0004.pt', '1462-170142-0019.pt', '1272-141231-0026.pt', '5895-34615-0011.pt', '5895-34629-0021.pt', '2428-83699-0003.pt', '1272-135031-0012.pt', '3000-15664-0037.pt', '2035-147961-0012.pt', '7850-281318-0021.pt', '5895-34629-0010.pt', '84-121550-0035.pt', '7850-286674-0011.pt', '1988-147956-0008.pt', '7976-110523-0017.pt', '8297-275156-0013.pt', '2412-153948-0008.pt', '5694-64038-0006.pt', '3536-23268-0006.pt', '2803-154320-0003.pt', '777-126732-0069.pt', '1272-135031-0024.pt', '7976-110523-0011.pt', '2803-161169-0003.pt', '777-126732-0034.pt', '5895-34622-0012.pt', '6295-244435-0007.pt', '2035-147961-0008.pt', '84-121550-0015.pt', '1272-141231-0016.pt', '6241-61946-0009.pt', '2035-147961-0034.pt', '251-118436-0008.pt', '3536-23268-0030.pt', '3752-4944-0046.pt', '6241-61946-0002.pt', '1988-147956-0029.pt', '777-126732-0014.pt', '1272-141231-0030.pt', '5338-284437-0030.pt', '1272-141231-0031.pt', '777-126732-0024.pt', '7850-286674-0010.pt', '3576-138058-0021.pt', '3576-138058-0008.pt', '777-126732-0079.pt', '6241-61946-0003.pt', '174-168635-0008.pt', '5895-34615-0005.pt', '3752-4944-0051.pt', '251-136532-0002.pt', '2035-147961-0019.pt', '1988-24833-0018.pt', '7850-281318-0008.pt', '3752-4944-0057.pt', '6295-244435-0037.pt', '3752-4944-0031.pt', '5338-284437-0026.pt', '1988-24833-0006.pt', '5895-34629-0028.pt', '251-136532-0019.pt', '3752-4944-0018.pt', '777-126732-0008.pt', '174-168635-0004.pt', '1272-135031-0003.pt', '8297-275156-0011.pt', '251-136532-0016.pt', '2035-147960-0013.pt', '777-126732-0040.pt', '1988-24833-0026.pt', '3536-23268-0028.pt', '1462-170145-0000.pt', '2428-83699-0033.pt', '3576-138058-0031.pt', '2428-83699-0037.pt', '1462-170145-0009.pt', '3536-23268-0027.pt', '1988-24833-0023.pt', '8842-304647-0009.pt', '7850-281318-0018.pt', '3752-4944-0041.pt', '2035-147961-0009.pt', '1988-147956-0001.pt', '5895-34629-0020.pt', '2428-83699-0026.pt', '5338-284437-0027.pt', '3576-138058-0029.pt', '5895-34629-0007.pt', '3576-138058-0033.pt', '3576-138058-0034.pt', '3000-15664-0042.pt', '84-121550-0006.pt', '7976-110523-0007.pt', '5694-64038-0010.pt', '777-126732-0015.pt', '5895-34622-0011.pt', '1272-141231-0007.pt', '84-121550-0034.pt', '5338-24640-0002.pt', '2412-153948-0001.pt', '5338-284437-0023.pt', '6295-244435-0031.pt', '6241-61943-0021.pt', '251-136532-0008.pt', '5338-284437-0031.pt', '84-121550-0013.pt', '3536-23268-0016.pt', '3752-4944-0035.pt', '777-126732-0054.pt', '2428-83699-0015.pt', '84-121550-0023.pt', '6295-244435-0001.pt', '7850-286674-0009.pt', '3576-138058-0013.pt', '1462-170142-0036.pt', '777-126732-0001.pt', '6241-61943-0000.pt', '3536-23268-0003.pt', '1988-147956-0028.pt', '1272-141231-0014.pt', '7850-286674-0014.pt', '84-121550-0021.pt', '6241-61946-0023.pt', '2035-147960-0007.pt', '5338-284437-0021.pt', '84-121550-0029.pt', '2035-147961-0017.pt', '7850-281318-0017.pt', '5895-34622-0013.pt', '84-121550-0009.pt', '1272-135031-0014.pt', '8842-304647-0000.pt', '1988-147956-0025.pt', '5694-64038-0009.pt', '1988-147956-0002.pt', '5895-34615-0019.pt', '3752-4944-0022.pt', '2428-83699-0025.pt', '777-126732-0010.pt', '2035-152373-0018.pt', '7850-281318-0005.pt', '3752-4944-0003.pt', '2412-153948-0005.pt', '6241-61943-0024.pt', '2803-154320-0010.pt', '1272-141231-0005.pt', '84-121550-0027.pt', '3000-15664-0027.pt', '777-126732-0076.pt', '1272-135031-0022.pt', '1272-135031-0020.pt', '5895-34622-0010.pt', '5895-34629-0004.pt', '3000-15664-0040.pt', '1272-135031-0011.pt', '3752-4944-0045.pt', '5694-64038-0023.pt', '777-126732-0013.pt', '3000-15664-0016.pt', '777-126732-0000.pt', '6241-61946-0015.pt', '2412-153948-0007.pt', '5895-34622-0008.pt', '1272-141231-0032.pt', '2035-152373-0013.pt', '6319-57405-0005.pt', '2428-83699-0027.pt', '3000-15664-0006.pt', '2035-147960-0012.pt', '2428-83699-0039.pt', '8297-275156-0002.pt', '2428-83699-0020.pt', '1462-170145-0004.pt', '251-118436-0015.pt', '1272-135031-0007.pt', '5694-64038-0007.pt', '6241-61943-0017.pt', '5895-34615-0012.pt', '3752-4944-0066.pt', '84-121550-0030.pt', '251-118436-0019.pt', '3752-4944-0033.pt', '777-126732-0049.pt', '5895-34615-0018.pt', '5895-34622-0021.pt', '3752-4944-0023.pt', '5895-34629-0018.pt', '777-126732-0071.pt', '1272-141231-0008.pt', '3752-4944-0015.pt', '777-126732-0011.pt', '777-126732-0020.pt', '2803-161169-0007.pt', '3576-138058-0004.pt', '3000-15664-0011.pt', '2035-147961-0006.pt', '174-168635-0021.pt', '2803-154320-0014.pt', '777-126732-0035.pt', '3000-15664-0026.pt', '2803-161169-0000.pt', '6241-61943-0003.pt', '3752-4944-0053.pt', '2035-147961-0030.pt', '6295-244435-0008.pt', '5694-64038-0013.pt', '1462-170142-0039.pt', '3752-4944-0029.pt', '7850-281318-0003.pt', '6241-61943-0013.pt', '5694-64038-0022.pt', '5895-34615-0020.pt', '3576-138058-0037.pt', '2803-161169-0008.pt', '777-126732-0042.pt', '84-121550-0000.pt', '3000-15664-0021.pt', '5338-284437-0033.pt', '1272-135031-0017.pt', '6241-61943-0019.pt', '3752-4944-0007.pt', '5694-64038-0024.pt', '6241-61946-0022.pt', '1462-170142-0015.pt', '8297-275156-0008.pt', '3752-4944-0027.pt', '1462-170142-0038.pt', '5694-64038-0017.pt', '1988-24833-0021.pt', '84-121550-0016.pt', '777-126732-0074.pt', '5338-24640-0003.pt', '2428-83699-0018.pt', '777-126732-0004.pt', '2035-147961-0040.pt', '5895-34629-0032.pt', '3000-15664-0032.pt', '6241-61943-0001.pt', '777-126732-0032.pt', '251-118436-0005.pt', '3000-15664-0036.pt', '777-126732-0018.pt', '2428-83699-0014.pt', '6241-61946-0013.pt', '7850-281318-0009.pt', '5895-34622-0001.pt', '777-126732-0056.pt', '2035-147960-0014.pt', '6295-244435-0036.pt', '777-126732-0078.pt', '251-136532-0001.pt', '6319-57405-0003.pt', '6295-244435-0006.pt', '251-136532-0010.pt', '2428-83699-0011.pt', '7850-286674-0008.pt', '1272-141231-0025.pt', '3576-138058-0000.pt', '5895-34615-0008.pt', '3752-4944-0021.pt', '251-118436-0012.pt', '1462-170142-0013.pt', '5895-34629-0016.pt', '1988-147956-0009.pt', '5694-64038-0019.pt', '84-121550-0007.pt', '6241-61946-0016.pt', '3576-138058-0030.pt', '8842-304647-0006.pt', '1993-147964-0000.pt', '2035-147961-0001.pt', '251-118436-0016.pt', '1462-170145-0013.pt', '5338-284437-0017.pt', '6319-57405-0001.pt', '1272-141231-0020.pt', '6295-244435-0022.pt', '1988-147956-0000.pt', '777-126732-0033.pt', '1988-147956-0003.pt', '7850-281318-0000.pt', '2412-153948-0004.pt', '1988-147956-0023.pt', '8297-275156-0005.pt', '1462-170145-0008.pt', '1272-141231-0001.pt', '1272-135031-0010.pt', '6295-244435-0003.pt', '251-136532-0004.pt', '5895-34629-0014.pt', '3752-4944-0014.pt', '5895-34629-0012.pt', '7850-281318-0012.pt', '777-126732-0065.pt', '1462-170142-0024.pt', '3536-23268-0026.pt', '1988-147956-0005.pt', '7976-110523-0000.pt', '174-168635-0006.pt', '1988-24833-0016.pt', '1272-141231-0015.pt', '1462-170145-0020.pt', '3752-4944-0020.pt', '2803-161169-0016.pt', '777-126732-0044.pt', '1988-147956-0011.pt', '174-168635-0003.pt', '5694-64038-0018.pt', '2035-147960-0003.pt', '5895-34615-0009.pt', '3536-23268-0015.pt', '3752-4944-0030.pt', '3752-4944-0009.pt', '7976-110523-0021.pt', '174-168635-0015.pt', '7850-281318-0015.pt', '7850-281318-0022.pt', '5895-34629-0023.pt', '7976-110523-0020.pt', '6295-244435-0028.pt', '3536-23268-0019.pt', '777-126732-0041.pt', '3000-15664-0007.pt', '251-118436-0020.pt', '777-126732-0064.pt', '2412-153948-0011.pt', '5895-34622-0007.pt', '5338-284437-0016.pt', '2035-147960-0005.pt', '7850-286674-0013.pt', '3752-4944-0068.pt', '3752-4944-0019.pt', '2428-83699-0022.pt', '1988-147956-0019.pt', '1462-170145-0003.pt', '174-168635-0013.pt', '3536-23268-0020.pt', '3576-138058-0006.pt', '3752-4944-0008.pt', '3576-138058-0002.pt', '1988-147956-0010.pt', '5895-34629-0017.pt', '1462-170142-0037.pt', '1272-141231-0002.pt', '1988-24833-0010.pt', '777-126732-0002.pt', '2428-83699-0038.pt', '2035-147961-0037.pt', '1462-170145-0017.pt', '3000-15664-0005.pt', '7850-281318-0013.pt', '7850-281318-0020.pt', '7850-281318-0002.pt', '5694-64038-0014.pt', '2035-147960-0011.pt', '84-121550-0019.pt', '3752-4944-0037.pt', '5895-34629-0011.pt', '3752-4944-0044.pt', '1988-24833-0001.pt', '3752-4944-0055.pt', '2412-153948-0006.pt', '1462-170142-0027.pt', '1272-141231-0029.pt', '7976-110523-0016.pt', '2035-147961-0033.pt', '2803-161169-0001.pt', '1462-170145-0006.pt', '777-126732-0077.pt', '5338-284437-0019.pt', '5694-64038-0015.pt', '3000-15664-0044.pt', '2412-153948-0010.pt', '777-126732-0029.pt', '3752-4944-0047.pt', '3576-138058-0039.pt', '2035-147961-0028.pt', '2035-147961-0025.pt', '6319-57405-0006.pt', '8842-304647-0011.pt', '777-126732-0009.pt', '1988-24833-0015.pt', '8297-275156-0012.pt', '2428-83699-0040.pt', '1462-170142-0042.pt', '777-126732-0050.pt', '251-136532-0011.pt', '3000-15664-0020.pt', '5338-24640-0000.pt', '1272-141231-0006.pt', '2803-154320-0008.pt', '6295-244435-0004.pt', '3576-138058-0005.pt', '6295-244435-0017.pt', '5895-34622-0005.pt', '7976-110523-0012.pt', '3000-15664-0039.pt', '84-121550-0022.pt', '2428-83699-0017.pt', '174-168635-0017.pt', '2035-152373-0012.pt', '2035-147961-0022.pt', '3752-4944-0049.pt', '3000-15664-0019.pt', '1462-170142-0021.pt', '2035-147961-0031.pt', '1462-170142-0003.pt', '2412-153948-0009.pt', '3000-15664-0043.pt', '1988-147956-0027.pt', '7850-286674-0001.pt', '7976-110523-0019.pt', '251-118436-0002.pt', '251-136532-0021.pt', '1272-141231-0024.pt', '6241-61943-0009.pt', '777-126732-0017.pt', '3752-4944-0063.pt', '2035-147961-0004.pt', '84-121550-0005.pt', '777-126732-0003.pt', '3752-4944-0042.pt', '5895-34622-0015.pt', '3536-23268-0007.pt', '3000-15664-0028.pt', '2803-161169-0006.pt', '84-121550-0024.pt', '5895-34622-0019.pt', '2035-152373-0009.pt', '1462-170145-0012.pt', '777-126732-0043.pt', '6241-61943-0014.pt', '5895-34615-0000.pt', '5338-284437-0005.pt', '3752-4944-0058.pt', '2035-147961-0000.pt', '174-168635-0001.pt', '6241-61943-0020.pt', '3536-23268-0017.pt', '6319-57405-0009.pt', '1988-24833-0005.pt', '2035-147961-0024.pt', '1988-147956-0024.pt', '1272-135031-0004.pt', '6241-61946-0017.pt', '777-126732-0080.pt', '3536-23268-0004.pt', '2428-83699-0007.pt', '1988-147956-0022.pt', '3576-138058-0032.pt', '7850-281318-0004.pt', '1988-147956-0013.pt', '5895-34629-0033.pt', '251-118436-0006.pt', '3752-4944-0032.pt', '3752-4944-0024.pt', '1272-135031-0002.pt', '5338-284437-0013.pt', '5338-284437-0028.pt', '6295-244435-0029.pt', '174-168635-0005.pt', '5895-34622-0018.pt', '2803-161169-0014.pt', '5338-24640-0008.pt', '777-126732-0025.pt', '6241-61943-0018.pt', '1272-141231-0012.pt', '777-126732-0007.pt', '1993-147964-0008.pt', '1462-170142-0014.pt', '1988-24833-0012.pt', '84-121550-0031.pt', '2035-147961-0029.pt', '6295-244435-0027.pt', '1988-147956-0016.pt', '6319-57405-0008.pt', '2035-147961-0018.pt', '3576-138058-0038.pt', '3752-4944-0064.pt', '251-118436-0007.pt', '1988-24833-0009.pt', '84-121550-0011.pt', '2035-147961-0032.pt', '6319-57405-0002.pt', '3000-15664-0001.pt', '3752-4944-0060.pt', '1988-24833-0017.pt', '5338-284437-0008.pt', '3000-15664-0003.pt', '2428-83699-0002.pt', '1272-135031-0006.pt', '777-126732-0006.pt', '7850-286674-0004.pt', '5895-34615-0013.pt', '3000-15664-0041.pt', '251-136532-0009.pt', '2035-152373-0008.pt', '3000-15664-0000.pt', '5338-24640-0006.pt', '251-118436-0001.pt', '3752-4944-0028.pt', '2428-83699-0030.pt', '5895-34629-0003.pt', '251-118436-0022.pt', '8297-275156-0001.pt', '2035-147961-0026.pt', '2035-152373-0004.pt', '2035-147960-0002.pt', '3000-15664-0004.pt', '6295-244435-0021.pt', '1462-170145-0001.pt', '1462-170145-0002.pt', '7850-281318-0010.pt', '6295-244435-0014.pt', '1462-170145-0014.pt', '1988-147956-0026.pt', '2428-83699-0031.pt', '5694-64038-0020.pt', '3000-15664-0017.pt', '6241-61943-0010.pt', '777-126732-0072.pt', '1462-170142-0030.pt', '2035-152373-0011.pt', '1272-135031-0023.pt', '5338-284437-0001.pt', '3576-138058-0026.pt', '1272-135031-0015.pt', '777-126732-0036.pt', '3752-4944-0012.pt', '1462-170142-0007.pt', '6295-244435-0015.pt', '2035-147961-0003.pt', '2035-147960-0008.pt', '7850-286674-0015.pt', '5895-34629-0008.pt', '3576-138058-0023.pt', '3576-138058-0040.pt', '174-168635-0016.pt', '1462-170142-0035.pt', '3536-23268-0011.pt', '1993-147964-0002.pt', '1988-24833-0000.pt', '2803-154320-0009.pt', '5338-284437-0007.pt', '84-121550-0017.pt', '1988-24833-0027.pt', '3536-23268-0021.pt', '1272-141231-0011.pt', '2035-147961-0035.pt']\n", "Size of 3576-138058-0019 torch.Size([994, 40])\n" ] } ], "source": [ "import os\n", "print(os.listdir(\"feature_cache\"))\n", "test_id = dataset[0][\"id\"]\n", "print(\"Size of\", test_id, torch.load(f\"feature_cache/{test_id}.pt\").shape)" ] }, { "cell_type": "markdown", "metadata": { "id": "R0WcsqDVNWMg" }, "source": [ "You can warm the cache by just loading every item. We provide a convenience function for this:" ] }, { "cell_type": "code", "execution_count": 95, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "ZGEee9mvNWMg", "outputId": "73786759-14d3-47fb-93f5-545795dc82f0" }, "outputs": [ { "output_type": "stream", "name": "stderr", "text": [ "100%|██████████| 1089/1089 [00:09<00:00, 118.08it/s]\n" ] } ], "source": [ "dataset.iterate_once()" ] }, { "cell_type": "code", "execution_count": 96, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "c4uZIuguNWMg", "outputId": "16ef8e42-7649-4ef3-a043-7991bfb8179c" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Number of files in the cache folder: 1089\n" ] } ], "source": [ "print(\"Number of files in the cache folder:\", len(os.listdir(\"feature_cache\")))" ] }, { "cell_type": "markdown", "metadata": { "id": "fFXowLeYNWMg" }, "source": [ "#### HDF5 cached pipelines (single-file cache)\n", "\n", "`CachedHDF5DynamicItem` keeps every cached output in a single HDF5 file instead of one `.pt` file per example. This reduces filesystem overhead and is easier to share across multi-worker dataloaders. The first argument still needs to be the example `id`, and optional compression is supported.\n" ] }, { "cell_type": "code", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "IR_-VA3-NWMg", "outputId": "03be58f0-c8db-4a23-f814-301d66200f9c" }, "execution_count": 97, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "('3576-138058-0019', torch.Size([994, 40]))" ] }, "metadata": {}, "execution_count": 97 } ], "source": [ "import os, shutil\n", "from speechbrain.integrations.hdf5.cached_item import CachedHDF5DynamicItem\n", "\n", "shutil.rmtree(\"hdf5_feature_cache\", ignore_errors=True)\n", "os.makedirs(\"hdf5_feature_cache\", exist_ok=True)\n", "\n", "hdf5_filterbank = speechbrain.lobes.features.Fbank()\n", "\n", "@CachedHDF5DynamicItem.cache(\n", " \"hdf5_feature_cache\",\n", " compression=\"gzip\",\n", " cache_filename=\"features.hdf5\",\n", ")\n", "@speechbrain.utils.data_pipeline.takes(\"id\", \"sig\")\n", "@speechbrain.utils.data_pipeline.provides(\"hdf5_feats\")\n", "def hdf5_feature_pipeline(uid, sig):\n", " # Deterministic features are great candidates for caching.\n", " return hdf5_filterbank(sig.unsqueeze(0)).squeeze(0)\n", "\n", "speechbrain.dataio.dataset.add_dynamic_item([dataset], hdf5_feature_pipeline)\n", "speechbrain.dataio.dataset.set_output_keys([dataset], [\"id\", \"hdf5_feats\"])\n", "\n", "first = dataset[0]\n", "first[\"id\"], first[\"hdf5_feats\"].shape\n" ] }, { "cell_type": "markdown", "metadata": { "id": "l4BQ8wDcNWMh" }, "source": [ "The cache now lives in a single file instead of many small ones:\n" ] }, { "cell_type": "code", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "2gxXDwsxNWMh", "outputId": "d7fa1909-92de-4578-ee89-19bd0324353f" }, "execution_count": 98, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Cache file: hdf5_feature_cache/features.hdf5\n", "Datasets inside cache (truncated): ['3576-138058-0019']\n", "Compression: gzip\n" ] } ], "source": [ "hdf5_path = hdf5_feature_pipeline.hdf5_path\n", "print(\"Cache file:\", hdf5_path)\n", "print(\"Datasets inside cache (truncated):\", list(hdf5_feature_pipeline.hdf5file.keys())[:3])\n", "print(\"Compression:\", hdf5_feature_pipeline.hdf5file[first[\"id\"]].compression)\n" ] }, { "cell_type": "markdown", "metadata": { "id": "ms6e--ZjNWMh" }, "source": [ "You can warm the cache once, then reopen it read-only when using multiple DataLoader workers to avoid write contention:\n" ] }, { "cell_type": "code", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "qY-8lg6gNWMh", "outputId": "4e4b0b9a-e664-4969-9c54-faeafde53fa8" }, "execution_count": 99, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "HDF5 mode after switching: r\n", "Number of cached items: 1089\n" ] } ], "source": [ "dataset.iterate_once(output_keys=[\"id\", \"hdf5_feats\"], progressbar=False)\n", "hdf5_feature_pipeline.change_file_mode(\"r\")\n", "print(\"HDF5 mode after switching:\", hdf5_feature_pipeline.hdf5file.mode)\n", "print(\"Number of cached items:\", len(hdf5_feature_pipeline.hdf5file.keys()))\n" ] }, { "cell_type": "markdown", "metadata": { "id": "WZJnmyiou6cK" }, "source": [ "### CategoricalEncoder" ] }, { "cell_type": "markdown", "metadata": { "id": "18cYd9eT7iuZ" }, "source": [ "SpeechBrain `dataio` provides a `CategoricalEncoder` class for encoding labels which belongs to a discrete set: e.g. for speaker recognition or any other multi-class classification problem.\n", "\n", "Given a collection of hashables (e.g. strings) it encodes\n", " every unique item to an integer value: `[\"spk0\", \"spk1\"]` --> `[0, 1]`\n", "\n", "\n", " Internally the correspondence between each label to its index is handled by\n", " two dictionaries: `lab2ind` and `ind2lab`.\n", "\n", "It is built to tightly integrate with `DynamicItemDataset` and `dataIO pipelines`.\n", "\n", "For example one can obtain the encoding for speaker identities (`spkID` in JSON) from our Mini-LibriSpeech dataset by creating an instance of CategoricalEncoder and fitting it to the dataset object." ] }, { "cell_type": "code", "execution_count": 100, "metadata": { "id": "oAKvZSz5DX-N" }, "outputs": [], "source": [ "from speechbrain.dataio.encoder import CategoricalEncoder\n", "spk_id_encoder = CategoricalEncoder()" ] }, { "cell_type": "markdown", "metadata": { "id": "7ICJwSyUDyHL" }, "source": [ "Since `DynamicItemDataset` right now does not return spkID we have firstly to set its output to return that dynamic item:" ] }, { "cell_type": "code", "execution_count": 101, "metadata": { "id": "OYIqLGDDEBFF", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "6eff4d71-f015-4230-a457-95e8a0d14611" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'spkID': 3576}" ] }, "metadata": {}, "execution_count": 101 } ], "source": [ "speechbrain.dataio.dataset.set_output_keys(\n", " [dataset], [\"spkID\"],\n", " )\n", "# sig is a torch.tensor with audio signal as specified before.\n", "# REMEMBER: no need to specify the pipeline for spkID as we can read directly the value from the JSON.\n", "dataset[0]" ] }, { "cell_type": "markdown", "metadata": { "id": "wqIDYxTcEg-s" }, "source": [ "The speaker identity `spkID` is a string.\n", "\n", "Note that in librispeech it is a string containing a unique integer so one can argue that performing the encoding here is pointless as casting to integer will suffice.\n", "\n", "However, it could happen that it is not an unique integer but an unique string like `spk1`, `spk2` et cetera.\n", "\n", "`spk_id_encoder` can be used for this purpose. We fit the encoder to the dataset and specify which *dynamic item* we want to encode:" ] }, { "cell_type": "code", "execution_count": 102, "metadata": { "id": "0JQxKP-9F2-B" }, "outputs": [], "source": [ "spk_id_encoder.update_from_didataset(dataset, \"spkID\")" ] }, { "cell_type": "markdown", "metadata": { "id": "83_QlLNRXEPl" }, "source": [ "**NOTE**\n", "\n", "\n", "This will iterate over dataset fetch for each example spkID and construct\n", "internal dicts lab2ind and ind2lab.\n", "\n", "Because of this, it is important to call `dataset.set_output_keys` avoiding\n", "computationally costly dynamic items (e.g. can happen if the pipeline does data augmentation) before fitting the encoder.\n", "\n", "Setting only the key on which the encoder will be fitted is a good approach." ] }, { "cell_type": "markdown", "metadata": { "id": "8U0Qy4DuX9BO" }, "source": [ "We can look now at how much unique speaker ids there are in the dataset by using `__len__`" ] }, { "cell_type": "code", "execution_count": 103, "metadata": { "id": "tz-Ntq0zF-49", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "2fc7efb4-83ca-411c-bf71-b1021ec31044" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "26" ] }, "metadata": {}, "execution_count": 103 } ], "source": [ "len(spk_id_encoder)" ] }, { "cell_type": "markdown", "metadata": { "id": "5MIcC0sAYBEe" }, "source": [ "We can also take a look to the encoder internal dictionaries `lab2ind` ans `ind2lab` which contains the mappings between the labels (speaker ids in this case) and corresponding integers encodings:" ] }, { "cell_type": "code", "execution_count": 104, "metadata": { "id": "YoLjI4HtGIgC", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "49042c9f-49dd-4624-fab2-7095420cb79e" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{3576: 0,\n", " 174: 1,\n", " 6295: 2,\n", " 3752: 3,\n", " 1988: 4,\n", " 5694: 5,\n", " 1462: 6,\n", " 1272: 7,\n", " 2428: 8,\n", " 7976: 9,\n", " 2412: 10,\n", " 5895: 11,\n", " 251: 12,\n", " 2803: 13,\n", " 8842: 14,\n", " 5338: 15,\n", " 6241: 16,\n", " 3000: 17,\n", " 6319: 18,\n", " 84: 19,\n", " 777: 20,\n", " 7850: 21,\n", " 8297: 22,\n", " 1993: 23,\n", " 2035: 24,\n", " 3536: 25}" ] }, "metadata": {}, "execution_count": 104 } ], "source": [ "spk_id_encoder.lab2ind\n", "# contains label --> integer encoding" ] }, { "cell_type": "code", "execution_count": 105, "metadata": { "id": "Jm23A0dCIuSG", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "8d113311-2e7b-4c64-caab-c13b21394993" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{0: 3576,\n", " 1: 174,\n", " 2: 6295,\n", " 3: 3752,\n", " 4: 1988,\n", " 5: 5694,\n", " 6: 1462,\n", " 7: 1272,\n", " 8: 2428,\n", " 9: 7976,\n", " 10: 2412,\n", " 11: 5895,\n", " 12: 251,\n", " 13: 2803,\n", " 14: 8842,\n", " 15: 5338,\n", " 16: 6241,\n", " 17: 3000,\n", " 18: 6319,\n", " 19: 84,\n", " 20: 777,\n", " 21: 7850,\n", " 22: 8297,\n", " 23: 1993,\n", " 24: 2035,\n", " 25: 3536}" ] }, "metadata": {}, "execution_count": 105 } ], "source": [ "spk_id_encoder.ind2lab # contains integer encoding --> label" ] }, { "cell_type": "markdown", "metadata": { "id": "DZEqe2d1Vthc" }, "source": [ "Once fitted the `CategoricalEncoder` object can be used in a suitably defined pipeline to encode the spkID key and return the encoded value:" ] }, { "cell_type": "code", "execution_count": 106, "metadata": { "id": "tX43vtVTyuCy" }, "outputs": [], "source": [ "@speechbrain.utils.data_pipeline.takes(\"spkID\")\n", "@speechbrain.utils.data_pipeline.provides(\"spkid_encoded\")\n", "def spk_id_encoding(spkid):\n", " return torch.LongTensor([spk_id_encoder.encode_label(spkid)])\n" ] }, { "cell_type": "code", "execution_count": 107, "metadata": { "id": "y1A41rDQyy-C", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "864bcffb-d970-4b7b-ad2e-64997e70e122" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'spkid_encoded': tensor([2])}" ] }, "metadata": {}, "execution_count": 107 } ], "source": [ "speechbrain.dataio.dataset.add_dynamic_item([dataset], spk_id_encoding)\n", "speechbrain.dataio.dataset.set_output_keys(\n", " [dataset], [\"spkid_encoded\"],\n", " )\n", "\n", "dataset[100]" ] }, { "cell_type": "markdown", "metadata": { "id": "knC4t9fKvHHU" }, "source": [ "### PaddedBatch and SaveableDataLoader\n", "\n", "SpeechBrain offers a way to conveniently pad right automatically tensors of different length on multiple dimensions.\n", "This is achieved using the `PaddedBatch` class defined in `speechbrain.dataio.batch`.\n", "\n", "`PaddedBatch` is both a `collate_fn` and a batch object.\n", "\n", "When a `torch.utils.data.Dataset` (and thus also a `DynamicItemDataset`) is passed to the `Brain` class `PaddedBatch` is used as the default collate function `collate_fn` and examples are automatically padded together.\n", "\n", "As the default DataLoader the Brain class instantiates, a SpeechBrain custom DataLoader: `speechbrain.dataio.dataloader.SaveableDataLoader`.\n", "\n", "\n", "This DataLoader is identical to the plain one except that it allows for intra-epoch saving. So if for some reason training stops in the middle of an epoch it is possible to resume from exactly that step. See the [Checkpointing Tutorial](https://speechbrain.readthedocs.io/en/latest/tutorials/basics/checkpointing.html).\n", "The default `collate_fn` for this DataLoader is `PaddedBatch`.\n" ] }, { "cell_type": "code", "execution_count": 108, "metadata": { "id": "NtsZ0UA6vLfc" }, "outputs": [], "source": [ "from speechbrain.dataio.dataloader import SaveableDataLoader\n", "from speechbrain.dataio.batch import PaddedBatch\n", "\n", "speechbrain.dataio.dataset.set_output_keys(\n", " [dataset], [\"id\", \"spkid_encoded\", \"signal\"],\n", " )" ] }, { "cell_type": "markdown", "metadata": { "id": "Ljw1yIG3xRPT" }, "source": [ "We set as the dynamic items we are requesting `sig` which is the audio tensor\n", "and the speaker id encoded with the `CategoricalEncoder` object (`spkid_encoded`) defined before and the example `id`." ] }, { "cell_type": "code", "execution_count": 109, "metadata": { "id": "puBQt7QRwmnZ" }, "outputs": [], "source": [ "dataloader = SaveableDataLoader(dataset, batch_size=2, collate_fn=PaddedBatch)" ] }, { "cell_type": "code", "execution_count": 110, "metadata": { "id": "ccIqOHQkxEmD" }, "outputs": [], "source": [ "batch_obj = next(iter(dataloader)) # let's look at the batch obj" ] }, { "cell_type": "code", "execution_count": 111, "metadata": { "id": "cpFw6pycxJNC", "colab": { "base_uri": "https://localhost:8080/", "height": 221 }, "outputId": "1bf327d6-84e3-469d-bdb8-85546ebb6730" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "speechbrain.dataio.batch.PaddedBatch" ], "text/html": [ "
\n", "
speechbrain.dataio.batch.PaddedBatch
def __init__(examples, padded_keys=None, device_prep_keys=None, padding_func=batch_pad_right, padding_kwargs=None, per_key_padding_kwargs=None, apply_default_convert=True, nonpadded_stack=True)
/usr/local/lib/python3.12/dist-packages/speechbrain/dataio/batch.pyCollate_fn when examples are dicts and have variable-length sequences.\n",
              "\n",
              "Different elements in the examples get matched by key.\n",
              "All numpy tensors get converted to Torch (PyTorch default_convert)\n",
              "Then, by default, all torch.Tensor valued elements get padded and support\n",
              "collective pin_memory() and to() calls.\n",
              "Regular Python data types are just collected in a list.\n",
              "\n",
              "Arguments\n",
              "---------\n",
              "examples : list\n",
              "    List of example dicts, as produced by Dataloader.\n",
              "padded_keys : list, None\n",
              "    (Optional) List of keys to pad on. If None, pad all torch.Tensors\n",
              "device_prep_keys : list, None\n",
              "    (Optional) Only these keys participate in collective memory pinning and moving with\n",
              "    to().\n",
              "    If None, defaults to all items with torch.Tensor values.\n",
              "padding_func : callable, optional\n",
              "    Called with a list of tensors to be padded together. Needs to return\n",
              "    two tensors: the padded data, and another tensor for the data lengths.\n",
              "padding_kwargs : dict, None\n",
              "    (Optional) Extra kwargs to pass to padding_func. E.G. mode, value\n",
              "    This is used as the default padding configuration for all keys.\n",
              "per_key_padding_kwargs : dict, None\n",
              "    (Optional) Per-key padding configuration. Keys in this dict should match\n",
              "    the keys in the examples. Each value should be a dict with padding parameters\n",
              "    (e.g., {'value': -100, 'mode': 'constant'}). If a key is not in this dict,\n",
              "    the global padding_kwargs will be used.\n",
              "apply_default_convert : bool\n",
              "    Whether to apply PyTorch default_convert (numpy to torch recursively,\n",
              "    etc.) on all data. Default:True, usually does the right thing.\n",
              "nonpadded_stack : bool\n",
              "    Whether to apply PyTorch-default_collate-like stacking on values that\n",
              "    didn't get padded. This stacks if it can, but doesn't error out if it\n",
              "    cannot. Default:True, usually does the right thing.\n",
              "\n",
              "Example\n",
              "-------\n",
              ">>> batch = PaddedBatch(\n",
              "...     [\n",
              "...         {"id": "ex1", "foo": torch.Tensor([1.0])},\n",
              "...         {"id": "ex2", "foo": torch.Tensor([2.0, 1.0])},\n",
              "...     ]\n",
              "... )\n",
              ">>> # Attribute or key-based access:\n",
              ">>> batch.id\n",
              "['ex1', 'ex2']\n",
              ">>> batch["id"]\n",
              "['ex1', 'ex2']\n",
              ">>> # torch.Tensors get padded\n",
              ">>> type(batch.foo)\n",
              "<class 'speechbrain.dataio.batch.PaddedData'>\n",
              ">>> batch.foo.data\n",
              "tensor([[1., 0.],\n",
              "        [2., 1.]])\n",
              ">>> batch.foo.lengths\n",
              "tensor([0.5000, 1.0000])\n",
              ">>> # Batch supports collective operations:\n",
              ">>> _ = batch.to(dtype=torch.half)\n",
              ">>> batch.foo.data\n",
              "tensor([[1., 0.],\n",
              "        [2., 1.]], dtype=torch.float16)\n",
              ">>> batch.foo.lengths\n",
              "tensor([0.5000, 1.0000], dtype=torch.float16)\n",
              ">>> # Numpy tensors get converted to torch and padded as well:\n",
              ">>> import numpy as np\n",
              ">>> batch = PaddedBatch(\n",
              "...     [{"wav": np.asarray([1, 2, 3, 4])}, {"wav": np.asarray([1, 2, 3])}]\n",
              "... )\n",
              ">>> batch.wav  # +ELLIPSIS\n",
              "PaddedData(data=tensor([[1, 2,...\n",
              ">>> # Basic stacking collation deals with non padded data:\n",
              ">>> batch = PaddedBatch(\n",
              "...     [\n",
              "...         {\n",
              "...             "spk_id": torch.tensor([1]),\n",
              "...             "wav": torch.tensor([0.1, 0.0, 0.3]),\n",
              "...         },\n",
              "...         {\n",
              "...             "spk_id": torch.tensor([2]),\n",
              "...             "wav": torch.tensor([0.2, 0.3, -0.1]),\n",
              "...         },\n",
              "...     ],\n",
              "...     padded_keys=["wav"],\n",
              "... )\n",
              ">>> batch.spk_id\n",
              "tensor([[1],\n",
              "        [2]])\n",
              ">>> # And some data is left alone:\n",
              ">>> batch = PaddedBatch(\n",
              "...     [{"text": ["Hello"]}, {"text": ["How", "are", "you?"]}]\n",
              "... )\n",
              ">>> batch.text\n",
              "[['Hello'], ['How', 'are', 'you?']]\n",
              ">>> # Per-key padding configuration:\n",
              ">>> batch = PaddedBatch(\n",
              "...     [\n",
              "...         {\n",
              "...             "wav": torch.tensor([1, 2, 3]),\n",
              "...             "labels": torch.tensor([1, 2]),\n",
              "...         },\n",
              "...         {"wav": torch.tensor([4, 5]), "labels": torch.tensor([3])},\n",
              "...     ],\n",
              "...     per_key_padding_kwargs={\n",
              "...         "wav": {"value": 0},\n",
              "...         "labels": {"value": -100},\n",
              "...     },\n",
              "... )\n",
              ">>> batch.wav.data\n",
              "tensor([[1, 2, 3],\n",
              "        [4, 5, 0]])\n",
              ">>> batch.labels.data\n",
              "tensor([[   1,    2],\n",
              "        [   3, -100]])
\n", " \n", "
" ] }, "metadata": {}, "execution_count": 111 } ], "source": [ "batch_obj # the dataloader returns an PaddedBatch obj now\n", "type(batch_obj)" ] }, { "cell_type": "markdown", "metadata": { "id": "8IZb33Bt0L9d" }, "source": [ "Dynamic Items can be accessed in the batch object by using `dict` syntax:" ] }, { "cell_type": "code", "execution_count": 112, "metadata": { "id": "dB42KZ3AxLth", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "643c11bb-fbf0-49e1-a9b5-7a1d2799e0c6" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "PaddedData(data=tensor([[0],\n", " [0]]), lengths=tensor([1., 1.]))" ] }, "metadata": {}, "execution_count": 112 } ], "source": [ "batch_obj[\"spkid_encoded\"]" ] }, { "cell_type": "code", "execution_count": 113, "metadata": { "id": "ZKJlXaW10XRg", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "c5186323-026f-4477-d0b8-f31ac2db1614" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "PaddedData(data=tensor([[ 0.0020, 0.0006, 0.0004, ..., -0.0033, -0.0034, -0.0029],\n", " [-0.0018, -0.0023, -0.0027, ..., 0.0000, 0.0000, 0.0000]]), lengths=tensor([1.0000, 0.6220]))" ] }, "metadata": {}, "execution_count": 113 } ], "source": [ "batch_obj[\"signal\"]" ] }, { "cell_type": "code", "execution_count": 114, "metadata": { "id": "gEG6g0sc0ZXn", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "5fa1ffa7-b0cb-436a-dd81-4d4f01f9e087" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "['3576-138058-0019', '3576-138058-0021']" ] }, "metadata": {}, "execution_count": 114 } ], "source": [ "batch_obj[\"id\"] # example ids in this batch useful for debugging" ] }, { "cell_type": "markdown", "metadata": { "id": "UF3k_9060g4y" }, "source": [ "As said, all elements in PaddedBatch which are `torch.Tensors` are padded together by adding zeros to the right.\n", "When these elements are accessed a [namedtuple](https://docs.python.org/3/library/collections.html#collections.namedtuple) is returned: the actual padded tensors and a `length` tensor." ] }, { "cell_type": "code", "execution_count": 115, "metadata": { "id": "G2pFsSa702_x" }, "outputs": [], "source": [ "wav_data, length = batch_obj[\"signal\"]" ] }, { "cell_type": "markdown", "metadata": { "id": "GhPDU20bcvNA" }, "source": [ "As it is a [namedtuple](https://docs.python.org/3/library/collections.html#collections.namedtuple) the two items *length* and *data* are also accessible as attributes:" ] }, { "cell_type": "code", "execution_count": 116, "metadata": { "id": "glL_x9sqb8vO" }, "outputs": [], "source": [ "lengths = batch_obj[\"signal\"].lengths\n", "wav_data = batch_obj[\"signal\"].data" ] }, { "cell_type": "code", "execution_count": 117, "metadata": { "id": "YDzqHldc0bBe", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "0d13cecb-97ed-4279-e7d1-50c31215e8c0" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "tensor([1.0000, 0.6220])" ] }, "metadata": {}, "execution_count": 117 } ], "source": [ "lengths" ] }, { "cell_type": "markdown", "metadata": { "id": "zSbkh9tJ08j2" }, "source": [ "This length tensor contains the relative true length of each sequence.\n", "In this example it means that the second example in the batch has not been padded (relative length == 1) while the first instead has been padded to more twice its length.\n", "\n", "The use of relative lengths instead of absolute indexes guarantees that that these values do not change even after feature extraction: the relative true length remains the same even after STFT whatever is the window.\n", "\n", "The absolute indexes are easy to obtain:" ] }, { "cell_type": "code", "execution_count": 118, "metadata": { "id": "tx8HUi2U1Tsu", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "63974e5d-2a89-442d-87cf-6a294ab7ac24" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "tensor([158960, 98879])" ] }, "metadata": {}, "execution_count": 118 } ], "source": [ "abs_lens = (lengths*wav_data.shape[1]).long()\n", "abs_lens" ] }, { "cell_type": "code", "execution_count": 119, "metadata": { "id": "KLClRlo-1xjg", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "ed4b3d3a-30a1-4b11-8368-74d97115736f" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "tensor([-0.0018, -0.0023, -0.0027, ..., 0.0042, 0.0052, 0.0038])" ] }, "metadata": {}, "execution_count": 119 } ], "source": [ "wav_data[1][:abs_lens[1]] # no zeros" ] }, { "cell_type": "code", "execution_count": 120, "metadata": { "id": "NmH1C4Dx2Fyt", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "a561c82d-e9cd-4799-bdb6-90b9dbada775" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "tensor([0.0019, 0.0000, 0.0000, ..., 0.0000, 0.0000, 0.0000])" ] }, "metadata": {}, "execution_count": 120 } ], "source": [ "wav_data[1][abs_lens[1]:] # zeros begins at abs_lens[0]" ] }, { "cell_type": "markdown", "metadata": { "id": "BRIP5d4h2e2Y" }, "source": [ "The PaddedBatch object allows for conveniently moving all dynamic items which are` torch.Tensor` to the right device using to:" ] }, { "cell_type": "code", "execution_count": 121, "metadata": { "id": "gtn6h1hM2Xw2" }, "outputs": [], "source": [ "batch_obj = batch_obj.to(\"cpu\")" ] }, { "cell_type": "markdown", "metadata": { "id": "IyZ84-4-20wn" }, "source": [ "Of course items which are not tensors such as `id` are not moved and are not padded. Instead they are simply returned as a list." ] }, { "cell_type": "code", "execution_count": 122, "metadata": { "id": "O8-4oUMw2xNd", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "05816f8e-bd9e-41a8-f469-37c38f5e305f" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "['3576-138058-0019', '3576-138058-0021']" ] }, "metadata": {}, "execution_count": 122 } ], "source": [ "batch_obj[\"id\"]" ] }, { "cell_type": "markdown", "metadata": { "id": "Vz09N7Zb3Iho" }, "source": [ "It is also possible to iterate over the examples of `PaddedBatch`:" ] }, { "cell_type": "code", "execution_count": 123, "metadata": { "id": "05vyHnk23H8X", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "5d6f6b79-645c-4fe9-90eb-573c06671964" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "['3576-138058-0019', '3576-138058-0021']\n", "PaddedData(data=tensor([[0],\n", " [0]]), lengths=tensor([1., 1.]))\n", "PaddedData(data=tensor([[ 0.0020, 0.0006, 0.0004, ..., -0.0033, -0.0034, -0.0029],\n", " [-0.0018, -0.0023, -0.0027, ..., 0.0000, 0.0000, 0.0000]]), lengths=tensor([1.0000, 0.6220]))\n" ] } ], "source": [ "for ex in batch_obj:\n", " print(ex)" ] }, { "cell_type": "markdown", "metadata": { "id": "sXjZOd3O3tt1" }, "source": [ "And access a single example by its position:" ] }, { "cell_type": "code", "execution_count": 124, "metadata": { "id": "2mPr65B22_r8", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "087360a2-824d-43d2-9a66-4d64e6dc09b8" }, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "PaddedData(data=tensor([[0],\n", " [0]]), lengths=tensor([1., 1.]))" ] }, "metadata": {}, "execution_count": 124 } ], "source": [ "batch_obj.at_position(1)" ] }, { "cell_type": "markdown", "metadata": { "id": "Ze8DO5Nj32eE" }, "source": [ "These methods can be conveniently used in the `Brain` class `compute_forward` and `compute_objectives` methods.\n", "As we have shown in the first example of this tutorial where a complete dataIO example was illustrated:\n", "\n", "\n", "\n", "\n", "```python\n", "def compute_forward(self, batch, stage):\n", " audio, audio_len = batch[\"sig\"]\n", " # the examples are automatically padded, audio_len contains the relative\n", " # length of the original sequence.\n", " return self.modules.model(audio.unsqueeze(1)).mean(-1).unsqueeze(-1)\n", " \n", " def compute_objectives(self, logits, batch, stage):\n", " spk_ids, _ = batch[\"spkid_encoded\"]\n", " return torch.nn.functional.cross_entropy(logits, spk_ids)\n", "```\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "ufpPurk3bsvc" }, "source": [ "## Full Example: Training a simple Speaker Recognition System." ] }, { "cell_type": "markdown", "metadata": { "id": "yKox1vfgbyey" }, "source": [ "Hereafter we show how the **DynamicItemDataset**, **DIPs** and **CategoricalEncoder** can be used to build a data pipeline for Speaker Recognition.\n", "\n", "In particular we have to:\n", "\n", "- read the audio\n", "- read the speaker ID from annotation and encode it to integer\n" ] }, { "cell_type": "markdown", "metadata": { "id": "_0e4ksGZpErL" }, "source": [ "We firstly instantiate the dataset from that JSON annotation" ] }, { "cell_type": "code", "execution_count": 125, "metadata": { "id": "9RKlcn6JpKo9" }, "outputs": [], "source": [ "dataset = DynamicItemDataset.from_json(\"data.json\")" ] }, { "cell_type": "markdown", "metadata": { "id": "KdI7Uakdi1kh" }, "source": [ "Then fit the **CategoricalEncoder** to speaker IDs (`spkID`) in the annotation." ] }, { "cell_type": "code", "execution_count": 126, "metadata": { "id": "4dLTFQyPi0yk" }, "outputs": [], "source": [ "spk_id_encoder = CategoricalEncoder()\n", "spk_id_encoder.update_from_didataset(dataset, \"spkID\")" ] }, { "cell_type": "markdown", "metadata": { "id": "aM2U403ejF3b" }, "source": [ "We add the **DIP** which encodes `spkID`" ] }, { "cell_type": "code", "execution_count": 127, "metadata": { "id": "IRWERFtjjFEF" }, "outputs": [], "source": [ "dataset.add_dynamic_item(spk_id_encoder.encode_label_torch, takes=\"spkID\", provides=\"spk_encoded\")\n" ] }, { "cell_type": "markdown", "metadata": { "id": "2PNpmwVZjPLn" }, "source": [ "We add the **DIP** for reading the audio\n" ] }, { "cell_type": "code", "execution_count": 128, "metadata": { "id": "L4ccm3_KjSOF" }, "outputs": [], "source": [ "dataset.add_dynamic_item(speechbrain.dataio.dataio.read_audio, takes=\"file_path\", provides=\"signal\")\n" ] }, { "cell_type": "markdown", "metadata": { "id": "ge4RwtGSNWMm" }, "source": [ "#### Caching features for the speaker pipeline\n", "\n", "We can cache the filterbank features so each epoch only reads them from a single HDF5 file instead of recomputing them or creating thousands of small `.pt` files. This mirrors the caching workflow shown earlier, but plugs directly into the speaker-recognition `DynamicItemDataset`.\n" ] }, { "cell_type": "code", "metadata": { "id": "_6davA36NWMm" }, "execution_count": 129, "outputs": [], "source": [ "import os, shutil\n", "from speechbrain.integrations.hdf5.cached_item import CachedHDF5DynamicItem\n", "from speechbrain.lobes.features import Fbank\n", "\n", "# Clean cache for a reproducible run in the notebook\n", "shutil.rmtree(\"spk_feat_cache\", ignore_errors=True)\n", "os.makedirs(\"spk_feat_cache\", exist_ok=True)\n", "\n", "fbank = Fbank()\n", "\n", "@CachedHDF5DynamicItem.cache(\n", " cache_location=\"spk_feat_cache\",\n", " cache_filename=\"speaker_feats.hdf5\",\n", " compression=\"gzip\",\n", ")\n", "@speechbrain.utils.data_pipeline.takes(\"id\", \"signal\")\n", "@speechbrain.utils.data_pipeline.provides(\"feats\")\n", "def cached_fbank(uid, sig):\n", " return fbank(sig.unsqueeze(0)).squeeze(0)\n", "\n", "dataset.add_dynamic_item(cached_fbank)\n" ] }, { "cell_type": "markdown", "metadata": { "id": "0s13XGkjNWMm" }, "source": [ "The cache is lazy: the first access to an utterance writes it into `speaker_feats.hdf5`. Reusing the notebook (or multiple workers) just reads from the same file.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "0_oJNpxkpgqF" }, "source": [ "and set the outputs of the dataset we want to access in training loop" ] }, { "cell_type": "code", "execution_count": 130, "metadata": { "id": "sahSr0yJpkhY" }, "outputs": [], "source": [ "dataset.set_output_keys([\"id\", \"feats\", \"spk_encoded\"])\n" ] }, { "cell_type": "markdown", "metadata": { "id": "Ovhe-jc8jWzh" }, "source": [ "We sort the dataset based on length to speed up training so that we minimize in batches the amount of padded elements." ] }, { "cell_type": "code", "execution_count": 131, "metadata": { "id": "jG36aYVvjWB7" }, "outputs": [], "source": [ "sorted_data = dataset.filtered_sorted(sort_key=\"length\")" ] }, { "cell_type": "markdown", "metadata": { "id": "IPGrUCU5kNY3" }, "source": [ "We can train now a simple classifier, by passing the dataset object directly to the **Brain** class. The **Brain** class will automatically create a SaveableDataLoader with specified `train_loader_kwargs` and will be handling the padding for you." ] }, { "cell_type": "code", "execution_count": 132, "metadata": { "id": "OFFiFjaek8uN", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "b63d6a3b-7ce0-406e-eb32-719215c702d2" }, "outputs": [ { "output_type": "stream", "name": "stderr", "text": [ "INFO:speechbrain.core:Gradscaler enabled: `False`\n", "INFO:speechbrain.core:Using training precision: `--precision=fp32`\n", "INFO:speechbrain.core:Using evaluation precision: `--eval_precision=fp32`\n", "INFO:speechbrain.core:SimpleBrain Model Statistics:\n", "* Total Number of Trainable Parameters: 23.8k\n", "* Total Number of Parameters: 23.8k\n", "* Trainable Parameters represent 100.0000% of the total size.\n", "100%|██████████| 68/68 [00:25<00:00, 2.70it/s, train_loss=4.22]\n" ] } ], "source": [ "from speechbrain.lobes.features import MFCC, Fbank\n", "from speechbrain.nnet.losses import nll_loss\n", "\n", "\n", "class SimpleBrain(speechbrain.Brain):\n", " def compute_forward(self, batch, stage):\n", " x = batch.feats.data\n", " x = self.modules.encoder(x)\n", " x = self.modules.pooling(x, batch.feats.lengths)\n", " x = self.modules.to_output(x)\n", " return self.modules.softmax(x)\n", "\n", " def compute_objectives(self, logits, batch, stage):\n", " return nll_loss(logits, batch.spk_encoded.data)\n", "\n", "modules = {\n", " \"encoder\": torch.nn.Sequential(torch.nn.Linear(40, 256),\n", " torch.nn.ReLU()),\n", " \"pooling\": speechbrain.nnet.pooling.StatisticsPooling(),\n", " \"to_output\": torch.nn.Linear(512, len(spk_id_encoder)),\n", " \"softmax\": speechbrain.nnet.activations.Softmax(apply_log=True)\n", "}\n", "brain = SimpleBrain(modules, opt_class=lambda x: torch.optim.SGD(x, 0.01), run_opts={\"device\": \"cpu\"})\n", "brain.fit(range(1), train_set=sorted_data,\n", " train_loader_kwargs={\"batch_size\": 16, \"drop_last\":True})\n" ] }, { "cell_type": "markdown", "metadata": { "id": "H9vn3zCqNWMn" }, "source": [ "## Authors\n", "\n", "- SpeechBrain team: Mirco Ravanelli, Titouan Parcollet, Peter Plantinga, and Adel Moumen (2026)" ] }, { "cell_type": "markdown", "metadata": { "id": "lvCQK0beq8Fc" }, "source": [ "## Acknowledgements\n", "\n", "\n", "\n", "* Many thanks to Nasser Benabderrazik ([lenassero](https://github.com/lenassero)) who helped improving this Tutorial.\n", "\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "sb_auto_footer", "tags": [ "sb_auto_footer" ] }, "source": [ "## Citing SpeechBrain\n", "\n", "If you use SpeechBrain in your research or business, please cite it using the following BibTeX entry:\n", "\n", "```bibtex\n", "@misc{speechbrainV1,\n", " title={Open-Source Conversational AI with {SpeechBrain} 1.0},\n", " author={Mirco Ravanelli and Titouan Parcollet and Adel Moumen and Sylvain de Langen and Cem Subakan and Peter Plantinga and Yingzhi Wang and Pooneh Mousavi and Luca Della Libera and Artem Ploujnikov and Francesco Paissan and Davide Borra and Salah Zaiem and Zeyu Zhao and Shucong Zhang and Georgios Karakasidis and Sung-Lin Yeh and Pierre Champion and Aku Rouhe and Rudolf Braun and Florian Mai and Juan Zuluaga-Gomez and Seyed Mahed Mousavi and Andreas Nautsch and Xuechen Liu and Sangeet Sagar and Jarod Duret and Salima Mdhaffar and Gaelle Laperriere and Mickael Rouvier and Renato De Mori and Yannick Esteve},\n", " year={2024},\n", " eprint={2407.00463},\n", " archivePrefix={arXiv},\n", " primaryClass={cs.LG},\n", " url={https://arxiv.org/abs/2407.00463},\n", "}\n", "@misc{speechbrain,\n", " title={{SpeechBrain}: A General-Purpose Speech Toolkit},\n", " author={Mirco Ravanelli and Titouan Parcollet and Peter Plantinga and Aku Rouhe and Samuele Cornell and Loren Lugosch and Cem Subakan and Nauman Dawalatabad and Abdelwahab Heba and Jianyuan Zhong and Ju-Chieh Chou and Sung-Lin Yeh and Szu-Wei Fu and Chien-Feng Liao and Elena Rastorgueva and François Grondin and William Aris and Hwidong Na and Yan Gao and Renato De Mori and Yoshua Bengio},\n", " year={2021},\n", " eprint={2106.04624},\n", " archivePrefix={arXiv},\n", " primaryClass={eess.AS},\n", " note={arXiv:2106.04624}\n", "}\n", "```" ] } ], "metadata": { "colab": { "provenance": [] }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.11" } }, "nbformat": 4, "nbformat_minor": 0 }