diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 8343da4..0000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -*.onnx filter=lfs diff=lfs merge=lfs -text -*.tflite filter=lfs diff=lfs merge=lfs -text \ No newline at end of file diff --git a/.github/workflows/build_and_publish_to_pypi.yml b/.github/workflows/build_and_publish_to_pypi.yml index ce8e4be..bee4a13 100755 --- a/.github/workflows/build_and_publish_to_pypi.yml +++ b/.github/workflows/build_and_publish_to_pypi.yml @@ -3,6 +3,9 @@ name: Publish Python distributions to PyPI on: push: workflow_dispatch: + create: + tags: + - "*" jobs: build-n-publish: @@ -10,8 +13,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@master - with: - lfs: true - name: Set up Python 3.8 uses: actions/setup-python@v3 with: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6a13242..ffc7c50 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -8,6 +8,7 @@ on: branches: [ "main" ] pull_request: branches: [ "main" ] + workflow_dispatch: jobs: unit_tests_linux: @@ -18,8 +19,6 @@ jobs: steps: - uses: actions/checkout@v3 - with: - lfs: true - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v3 with: @@ -42,8 +41,6 @@ jobs: steps: - uses: actions/checkout@v3 - with: - lfs: true - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v3 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 0484d60..a69c7ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Change Log +## v0.6.0 - 2023/06/15 + +### Added + +* Various bug fixes, and some new functionality in `model.py` to control repeated detections + +### Changed + +* Models are no longer included in the PyPi package, and must be downloaded separately + +### Removed + ## v0.5.0 - 2023/06/15 ### Added diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index eef6e33..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -recursive-include openwakeword *.onnx -recursive-include openwakeword *.tflite \ No newline at end of file diff --git a/README.md b/README.md index 7e5f4f5..d6f6566 100644 --- a/README.md +++ b/README.md @@ -11,12 +11,21 @@ openWakeWord is an open-source wakeword library that can be used to create voice # Updates +**2024/02/11** +- v0.6.0 of openWakeWord released. See the [changelog](CHANGELOG.md) for a full descriptions of new features and changes. + +**2023/11/09** +- Added example scripts under `examples/web` that demonstrate streaming audio from a web application into openWakeWord. + +**2023/10/11** +- Significant improvements to the process of [training new models](#training-new-models), including an example Google Colab notebook demonstrating how to train a basic wake word model in <1 hour. + **2023/06/15** - v0.5.0 of openWakeWord released. See the [changelog](CHANGELOG.md) for a full descriptions of new features and changes. # Demo -You can try an online demo of the included pre-trained models via HuggingFace Spaces [right here!](https://huggingface.co/spaces/davidscripka/openWakeWord). +You can try an online demo of the included pre-trained models via HuggingFace Spaces [right here](https://huggingface.co/spaces/davidscripka/openWakeWord)! Note that real-time detection of a microphone stream can occasionally behave strangely in Spaces. For the most reliable testing, perform a local installation as described below. @@ -41,16 +50,20 @@ Many thanks to [TeaPoly](https://github.com/TeaPoly/speexdsp-ns-python) for thei # Usage -For quick local testing, clone this repository and use the included [example script](examples/detect_from_microphone.py) to try streaming detection from a local microphone. **Important note!** The model files are stored in this repo using [git-lfs](https://git-lfs.com/); make sure it is installed on your system and if needed use `git-lfs fetch --all` to make sure the the models download correctly. +For quick local testing, clone this repository and use the included [example script](examples/detect_from_microphone.py) to try streaming detection from a local microphone. You can individually download pre-trained models from current and past [releases](https://github.com/dscripka/openWakeWord/releases/), or you can download them using Python (see below). Adding openWakeWord to your own Python code requires just a few lines: ```python +import openwakeword from openwakeword.model import Model -# Instantiate the model +# One-time download of all pre-trained models (or only select models) +openwakeword.utils.download_models() + +# Instantiate the model(s) model = Model( - wakeword_models=["path/to/model.onnx"], # can also leave this argument empty to load all of the included pre-trained models + wakeword_models=["path/to/model.tflite"], # can also leave this argument empty to load all of the included pre-trained models ) # Get audio data containing 16-bit 16khz PCM audio data from a file, microphone, network stream, etc. @@ -130,7 +143,7 @@ The table below lists each model, examples of the word/phrases it is trained to | current weather | "what's the weather" | [docs](docs/models/weather.md) | | timers | "set a 10 minute timer" | [docs](docs/models/timers.md) | -Based on the methods discussed in [performance testing](#performance-and-evaluation), each included model aims to meet the target performance criteria of <5% false-reject rates and <0.5/hour false-accept rates with appropriate threshold tuning. These levels are subjective, but hopefully are below the annoyance threshold where the average user becomes frustrated with a system that often misses intended activations and/or causes disruption by activating too frequently at undesired times. For example, at these performance levels a user could expect to have the model process continuous mixed content audio of several hours with at most a few false activations, and have a failed intended activation in only 1/20 attempts (and a failed retry in only 1/400 attempts). +Based on the methods discussed in [performance testing](#performance-and-evaluation), each included model aims to meet the target performance criteria of <5% false-reject rates and <0.5/hour false-accept rates with appropriate threshold tuning. These levels are subjective, but hopefully are below the annoyance threshold where the average user becomes frustrated with a system that often misses intended activations and/or causes disruption by activating too frequently at undesired times. For example, at these performance levels a user could expect to have the model process continuous mixed content audio of several hours with at most a few false activations, and have a failed intended activation in only 1/20 attempts (and a failed retry in only 1/400 attempts). If you have a new wake word or phrase that you would like to see included in the next release, please open an issue, and we'll do a best to train a model! The focus of these requests and future release will be on words and phrases that have broad general usage versus highly specific application. @@ -206,7 +219,15 @@ While the models are trained with background noise to increase robustness, in so # Training New Models -Training new models is conceptually simple, and the entire process is demonstrated in a [tutorial notebook](notebooks/training_models.ipynb). +openWakeWord includes an automated utility that greatly simplifies the process of training custom models. This can be used in two ways: + +1) A simple [Google Colab](https://colab.research.google.com/drive/1q1oe2zOyZp7UsB3jJiQ1IFn8z5YfjwEb?usp=sharing) notebook with an easy to use interface and simple end-to-end process. This allows anyone to produce a custom model very quickly (<1 hour) and doesn't require any development experience, but the performance of the model may be low in some deployment scenarios. + +2) A more detailed [notebook](notebooks/automatic_model_training.ipynb) (also on [Google Colab](https://colab.research.google.com/drive/1yyFH-fpguX2BTAW8wSQxTrJnJTM-0QAd?usp=sharing)) that describes the training process in more details, and enables more customization. This can produce high quality models, but requires more development experience. + +For a collection of models trained using the notebooks above by the Home Assistant Community (and with much gratitude to @fwartner), see the excellent repository [here](https://github.com/fwartner/home-assistant-wakewords-collection). + +For users interested in understanding the fundamental concepts behind model training there is a more detailed, educational [tutorial notebook](notebooks/training_models.ipynb) also available. However, this specific notebook is not intended for training production models, and the automated process above is recommended for that purpose. Fundamentally, a new model requires two data generation and collection steps: @@ -227,9 +248,11 @@ Future release road maps may have non-english support. In particular, [Mycroft.A **Can openWakeWord be run in a browser with javascript?** - While the ONNX runtime [does support javascript](https://onnxruntime.ai/docs/get-started/with-javascript.html), much of the other functionality required for openWakeWord models would need to be ported. This is not currently on the roadmap, but please open an issue/start a discussion if this feature is of particular interest. +- As a potential work-around for some applications, the example scripts in `examples/web` demonstrate how audio can be captured in a browser and streaming via websockets into openWakeWord running in a Python backend server. +- Other potential options could include projects like `pyodide` (see [here](https://github.com/pyodide/pyodide/issues/4220)) for a related issue. **Is there a C++ version of openWakeWord?** -- While the ONNX runtime [also has a C++ API](https://onnxruntime.ai/docs/get-started/with-cpp.html), there isn't an official C++ implementation of the full openWakeWord library. However, [@synesthesiam](https://github.com/synesthesiam) has created a [C++ version](https://github.com/rhasspy/openWakeWord-cpp) of openWakeWord with the essential functionality implemented. +- While the ONNX runtime [also has a C++ API](https://onnxruntime.ai/docs/get-started/with-cpp.html), there isn't an official C++ implementation of the full openWakeWord library. However, [@synesthesiam](https://github.com/synesthesiam) has created a [C++ version of openWakeWord](https://github.com/rhasspy/openWakeWord-cpp) with basic functionality implemented. **Why are there three separate models instead of just one?** - Separating the models was an intentional choice to provide flexibility and optimize the efficiency of the end-to-end prediction process. For example, with separate melspectrogram, embedding, and prediction models, each one can operate on different size inputs of audio to optimize overall latency and share computations between models. It certainly is possible to make a combined model with all of the steps integrated, though, if that was a requirement of a particular use case. @@ -237,6 +260,16 @@ Future release road maps may have non-english support. In particular, [Mycroft.A **I still get a large number of false activations when I use the pre-trained models, how can I reduce these?** - First, review the [recommendations for usage](#recommendations-for-usage) and ensure that these options do not improve overall system accuracy. Second, experiment with [custom verifier models](#user-specific-models), if possible. If neither of these approaches are helping, please open an issue with details of the deployment environment and the types of false activations that you are experiencing. We certainly appreciate feedback & requests on how to improve the base pre-trained models! +# Acknowledgements + +I am very grateful for the encouraging and positive response from the open-source community since the release of openWakeWord in January 2023. In particular, I want to acknowledge and thank the following individuals and groups for their feedback, collaboration, and development support: + +- [synesthesiam](https://github.com/synesthesiam) +- [SecretSauceAI](https://github.com/secretsauceai) +- [OpenVoiceOS](https://github.com/OpenVoiceOS) +- [Nabu Casa](https://github.com/NabuCasa) +- [Home Assistant](https://github.com/home-assistant) + # License -All of the code in this repository is licensed under the **Apache 2.0** license. All of the included pre-trained models are licensed under the [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/) license due to the inclusion of datasets with unknown or restrictive licensing as part of the training data. If you are interested in pre-trained models with more permissive licensing, please raise an issue and we will try to add them to a future release. \ No newline at end of file +All of the code in this repository is licensed under the **Apache 2.0** license. All of the included pre-trained models are licensed under the [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/) license due to the inclusion of datasets with unknown or restrictive licensing as part of the training data. If you are interested in pre-trained models with more permissive licensing, please raise an issue and we will try to add them to a future release. diff --git a/examples/capture_activations.py b/examples/capture_activations.py index fae900e..8f8e80d 100644 --- a/examples/capture_activations.py +++ b/examples/capture_activations.py @@ -68,10 +68,26 @@ default=False, required=False ) +parser=argparse.ArgumentParser() +parser.add_argument( + "--chunk_size", + help="How much audio (in number of 16khz samples) to predict on at once", + type=int, + default=1280, + required=False +) +parser.add_argument( + "--model_path", + help="The path of a specific model to load", + type=str, + default="", + required=False +) parser.add_argument( - "--model", - help="The model to use for openWakeWord, leave blank to use all available models", + "--inference_framework", + help="The inference framework to use (either 'onnx' or 'tflite'", type=str, + default='tflite', required=False ) parser.add_argument( @@ -87,25 +103,26 @@ FORMAT = pyaudio.paInt16 CHANNELS = 1 RATE = 16000 -CHUNK = 1280 +CHUNK = args.chunk_size audio = pyaudio.PyAudio() mic_stream = audio.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) # Load pre-trained openwakeword models -if args.model: +if args.model_path: model_paths = openwakeword.get_pretrained_model_paths() for path in model_paths: - if args.model in path: + if args.model_path in path: model_path = path if model_path: owwModel = Model( - wakeword_model_paths=[model_path], + wakeword_models=[model_path], enable_speex_noise_suppression=args.noise_suppression, - vad_threshold = args.vad_threshold - ) + vad_threshold = args.vad_threshold, + inference_framework=args.inference_framework + ) else: - print(f'Could not find model \"{args.model}\"') + print(f'Could not find model \"{args.model_path}\"') exit() else: owwModel = Model( diff --git a/examples/custom_model.yml b/examples/custom_model.yml new file mode 100644 index 0000000..a41d327 --- /dev/null +++ b/examples/custom_model.yml @@ -0,0 +1,101 @@ +## Configuration file to be used with `train.py` to create custom wake word/phrase models + +# The name of the model (will be used when creating directoires and when saving the final .onnx and .tflite files) +model_name: "my_model" + +# The target word/phrase to be detected by the model. Adding multiple unique words/phrases will +# still only train a binary model detection model, but it will activate on any one of the provided words/phrases. +target_phrase: + - "hey jarvis" + +# Specific phrases that you do *not* want the model to activate on, outside of those generated automatically via phoneme overlap +# This can be a good way to reduce false positives if you notice that, in practice, certain words or phrases are problematic +custom_negative_phrases: [] + +# The total number of positive samples to generate for training (minimum of 20,000 recommended, often 100,000+ is best) +n_samples: 10000 + +# The total number of positive samples to generate for validation and early stopping of model training +n_samples_val: 2000 + +# The batch size to use with Piper TTS when generating synthetic training data +tts_batch_size: 50 + +# The batch size to use when performing data augmentation on generated clips prior to training +# It's recommended that this not be too large to ensure that there is enough variety in the augmentation +augmentation_batch_size: 16 + +# The path to a fork of the piper-sample-generator repository for TTS (https://github.com/dscripka/piper-sample-generator) +piper_sample_generator_path: "./piper-sample-generator" + +# The output directory for the generated synthetic clips, openwakeword features, and trained models +# Sub-directories will be automatically created for train and test clips for both positive and negative examples +output_dir: "./my_custom_model" + +# The directories containing Room Impulse Response recordings +rir_paths: + - "./mit_rirs" + +# The directories containing background audio files to mix with training data +background_paths: + - "./background_clips" + +# The duplication rate for the background audio clips listed above (1 or higher). Can be useful as a way to oversample +# a particular type of background noise more relevant to a given deployment environment. Values apply in the same +# order as the background_paths list above. Only useful when multiple directories are provided above. +background_paths_duplication_rate: + - 1 + +# The location of pre-computed openwakeword features for false-positive validation data +# If you do not have deployment environment validation data, a good general purpose dataset with +# a reasonable mix with ~11 hours of speech, noise, and music is available here: https://huggingface.co/datasets/davidscripka/openwakeword_features +false_positive_validation_data_path: "./validation_set_features.npy" + +# The number of times to apply augmentations to the generated training data +# Values greater than 1 reuse each generation that many times, producing overall unique +# clips for training due to the randomness intrinsic to the augmentation despite using +# the same original synthetic generation. Can be a useful way to increase model robustness +# without having to generate extremely large numbers of synthetic examples. +augmentation_rounds: 1 + +# Paths to pre-computed openwakeword features for positive and negative data. Each file must be a saved +# .npy array (see the example notebook on manually training new models for details on how to create these). +# There is no limit on the number of files but training speed will decrease as more +# data will need to be read from disk for each additional file. +# Also, there is a custom dataloader that uses memory-mapping with loading data, so the total size +# of the files is not limited by the amount of available system memory (though this will result +# in decreased training throughput depending on the speed of the underlying storage device). A fast +# NVME SSD is recommended for optimal performance. + +feature_data_files: + "ACAV100M_sample": "./openwakeword_features_ACAV100M_2000_hrs_16bit.npy" + +# Define the number of examples from each data file per batch. Note that the key names here +# must correspond to those define in the `feature_data_files` dictionary above (except for +# the `positive` and `adversarial_negative` keys, which are automatically defined). The sum +# of the values for each key define the total batch size for training. Initial testing indicates +# that batch sizes of 1024-4096 work well in practice. + +batch_n_per_class: + "ACAV100M_sample": 1024 + "adversarial_negative": 50 + "positive": 50 + +# Define the type of size of the openwakeword model to train. Increasing the layer size +# may result in a more capable model, at the cost of decreased inference speed. The default +# value (32) seems to work well in practice for most wake words/phrases. + +model_type: "dnn" +layer_size: 32 + +# Define training parameters. The values below are recommended defaults for most applications, +# but unique deployment environments will likely require testing to determine which values +# are the most appropriate. + +# The maximum number of steps to train the model +steps: 50000 + +# The maximum negative weight and target false positives per hour, used to control the auto training process +# The target false positive rate may not be achieved, and adjusting the maximum negative weight may be necessary +max_negative_weight: 1500 +target_false_positives_per_hour: 0.2 \ No newline at end of file diff --git a/examples/detect_from_microphone.py b/examples/detect_from_microphone.py index 7c21e10..6e69c92 100644 --- a/examples/detect_from_microphone.py +++ b/examples/detect_from_microphone.py @@ -22,10 +22,10 @@ parser=argparse.ArgumentParser() parser.add_argument( "--chunk_size", - help="How much audio (in samples) to predict on at once", + help="How much audio (in number of samples) to predict on at once", type=int, default=1280, - required=True + required=False ) parser.add_argument( "--model_path", diff --git a/examples/web/README.md b/examples/web/README.md new file mode 100644 index 0000000..bd4e970 --- /dev/null +++ b/examples/web/README.md @@ -0,0 +1,21 @@ +# Examples + +This folder contains examples of using openWakeWord with web applications. + +## Websocket Streaming + +As openWakeWord does not have a native Javascript port, using it within a web browswer is best accomplished with websocket streaming of the audio data from the browser to a simple Python application. To install the requirements for this example: + +``` +pip install aiohttp +pip install resampy +``` + +The `streaming_client.html` page shows a simple implementation of audio capture and streamimng from a microphone and streaming in a browser, and the `streaming_server.py` file is the corresponding websocket server that passes the audio into openWakeWord. + +To run the example, execute `python streaming_server.py` (add the `--help` argument to see options) and navigate to `localhost:9000` in your browser. + +Note that this example is illustrative only, and integration of this approach with other web applications may have different requirements. In particular, some key considerations: + +- This example captures PCM audio from the web browser and streams full 16-bit integer representations of ~250 ms audio chunks over the websocket connection. In practice, bandwidth efficient streams of compressed audio may be more suitable for some applications. +- The browser captures audio at the native sampling rate of the capture device, which can require re-sampling prior to passing the audio data to openWakeWord. This example uses the `resampy` library which has a good balance between performance and quality, but other resampling approaches that optimize different aspects may be more suitable for some applications. \ No newline at end of file diff --git a/examples/web/streaming_client.html b/examples/web/streaming_client.html new file mode 100644 index 0000000..c2df273 --- /dev/null +++ b/examples/web/streaming_client.html @@ -0,0 +1,197 @@ + + + + + + Websocket Microphone Streaming + + + +

Streaming Audio to openWakeWord Using Websockets

+ + + + + + + + + + + +
WakewordDetected
+ + + + \ No newline at end of file diff --git a/examples/web/streaming_server.py b/examples/web/streaming_server.py new file mode 100644 index 0000000..449d251 --- /dev/null +++ b/examples/web/streaming_server.py @@ -0,0 +1,112 @@ +# Copyright 2023 David Scripka. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +####################################################################################### + +# This example scripts runs openWakeWord in a simple web server receiving audio +# from a web page using websockets. + +####################################################################################### + +# Imports +import aiohttp +from aiohttp import web +import numpy as np +from openwakeword import Model +import resampy +import argparse +import json + +# Define websocket handler +async def websocket_handler(request): + ws = web.WebSocketResponse() + await ws.prepare(request) + + # Send loaded models + await ws.send_str(json.dumps({"loaded_models": list(owwModel.models.keys())})) + + # Start listening for websocket messages + async for msg in ws: + # Get the sample rate of the microphone from the browser + if msg.type == aiohttp.WSMsgType.TEXT: + sample_rate = int(msg.data) + elif msg.type == aiohttp.WSMsgType.ERROR: + print(f"WebSocket error: {ws.exception()}") + else: + # Get audio data from websocket + audio_bytes = msg.data + + # Add extra bytes of silence if needed + if len(msg.data) % 2 == 1: + audio_bytes += (b'\x00') + + # Convert audio to correct format and sample rate + data = np.frombuffer(audio_bytes, dtype=np.int16) + if sample_rate != 16000: + data = resampy.resample(data, sample_rate, 16000) + + # Get openWakeWord predictions and set to browser client + predictions = owwModel.predict(data) + + activations = [] + for key in predictions: + if predictions[key] >= 0.5: + activations.append(key) + + if activations != []: + await ws.send_str(json.dumps({"activations": activations})) + + return ws + +# Define static file handler +async def static_file_handler(request): + return web.FileResponse('./streaming_client.html') + +app = web.Application() +app.add_routes([web.get('/ws', websocket_handler), web.get('/', static_file_handler)]) + +if __name__ == '__main__': + # Parse CLI arguments + parser=argparse.ArgumentParser() + parser.add_argument( + "--chunk_size", + help="How much audio (in number of samples) to predict on at once", + type=int, + default=1280, + required=False + ) + parser.add_argument( + "--model_path", + help="The path of a specific model to load", + type=str, + default="", + required=False + ) + parser.add_argument( + "--inference_framework", + help="The inference framework to use (either 'onnx' or 'tflite'", + type=str, + default='tflite', + required=False + ) + args=parser.parse_args() + + # Load openWakeWord models + if args.model_path != "": + owwModel = Model(wakeword_models=[args.model_path], inference_framework=args.inference_framework) + else: + owwModel = Model(inference_framework=args.inference_framework) + + # Start webapp + web.run_app(app, host='localhost', port=9000) \ No newline at end of file diff --git a/notebooks/.gitignore b/notebooks/.gitignore new file mode 100644 index 0000000..b0f0998 --- /dev/null +++ b/notebooks/.gitignore @@ -0,0 +1 @@ +cv11_test_clips diff --git a/notebooks/automatic_model_training.ipynb b/notebooks/automatic_model_training.ipynb new file mode 100644 index 0000000..51ed036 --- /dev/null +++ b/notebooks/automatic_model_training.ipynb @@ -0,0 +1,494 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c1eab0b3", + "metadata": { + "id": "c1eab0b3" + }, + "source": [ + "# Introduction" + ] + }, + { + "cell_type": "markdown", + "id": "882058c5", + "metadata": { + "id": "882058c5" + }, + "source": [ + "This notebook demonstrates how to train custom openWakeWord models using pre-defined datasets and an automated process for dataset generation and training. While not guaranteed to always produce the best performing model, the methods shown in this notebook often produce baseline models with releatively strong performance.\n", + "\n", + "Manual data preparation and model training (e.g., see the [training models](training_models.ipynb) notebook) remains an option for when full control over the model development process is needed.\n", + "\n", + "At a high level, the automatic training process takes advantages of several techniques to try and produce a good model, including:\n", + "\n", + "- Early-stopping and checkpoint averaging (similar to [stochastic weight averaging](https://arxiv.org/abs/1803.05407)) to search for the best models found during training, according to the validation data\n", + "- Variable learning rates with cosine decay and multiple cycles\n", + "- Adaptive batch construction to focus on only high-loss examples when the model begins to converge, combined with gradient accumulation to ensure that batch sizes are still large enough for stable training\n", + "- Cycical weight schedules for negative examples to help the model reduce false-positive rates\n", + "\n", + "See the contents of the `train.py` file for more details." + ] + }, + { + "cell_type": "markdown", + "id": "e08d031b", + "metadata": { + "id": "e08d031b" + }, + "source": [ + "# Environment Setup" + ] + }, + { + "cell_type": "markdown", + "id": "aee78c37", + "metadata": { + "id": "aee78c37" + }, + "source": [ + "To begin, we'll need to install the requirements for training custom models. In particular, a relatively recent version of Pytorch and custom fork of the [piper-sample-generator](https://github.com/dscripka/piper-sample-generator) library for generating synthetic examples for the custom model.\n", + "\n", + "**Important Note!** Currently, automated model training is only supported on linux systems due to the requirements of the text to speech library used for synthetic sample generation (Piper). It may be possible to use Piper on Windows/Mac systems, but that has not (yet) been tested." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4b1227eb", + "metadata": { + "id": "4b1227eb" + }, + "outputs": [], + "source": [ + "## Environment setup\n", + "\n", + "# install piper-sample-generator (currently only supports linux systems)\n", + "!git clone https://github.com/rhasspy/piper-sample-generator\n", + "!wget -O piper-sample-generator/models/en_US-libritts_r-medium.pt 'https://github.com/rhasspy/piper-sample-generator/releases/download/v2.0.0/en_US-libritts_r-medium.pt'\n", + "!pip install piper-phonemize\n", + "!pip install webrtcvad\n", + "\n", + "# install openwakeword (full installation to support training)\n", + "!git clone https://github.com/dscripka/openwakeword\n", + "!pip install -e ./openwakeword\n", + "!cd openwakeword\n", + "\n", + "# install other dependencies\n", + "!pip install mutagen==1.47.0\n", + "!pip install torchinfo==1.8.0\n", + "!pip install torchmetrics==1.2.0\n", + "!pip install speechbrain==0.5.14\n", + "!pip install audiomentations==0.33.0\n", + "!pip install torch-audiomentations==0.11.0\n", + "!pip install acoustics==0.2.6\n", + "!pip install tensorflow-cpu==2.8.1\n", + "!pip install tensorflow_probability==0.16.0\n", + "!pip install onnx_tf==1.10.0\n", + "!pip install pronouncing==0.2.0\n", + "!pip install datasets==2.14.6\n", + "!pip install deep-phonemizer==0.0.19\n", + "\n", + "# Download required models (workaround for Colab)\n", + "import os\n", + "os.makedirs(\"./openwakeword/openwakeword/resources/models\")\n", + "!wget https://github.com/dscripka/openWakeWord/releases/download/v0.5.1/embedding_model.onnx -O ./openwakeword/openwakeword/resources/models/embedding_model.onnx\n", + "!wget https://github.com/dscripka/openWakeWord/releases/download/v0.5.1/embedding_model.tflite -O ./openwakeword/openwakeword/resources/models/embedding_model.tflite\n", + "!wget https://github.com/dscripka/openWakeWord/releases/download/v0.5.1/melspectrogram.onnx -O ./openwakeword/openwakeword/resources/models/melspectrogram.onnx\n", + "!wget https://github.com/dscripka/openWakeWord/releases/download/v0.5.1/melspectrogram.tflite -O ./openwakeword/openwakeword/resources/models/melspectrogram.tflite\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d4c1056e", + "metadata": { + "ExecuteTime": { + "end_time": "2023-09-04T13:42:01.183840Z", + "start_time": "2023-09-04T13:41:59.752153Z" + }, + "id": "d4c1056e" + }, + "outputs": [], + "source": [ + "# Imports\n", + "\n", + "import os\n", + "import numpy as np\n", + "import torch\n", + "import sys\n", + "from pathlib import Path\n", + "import uuid\n", + "import yaml\n", + "import datasets\n", + "import scipy\n", + "from tqdm import tqdm\n" + ] + }, + { + "cell_type": "markdown", + "id": "e9d7a05a", + "metadata": { + "id": "e9d7a05a" + }, + "source": [ + "# Download Data" + ] + }, + { + "cell_type": "markdown", + "id": "c52f75cc", + "metadata": { + "id": "c52f75cc" + }, + "source": [ + "When training new openWakeWord models using the automated procedure, four specific types of data are required:\n", + "\n", + "1) Synthetic examples of the target word/phrase generated with text-to-speech models\n", + "\n", + "2) Synthetic examples of adversarial words/phrases generated with text-to-speech models\n", + "\n", + "3) Room impulse reponses and noise/background audio data to augment the synthetic examples and make them more realistic\n", + "\n", + "4) Generic \"negative\" audio data that is very unlikely to contain examples of the target word/phrase in the context where the model should detect it. This data can be the original audio data, or precomputed openWakeWord features ready for model training.\n", + "\n", + "5) Validation data to use for early-stopping when training the model.\n", + "\n", + "For the purposes of this notebook, all five of these sources will either be generated manually or can be obtained from HuggingFace thanks to their excellent `datasets` library and extremely generous hosting policy. Also note that while only a portion of some datasets are downloaded, for the best possible performance it is recommended to download the entire dataset and keep a local copy for future training runs." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d25a93b1", + "metadata": { + "ExecuteTime": { + "end_time": "2023-09-04T01:07:17.746749Z", + "start_time": "2023-09-04T01:07:17.740846Z" + }, + "id": "d25a93b1" + }, + "outputs": [], + "source": [ + "# Download room impulse responses collected by MIT\n", + "# https://mcdermottlab.mit.edu/Reverb/IR_Survey.html\n", + "\n", + "output_dir = \"./mit_rirs\"\n", + "if not os.path.exists(output_dir):\n", + " os.mkdir(output_dir)\n", + "rir_dataset = datasets.load_dataset(\"davidscripka/MIT_environmental_impulse_responses\", split=\"train\", streaming=True)\n", + "\n", + "# Save clips to 16-bit PCM wav files\n", + "for row in tqdm(rir_dataset):\n", + " name = row['audio']['path'].split('/')[-1]\n", + " scipy.io.wavfile.write(os.path.join(output_dir, name), 16000, (row['audio']['array']*32767).astype(np.int16))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2c0e178b", + "metadata": { + "id": "2c0e178b" + }, + "outputs": [], + "source": [ + "## Download noise and background audio\n", + "\n", + "# Audioset Dataset (https://research.google.com/audioset/dataset/index.html)\n", + "# Download one part of the audioset .tar files, extract, and convert to 16khz\n", + "# For full-scale training, it's recommended to download the entire dataset from\n", + "# https://huggingface.co/datasets/agkphysics/AudioSet, and\n", + "# even potentially combine it with other background noise datasets (e.g., FSD50k, Freesound, etc.)\n", + "\n", + "if not os.path.exists(\"audioset\"):\n", + " os.mkdir(\"audioset\")\n", + "\n", + "fname = \"bal_train09.tar\"\n", + "out_dir = f\"audioset/{fname}\"\n", + "link = \"https://huggingface.co/datasets/agkphysics/AudioSet/resolve/main//" + fname\n", + "!wget -O {out_dir} {link}\n", + "!cd audioset && tar -xvf bal_train09.tar\n", + "\n", + "output_dir = \"./audioset_16k\"\n", + "if not os.path.exists(output_dir):\n", + " os.mkdir(output_dir)\n", + "\n", + "# Convert audioset files to 16khz sample rate\n", + "audioset_dataset = datasets.Dataset.from_dict({\"audio\": [str(i) for i in Path(\"audioset/audio\").glob(\"**/*.flac\")]})\n", + "audioset_dataset = audioset_dataset.cast_column(\"audio\", datasets.Audio(sampling_rate=16000))\n", + "for row in tqdm(audioset_dataset):\n", + " name = row['audio']['path'].split('/')[-1].replace(\".flac\", \".wav\")\n", + " scipy.io.wavfile.write(os.path.join(output_dir, name), 16000, (row['audio']['array']*32767).astype(np.int16))\n", + "\n", + "# Free Music Archive dataset (https://github.com/mdeff/fma)\n", + "output_dir = \"./fma\"\n", + "if not os.path.exists(output_dir):\n", + " os.mkdir(output_dir)\n", + "fma_dataset = datasets.load_dataset(\"rudraml/fma\", name=\"small\", split=\"train\", streaming=True)\n", + "fma_dataset = iter(fma_dataset.cast_column(\"audio\", datasets.Audio(sampling_rate=16000)))\n", + "\n", + "n_hours = 1 # use only 1 hour of clips for this example notebook, recommend increasing for full-scale training\n", + "for i in tqdm(range(n_hours*3600//30)): # this works because the FMA dataset is all 30 second clips\n", + " row = next(fma_dataset)\n", + " name = row['audio']['path'].split('/')[-1].replace(\".mp3\", \".wav\")\n", + " scipy.io.wavfile.write(os.path.join(output_dir, name), 16000, (row['audio']['array']*32767).astype(np.int16))\n", + " i += 1\n", + " if i == n_hours*3600//30:\n", + " break\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d01ec467", + "metadata": { + "id": "d01ec467" + }, + "outputs": [], + "source": [ + "# Download pre-computed openWakeWord features for training and validation\n", + "\n", + "# training set (~2,000 hours from the ACAV100M Dataset)\n", + "# See https://huggingface.co/datasets/davidscripka/openwakeword_features for more information\n", + "!wget https://huggingface.co/datasets/davidscripka/openwakeword_features/resolve/main/openwakeword_features_ACAV100M_2000_hrs_16bit.npy\n", + "\n", + "# validation set for false positive rate estimation (~11 hours)\n", + "!wget https://huggingface.co/datasets/davidscripka/openwakeword_features/resolve/main/validation_set_features.npy" + ] + }, + { + "cell_type": "markdown", + "id": "cfe82647", + "metadata": { + "id": "cfe82647" + }, + "source": [ + "# Define Training Configuration" + ] + }, + { + "cell_type": "markdown", + "id": "b2e71329", + "metadata": { + "id": "b2e71329" + }, + "source": [ + "For automated model training openWakeWord uses a specially designed training script and a [YAML](https://yaml.org/) configuration file that defines all of the information required for training a new wake word/phrase detection model.\n", + "\n", + "It is strongly recommended that you review [the example config file](../examples/custom_model.yml), as each value is fully documented there. For the purposes of this notebook, we'll read in the YAML file to modify certain configuration parameters before saving a new YAML file for training our example model. Specifically:\n", + "\n", + "- We'll train a detection model for the phrase \"hey sebastian\"\n", + "- We'll only generate 5,000 positive and negative examples (to save on time for this example)\n", + "- We'll only generate 1,000 validation positive and negative examples for early stopping (again to save time)\n", + "- The model will only be trained for 10,000 steps (larger datasets will benefit from longer training)\n", + "- We'll reduce the target metrics to account for the small dataset size and limited training.\n", + "\n", + "On the topic of target metrics, there are *not* specific guidelines about what these metrics should be in practice, and you will need to conduct testing in your target deployment environment to establish good thresholds. However, from very limited testing the default values in the config file (accuracy >= 0.7, recall >= 0.5, false-positive rate <= 0.2 per hour) seem to produce models with reasonable performance.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fb0b6e4f", + "metadata": { + "ExecuteTime": { + "end_time": "2023-09-04T18:11:33.893397Z", + "start_time": "2023-09-04T18:11:33.878938Z" + }, + "id": "fb0b6e4f" + }, + "outputs": [], + "source": [ + "# Load default YAML config file for training\n", + "config = yaml.load(open(\"openwakeword/examples/custom_model.yml\", 'r').read(), yaml.Loader)\n", + "config" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "482cf2d0", + "metadata": { + "ExecuteTime": { + "end_time": "2023-09-04T15:07:00.859210Z", + "start_time": "2023-09-04T15:07:00.841472Z" + }, + "id": "482cf2d0" + }, + "outputs": [], + "source": [ + "# Modify values in the config and save a new version\n", + "\n", + "config[\"target_phrase\"] = [\"hey sebastian\"]\n", + "config[\"model_name\"] = config[\"target_phrase\"][0].replace(\" \", \"_\")\n", + "config[\"n_samples\"] = 1000\n", + "config[\"n_samples_val\"] = 1000\n", + "config[\"steps\"] = 10000\n", + "config[\"target_accuracy\"] = 0.6\n", + "config[\"target_recall\"] = 0.25\n", + "\n", + "config[\"background_paths\"] = ['./audioset_16k', './fma'] # multiple background datasets are supported\n", + "config[\"false_positive_validation_data_path\"] = \"validation_set_features.npy\"\n", + "config[\"feature_data_files\"] = {\"ACAV100M_sample\": \"openwakeword_features_ACAV100M_2000_hrs_16bit.npy\"}\n", + "\n", + "with open('my_model.yaml', 'w') as file:\n", + " documents = yaml.dump(config, file)" + ] + }, + { + "cell_type": "markdown", + "id": "aa6b2ab0", + "metadata": { + "id": "aa6b2ab0" + }, + "source": [ + "# Train the Model" + ] + }, + { + "cell_type": "markdown", + "id": "a51202c0", + "metadata": { + "id": "a51202c0" + }, + "source": [ + "With the data downloaded and training configuration set, we can now start training the model. We'll do this in parts to better illustrate the sequence, but you can also execute every step at once for a fully automated process." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f01531fa", + "metadata": { + "ExecuteTime": { + "end_time": "2023-09-04T13:50:08.803326Z", + "start_time": "2023-09-04T13:50:06.790241Z" + }, + "id": "f01531fa" + }, + "outputs": [], + "source": [ + "# Step 1: Generate synthetic clips\n", + "# For the number of clips we are using, this should take ~10 minutes on a free Google Colab instance with a T4 GPU\n", + "# If generation fails, you can simply run this command again as it will continue generating until the\n", + "# number of files meets the targets specified in the config file\n", + "\n", + "!{sys.executable} openwakeword/openwakeword/train.py --training_config my_model.yaml --generate_clips" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "afeedae4", + "metadata": { + "ExecuteTime": { + "end_time": "2023-09-04T13:56:08.781018Z", + "start_time": "2023-09-04T13:55:40.203515Z" + }, + "id": "afeedae4" + }, + "outputs": [], + "source": [ + "# Step 2: Augment the generated clips\n", + "\n", + "!{sys.executable} openwakeword/openwakeword/train.py --training_config my_model.yaml --augment_clips" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9ad81ea0", + "metadata": { + "ExecuteTime": { + "end_time": "2023-09-04T15:11:14.742260Z", + "start_time": "2023-09-04T15:07:03.755159Z" + }, + "id": "9ad81ea0" + }, + "outputs": [], + "source": [ + "# Step 3: Train model\n", + "\n", + "!{sys.executable} openwakeword/openwakeword/train.py --training_config my_model.yaml --train_model" + ] + }, + { + "cell_type": "code", + "source": [ + "# Step 4 (Optional): On Google Colab, sometimes the .tflite model isn't saved correctly\n", + "# If so, run this cell to retry\n", + "\n", + "# Manually save to tflite as this doesn't work right in colab\n", + "def convert_onnx_to_tflite(onnx_model_path, output_path):\n", + " \"\"\"Converts an ONNX version of an openwakeword model to the Tensorflow tflite format.\"\"\"\n", + " # imports\n", + " import onnx\n", + " import logging\n", + " import tempfile\n", + " from onnx_tf.backend import prepare\n", + " import tensorflow as tf\n", + "\n", + " # Convert to tflite from onnx model\n", + " onnx_model = onnx.load(onnx_model_path)\n", + " tf_rep = prepare(onnx_model, device=\"CPU\")\n", + " with tempfile.TemporaryDirectory() as tmp_dir:\n", + " tf_rep.export_graph(os.path.join(tmp_dir, \"tf_model\"))\n", + " converter = tf.lite.TFLiteConverter.from_saved_model(os.path.join(tmp_dir, \"tf_model\"))\n", + " tflite_model = converter.convert()\n", + "\n", + " logging.info(f\"####\\nSaving tflite mode to '{output_path}'\")\n", + " with open(output_path, 'wb') as f:\n", + " f.write(tflite_model)\n", + "\n", + " return None\n", + "\n", + "convert_onnx_to_tflite(f\"my_custom_model/{config['model_name']}.onnx\", f\"my_custom_model/{config['model_name']}.tflite\")\n" + ], + "metadata": { + "id": "JSKWWLalnYzR" + }, + "id": "JSKWWLalnYzR", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "After the model finishes training, the auto training script will automatically convert it to ONNX and tflite versions, saving them as `my_custom_model/.onnx/tflite` in the present working directory, where `` is defined in the YAML training config file. Either version can be used as normal with `openwakeword`. I recommend testing them with the [`detect_from_microphone.py`](https://github.com/dscripka/openWakeWord/blob/main/examples/detect_from_microphone.py) example script to see how the model performs!" + ], + "metadata": { + "id": "f9OyUW3ltOSs" + }, + "id": "f9OyUW3ltOSs" + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "name": "python" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "colab": { + "provenance": [] + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file diff --git a/notebooks/converting_google_speech_embedding_model.ipynb b/notebooks/converting_google_speech_embedding_model.ipynb new file mode 100644 index 0000000..4df8ea3 --- /dev/null +++ b/notebooks/converting_google_speech_embedding_model.ipynb @@ -0,0 +1,1113 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "838ffa12", + "metadata": {}, + "source": [ + "This notebook demonstrates how the speech embedding model from Google (https://www.kaggle.com/models/google/speech-embedding/frameworks/tensorFlow1/variations/speech-embedding/versions/1) is re-implemented in Keras manually, which can then be converted to ONNX and tflite formats for use in openWakeWord.\n", + "\n", + "Note that Keras was used here, but in theory other deep learning frameworks (e.g., PyTorch) could work as well." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "893d29dc", + "metadata": { + "ExecuteTime": { + "end_time": "2024-01-18T00:26:11.649261Z", + "start_time": "2024-01-18T00:26:10.190666Z" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2024-01-17 19:26:10.372628: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n", + "2024-01-17 19:26:10.372640: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n" + ] + } + ], + "source": [ + "# Imports\n", + "\n", + "import os\n", + "import numpy as np\n", + "import scipy\n", + "import tensorflow as tf\n", + "import tensorflow_hub as hub # install with `pip install tensorflow_hub`\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "id": "fe3054ae", + "metadata": {}, + "source": [ + "# Load Orignal Model from TFHub" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "fa2bc0d3", + "metadata": { + "ExecuteTime": { + "end_time": "2024-01-18T00:26:12.257919Z", + "start_time": "2024-01-18T00:26:11.650661Z" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2024-01-17 19:26:11.857817: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:936] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2024-01-17 19:26:11.858167: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n", + "2024-01-17 19:26:11.858193: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcublas.so.11'; dlerror: libcublas.so.11: cannot open shared object file: No such file or directory\n", + "2024-01-17 19:26:11.858215: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcublasLt.so.11'; dlerror: libcublasLt.so.11: cannot open shared object file: No such file or directory\n", + "2024-01-17 19:26:11.858237: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcufft.so.10'; dlerror: libcufft.so.10: cannot open shared object file: No such file or directory\n", + "2024-01-17 19:26:11.858258: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcurand.so.10'; dlerror: libcurand.so.10: cannot open shared object file: No such file or directory\n", + "2024-01-17 19:26:11.858278: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcusolver.so.11'; dlerror: libcusolver.so.11: cannot open shared object file: No such file or directory\n", + "2024-01-17 19:26:11.858299: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcusparse.so.11'; dlerror: libcusparse.so.11: cannot open shared object file: No such file or directory\n", + "2024-01-17 19:26:11.858320: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudnn.so.8'; dlerror: libcudnn.so.8: cannot open shared object file: No such file or directory\n", + "2024-01-17 19:26:11.858325: W tensorflow/core/common_runtime/gpu/gpu_device.cc:1850] Cannot dlopen some GPU libraries. Please make sure the missing libraries mentioned above are installed properly if you would like to use GPU. Follow the guide at https://www.tensorflow.org/install/gpu for how to download and setup the required libraries for your platform.\n", + "Skipping registering GPU devices...\n", + "2024-01-17 19:26:11.858458: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX512F FMA\n", + "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n" + ] + } + ], + "source": [ + "# Load the original speech embedding model (now hosted on Kaggle) as a KerasLayer object\n", + "\n", + "embedding_model_url = \"https://tfhub.dev/google/speech_embedding/1/"\n", + "embedding_model = hub.KerasLayer(embedding_model_url, trainable=False)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "6769931f", + "metadata": { + "ExecuteTime": { + "end_time": "2024-01-18T00:26:12.375204Z", + "start_time": "2024-01-18T00:26:12.259632Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Embedding Output Shape: (1, 1, 1, 96)\n" + ] + } + ], + "source": [ + "# Get predictions from the embedding model for a chunk of ~775 ms audio data (at 16khz)\n", + "# This is the minimum input size for the model per the documentation here: https://www.kaggle.com/models/google/speech-embedding/frameworks/tensorFlow1/variations/speech-embedding/versions/1\n", + "\n", + "# Load sample clip, and select a 775 ms chunk and normalize between -1 and 1\n", + "sr, sample_data = scipy.io.wavfile.read(\"../tests/data/hey_mycroft_test.wav\")\n", + "sample_data = (sample_data[0:12400][None,]/32767).astype(np.float32)\n", + "embeddings = embedding_model(sample_data)\n", + "print(\"Embedding Output Shape:\", embeddings.shape)" + ] + }, + { + "cell_type": "markdown", + "id": "e8acfba9", + "metadata": {}, + "source": [ + "# Convert original model to tflite" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "b4ee1693", + "metadata": { + "ExecuteTime": { + "end_time": "2024-01-18T00:26:14.554068Z", + "start_time": "2024-01-18T00:26:12.376427Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING:tensorflow:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.\n", + "2024-01-17 19:26:12.970115: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:tensorflow:Assets written to: google_speech_embedding_fixed_input/assets\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:tensorflow:Assets written to: google_speech_embedding_fixed_input/assets\n", + "2024-01-17 19:26:14.061242: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:357] Ignored output_format.\n", + "2024-01-17 19:26:14.061261: W tensorflow/compiler/mlir/lite/python/tf_tfl_flatbuffer_helpers.cc:360] Ignored drop_control_dependency.\n", + "2024-01-17 19:26:14.061688: I tensorflow/cc/saved_model/reader.cc:43] Reading SavedModel from: google_speech_embedding_fixed_input\n", + "2024-01-17 19:26:14.066816: I tensorflow/cc/saved_model/reader.cc:78] Reading meta graph with tags { serve }\n", + "2024-01-17 19:26:14.066828: I tensorflow/cc/saved_model/reader.cc:119] Reading SavedModel debug info (if present) from: google_speech_embedding_fixed_input\n", + "2024-01-17 19:26:14.076781: I tensorflow/cc/saved_model/loader.cc:228] Restoring SavedModel bundle.\n", + "2024-01-17 19:26:14.173155: I tensorflow/cc/saved_model/loader.cc:212] Running initialization op on SavedModel bundle at path: google_speech_embedding_fixed_input\n", + "2024-01-17 19:26:14.236537: I tensorflow/cc/saved_model/loader.cc:301] SavedModel load for tags { serve }; Status: success: OK. Took 174850 microseconds.\n", + "2024-01-17 19:26:14.288965: I tensorflow/compiler/mlir/tensorflow/utils/dump_mlir_util.cc:237] disabling MLIR crash reproducer, set env var `MLIR_CRASH_REPRODUCER_DIRECTORY` to enable.\n", + "2024-01-17 19:26:14.405541: W tensorflow/compiler/mlir/lite/flatbuffer_export.cc:1881] Graph contains the following resource op(s), that use(s) resource type. Currently, the resource type is not natively supported in TFLite. Please consider not using the resource type if there are issues with either TFLite converter or TFLite runtime:\n", + "Resource ops: TensorArrayGatherV3, TensorArrayReadV3, TensorArrayScatterV3, TensorArrayV3, TensorArrayWriteV3\n", + "Details:\n", + "\ttf.TensorArrayGatherV3(tensor<2x!tf_type.resource>>, tensor, tensor) -> (tensor) : {device = \"\", element_shape = #tf_type.shape}\n", + "\ttf.TensorArrayReadV3(tensor<2x!tf_type.resource>>, tensor, tensor) -> (tensor<*xf32>) : {device = \"\"}\n", + "\ttf.TensorArrayScatterV3(tensor<2x!tf_type.resource>>, tensor, tensor, tensor) -> (tensor) : {device = \"\"}\n", + "\ttf.TensorArrayV3(tensor) -> (tensor<2x!tf_type.resource>>, tensor) : {clear_after_read = true, device = \"\", dtype = f32, dynamic_size = false, element_shape = #tf_type.shape<*>, identical_element_shapes = true, tensor_array_name = \"\"}\n", + "\ttf.TensorArrayWriteV3(tensor<2x!tf_type.resource>>, tensor, tensor, tensor) -> (tensor) : {device = \"\"}\n", + "2024-01-17 19:26:14.405561: W tensorflow/compiler/mlir/lite/flatbuffer_export.cc:1892] TFLite interpreter needs to link Flex delegate in order to run the model since it contains the following Select TFop(s):\n", + "Flex ops: FlexTensorArrayGatherV3, FlexTensorArrayReadV3, FlexTensorArrayScatterV3, FlexTensorArrayV3, FlexTensorArrayWriteV3\n", + "Details:\n", + "\ttf.TensorArrayGatherV3(tensor<2x!tf_type.resource>>, tensor, tensor) -> (tensor) : {device = \"\", element_shape = #tf_type.shape}\n", + "\ttf.TensorArrayReadV3(tensor<2x!tf_type.resource>>, tensor, tensor) -> (tensor<*xf32>) : {device = \"\"}\n", + "\ttf.TensorArrayScatterV3(tensor<2x!tf_type.resource>>, tensor, tensor, tensor) -> (tensor) : {device = \"\"}\n", + "\ttf.TensorArrayV3(tensor) -> (tensor<2x!tf_type.resource>>, tensor) : {clear_after_read = true, device = \"\", dtype = f32, dynamic_size = false, element_shape = #tf_type.shape<*>, identical_element_shapes = true, tensor_array_name = \"\"}\n", + "\ttf.TensorArrayWriteV3(tensor<2x!tf_type.resource>>, tensor, tensor, tensor) -> (tensor) : {device = \"\"}\n", + "See instructions: https://www.tensorflow.org/lite/guide/ops_select\n" + ] + } + ], + "source": [ + "# Build model with specific input size, and save\n", + "inputs = tf.keras.Input((12400,))\n", + "x = embedding_model(inputs)\n", + "model = tf.keras.Model(inputs=inputs, outputs=x)\n", + "model.save(\"google_speech_embedding_fixed_input\")\n", + "\n", + "speech_embedding_dir = \"google_speech_embedding_fixed_input\"\n", + "# speech_embedding_dir = \"google_speech_embedding_savedmodel/\"\n", + "\n", + "converter = tf.lite.TFLiteConverter.from_saved_model(speech_embedding_dir)#, tags=[\"train\"])\n", + "# convert = tf.lite.TFLiteConverter.from_keras_model(embedding_model)\n", + "converter.target_spec.supported_ops = [\n", + " tf.lite.OpsSet.TFLITE_BUILTINS, tf.lite.OpsSet.SELECT_TF_OPS\n", + "]\n", + "# converter.allow_custom_ops = True\n", + "\n", + "tflite_model = converter.convert()\n", + "with open(speech_embedding_dir + '/speech_embeddings.tflite', 'wb') as f:\n", + " f.write(tflite_model)\n" + ] + }, + { + "cell_type": "markdown", + "id": "927ebfda", + "metadata": {}, + "source": [ + "# Comparing Log-Mel Features" + ] + }, + { + "cell_type": "markdown", + "id": "48c7138b", + "metadata": {}, + "source": [ + "The speech embedding model from Google computes it's own input features from raw audio, which is convenient, but not ideal as it combines pre-processing with the model in a way that makes the model less understandable. In particular, this is (to my knowledge) the total information provided about the feature creation:\n", + "\n", + "From the model page [here:](https://www.kaggle.com/models/google/speech-embedding/frameworks/tensorFlow1/variations/speech-embedding/versions/1)\n", + "```\n", + "The module computes its own 32 dimensional log-mel features from the provided audio samples using the following parameters:\n", + "\n", + " stft window size: 25ms\n", + " stft window step: 10ms\n", + " mel band limits: 60Hz - 3800Hz\n", + " mel frequency bins: 32\n", + "```\n", + "\n", + "And then this excerpt from the corresponding [paper](https://arxiv.org/abs/2002.01322):\n", + "\n", + "```\n", + "Our model is designed for deployment in an environment\n", + "where both memory and compute power are very limited,\n", + "such as on a digital signal processor (DSP). It runs on top of a\n", + "low footprint feature extractor that provides a 32 dimensional\n", + "log mel feature vector covering the frequency range from\n", + "60 Hz to 3800 Hz, quantized to 8 bits every 10 ms\n", + "```\n", + "\n", + "It seems likely that this implementation is simply a [spectrogram](https://librosa.org/doc/main/generated/librosa.feature.melspectrogram.html) with [log scaling](https://librosa.org/doc/main/generated/librosa.power_to_db.html), but the investigation below shows that this may note be the case.\n", + "\n", + "If you have a theory as to what the original model is doing, or why a standard log-mel spectrogram does not match, please open an issue on the [openWakeWord](https://github.com/dscripka/openWakeWord), I would love learn more about this!" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "6599a6a0", + "metadata": { + "ExecuteTime": { + "end_time": "2024-01-18T00:26:14.703602Z", + "start_time": "2024-01-18T00:26:14.555114Z" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO: Created TensorFlow Lite delegate for select TF ops.\n", + "2024-01-17 19:26:14.557849: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:936] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2024-01-17 19:26:14.558198: W tensorflow/core/common_runtime/gpu/gpu_device.cc:1850] Cannot dlopen some GPU libraries. Please make sure the missing libraries mentioned above are installed properly if you would like to use GPU. Follow the guide at https://www.tensorflow.org/install/gpu for how to download and setup the required libraries for your platform.\n", + "Skipping registering GPU devices...\n", + "INFO: TfLiteFlexDelegate delegate: 4 nodes delegated out of 76 nodes with 2 partitions.\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Embedding model features shape: (32, 76)\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAD+CAYAAACa2mffAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABC4UlEQVR4nO29e5BVV53+/Zz7pS+naaC76XAJuUguCDrEIKKZmGCQ8WclmrKi49SQ0dExA44JTqnUq8bLOESt0egMkhknk2hpRONPdOKUZCIxnTczIRqUl1wMBkKguXQ30PQ53ed+9t7vH5m0dvr7rMkhcBq6n0/VqaLXPmvvtb5r7XW+nLOe/YSCIAgghBBCCNEgwhPdACGEEEJMLZR8CCGEEKKhKPkQQgghRENR8iGEEEKIhqLkQwghhBANRcmHEEIIIRqKkg8hhBBCNBQlH0IIIYRoKEo+hBBCCNFQohPdgJfi+z4OHz6MlpYWhEKhiW6OEEIIIV4GQRBgeHgY3d3dCIf/l+82gtPEP/3TPwXz5s0LEolEcPnllwePPfbYy6rX29sbANBLL7300ksvvc7CV29v7//6WX9avvn4/ve/j3Xr1uGOO+7A0qVLcfvtt2PlypXYvXs3Ojo6nHVbWloAAK/9P/8PIrHk+OP782a94wtb6DljhcAsH57DM7OYfRmEfPtcAFBttr+p8R1RjiwZMsvPbTvBKxHikRo9Fg7Z7fYD/u0SO1asxWidVLRqlqejFVonHvLqbkM0zOtESF89R19ZnaofoXVqgT1/Cl6c1slX7WMJx9hVXBOIkIzY48DmgetYGLxOJlY0y+OO8WmN2nUAYLDSbJb/v4fOo3Vqu+17P5bl493U55vlfoTXGVxsxyHEhw7xQXuOhB118heVzfK3XPxbWqcjPmyWRx33VoUs/x6Z1wCQ9xL2uRz3ydGyPaYAEA3b43Cs2ETr7O+bbpbP7uBr5pEnuszyIOy4H7oLdp1e3rZo3p4/zb38OvFhOwaRkl0OACFiyVZp4eMQH7bngqtOcaZ9LJ4ja2y1hF3/9/Ojn+MuTkvy8ZWvfAUf+MAH8Bd/8RcAgDvuuAP/8R//gX/7t3/DJz7xCWfdF39qicSSiBrJRzRiBzASH//e0TpVO1CRBL/JyNrtTD78hD3xQq7kI23fzLEm/gHGiEV4f05l8lGt8bbFonadmCMGrg+qiU4+Qo5FNUwWaVd8olUy3o6xC04i+YiRD9FTnXzE4/Y4xB2frokoPxav2Iktu08AwE/a936k5BjvuL2whxzJRzhZf/LB1pgwn1YIp+w2xJv5vErE7bjFQnxehU4i+ah65D8ejjkaizruB5J8RMN8vMMpe7yjTY46ZI44k4+03baAnAsAIjV77CJxfp1ojCQfniP5IJ9DfoxPrGjUvldddSJx+5irPwBe1paJU77htFKpYMeOHVixYsXvLxIOY8WKFXj00UfHvb9cLiOXy415CSGEEGLycsqTj2PHjsHzPHR2do4p7+zsRF9f37j3b9iwAZlMZvQ1Z86cU90kIYQQQpxBTLjUdv369chms6Ov3t7eiW6SEEIIIU4jp3zPx4wZMxCJRNDf3z+mvL+/H11d4zf9JBIJJBL8tzohhBBCTC5OefIRj8exZMkSbNu2Dddddx2AF57dsW3bNqxdu/blN6wYIFobv6klP9feaZzI8c051bT9BU/U3swMAIjlySbVSv1ql2oLr/PH5+wzy989fTutEwfZtQy+cWjYtzdJuTaXtUXsACVDZDcugDjscYiF+PgkHTvyyR5eR0+BCNnsVCE7xAGQVgNkrzIAwIN9nYJj891xP22W532egJcCe5Of7xg7j3ypeTKbbmOOHZVsLjSFbcUGAEQcG1ifKp9jlt9fupjWiY/YfarZoQYAsOlY6nRswCaba1v38/FmUyF5jMeg1mwrw65o3U3rsHt1yONBOO7ZKpRjVa5USJCNxAcLbbSOS+mWq6TMcs/nczuZts+XJEo7APDY5tEUX3uCGlllHJstY2QuOpY/eHG7TmqA96c8zd7E61JRMZjaBgDKbWQdIXtuvTp+Szktapd169Zh9erVuOyyy3D55Zfj9ttvRz6fH1W/CCGEEGLqclqSjxtuuAFHjx7Fpz/9afT19eE1r3kNtm7dOm4TqhBCCCGmHqft8epr166t62cWIYQQQkwNJlztIoQQQoiphZIPIYQQQjSUM87V9kWiJQ/R2vidyLWQvQM5dYTvrvfSdjcLHdyjhO0Ajhb47uhSm61YCPl8B313YsgsnxMZoXUOkx3sLvVDX7XNLGeqCABoDZfMcqaKAPgjuquOtrnULkmiXHFsHj8pPNIlpmhxkXD0hyk9BonyAABKvj1PmQoGAKqBfZ+MsG3qAGKOdtdbJxHmO/Vd9JbazfJanvc1Q5Qj5TY+dokTdruz8/k8jebsmDYd5rMxP8s+n8tViz0G28XDwwvM8lzNVpMAQJlIcYZrDuUV8XVy+Urtzc6gx+a3DprlLvuE4bKt9Ch7PKgh8tjzEFEwAUD4sH2vNB/g8yo9YM+FxBCPT6RstyH6lK2EBIBot71/strO1U2RIvF7OniU1ynNNsvz3URt45IHvvS9L/udQgghhBCnACUfQgghhGgoSj6EEEII0VCUfAghhBCioSj5EEIIIURDUfIhhBBCiIZyxkpt/WgYfmx8bpQYtE2FyjPqd8aNFR1mdM12XsbKAW62kzjB5Uf7CrYM7dfJblrne/2X02OM4YrduFiES82aYxeZ5TWH6ROT2kYdzkrnpIboscGKbSRY9Lj0klFzyH19YrjGyl3EHTFNRWy5244+W9IGANGwHbtKjd++bemiWV6s8jqtSVuuXvG4jd85zVmz3DXe56aP02OHSm32gTC/h4bn2uVtv+N10vvtdgev47LQdJ89F6JEKgkA6QG7vDCTz8Vy2R6jvlqG1okRaeqCdB+vQwwDXfJ7JtX+TW4OrXN+5hg9xmDrFQBkh205adUxTzHdntvBCVsyCgBMLR7P8nkVz9njkHyOz/mQb58vmGHLzgHAT9nrXzXD18XoiP3ZGYrzGPhRe8637LPXl1rNfjyDhb75EEIIIURDUfIhhBBCiIai5EMIIYQQDUXJhxBCCCEaipIPIYQQQjSUM1btEil7iHjjdw6HS/YW5CDMd+wmBu06+XO4Qqaasnf5RhzGObG8fSxS5nWeGuwyy5dmnqN1/mLWI2Z51eFWdbxmG5dNj3IDu7ZwwSx3GZpViKGZC5ep2v4IVx8wkmSbetihwGCmfK46ZWL4dqzK+/NM1jaEel1XL63THs+b5YkwN6uiMSDGdi5ijuu0EPPBlgjf9T5I5iIA9PRfYJaHonwc2HR03avV6baKqtrqsCwM2XOk2M7n/PA8ex2J2UP6Qhuy9rrETAkBYHnT78zy5yodtE6WGFS65m9vcZpZ7lLARUncAGCkavc1W+ZqF3quIW6qFhq0J0mswNVsIc8+FjiUV9ER+74LjdhrKQB459hrXHiEm6VGBu11Oxl2qKg67PjEIzwG8aytkAnnSds83uZx53jZ7xRCCCGEOAUo+RBCCCFEQ1HyIYQQQoiGouRDCCGEEA1FyYcQQgghGoqSDyGEEEI0lFMutf3MZz6Dz372s2PKFixYgGeeeaau88SPFRA1DLoK81rN94e4txPivbapT27+ObROaQYxkXJIs5hvWcThgXZiyJa1tUW4Fu+86KBZXnBIbZ8u2n2dE+OGR5fEh83yGOo3WxvyuYTxV2UeoMXpA3VfixpmOYzlXDLlunGoBKdFbcndiRqXCcbI5HaZ3g0TA7B8jcvLfTKunuM6zCgvHbYlegDwHDFTBIBsIWWWh49yKX0sR9oXcEmkl7LlsV4rX0i8ZnsO19Jcaus12efzEg5zxqJ9vgRzOgPwX/lXmeXZmh1PAJibsNeRGTEuv2fy7l1Zx1rqMIHMV/m4MvyKHR+XHNtP28f8Gh+7mO09CM/hYRpE2YcAv041Y9+r8ZpD9t1/1CwOD+VoFf8Ntoy9PIPPkUiZxG2aHYRarQS8zI/60/Kcj0svvRQ///nPf3+R6Bn7OBEhhBBCNJjTkhVEo1F0ddkPz3op5XIZ5fLvH0ySy/HMTQghhBBnP6dlz8ezzz6L7u5unHfeeXjve9+LAwf4V+cbNmxAJpMZfc2ZM+d0NEkIIYQQZwinPPlYunQp7r77bmzduhWbNm3Cvn378KY3vQnDw/b+gfXr1yObzY6+env5Y6aFEEIIcfZzyn92WbVq1ei/Fy1ahKVLl2LevHn4wQ9+gPe///3j3p9IJJBIOHbwCCGEEGJScdp3gra1teFVr3oV9uzZU1e9ckcTvOj4XcCpQ/ZO7PJMrhbwm+1jiRzf2R6u2l8KDc/lXxal++zd9elj3JgrF7Xb4DLf+vzRt5nlJY8P50ChxSzf2Tyb1pmTOmGWR8N8FzYzNHMpTZ4vTKfH+ot2u6se3z3OTK7CIa5+yBbtHeeW4upF4mTsOtNcLTA7PWSWb3veVisAQKapaJZXPR7Tprg9Dq0JbvjWnrAVVu1xbop1ftLede+i7PN5ujtiG6FVqlxxw4Q1qaNcHTJ4kf0fnlgLV5nNnGZ/e9t3NEPr4MRJqDmIQsalgHtN636zPOmQAR71bHO9XxfPpXWKRLkyN22vFYB7vJ8u2UaLxQpXyDARUyzG+1qJEoWMQ+2S7rcv5MX5XCzNsNsdrnKDPyYe9FM8BhFi1hdKc+VKtGDHJ3ac399BzI5PrdW+f8Iuhc5L3/uy33mSjIyMYO/evZg1a9bpvpQQQgghzgJOefLxt3/7t+jp6cHzzz+P//7v/8Y73vEORCIRvOc97znVlxJCCCHEWcgp/9nl4MGDeM973oPjx49j5syZeOMb34jt27dj5syZp/pSQgghhDgLOeXJx+bNm0/1KYUQQggxiZC3ixBCCCEaipIPIYQQQjSUM9Z0xUuEEYqNz42YcU+0wOWsoaO2gVLpsmmO69vl8SyXaw7PtzVT8RGe45WH7Qs9mecSWCYZHa5yR7NE1I7Ps8f5Xhy/3e6PS7LKTKTSUW40VqpxSdnBwTaz3PO43C2ZJHJfhzS1TMztvCK/RcI5+1h/hBunXXHVA2b5BZf00zqMauAwqyLyxnSkbJYDQDJkx60lwuW5rM7Rmi2RBoD9hXZ6LLvflq02H+PjXbG9JlHo4vPKJ4eiDrnm/FZ7HckRmTYAFPvsY8ykDgAiOXtc4w7Z7MywPa4PFmwzMYCbSl7V9FtaZyhlSzm35S6ldX43wmWm6Zg9fw4f4nME5N73HLLZ6HF7wJsO8nmV77bLmQQXAJLH7f74cb72lKaTtjk+02oXzzXLIwUuLw/V7HbnLmqjdWLD9pxLHbYfJxDy+PryUvTNhxBCCCEaipIPIYQQQjQUJR9CCCGEaChKPoQQQgjRUJR8CCGEEKKhnLFqFz8Wgh8bvxOZGd2EfL4DGTV717DD6wzlaUS54lC7kA3nqCX5jurEIXun83PncbO1c9JZs7wzZRtfAcCeIVuBkT3ATbGGm+0dzZ3pHK3TRFQt2QpXBAyVuRkSIxLh4xAEdrxZOQD4NTIZiMEgAPgJW7EQyfAd5wlivLdrhKubfDJRwyGumIiRY9EwV0zw6/O4HS7a8+eZo7ZhGAAURriLdSxn95WpzwAgecwuT/fxcSh02icsFbgR3GPPn2uW+77D9I6EO9LOVQG1nN2GZ8s8pkOebZ75liZu6Dk3aptX7qtyZdreqq2OW5TupXU64ny9+P+G55jlB1vbaJ1ykSjTylztEo7Z60X2UocRGhk7l3IlRCYque0BAPERuw3FLr5mMq++sMfreMbnKeD+fEr325+dlRn2fKuxddRA33wIIYQQoqEo+RBCCCFEQ1HyIYQQQoiGouRDCCGEEA1FyYcQQgghGoqSDyGEEEI0lDNWapsYrCBqmMjVmmyZlW+Y0L1IdOG8uq/P/LeqzVyWxPDivE7rc3b5bzu49PK3vn0s5JBEBmFbapbq5/K0Z8l19jpkY36cSGAdbXMoRpE4bo9r8jiX2vpR+1rJEYchFJFyegne7ioxNKu2caliE9FjL299ltZZlDhklncTs0AASIfsca0GPNhDvn2s17MlmQDwWOF8s7xQ45LV354gjl0A4lk73oVZvN1BxJ4jsWE+DjUy4IHLsLDFPl/lSS5XjxZIf0a46V2EGFHuL3LDwvMyR83y59gkBXC4Zt/IQz6X+XdFbZn/r4vn0jrHqtxkMB625/D5M4l+GsDxoi3znJnO0zpDJVvOX6rxj8CjA3bsKlG+Zg7DPhYbdsj8yRrX1Mdl8dW0XacW4ddJHbVj3dTnMLBL2v0pt9lxq1VfvpRf33wIIYQQoqEo+RBCCCFEQ1HyIYQQQoiGouRDCCGEEA1FyYcQQgghGkrdapeHH34YX/7yl7Fjxw4cOXIEW7ZswXXXXTd6PAgC3HrrrfjmN7+JoaEhLF++HJs2bcKFF15Y13W8dBSh6Pjmhav2rvfE0QI9V3mmvTvatcs3WrR3+dZSDvUDUcIkcg45x0nAjMvCEcfu6LytPohwQYBThcIIiIFTqIlLZAKHMVc5ZKsCksd4nWjJbkP6GI/P8Gx7vEszuUKm2mYHaHorn4vDnr3r/pLkQVonEbLbnXeYKfaRQ89VO2id58r2sT1FXufpE11m+YEj7bRO/DBXepRm2A2PFvl4R4p2eXj3flonuGah3bY0n6flkt3uRM4xf6eR+6HM/98XP2Efe/yobcIGAANlW5HUkbDNIQFgYZM9586LD9A6T5TsNgxUuKpmWoyrUGJkbhc9PkeY0WGUnAsA5racMMtzVW7EVq3Za4LLaHHYZ3Fw/T/fPl/aFjABAGIFe14lhviC7iXIGtfOlWnNz9rqpnC1ySyvEQWVeY6X/c7/IZ/PY/Hixdi4caN5/Etf+hK+/vWv44477sBjjz2GpqYmrFy5EqVSqd5LCSGEEGISUvc3H6tWrcKqVavMY0EQ4Pbbb8cnP/lJXHvttQCAb3/72+js7MSPf/xjvPvd735lrRVCCCHEWc8p3fOxb98+9PX1YcWKFaNlmUwGS5cuxaOPPmrWKZfLyOVyY15CCCGEmLyc0uSjr68PANDZ2TmmvLOzc/TYS9mwYQMymczoa84c/rumEEIIIc5+Jlztsn79emSz2dFXb2/vRDdJCCGEEKeRU5p8dHW9sPO9v79/THl/f//osZeSSCTQ2to65iWEEEKIycspNZabP38+urq6sG3bNrzmNa8BAORyOTz22GO46aab6jpX8tAwooYONJSzZVtBijiDAfBm27IghzILkSrRKjp85cpt9sFakldixmXRIX4dr0rOV+HXiZfIdbgKjpq6RYm0EQBKM0kMKjzPjZR5uxOD9rEK9/JC4oQ9diOzuCFUaYZ9HS/J9cZRYgB2rI8n0N8Nv84sj4SX0Dqd6WGz3A94TCu+3ddijUsYwyE7blWPx+1ozpZ4xnod92OKS4TZXJj1CJfFs/9ChdK2rBkAArLyVQo8PqGCXSnKlYqUxFEe0/SAHZ+WBHG7BJCM2BLHZ3MzaZ2yb/fn6Qg3/kuR6wxW7DUWAHYOcZPMkYo9T9i8AoBYzJ4LNSKNBYBalRgt5vl4x5pt2erMNi5fHiZT2/VogDBRxxZm8v60P2XL+cvT+X0XkNORaQAACFXtWEeKdnlQc9ynL6Hu5GNkZAR79uwZ/Xvfvn3YuXMn2tvbMXfuXNx88834u7/7O1x44YWYP38+PvWpT6G7u3vMs0CEEEIIMXWpO/l4/PHH8eY3v3n073Xr1gEAVq9ejbvvvhsf+9jHkM/n8cEPfhBDQ0N44xvfiK1btyKZ5A9zEUIIIcTUoe7k48orr0QQ8K9NQ6EQPve5z+Fzn/vcK2qYEEIIISYnE652EUIIIcTUQsmHEEIIIRrKKVW7nEpChSJC4TqczWK8K/GcvQO33OYwuJpm52XlDN+17JNd78UOnuPVyFYYL8X7Hp5u73r3a/w6XpUcC3gMmCKgOJvLhMLEQC4a5f2pZvkO7ShRGHhx/tNfsdM+5rti2mK3u6mZexKxmdAe5+ZK52YGzfLnhqbTOtmKrdrwfD7eJwp2HWaW5aJa4fdWbdieP6EWPj6xYYcpYME+RoQ4AIBEP5FfJfm8Ykq3lmncFLCQsM8XOmQbVwJAdZp9ofAAjylTwEUcTo+zkvaToWfGuTIjV7PnSNHj8p3WqH0/uMzWmmNcpdM33GKWl4b52JXIojnvXO7ENtBjK3gCxzxtmmnHbijPVVRMxRTL8+t4cTt25WkOA7tzyf3d5FDVECFKmCk7ARTOn2aWRwv2vPYjL3990TcfQgghhGgoSj6EEEII0VCUfAghhBCioSj5EEIIIURDUfIhhBBCiIai5EMIIYQQDeWMldrWDhwCQuNlfKGo3eRwy3x6rpBvS4mYBBcAailbQth8iNcZ6SZtc3jtxIjStWibAAMA/KO21MyhxKOGXfGsQzrMZgdzKALgD9vHAkfbHMpUarrkcvhjsswKV0TCJ1LkkazDnKxs97XcxuW5C2cfNstnxB0Of4REmAdupM2WKmarvD+5ij2vTpR4nVKTPYGLZS7hrgbchKy51y6PZelEQK3FloaGXANOpk8swmXkrc22pLeQ5PFh16kQCS4AVIhB5eXNtkwbAFoi9pyLRfl1Xt100Czvr3LXxiq59zsTttT3BbjR4uIO+37Yl+TS8+N5e1xbE/y+O3SpLaGOJ/g9lM3a1wlHuDQ1RZTaI3NoFaSP2OcLMwNRAJVWYuCZdsnY7eswaTcAVFrsD4GWQ+T61ZefUuibDyGEEEI0FCUfQgghhGgoSj6EEEII0VCUfAghhBCioSj5EEIIIURDOWPVLtH5cxENGzv2q7Z0JBg4Ts8Vq9k7vguv4juqoyV7Z3DTM9y8KFKyz+fH+G7iaou9ezx9hCtKSjNs6YhDhILkoN2G5HG+c7vUTgyuiHLmf1phlzqqeNxDCrUm0tfpXP2QSNk72DubiAEZgGTUnldVh3lblpi3tTdxc7ILEv1meUeMqwV2ka3yzBgMAA6M2IZQB4e4kqFGTOcqDuM/MtwIF/hkTA7wmMZz9njn5/C+tuwdtg84FFbsXknGuDQtRowuy5fysQvvt43T/Ay/TqhkN264SlwoAaTT9v3gUkSFSYBizHXPcb5morYBgAJz3AQQIW3YB742l4r2+Q5m+dxmqpayQ5UVEKPOIMzjUyNCLpeqMFK2b6IKFwkhdYwpOF3rud0fqmoEkBwk6zm5f1yqxpeibz6EEEII0VCUfAghhBCioSj5EEIIIURDUfIhhBBCiIai5EMIIYQQDUXJhxBCCCEaSt1S24cffhhf/vKXsWPHDhw5cgRbtmzBddddN3r8xhtvxLe+9a0xdVauXImtW7fWdZ3afttYDr4tc4p2ddJzBbkR+4DP5VwMv4VL/mInbLlZEOM5XrRkD8GJCx3XGWGSKS6zYgZtiSzXRsXytjysNI3Lxrykfcyh3kNppqvddl8rDvleOWHL5wZa6pfVgVz/hUp2cSnD27arw5bNLml6ntZ5Y+vvzPLtI+fTOhEiC41G+HhXK/ZcDMV5naBc//9fXJJwZsRWnM7nXBC25awtz3PJM7tXmmNcwj0taZ8vX+Hj3bTAfgRAzeNxO9Fvayx9h5kik7N2x07QOkxSO+yQ586M2rLiw1Vb2g0AzZEyPfa7kQ6zvD9rjykA1Ar2PB0abKN1osN2vEOORwBEyDyND/Hx9pLEJK7ikNpW7DrRAq/DZLOZ57iEuzSNzDnHLVzsIJ8B0+0x8Mqn0Vgun89j8eLF2LhxI33PW9/6Vhw5cmT09b3vfa/eywghhBBiklL3Nx+rVq3CqlWrnO9JJBLo6nJ4wgshhBBiynJa9nw89NBD6OjowIIFC3DTTTfh+HH+9NFyuYxcLjfmJYQQQojJyylPPt761rfi29/+NrZt24YvfvGL6OnpwapVq+B59u+LGzZsQCaTGX3NmWP/Ji6EEEKIycEp93Z597vfPfrvV7/61Vi0aBHOP/98PPTQQ7j66qvHvX/9+vVYt27d6N+5XE4JiBBCCDGJOe3Gcueddx5mzJiBPXv2mMlHIpFAIjHeuCoUiyIUGt+8SMcs8zr+0WO0DeFZthImdYgYUgEozCOuPh5XZoxc0GyWM+MgAAjX7GMOMQe8BDmfY+c228AeuMQc5JjLKC9MNlsXOnkMXHgpu56XdjgYEXVGJMbr+KxLEd7ukEM5wugv2/Mq0szPVQpslY7LAKw9YSszRlLcJI4pMKp5rhIKF21JQKjmmIyOqcAMHdnufgAI1+zYhUe4ciXk2w5gmQQ3H5yXHrSv4+hQKmLfeIkIVyX8bGChWR4N1T/fnivbahIASJJFoeqQIz1XnGmWu0wOnxzk+/+OniCqlkP8fCli0uY01iR+oGUu0qHnSw/w8c6dZ5e7zDM9sp66FIJV8vE0dD7/SK8Q373KND6vwlW7bYnjdrmjyePPXcd7T4qDBw/i+PHjmDXLThqEEEIIMbWo+5uPkZER7NmzZ/Tvffv2YefOnWhvb0d7ezs++9nP4vrrr0dXVxf27t2Lj33sY7jggguwcuXKU9pwIYQQQpyd1J18PP7443jzm988+veL+zVWr16NTZs2YdeuXfjWt76FoaEhdHd345prrsHnP/9586cVIYQQQkw96k4+rrzySgQB/83r/vvvf0UNEkIIIcTkRt4uQgghhGgoSj6EEEII0VBOu9T2ZIl0dyISHr9PJIjZTWZyWgBA1Za1Bcw5CEDqiC1V9JsdpkJxW35UbuU5XttzthldpOwwQSPN9h2jWUvb5YWZPAY+aYJLOlwiBmCVbm5WBY/LMkNEyumUFcdtwVciwdsQIdLdZIxLIgtley7kT3CZ4PMj7Wb5LxNEowfgmtYnzfK21jyt80BgyzX7i9ywqylpS1ML4P1hOLzJkDzO50+liRhm7eUnDKLkvuu2pe8AN/o6XrIluADQlbSfvjwrmaV1EkR7/nSOq/+Ykd9gmdzEAPpito4y4RgIJqmtOTSrAyU7pkfyRPsJYOAYPxbpTZrlsRHHmkD0nC4hMnt0gUuey0JXbeJtSw3Y5ZGiY8632edjZqAAqFy9yqc8qq0kQjO48V/QZ48PU33XowbXNx9CCCGEaChKPoQQQgjRUJR8CCGEEKKhKPkQQgghRENR8iGEEEKIhqLkQwghhBAN5YyV2gbJBILIeKltdZot+wtXuJ9eiMiSCt1cQsjkpNXm+vO11CBv20i3/dj5SoZLs5jbbBDldagTrUOyyuS5PpEUA0B5JtFahR3usExOC4cbr8/HwQ/b07rk6Cuj4Gg3gvpjmq/Ymr/Hjp9L64TJBP4/rTtpnbdmnjDLBytcrskotHN5eT5iS/FAnHgBoJLhY5fI2fMniPCgFmbY86flENf9MSfPWJjfq8fKto6x5PFldFrcdsl98mA3rRMesOO9LzWd1kkS99yuFHfuLpN2D9e4Fcaxoh2DYoWPN47x80VO4qZsOmzfD5UMPxdbz+NcJU3PV253rGXEHtuzzYABAAFZY1yRCZEnADAXWoDLy6slPn9DHbYMN5+2x9svvnxfW33zIYQQQoiGouRDCCGEEA1FyYcQQgghGoqSDyGEEEI0FCUfQgghhGgoZ6zapdTdjGh0/E766LC9qzuStXeVA4DfYu/IrziUK4bQBgAXOACg25Nd12F1qhmHeidtHwvH+O7+QrvdBu8A34lezdjn85P8OuEme3xmto/QOkcPTKPHQkTV4sf4jvPwiK1+cHoeEaVQOObYvc3mQo1PEqYKCDFJFoDnC7bK4ZkkNydri9jGiH/UeoDW+W3EPp9LAZJN2/fWYDM3aKsQ1QgAoNcuHul2KKK49x/Fa7MrzWsepHUqxLmx4vO2HSV9dY23lyLqB0edaNie3XFHcNixKpPTAWhN2EaYw8RkEQAiZX4/MIVeNOeoQ8Jd4Z6J8GfY52vez2MaG7aP1VIO0ztm+MZvB27G5hDaMVVLpY2vcmxYw0k+R8IREoOEvSYEvtQuQgghhDhDUfIhhBBCiIai5EMIIYQQDUXJhxBCCCEaipIPIYQQQjQUJR9CCCGEaCh1SW03bNiAH/3oR3jmmWeQSqXwhje8AV/84hexYMGC0feUSiV89KMfxebNm1Eul7Fy5Up84xvfQGdnZ10Ni5Q9RLzxsp3IsG10g4jDaCxhd7PaxCVTNaJY8hymasy8yEWU1XGkhdGELY0KuczbiAas3EWc2wCEUkQ25fEYxEjbStWTU3VH8+RaDt0sk/Y5PJeo3C1U5YZZTPLHhZdAuc2OQ4RIJQFgsGybwe3Mz6V15iZsyWh7lEueF6T7zfIUMS0DuFFdOsbr7M1zWWahn0u/GTXiD9nU5xhwEu6jJS4DZgZ/h0YytE5n2o531CHh9prt2Lmktj55BkDCIbWdEbNN59i5AC43LjvuExf0HirxvqaP2n3y4nyNYTLT+IjDfJA8IiFqq40BcMO3eNTxWZMmcmO29gHwkuTRAC5ZM3k8gVdxrFhxMk/Z51MdX2fU9c1HT08P1qxZg+3bt+OBBx5AtVrFNddcg3w+P/qeW265Bffddx/uvfde9PT04PDhw3jnO99Zz2WEEEIIMYmp67+jW7duHfP33XffjY6ODuzYsQNXXHEFstks7rzzTtxzzz246qqrAAB33XUXLr74Ymzfvh2vf/3rx52zXC6jXP79txm5XO5k+iGEEEKIs4RXtOcjm80CANrb2wEAO3bsQLVaxYoVK0bfc9FFF2Hu3Ll49NFHzXNs2LABmUxm9DVnzpxX0iQhhBBCnOGcdPLh+z5uvvlmLF++HAsXLgQA9PX1IR6Po62tbcx7Ozs70dfXZ55n/fr1yGazo6/eXvJ8ZSGEEEJMCk7a22XNmjV48skn8cgjj7yiBiQSCSQS9W8yE0IIIcTZyUklH2vXrsVPf/pTPPzww5g9e/ZoeVdXFyqVCoaGhsZ8+9Hf34+urq66rlFLRoDo+F241Tm2e1A8x3fXV1vsndguQ6pYnqhD+MZ2lNvJTmOHCKZATIrCTUTVA6ApbR9z7lInapNajE+BFGlDyCEimNGcN8uPjXBnpUiefwFXbSa7uh3+RX7crsNMrAAgVCLGe2mHiV7FDoSf4NepVsg4xPlkLFRtdcjhIp+MNWJ2FiOmhADQHTthls+LH6N1DldtU8DHgvm0zsGmNnqsPM3ua+KEYxc/mT4j3XxuR3L2GB12KFdyBdtEL+xQmeWJ4VqtyhUGibS9lvnEZBEASp69xj2V5eaDF7TY8WmO8LWnFrfb3d5kGxkCwKEkd3xj91CkQqug2mS3Icw/AuCR/9/6DhWKTwQ8Icfa09RvrxfMIPN/jtZVDACRkn3QtV75M+ygRo5x9ZmXstudPmjPHa/stO8cQ10/uwRBgLVr12LLli148MEHMX/+2AVmyZIliMVi2LZt22jZ7t27ceDAASxbtqyeSwkhhBBiklLXNx9r1qzBPffcg5/85CdoaWkZ3ceRyWSQSqWQyWTw/ve/H+vWrUN7eztaW1vx4Q9/GMuWLTOVLkIIIYSYetSVfGzatAkAcOWVV44pv+uuu3DjjTcCAL761a8iHA7j+uuvH/OQMSGEEEIIoM7kIwj+9yd4JpNJbNy4ERs3bjzpRgkhhBBi8iJvFyGEEEI0FCUfQgghhGgoJ/2cj9NNpOwj4o2X7RS6bFlQrMCliuU2W5rF5FcAMDKb5GUO+RPDd0g8faJy6pjBHzM/q8k+lq/yDjFTqqNJLoGd05o1y2tM2wjggpajZvme+Exa5+kRx0D4dsBDA1weFkTqN/jzU7ZELIg5pGssdydtBrgss1Tk/elnMmmHfC9btt3WysQYDACWZ541y5MODSOT517SbMtSAeBgpo0e6/dtWabHw4O4PU2pWSAAxAft2A2NEJc6AD4Z18AxDjOm2eZtiSjXa44U7fuhto+b3j0fsTtbq/G27RmYYZbPmsbXnpa4LcNtTXC3tYPTuG42dMjuq2OJQWGmfdBlRheE7bGLOqShlVay9jikthViVhqp8LZRGbnjs6ZKpkKk4JAOZ23tMHs0AQAgbsen1GGX+6XTJLUVQgghhHilKPkQQgghRENR8iGEEEKIhqLkQwghhBANRcmHEEIIIRrKGat28eNh+NHxuVEtae/mrTbxrhQ67BxrZA7f5eu12Tv8k218V7dHdpZXS44wF20lzsL2Plrl4qYj9nUCblbVW2o3y5tj3ETqdW377ToRHoMycWN6bsTeWQ8AIYcxl+/Z411rcWw5Z6dLvvyd2C8H9tC9kMMUy6vacyTsUNWEiMqiSFQwAFfCHIm00jo7o3PN8nMStqIFANJhu7MjDilZvsKlK2xqOU0gR+pXNzHvtOKwQ3lFxi6W4fdQpUaM2NJFWufYwTb7Oo4pXzhkyx9C5P4BAOZDub8/zS/Uaq+Lrns4cKi/mHLEpVRqPuwIBKE43R67cgv//3dy0G5Ebh5fZwvExy/V7xgHchsnTjjmNRs8h7moH7f7WsvweIZH7MYxQ0CwcuscL/udQgghhBCnACUfQgghhGgoSj6EEEII0VCUfAghhBCioSj5EEIIIURDUfIhhBBCiIZyxkpta8kwEBufG/lE5cSMg1x407lhVqLZls9lmrhELh6xJUt9g1zeGG2xr7Oo+SCt86b078zyMDGPA4D/jpxvll/cxPPPtzb9lh5j/Ko0xywfrnAJY1smT4+d2D/NLA87zKq8it2npgyXCFer9sTyPR6fIGHPOZ9IMgEgREzvXHLEeMrWmc5s4nGrkhslGeFznsHk0wAQI1pJz/H/mkSU62azbUS+7Gh2bMQubznoMJucZvcp5JA8szGKRHmdwSMZszzf5pD0Joj00SGlTxy3jxElNAAuc2VmlwCAfvs6TC4KuI01I2U7phW+ZMIjklHXZ0C4Zreh2sLreEkiTeX+fpSyvYwBAKLkI2V4nkM2G7P7QyWwALykXSfS4ri58vY8DTN1OVedjz/Hy3+rEEIIIcQrR8mHEEIIIRqKkg8hhBBCNBQlH0IIIYRoKEo+hBBCCNFQ6lK7bNiwAT/60Y/wzDPPIJVK4Q1veAO++MUvYsGCBaPvufLKK9HT0zOm3l/91V/hjjvuqKth4UqAsGHclRyyd5ZXHAZBbFc3iCoCAMoj9i7fEw7jHrYbPupwhGpN2wqMwVoTrXOgZm+djtOOAsdqLWb5QMUuB4DXpZ4zy5OO6wx5tinVzBSRJMBtNBZqs7frp5scBn9kl3rcobIIEaUQU8EAQI2YhgU1l/KK7NR31PFT9rHAMRcTEbuvLkUUg5nHAUCSyFAi4AoQVxtqTXa9+Al+r3pEdVRN8zoR0qWgzMc7FLfnfbnI1UAg6qby8RS/DjGDS5xwGLSRcMezPNbRkn2sRuL5woXs4liBX8dlChgQQ7pSG29DlNz6XoK3gS1ZTX18LYuUiTqkxOdIpdVud3k6rYIqUc8wdQoABGRqs3gCoHORqQMBIERimhyw63hEvWRR1zcfPT09WLNmDbZv344HHngA1WoV11xzDfL5sZK/D3zgAzhy5Mjo60tf+lI9lxFCCCHEJKaubz62bt065u+7774bHR0d2LFjB6644orR8nQ6ja6urlPTQiGEEEJMKl7Rno9sNgsAaG9vH1P+3e9+FzNmzMDChQuxfv16FAoFeo5yuYxcLjfmJYQQQojJy0k/4dT3fdx8881Yvnw5Fi5cOFr+p3/6p5g3bx66u7uxa9cufPzjH8fu3bvxox/9yDzPhg0b8NnPfvZkmyGEEEKIs4yTTj7WrFmDJ598Eo888siY8g9+8IOj/371q1+NWbNm4eqrr8bevXtx/vnjH/G9fv16rFu3bvTvXC6HOXPsR3QLIYQQ4uznpJKPtWvX4qc//SkefvhhzJ492/nepUuXAgD27NljJh+JRAKJhMPnQAghhBCTirqSjyAI8OEPfxhbtmzBQw89hPnz5/+vdXbu3AkAmDVrVl0N8xMh+LHxsh2rzFUOAPFhWy4UO8ElUz4xL6o4ZILxtC07LBW4lDSVsDV/PtO0AagSFycmewSAjpi9l6bqMKt6unwOPcb4Vc6eE0/28fEvDjuSz6LdvrxDUeYX7fgUiNTspCHy2Mgwj6nXbGsiw0W+/crP2MeKNS7x7EgP02MMbhLH52IpsNtwoNhulgPAQNbhzEXk6i6ZKZvCI918HCIVIqPM8TqxYbuvtRSfV/45ti40cMzFgBgThjzetqYj9rxi/QSAKjGVjBXrl+dWHAaV8RyXsyaO205k8SxfMyMVu6/lNv5xxqSp5Vbe7tSg3e6WXi49r2TsNgQRPnbMdC7s8oAkQ1Sd53B2Y+aVjmUx3mHv1yzn7XvYJ/PDoq7kY82aNbjnnnvwk5/8BC0tLejr6wMAZDIZpFIp7N27F/fccw/+5E/+BNOnT8euXbtwyy234IorrsCiRYvquZQQQgghJil1JR+bNm0C8MKDxP6Qu+66CzfeeCPi8Th+/vOf4/bbb0c+n8ecOXNw/fXX45Of/OQpa7AQQgghzm7q/tnFxZw5c8Y93VQIIYQQ4g+Rt4sQQgghGoqSDyGEEEI0lJN+zsfpJjbiIRodv9vYj9o7dsNVh1lVkqgSSjz3qrUQpyaivgAAL27XmdUxROtEiHrGpRZgZCJFeuyytG0Sd368n9Z5ZGSBWf7UMFeu7BmcYZYXj9mGcwCQPuDYpc5EDiHH1CV1/JjjZ0NyIVcdl/ETI1Ql87eTG+W1EPPBGQ6zPobvMKNjyqdnRvh4n6jYBmm7DnKllD/I1U2pPqLAGHGNnV3sxXlfqdkZUwQAqKWJEVszV3OwFSZwmJMxtZSXpFWooZkf5WscUwkFYYeBHelqzCE/qzgUJX7M7hQzCwSACDFCY4oWAMieZ3c2McTbXcrYdVyGhSw+Ve4TinInMYFs4nKXSJR8PpUdaykxLAyxc4GbVwaziYqrwNexl6JvPoQQQgjRUJR8CCGEEKKhKPkQQgghRENR8iGEEEKIhqLkQwghhBANRcmHEEIIIRrKGSu19aNh+LHxuVH6iG2c4yW5dC3UanczxOR2AJL9RGbVzKVZoSG7zpHj3CQpNM02KTo+wqWpv2uaaZYz2S4APJIa7ygMAFkilQSAwycyZnkyziVgQwMtZnnUYdgVtb2LAACRst0nj8inAQBMOeaQEDITp4hDOcZk38Uufp0KkbWFI/XL3QYKdqwBIBq2z5eI8El/ILAdrti5nNdJ8DlSKfA5l9lnn6/SXL/8k5mgAdxwLUyk0IBDWp3g8aGmXTFeJ0wM5EKOy0SIn1jUYRIXHyEGbS0OKSlpQ3qAj3ehgxsgxvJEZkrM9QBuIhoj/QGA9mfsOAQRx3gTqbZL0hshj3yIOtaRUIXIpMHjFhqxGxGe5TCWI6drbeEL8EXTB8zy57LTzXIvXsZ+3oIx6JsPIYQQQjQUJR9CCCGEaChKPoQQQgjRUJR8CCGEEKKhKPkQQgghREM5Y9Uu8WwZUUNNEDlum2mFpnHnnsSRYbO8luTmbcUZdl6WOMF3R5fb7PJ4lis9ykXbWKnQwnc6+zPttvkOU6xDR+3G+Tl+HaRsGUE54tiFXbbbFs3ztjGDKwCI5e3yiEPJ4BNxETMYBIBogZzP4WdWnmmfr+YwnAuIuiniULu0Ju2t8tOTJDgACjU7CMUaH7uKby8HtYD3pzlq766f1sRNDvtCrbwNLQ4VE6tDTNUS2fqVHtGiY0kk/1ULXMZc5J4MOYzlwmXSn0Hen2oTU4DwOrER+/4utTnM6MiharPDcJP7CKLcZsc7fZjLQwJDBfnCAX6dWoi0z2FIylR41SYeHxY7l2oudcRum2tdrLTZc84b5vf3zDknzPJqjV+oRga8o8n+HK7CXt8s9M2HEEIIIRqKkg8hhBBCNBQlH0IIIYRoKEo+hBBCCNFQlHwIIYQQoqEo+RBCCCFEQ6lLartp0yZs2rQJzz//PADg0ksvxac//WmsWrUKAFAqlfDRj34UmzdvRrlcxsqVK/GNb3wDnZ2ddTcsXKwiHBmfG9U6bJmeZUL3IsxvzWU8xSRqnq2MBcBNqVxSs/gQMRVy9IdJaj3PUYdIakPEtAwAgjKRYKW4OVmIxoDH2mXmVSX+emGHKSAzhHKNN5MQltt422K22gwBMZwDuBSuluAd8ny7cdkyN2iLEMO3sMN8kBFlzm3gRnWu67jGrpq2Y9dyiLfBi9vzNJbnElhmChh2KAWjIPfqUW4c6bXbnY1l+b3KZJmlGY65aD9NADXuT8mvT8wcAaCcIYZmNd4f571KlKG58/jcTp5gEmEuGWVybJcUmU3hkO+oQ6ap63ODXYfc9gCASJHMxQ4e7OGC3Yi2Zm4sl6vYdQaL9sTyCg5ju5dQ1zcfs2fPxm233YYdO3bg8ccfx1VXXYVrr70WTz31FADglltuwX333Yd7770XPT09OHz4MN75znfWcwkhhBBCTHLq+ubj7W9/+5i/v/CFL2DTpk3Yvn07Zs+ejTvvvBP33HMPrrrqKgDAXXfdhYsvvhjbt2/H61//evOc5XIZ5fLvs6VcLldvH4QQQghxFnHSez48z8PmzZuRz+exbNky7NixA9VqFStWrBh9z0UXXYS5c+fi0UcfpefZsGEDMpnM6GvOnDkn2yQhhBBCnAXUnXw88cQTaG5uRiKRwIc+9CFs2bIFl1xyCfr6+hCPx9HW1jbm/Z2dnejr66PnW79+PbLZ7Oirt7e37k4IIYQQ4uyhbm+XBQsWYOfOnchms/jhD3+I1atXo6en56QbkEgkkEg4dmQKIYQQYlJRd/IRj8dxwQUXAACWLFmCX/3qV/ja176GG264AZVKBUNDQ2O+/ejv70dXV1fdDfOaEwhFjZ22ZKexl+Q7neMHbUOdYB7fCh4lO779GN9xHiKb68NVWoXW8dN8pz4jleJb9YOk3YhyiRsR1bJkF79LIRMjcXN0Jzzo2MVPNmKHaw5DKKJqiTiUDB7pavgYr8OuE3KojryEfawS5wn4QW+afR2HooQdicW4aoSZ283K1L8Pa7jE+xMpuRREdstrCV4nTMzBXAZgiazd13iufjVQtdlhhkfmfa2V3xDhKlPv8MuwdcRzxK3Sal/Hae5HDrkUfawOAISIci+R5fOUGUQyxRoAxIfrN45kSiF2D7vawNYXgKuBfLKWAkC13R7woMA/0qsR+3yZBHe9K3v2+ZhyxuPCmXG84ud8+L6PcrmMJUuWIBaLYdu2baPHdu/ejQMHDmDZsmWv9DJCCCGEmCTU9c3H+vXrsWrVKsydOxfDw8O455578NBDD+H+++9HJpPB+9//fqxbtw7t7e1obW3Fhz/8YSxbtowqXYQQQggx9agr+RgYGMCf//mf48iRI8hkMli0aBHuv/9+vOUtbwEAfPWrX0U4HMb1118/5iFjQgghhBAvUlfyceeddzqPJ5NJbNy4ERs3bnxFjRJCCCHE5EXeLkIIIYRoKHWrXU43QfDCjtxajTwjnqhdalW+e7zm2eeqVfkuXz9EPEoqDt+OMnnePt+4zdUuRf6Mfp/sTvZq/EIBUaj4JV7HL9qNC8HRoSKZUs64OdQhFXu8A8+h9CCXChyqIzZ7mI8OAICoLLyKw2OHKGRc4x0K2cdORu3iOdQuILvha1Hu11CN2RIil8eDV+L3HRvvECkHAI8p0BzqJrZeuMaO4fPuwC/aky5U4uo8jxwLO2wzQqSvLpVZrWrPBVcMggiLtUM24riF2BixtgGAR9fm+v29XGoXIvSA5+gQVbs4plXA1C4OLyq2NgfkHgaAUMSei7U8n1g1j8yRgj3p/eIL53rxc9xFKHg572ogBw8e1FNOhRBCiLOU3t5ezJ492/meMy758H0fhw8fRktLC0KhEHK5HObMmYPe3l60ttqOtpMdxUAxABSDF1EcFANAMQDOvBgEQYDh4WF0d3cjHHZ/i3jG/ewSDofNjKm1tfWMCO5EohgoBoBi8CKKg2IAKAbAmRWDTCbzst6nDadCCCGEaChKPoQQQgjRUM745CORSODWW2+d0uZzioFiACgGL6I4KAaAYgCc3TE44zacCiGEEGJyc8Z/8yGEEEKIyYWSDyGEEEI0FCUfQgghhGgoSj6EEEII0VCUfAghhBCioZzRycfGjRtx7rnnIplMYunSpfjlL3850U06rTz88MN4+9vfju7uboRCIfz4xz8eczwIAnz605/GrFmzkEqlsGLFCjz77LMT09jTwIYNG/C6170OLS0t6OjowHXXXYfdu3ePeU+pVMKaNWswffp0NDc34/rrr0d/f/8Etfj0sGnTJixatGj0qYXLli3Dz372s9HjUyEGL+W2225DKBTCzTffPFo22ePwmc98BqFQaMzroosuGj0+2fv/IocOHcKf/dmfYfr06UilUnj1q1+Nxx9/fPT4ZF8XAeDcc88dNxdCoRDWrFkD4OycC2ds8vH9738f69atw6233opf//rXWLx4MVauXImBgYGJbtppI5/PY/Hixdi4caN5/Etf+hK+/vWv44477sBjjz2GpqYmrFy5EiWHS+jZRE9PD9asWYPt27fjgQceQLVaxTXXXIN8Pj/6nltuuQX33Xcf7r33XvT09ODw4cN45zvfOYGtPvXMnj0bt912G3bs2IHHH38cV111Fa699lo89dRTAKZGDP6QX/3qV/jnf/5nLFq0aEz5VIjDpZdeiiNHjoy+HnnkkdFjU6H/J06cwPLlyxGLxfCzn/0MTz/9NP7hH/4B06ZNG33PZF8XgRfugT+cBw888AAA4F3veheAs3QuBGcol19+ebBmzZrRvz3PC7q7u4MNGzZMYKsaB4Bgy5Yto3/7vh90dXUFX/7yl0fLhoaGgkQiEXzve9+bgBaefgYGBgIAQU9PTxAEL/Q3FosF99577+h7fvvb3wYAgkcffXSimtkQpk2bFvzrv/7rlIvB8PBwcOGFFwYPPPBA8Md//MfBRz7ykSAIpsZcuPXWW4PFixebx6ZC/4MgCD7+8Y8Hb3zjG+nxqbguBkEQfOQjHwnOP//8wPf9s3YunJHffFQqFezYsQMrVqwYLQuHw1ixYgUeffTRCWzZxLFv3z709fWNiUkmk8HSpUsnbUyy2SwAoL29HQCwY8cOVKvVMTG46KKLMHfu3EkbA8/zsHnzZuTzeSxbtmzKxWDNmjV429veNqa/wNSZC88++yy6u7tx3nnn4b3vfS8OHDgAYOr0/9///d9x2WWX4V3vehc6Ojrw2te+Ft/85jdHj0/FdbFSqeA73/kO3ve+9yEUCp21c+GMTD6OHTsGz/PQ2dk5pryzsxN9fX0T1KqJ5cV+T5WY+L6Pm2++GcuXL8fChQsBvBCDeDyOtra2Me+djDF44okn0NzcjEQigQ996EPYsmULLrnkkikVg82bN+PXv/41NmzYMO7YVIjD0qVLcffdd2Pr1q3YtGkT9u3bhze96U0YHh6eEv0HgOeeew6bNm3ChRdeiPvvvx833XQT/uZv/gbf+ta3AEy9dREAfvzjH2NoaAg33ngjgLP3XohOdAOEsFizZg2efPLJMb9xTyUWLFiAnTt3IpvN4oc//CFWr16Nnp6eiW5Ww+jt7cVHPvIRPPDAA0gmkxPdnAlh1apVo/9etGgRli5dinnz5uEHP/gBUqnUBLascfi+j8suuwx///d/DwB47WtfiyeffBJ33HEHVq9ePcGtmxjuvPNOrFq1Ct3d3RPdlFfEGfnNx4wZMxCJRMbt1u3v70dXV9cEtWpiebHfUyEma9euxU9/+lP84he/wOzZs0fLu7q6UKlUMDQ0NOb9kzEG8XgcF1xwAZYsWYINGzZg8eLF+NrXvjZlYrBjxw4MDAzgj/7ojxCNRhGNRtHT04Ovf/3riEaj6OzsnBJx+EPa2trwqle9Cnv27Jky82DWrFm45JJLxpRdfPHFoz8/TaV1EQD279+Pn//85/jLv/zL0bKzdS6ckclHPB7HkiVLsG3bttEy3/exbds2LFu2bAJbNnHMnz8fXV1dY2KSy+Xw2GOPTZqYBEGAtWvXYsuWLXjwwQcxf/78MceXLFmCWCw2Jga7d+/GgQMHJk0MGL7vo1wuT5kYXH311XjiiSewc+fO0ddll12G9773vaP/ngpx+ENGRkawd+9ezJo1a8rMg+XLl4+T2//ud7/DvHnzAEyNdfEPueuuu9DR0YG3ve1to2Vn7VyY6B2vjM2bNweJRCK4++67g6effjr44Ac/GLS1tQV9fX0T3bTTxvDwcPCb3/wm+M1vfhMACL7yla8Ev/nNb4L9+/cHQRAEt912W9DW1hb85Cc/CXbt2hVce+21wfz584NisTjBLT813HTTTUEmkwkeeuih4MiRI6OvQqEw+p4PfehDwdy5c4MHH3wwePzxx4Nly5YFy5Ytm8BWn3o+8YlPBD09PcG+ffuCXbt2BZ/4xCeCUCgU/Od//mcQBFMjBhZ/qHYJgskfh49+9KPBQw89FOzbty/4r//6r2DFihXBjBkzgoGBgSAIJn//gyAIfvnLXwbRaDT4whe+EDz77LPBd7/73SCdTgff+c53Rt8z2dfFF/E8L5g7d27w8Y9/fNyxs3EunLHJRxAEwT/+4z8Gc+fODeLxeHD55ZcH27dvn+gmnVZ+8YtfBADGvVavXh0EwQuysk996lNBZ2dnkEgkgquvvjrYvXv3xDb6FGL1HUBw1113jb6nWCwGf/3Xfx1MmzYtSKfTwTve8Y7gyJEjE9fo08D73ve+YN68eUE8Hg9mzpwZXH311aOJRxBMjRhYvDT5mOxxuOGGG4JZs2YF8Xg8OOecc4Ibbrgh2LNnz+jxyd7/F7nvvvuChQsXBolEIrjooouCf/mXfxlzfLKviy9y//33BwDMvp2NcyEUBEEwIV+5CCGEEGJKckbu+RBCCCHE5EXJhxBCCCEaipIPIYQQQjQUJR9CCCGEaChKPoQQQgjRUJR8CCGEEKKhKPkQQgghRENR8iGEEEKIhqLkQwghhBANRcmHEEIIIRqKkg8hhBBCNJT/H6hZm5PgOBo8AAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Use the converted tflite model and get intermediate outputs to extract the log-mel features\n", + "\n", + "interpreter = tf.lite.Interpreter(\n", + " model_path=os.path.join(speech_embedding_dir, \"speech_embeddings.tflite\"),\n", + " num_threads=1,\n", + " experimental_preserve_all_tensors=True\n", + ")\n", + "interpreter.allocate_tensors()\n", + "\n", + "# Get input and output tensors\n", + "input_details = interpreter.get_input_details()\n", + "output_details = interpreter.get_output_details()\n", + "interpreter.set_tensor(input_details[0]['index'], sample_data)\n", + "interpreter.invoke()\n", + "\n", + "spec = interpreter.get_tensor(65) # This index is the log-mel features, to my knowledge\n", + "spec = spec.squeeze().T # transform for visualization\n", + "print(\"Embedding model features shape:\", spec.shape)\n", + "\n", + "_ = plt.imshow(spec)" + ] + }, + { + "cell_type": "markdown", + "id": "dc88eeaa", + "metadata": {}, + "source": [ + "This certainly *looks* like a log-mel spectrogram, and we can compute the same from the reference Librosa implementation for comparison." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "5363ba83", + "metadata": { + "ExecuteTime": { + "end_time": "2024-01-18T00:26:26.195376Z", + "start_time": "2024-01-18T00:26:25.418886Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Librosa features shape: (32, 76)\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import librosa\n", + "\n", + "S = librosa.feature.melspectrogram(y=sample_data, win_length=int(0.025*16000), \n", + " hop_length=int(0.010*16000), n_fft=512, center=True,\n", + " sr=16000, n_mels=32, fmin=60, fmax=3800, power=2)#, norm=None)\n", + "\n", + "S = librosa.power_to_db(S).squeeze()[:, 1:-1] # convert to logmel and remove edge columns from center=True\n", + "\n", + "print(\"Librosa features shape:\", spec.shape)\n", + "_ = plt.imshow(S)" + ] + }, + { + "cell_type": "markdown", + "id": "f03308c2", + "metadata": {}, + "source": [ + "Visually, these mel-spectrograms are very similar, but on closer inspection there are differences. Plotting at a single time slice better shows the difference:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "d80091c0", + "metadata": { + "ExecuteTime": { + "end_time": "2024-01-18T00:26:30.675702Z", + "start_time": "2024-01-18T00:26:30.579560Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "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Bz9wPOaBBx5g48aNfPzxx3zxxRds2LCBXbt2ufS8DQ0NzJs3j7CwMDZv3sw333xDaGgo8+fPbzFDs379ejIzM1m/fj2vv/46K1asaBHQLF68mLfffpt//vOfHD58mBdeeIHQ0FAMBgO33XYbr732Wovnfe2115g5cyZDhgxxapwWi4XXXnuNyMhI0tPTOzz2//7v//jVr37Fnj17GDZsGDfccAONjY0ALF26FIvFwqZNm9i/fz9/+9vfCA0NdfLVEkI46LxRnxCiC26++WbFZDIpISEhjsu1116rKIqizJo1S5kwYUKL4//85z8rl112WYvbcnNzFUA5evSoUllZqQQEBCjvvfee4/6SkhIlKChIueeeexy3AcrKlStbnCciIsKxq+p//vMfJT09XbHZbI77LRaLEhQUpKxZs8Yx9tTUVKWxsdFxzHXXXadcf/31iqIoytGjRxVAWbt2bZs/+5kzZxSTyaRs375dURRFqa+vV2JjY5UVK1a0+3o99NBDitFodLxWBoNBCQ8PVz7//PMWxzX/+bKyshRAefnllx33Hzx4UAGUw4cPK4qiKGPGjFEefvjhdp9XCOEcPz0DISFE11188cU899xzju9DQkIc1ydNmtTi2L1797J+/fo2/2rPzMyktraW+vp6pk2b5rg9Ojq601mD1vbu3cuJEycICwtrcXtdXR2ZmZmO70eNGoXJZHJ8n5iYyP79+wF1ycVkMjFr1qw2nyMpKYkrrriCV199lalTp/K///0Pi8XCdddd1+HY0tPT+e9//wtAZWUl7777Ltdddx3r169n8uTJ7T5u7NixLcYJUFhYyPDhw/nFL37BXXfdxRdffMHcuXP5/ve/3+J4IYRzJBgRopcKCQlpd1mieWACUFVVxZVXXsnf/va3845NTEx0ugrHYDCgKEqL25rnelRVVTFp0iTefPPN8x7br18/x3V/f//zzmuz2QAICgrqdBy33347N910E0888QSvvfYa119/PcHBwR0+JiAgoMXrNWHCBFatWsWTTz7JG2+80e7jmo/VYDAAOMZ6++23M2/ePD799FO++OILli9fzuOPP87Pf/7zTn8GIUQTyRkRwgdMnDiRgwcPMnDgQIYMGdLiEhISwuDBg/H392f79u2Ox5SWlrZI7gQ1oMjLy3N8f/z4cWpqalo8z/Hjx4mLizvveSIiIpwa65gxY7DZbOeV3TZ3+eWXExISwnPPPcfq1au57bbbnH0pWjCZTNTW1nbpsZrk5GTuvPNOPvroI+6//35eeumlbp1PCF8kwYgQPmDp0qWcO3eOG264ge+++47MzEzWrFnDrbfeitVqJTQ0lCVLlvDAAw/w1VdfceDAAW655RaMxpa/Ii655BKefvppdu/ezY4dO7jzzjtbzBzceOONxMbGsnDhQjZv3kxWVhYbNmzgF7/4BadPn3ZqrAMHDuTmm2/mtttuY9WqVY5zvPfee45jTCYTt9xyC8uWLWPo0KFkZGR0et7Gxkby8/PJz8/n+PHj/OUvf+HQoUMsXLjQyVfxfPfeey9r1qwhKyuLXbt2sX79ekaMGNHl8wnhqyQYEcIHJCUl8c0332C1WrnssssYM2YM9957L5GRkY6A47HHHmPGjBlceeWVzJ07l4suuui83JPHH3+c5ORkZsyYwY9+9CN+9atftVgeCQ4OZtOmTaSkpHDNNdcwYsQIlixZQl1dHeHh4U6P97nnnuPaa6/lZz/7GcOHD+eOO+6gurq6xTFLliyhvr6eW2+91alzHjx4kMTERBITExk/fjzvvfcezz33HIsXL3Z6XK1ZrVaWLl3KiBEjmD9/PsOGDePZZ5/t8vmE8FUGpfUCsBBC2M2ePZvx48fz5JNP6j2U82zevJk5c+aQm5tLfHy83sMRQnSDJLAKIXoVi8VCUVERDz/8MNddd50EIkL0AbJMI4ToVd5++21SU1MpKyvj0Ucf1Xs4Qgg3kGUaIYQQQuhKZkaEEEIIoSsJRoQQQgihKwlGhBBCCKErCUaEEEIIoSsJRoQQQgihKwlGhBBCCKErCUaEEEIIoSsJRoQQQgihKwlGhBBCCKGr/w/C90ZQj9ZRIgAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plot single time slice from both melspectrograms\n", + "_ = plt.plot(spec[:, 33])\n", + "_ = plt.plot(S[:, 33]/10 + 2) # apply simple scalar transformation to better align the points\n", + "_ = plt.xlabel(\"Frequency Bins\")" + ] + }, + { + "cell_type": "markdown", + "id": "98dce06c", + "metadata": {}, + "source": [ + "While the overall trend and specific frequency features are very similar between the two, they are not exact. After some time investigating this difference, eventually I moved on to other tasks with openWakeWord, and assumed that the similarity of the spectrograms would mean the downstream model performance would be relatively unnaffected. This assumption seems to have been largely true, and typically the performance difference between the openWakeWord implementation and the original Google embedding model is small.\n", + "\n", + "For completeness, below is the implementation of a melspectrogram using just PyTorch, so that it can be converted to ONNX/tflite for more efficient computation on a wide range of devices. This code was based on the implementation from [torchlibrosa](https://github.com/qiuqiangkong/torchlibrosa) and is identical to the librosa reference implementation to within rounding error." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "07e24374", + "metadata": {}, + "outputs": [], + "source": [ + "# torchlibrosa version of melspectrogram\n", + "\n", + "import torch\n", + "import torchlibrosa as tl\n", + "import numpy as np\n", + "\n", + "batch_size = 1\n", + "sample_rate = 16000\n", + "win_length = 400\n", + "hop_length = 160\n", + "n_mels = 32\n", + "nfft=512\n", + "\n", + "batch_audio = torch.empty(batch_size, 32000).uniform_(-1, 1) # (batch_size, sample_rate)\n", + "\n", + "def f(self, input):\n", + " r\"\"\"Power to db, this function is the pytorch implementation of \n", + " librosa.power_to_lb.\n", + " \"\"\"\n", + " ref_value = self.ref\n", + " log_spec = 10.0 * torch.log(torch.clamp(input, min=self.amin, max=np.inf))/torch.log(torch.tensor(10))\n", + " log_spec -= 10.0 * torch.log(torch.maximum(torch.tensor(self.amin), torch.tensor(ref_value)))/torch.log(torch.tensor(10))\n", + "\n", + " if self.top_db is not None:\n", + " if self.top_db < 0:\n", + " raise librosa.util.exceptions.ParameterError('top_db must be non-negative')\n", + " log_spec = torch.clamp(log_spec, min=log_spec.max() - self.top_db, max=np.inf)\n", + "\n", + " return log_spec\n", + "\n", + "tl.stft.LogmelFilterBank.power_to_db = f\n", + "\n", + "# TorchLibrosa feature extractor the same as librosa.feature.melspectrogram()\n", + "feature_extractor = torch.nn.Sequential(\n", + " tl.Spectrogram(\n", + " center=False,\n", + " n_fft=nfft,\n", + " hop_length=hop_length,\n", + " win_length=win_length,\n", + " ), tl.LogmelFilterBank(\n", + " n_fft=nfft,\n", + " sr=sample_rate,\n", + " n_mels=n_mels,\n", + " fmin=60,\n", + " fmax=3800,\n", + " is_log=True, # Default is true\n", + " ))\n", + "\n", + "# export to onnx\n", + "torch.onnx.export(feature_extractor, batch_audio, \"torchlibrosa_onnx_melspectrogram.onnx\",\n", + " opset_version=12, input_names = ['input'], output_names = ['output'], \n", + " dynamic_axes={\"input\": {0: 'batch_size', 1: 'samples'}, \"output\": {0: 'time'}})\n" + ] + }, + { + "cell_type": "markdown", + "id": "bbf87b19", + "metadata": {}, + "source": [ + "# Create New Model with Keras" + ] + }, + { + "cell_type": "markdown", + "id": "6bda8bd3", + "metadata": {}, + "source": [ + "After separting the log-mel feature calculution from the embedding model, we can now re-produce the rest of the model manually in Keras.\n", + "\n", + "Note that for many of the layers below, the hard-coded values and parameters were obtained by inspecting the tflite version of the original embedding model, using a tool like [Netron](http://www.netron.app)." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "4fca0fa3", + "metadata": { + "ExecuteTime": { + "end_time": "2024-01-18T00:27:56.152072Z", + "start_time": "2024-01-18T00:27:55.876595Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model: \"model_1\"\n", + "__________________________________________________________________________________________________\n", + " Layer (type) Output Shape Param # Connected to \n", + "==================================================================================================\n", + " input_2 (InputLayer) [(None, 76, 32, 1)] 0 [] \n", + " \n", + " zero_padding2d (ZeroPadding2D) (None, 76, 34, 1) 0 ['input_2[0][0]'] \n", + " \n", + " conv2d (Conv2D) (None, 74, 32, 24) 216 ['zero_padding2d[0][0]'] \n", + " \n", + " batch_normalization (BatchNorm (None, 74, 32, 24) 96 ['conv2d[0][0]'] \n", + " alization) \n", + " \n", + " tf.math.multiply (TFOpLambda) (None, 74, 32, 24) 0 ['batch_normalization[0][0]'] \n", + " \n", + " tf.math.truediv (TFOpLambda) (None, 74, 32, 24) 0 ['tf.math.multiply[0][0]'] \n", + " \n", + " tf.math.maximum (TFOpLambda) (None, 74, 32, 24) 0 ['tf.math.truediv[0][0]', \n", + " 'batch_normalization[0][0]'] \n", + " \n", + " tf.math.maximum_1 (TFOpLambda) (None, 74, 32, 24) 0 ['tf.math.maximum[0][0]'] \n", + " \n", + " conv2d_1 (Conv2D) (None, 74, 32, 24) 1728 ['tf.math.maximum_1[0][0]'] \n", + " \n", + " batch_normalization_1 (BatchNo (None, 74, 32, 24) 96 ['conv2d_1[0][0]'] \n", + " rmalization) \n", + " \n", + " tf.math.multiply_1 (TFOpLambda (None, 74, 32, 24) 0 ['batch_normalization_1[0][0]'] \n", + " ) \n", + " \n", + " tf.math.truediv_1 (TFOpLambda) (None, 74, 32, 24) 0 ['tf.math.multiply_1[0][0]'] \n", + " \n", + " tf.math.maximum_2 (TFOpLambda) (None, 74, 32, 24) 0 ['tf.math.truediv_1[0][0]', \n", + " 'batch_normalization_1[0][0]'] \n", + " \n", + " tf.math.maximum_3 (TFOpLambda) (None, 74, 32, 24) 0 ['tf.math.maximum_2[0][0]'] \n", + " \n", + " conv2d_2 (Conv2D) (None, 72, 32, 24) 1728 ['tf.math.maximum_3[0][0]'] \n", + " \n", + " batch_normalization_2 (BatchNo (None, 72, 32, 24) 96 ['conv2d_2[0][0]'] \n", + " rmalization) \n", + " \n", + " tf.math.multiply_2 (TFOpLambda (None, 72, 32, 24) 0 ['batch_normalization_2[0][0]'] \n", + " ) \n", + " \n", + " tf.math.truediv_2 (TFOpLambda) (None, 72, 32, 24) 0 ['tf.math.multiply_2[0][0]'] \n", + " \n", + " tf.math.maximum_4 (TFOpLambda) (None, 72, 32, 24) 0 ['tf.math.truediv_2[0][0]', \n", + " 'batch_normalization_2[0][0]'] \n", + " \n", + " tf.math.maximum_5 (TFOpLambda) (None, 72, 32, 24) 0 ['tf.math.maximum_4[0][0]'] \n", + " \n", + " max_pooling2d (MaxPooling2D) (None, 36, 16, 24) 0 ['tf.math.maximum_5[0][0]'] \n", + " \n", + " conv2d_3 (Conv2D) (None, 36, 16, 48) 3456 ['max_pooling2d[0][0]'] \n", + " \n", + " batch_normalization_3 (BatchNo (None, 36, 16, 48) 192 ['conv2d_3[0][0]'] \n", + " rmalization) \n", + " \n", + " tf.math.multiply_3 (TFOpLambda (None, 36, 16, 48) 0 ['batch_normalization_3[0][0]'] \n", + " ) \n", + " \n", + " tf.math.truediv_3 (TFOpLambda) (None, 36, 16, 48) 0 ['tf.math.multiply_3[0][0]'] \n", + " \n", + " tf.math.maximum_6 (TFOpLambda) (None, 36, 16, 48) 0 ['tf.math.truediv_3[0][0]', \n", + " 'batch_normalization_3[0][0]'] \n", + " \n", + " tf.math.maximum_7 (TFOpLambda) (None, 36, 16, 48) 0 ['tf.math.maximum_6[0][0]'] \n", + " \n", + " conv2d_4 (Conv2D) (None, 34, 16, 48) 6912 ['tf.math.maximum_7[0][0]'] \n", + " \n", + " batch_normalization_4 (BatchNo (None, 34, 16, 48) 192 ['conv2d_4[0][0]'] \n", + " rmalization) \n", + " \n", + " tf.math.multiply_4 (TFOpLambda (None, 34, 16, 48) 0 ['batch_normalization_4[0][0]'] \n", + " ) \n", + " \n", + " tf.math.truediv_4 (TFOpLambda) (None, 34, 16, 48) 0 ['tf.math.multiply_4[0][0]'] \n", + " \n", + " tf.math.maximum_8 (TFOpLambda) (None, 34, 16, 48) 0 ['tf.math.truediv_4[0][0]', \n", + " 'batch_normalization_4[0][0]'] \n", + " \n", + " tf.math.maximum_9 (TFOpLambda) (None, 34, 16, 48) 0 ['tf.math.maximum_8[0][0]'] \n", + " \n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " conv2d_5 (Conv2D) (None, 34, 16, 48) 6912 ['tf.math.maximum_9[0][0]'] \n", + " \n", + " batch_normalization_5 (BatchNo (None, 34, 16, 48) 192 ['conv2d_5[0][0]'] \n", + " rmalization) \n", + " \n", + " tf.math.multiply_5 (TFOpLambda (None, 34, 16, 48) 0 ['batch_normalization_5[0][0]'] \n", + " ) \n", + " \n", + " tf.math.truediv_5 (TFOpLambda) (None, 34, 16, 48) 0 ['tf.math.multiply_5[0][0]'] \n", + " \n", + " tf.math.maximum_10 (TFOpLambda (None, 34, 16, 48) 0 ['tf.math.truediv_5[0][0]', \n", + " ) 'batch_normalization_5[0][0]'] \n", + " \n", + " tf.math.maximum_11 (TFOpLambda (None, 34, 16, 48) 0 ['tf.math.maximum_10[0][0]'] \n", + " ) \n", + " \n", + " conv2d_6 (Conv2D) (None, 32, 16, 48) 6912 ['tf.math.maximum_11[0][0]'] \n", + " \n", + " batch_normalization_6 (BatchNo (None, 32, 16, 48) 192 ['conv2d_6[0][0]'] \n", + " rmalization) \n", + " \n", + " tf.math.multiply_6 (TFOpLambda (None, 32, 16, 48) 0 ['batch_normalization_6[0][0]'] \n", + " ) \n", + " \n", + " tf.math.truediv_6 (TFOpLambda) (None, 32, 16, 48) 0 ['tf.math.multiply_6[0][0]'] \n", + " \n", + " tf.math.maximum_12 (TFOpLambda (None, 32, 16, 48) 0 ['tf.math.truediv_6[0][0]', \n", + " ) 'batch_normalization_6[0][0]'] \n", + " \n", + " tf.math.maximum_13 (TFOpLambda (None, 32, 16, 48) 0 ['tf.math.maximum_12[0][0]'] \n", + " ) \n", + " \n", + " max_pooling2d_1 (MaxPooling2D) (None, 32, 8, 48) 0 ['tf.math.maximum_13[0][0]'] \n", + " \n", + " conv2d_7 (Conv2D) (None, 32, 8, 72) 10368 ['max_pooling2d_1[0][0]'] \n", + " \n", + " batch_normalization_7 (BatchNo (None, 32, 8, 72) 288 ['conv2d_7[0][0]'] \n", + " rmalization) \n", + " \n", + " tf.math.multiply_7 (TFOpLambda (None, 32, 8, 72) 0 ['batch_normalization_7[0][0]'] \n", + " ) \n", + " \n", + " tf.math.truediv_7 (TFOpLambda) (None, 32, 8, 72) 0 ['tf.math.multiply_7[0][0]'] \n", + " \n", + " tf.math.maximum_14 (TFOpLambda (None, 32, 8, 72) 0 ['tf.math.truediv_7[0][0]', \n", + " ) 'batch_normalization_7[0][0]'] \n", + " \n", + " tf.math.maximum_15 (TFOpLambda (None, 32, 8, 72) 0 ['tf.math.maximum_14[0][0]'] \n", + " ) \n", + " \n", + " conv2d_8 (Conv2D) (None, 30, 8, 72) 15552 ['tf.math.maximum_15[0][0]'] \n", + " \n", + " batch_normalization_8 (BatchNo (None, 30, 8, 72) 288 ['conv2d_8[0][0]'] \n", + " rmalization) \n", + " \n", + " tf.math.multiply_8 (TFOpLambda (None, 30, 8, 72) 0 ['batch_normalization_8[0][0]'] \n", + " ) \n", + " \n", + " tf.math.truediv_8 (TFOpLambda) (None, 30, 8, 72) 0 ['tf.math.multiply_8[0][0]'] \n", + " \n", + " tf.math.maximum_16 (TFOpLambda (None, 30, 8, 72) 0 ['tf.math.truediv_8[0][0]', \n", + " ) 'batch_normalization_8[0][0]'] \n", + " \n", + " tf.math.maximum_17 (TFOpLambda (None, 30, 8, 72) 0 ['tf.math.maximum_16[0][0]'] \n", + " ) \n", + " \n", + " conv2d_9 (Conv2D) (None, 30, 8, 72) 15552 ['tf.math.maximum_17[0][0]'] \n", + " \n", + " batch_normalization_9 (BatchNo (None, 30, 8, 72) 288 ['conv2d_9[0][0]'] \n", + " rmalization) \n", + " \n", + " tf.math.multiply_9 (TFOpLambda (None, 30, 8, 72) 0 ['batch_normalization_9[0][0]'] \n", + " ) \n", + " \n", + " tf.math.truediv_9 (TFOpLambda) (None, 30, 8, 72) 0 ['tf.math.multiply_9[0][0]'] \n", + " \n", + " tf.math.maximum_18 (TFOpLambda (None, 30, 8, 72) 0 ['tf.math.truediv_9[0][0]', \n", + " ) 'batch_normalization_9[0][0]'] \n", + " \n", + " tf.math.maximum_19 (TFOpLambda (None, 30, 8, 72) 0 ['tf.math.maximum_18[0][0]'] \n", + " ) \n", + " \n", + " conv2d_10 (Conv2D) (None, 28, 8, 72) 15552 ['tf.math.maximum_19[0][0]'] \n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " \n", + " batch_normalization_10 (BatchN (None, 28, 8, 72) 288 ['conv2d_10[0][0]'] \n", + " ormalization) \n", + " \n", + " tf.math.multiply_10 (TFOpLambd (None, 28, 8, 72) 0 ['batch_normalization_10[0][0]'] \n", + " a) \n", + " \n", + " tf.math.truediv_10 (TFOpLambda (None, 28, 8, 72) 0 ['tf.math.multiply_10[0][0]'] \n", + " ) \n", + " \n", + " tf.math.maximum_20 (TFOpLambda (None, 28, 8, 72) 0 ['tf.math.truediv_10[0][0]', \n", + " ) 'batch_normalization_10[0][0]'] \n", + " \n", + " tf.math.maximum_21 (TFOpLambda (None, 28, 8, 72) 0 ['tf.math.maximum_20[0][0]'] \n", + " ) \n", + " \n", + " max_pooling2d_2 (MaxPooling2D) (None, 14, 4, 72) 0 ['tf.math.maximum_21[0][0]'] \n", + " \n", + " conv2d_11 (Conv2D) (None, 14, 4, 96) 20736 ['max_pooling2d_2[0][0]'] \n", + " \n", + " batch_normalization_11 (BatchN (None, 14, 4, 96) 384 ['conv2d_11[0][0]'] \n", + " ormalization) \n", + " \n", + " tf.math.multiply_11 (TFOpLambd (None, 14, 4, 96) 0 ['batch_normalization_11[0][0]'] \n", + " a) \n", + " \n", + " tf.math.truediv_11 (TFOpLambda (None, 14, 4, 96) 0 ['tf.math.multiply_11[0][0]'] \n", + " ) \n", + " \n", + " tf.math.maximum_22 (TFOpLambda (None, 14, 4, 96) 0 ['tf.math.truediv_11[0][0]', \n", + " ) 'batch_normalization_11[0][0]'] \n", + " \n", + " tf.math.maximum_23 (TFOpLambda (None, 14, 4, 96) 0 ['tf.math.maximum_22[0][0]'] \n", + " ) \n", + " \n", + " conv2d_12 (Conv2D) (None, 12, 4, 96) 27648 ['tf.math.maximum_23[0][0]'] \n", + " \n", + " batch_normalization_12 (BatchN (None, 12, 4, 96) 384 ['conv2d_12[0][0]'] \n", + " ormalization) \n", + " \n", + " tf.math.multiply_12 (TFOpLambd (None, 12, 4, 96) 0 ['batch_normalization_12[0][0]'] \n", + " a) \n", + " \n", + " tf.math.truediv_12 (TFOpLambda (None, 12, 4, 96) 0 ['tf.math.multiply_12[0][0]'] \n", + " ) \n", + " \n", + " tf.math.maximum_24 (TFOpLambda (None, 12, 4, 96) 0 ['tf.math.truediv_12[0][0]', \n", + " ) 'batch_normalization_12[0][0]'] \n", + " \n", + " tf.math.maximum_25 (TFOpLambda (None, 12, 4, 96) 0 ['tf.math.maximum_24[0][0]'] \n", + " ) \n", + " \n", + " conv2d_13 (Conv2D) (None, 12, 4, 96) 27648 ['tf.math.maximum_25[0][0]'] \n", + " \n", + " batch_normalization_13 (BatchN (None, 12, 4, 96) 384 ['conv2d_13[0][0]'] \n", + " ormalization) \n", + " \n", + " tf.math.multiply_13 (TFOpLambd (None, 12, 4, 96) 0 ['batch_normalization_13[0][0]'] \n", + " a) \n", + " \n", + " tf.math.truediv_13 (TFOpLambda (None, 12, 4, 96) 0 ['tf.math.multiply_13[0][0]'] \n", + " ) \n", + " \n", + " tf.math.maximum_26 (TFOpLambda (None, 12, 4, 96) 0 ['tf.math.truediv_13[0][0]', \n", + " ) 'batch_normalization_13[0][0]'] \n", + " \n", + " tf.math.maximum_27 (TFOpLambda (None, 12, 4, 96) 0 ['tf.math.maximum_26[0][0]'] \n", + " ) \n", + " \n", + " conv2d_14 (Conv2D) (None, 10, 4, 96) 27648 ['tf.math.maximum_27[0][0]'] \n", + " \n", + " batch_normalization_14 (BatchN (None, 10, 4, 96) 384 ['conv2d_14[0][0]'] \n", + " ormalization) \n", + " \n", + " tf.math.multiply_14 (TFOpLambd (None, 10, 4, 96) 0 ['batch_normalization_14[0][0]'] \n", + " a) \n", + " \n", + " tf.math.truediv_14 (TFOpLambda (None, 10, 4, 96) 0 ['tf.math.multiply_14[0][0]'] \n", + " ) \n", + " \n", + " tf.math.maximum_28 (TFOpLambda (None, 10, 4, 96) 0 ['tf.math.truediv_14[0][0]', \n", + " ) 'batch_normalization_14[0][0]'] \n", + " \n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " tf.math.maximum_29 (TFOpLambda (None, 10, 4, 96) 0 ['tf.math.maximum_28[0][0]'] \n", + " ) \n", + " \n", + " max_pooling2d_3 (MaxPooling2D) (None, 10, 2, 96) 0 ['tf.math.maximum_29[0][0]'] \n", + " \n", + " conv2d_15 (Conv2D) (None, 10, 2, 96) 27648 ['max_pooling2d_3[0][0]'] \n", + " \n", + " batch_normalization_15 (BatchN (None, 10, 2, 96) 384 ['conv2d_15[0][0]'] \n", + " ormalization) \n", + " \n", + " tf.math.multiply_15 (TFOpLambd (None, 10, 2, 96) 0 ['batch_normalization_15[0][0]'] \n", + " a) \n", + " \n", + " tf.math.truediv_15 (TFOpLambda (None, 10, 2, 96) 0 ['tf.math.multiply_15[0][0]'] \n", + " ) \n", + " \n", + " tf.math.maximum_30 (TFOpLambda (None, 10, 2, 96) 0 ['tf.math.truediv_15[0][0]', \n", + " ) 'batch_normalization_15[0][0]'] \n", + " \n", + " tf.math.maximum_31 (TFOpLambda (None, 10, 2, 96) 0 ['tf.math.maximum_30[0][0]'] \n", + " ) \n", + " \n", + " conv2d_16 (Conv2D) (None, 8, 2, 96) 27648 ['tf.math.maximum_31[0][0]'] \n", + " \n", + " batch_normalization_16 (BatchN (None, 8, 2, 96) 384 ['conv2d_16[0][0]'] \n", + " ormalization) \n", + " \n", + " tf.math.multiply_16 (TFOpLambd (None, 8, 2, 96) 0 ['batch_normalization_16[0][0]'] \n", + " a) \n", + " \n", + " tf.math.truediv_16 (TFOpLambda (None, 8, 2, 96) 0 ['tf.math.multiply_16[0][0]'] \n", + " ) \n", + " \n", + " tf.math.maximum_32 (TFOpLambda (None, 8, 2, 96) 0 ['tf.math.truediv_16[0][0]', \n", + " ) 'batch_normalization_16[0][0]'] \n", + " \n", + " tf.math.maximum_33 (TFOpLambda (None, 8, 2, 96) 0 ['tf.math.maximum_32[0][0]'] \n", + " ) \n", + " \n", + " conv2d_17 (Conv2D) (None, 8, 2, 96) 27648 ['tf.math.maximum_33[0][0]'] \n", + " \n", + " batch_normalization_17 (BatchN (None, 8, 2, 96) 384 ['conv2d_17[0][0]'] \n", + " ormalization) \n", + " \n", + " tf.math.multiply_17 (TFOpLambd (None, 8, 2, 96) 0 ['batch_normalization_17[0][0]'] \n", + " a) \n", + " \n", + " tf.math.truediv_17 (TFOpLambda (None, 8, 2, 96) 0 ['tf.math.multiply_17[0][0]'] \n", + " ) \n", + " \n", + " tf.math.maximum_34 (TFOpLambda (None, 8, 2, 96) 0 ['tf.math.truediv_17[0][0]', \n", + " ) 'batch_normalization_17[0][0]'] \n", + " \n", + " tf.math.maximum_35 (TFOpLambda (None, 8, 2, 96) 0 ['tf.math.maximum_34[0][0]'] \n", + " ) \n", + " \n", + " conv2d_18 (Conv2D) (None, 6, 2, 96) 27648 ['tf.math.maximum_35[0][0]'] \n", + " \n", + " batch_normalization_18 (BatchN (None, 6, 2, 96) 384 ['conv2d_18[0][0]'] \n", + " ormalization) \n", + " \n", + " tf.math.multiply_18 (TFOpLambd (None, 6, 2, 96) 0 ['batch_normalization_18[0][0]'] \n", + " a) \n", + " \n", + " tf.math.truediv_18 (TFOpLambda (None, 6, 2, 96) 0 ['tf.math.multiply_18[0][0]'] \n", + " ) \n", + " \n", + " tf.math.maximum_36 (TFOpLambda (None, 6, 2, 96) 0 ['tf.math.truediv_18[0][0]', \n", + " ) 'batch_normalization_18[0][0]'] \n", + " \n", + " tf.math.maximum_37 (TFOpLambda (None, 6, 2, 96) 0 ['tf.math.maximum_36[0][0]'] \n", + " ) \n", + " \n", + " max_pooling2d_4 (MaxPooling2D) (None, 3, 1, 96) 0 ['tf.math.maximum_37[0][0]'] \n", + " \n", + " conv2d_19 (Conv2D) (None, 1, 1, 96) 27648 ['max_pooling2d_4[0][0]'] \n", + " \n", + "==================================================================================================\n", + "Total params: 332,088\n", + "Trainable params: 329,448\n", + "Non-trainable params: 2,640\n", + "__________________________________________________________________________________________________\n" + ] + } + ], + "source": [ + "# Recreate the embedding model after the melspectrogram layers\n", + "# That is, have the melspectrogram of the audio as the input instead of the raw audio\n", + "\n", + "# A custom function for the leaky relu activation function, to make exporting to ONNX/tflite easier\n", + "def MyLeakyReLU(alpha = 0.20000000298023224*2):\n", + " return lambda x : tf.keras.backend.maximum(alpha * x/2, x)\n", + "\n", + "# Define convolutional block helper functions\n", + "def batch_norm_and_activation(x):\n", + " x = tf.keras.layers.BatchNormalization()(x)\n", + " x = MyLeakyReLU()(x)\n", + " x = tf.maximum(x, -0.4000000059604645)\n", + " return x\n", + "\n", + "# Define contraint for zero mean conv2d layer\n", + "class CenterAround(tf.keras.constraints.Constraint):\n", + " \"\"\"Constrains weight tensors to be centered around `ref_value`.\"\"\"\n", + " def __init__(self, ref_value):\n", + " self.ref_value = ref_value\n", + "\n", + " def __call__(self, w):\n", + " mean = tf.reduce_mean(w, axis=(0,1))\n", + " return w - mean + self.ref_value\n", + "\n", + "\n", + "# Contruct inputs\n", + "inputs = tf.keras.Input((76, 32, 1)) # melspectrogram shape when provided with 12400 samples at 16 khz\n", + "\n", + "# Input conv block\n", + "x = tf.keras.layers.ZeroPadding2D((0,1))(inputs)\n", + "x = tf.keras.layers.Conv2D(24, (3,3), use_bias=False, kernel_constraint=CenterAround(0.0),\n", + " activation='relu', padding='valid')(x)\n", + "x = batch_norm_and_activation(x)\n", + "\n", + "# Conv block #1\n", + "x = tf.keras.layers.Conv2D(24, (1,3), use_bias=False, padding='same')(x)\n", + "x = batch_norm_and_activation(x)\n", + "x = tf.keras.layers.Conv2D(24, (3,1), use_bias=False, padding='valid')(x)\n", + "x = batch_norm_and_activation(x)\n", + "x = tf.keras.layers.MaxPool2D((2,2), (2,2), padding='valid')(x)\n", + "x = tf.keras.layers.Conv2D(48, (1,3), use_bias=False, padding='same')(x)\n", + "x = batch_norm_and_activation(x)\n", + "x = tf.keras.layers.Conv2D(48, (3,1), use_bias=False, padding='valid')(x)\n", + "x = batch_norm_and_activation(x)\n", + "\n", + "# Conv block #2\n", + "x = tf.keras.layers.Conv2D(48, (1,3), use_bias=False, padding='same')(x)\n", + "x = batch_norm_and_activation(x)\n", + "x = tf.keras.layers.Conv2D(48, (3,1), use_bias=False, padding='valid')(x)\n", + "x = batch_norm_and_activation(x)\n", + "x = tf.keras.layers.MaxPool2D((1,2), (1,2), padding='same')(x)\n", + "x = tf.keras.layers.Conv2D(72, (1,3), use_bias=False, padding='same')(x)\n", + "x = batch_norm_and_activation(x)\n", + "x = tf.keras.layers.Conv2D(72, (3,1), use_bias=False, padding='valid')(x)\n", + "x = batch_norm_and_activation(x)\n", + "\n", + "# Conv block #3\n", + "x = tf.keras.layers.Conv2D(72, (1,3), use_bias=False, padding='same')(x)\n", + "x = batch_norm_and_activation(x)\n", + "x = tf.keras.layers.Conv2D(72, (3,1), use_bias=False, padding='valid')(x)\n", + "x = batch_norm_and_activation(x)\n", + "x = tf.keras.layers.MaxPool2D((2,2), (2,2), padding='valid')(x)\n", + "x = tf.keras.layers.Conv2D(96, (1,3), use_bias=False, padding='same')(x)\n", + "x = batch_norm_and_activation(x)\n", + "x = tf.keras.layers.Conv2D(96, (3,1), use_bias=False, padding='valid')(x)\n", + "x = batch_norm_and_activation(x)\n", + "\n", + "# Conv block #4\n", + "x = tf.keras.layers.Conv2D(96, (1,3), use_bias=False, padding='same')(x)\n", + "x = batch_norm_and_activation(x)\n", + "x = tf.keras.layers.Conv2D(96, (3,1), use_bias=False, padding='valid')(x)\n", + "x = batch_norm_and_activation(x)\n", + "x = tf.keras.layers.MaxPool2D((1,2), (1,2), padding='valid')(x)\n", + "x = tf.keras.layers.Conv2D(96, (1,3), use_bias=False, padding='same')(x)\n", + "x = batch_norm_and_activation(x)\n", + "x = tf.keras.layers.Conv2D(96, (3,1), use_bias=False, padding='valid')(x)\n", + "x = batch_norm_and_activation(x)\n", + "\n", + "# Conv block #5\n", + "x = tf.keras.layers.Conv2D(96, (1,3), use_bias=False, padding='same')(x)\n", + "x = batch_norm_and_activation(x)\n", + "x = tf.keras.layers.Conv2D(96, (3,1), use_bias=False, padding='valid')(x)\n", + "x = batch_norm_and_activation(x)\n", + "x = tf.keras.layers.MaxPool2D((2,2), (2,2), padding=\"valid\")(x)\n", + "x = tf.keras.layers.Conv2D(96, (3,1), use_bias=False, padding='valid')(x)\n", + "\n", + "# Build the keras model\n", + "reimplemented_model = tf.keras.Model(inputs=inputs, outputs=x)\n", + "reimplemented_model.summary()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "3a83d707", + "metadata": { + "ExecuteTime": { + "end_time": "2024-01-18T00:28:05.030126Z", + "start_time": "2024-01-18T00:28:05.008907Z" + } + }, + "outputs": [], + "source": [ + "# Manually set the weights of the new Keras model with those from the original embedding model\n", + "\n", + "# Set weights for all layers\n", + "reimplemented_model.set_weights(embedding_model.get_weights())\n", + "\n", + "# Adjust weights of specific layer that needs to be centered around 0.0\n", + "reimplemented_model.layers[2].set_weights([CenterAround(0.0)(reimplemented_model.layers[2].weights[0])])\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eba224b4", + "metadata": {}, + "outputs": [], + "source": [ + "# Convert the new keras model to tflite format (optional for this notebook)\n", + "converter = tf.lite.TFLiteConverter.from_keras_model(model)\n", + "tflite_model = converter.convert()\n", + "\n", + "# Save the model.\n", + "with open('embedding_model.tflite', 'wb') as f:\n", + " f.write(tflite_model)" + ] + }, + { + "cell_type": "markdown", + "id": "7cfc246b", + "metadata": {}, + "source": [ + "# Compare Predictions" + ] + }, + { + "cell_type": "markdown", + "id": "4907f757", + "metadata": {}, + "source": [ + "Now that we have a re-implemented embedding model, we can verify that the predictions are the same as the original. Note that as discussed previously, the log-mel feature calculation is different, so we will start from the original audio features obtained via tflite and calculate the final embeddings from there." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "6d6ba4b5", + "metadata": { + "ExecuteTime": { + "end_time": "2024-01-18T00:29:27.288771Z", + "start_time": "2024-01-18T00:29:27.165734Z" + } + }, + "outputs": [ + { + "data": { + "image/png": "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3/vehxUrVmDFihX42Mc+hsceewxHH320t/0rr7yCM844A8lkEr29vbj44ouRyWS8+x3HwbXXXouFCxdC0zQce+yxuPfee0Ov+cQTT+DYY49FIpHACSecgF//+tcVy1OPPfYY3va2tyGZTGLRokW47LLLkM1my/5tsizj4x//OG6//Xbvtp07d+Khhx7Cxz/+8aLtb7nlFixfvhyqqmLlypX40Y9+FLp/w4YNOPXUU5FIJLB69Wr88Y9/LHqOHTt24LzzzkNXVxd6enrwgQ98AFu3bi27n1PBG0/+D9684d9Q+N2X6v7cHBwcHFEc0DkqUeRNG6uvua8lr/36tWchpVZ+u0dGRnDffffhX//1X5FMJkP3DQwM4Pzzz8fdd9+N733ve1543Q033IBrrrkG//iP/xj7nFu2bMGHP/xhXH755fj0pz+NF198EX/3d39XcV82bdqEX//61/jd736H0dFRnHfeefja176Gf/3XfwUAZLNZXHnllTj66KORyWRwzTXX4EMf+hDWrl1bVYvr2rVr8cYbb+BnP/tZye3Z35jNZnHWWWfh5JNPxrPPPot9+/bh05/+NC699FLceeedAIDvfOc7+Ld/+zfceuutWLNmDW6//Xa8//3vx2uvvYYVK1ZgYmIC73vf+/AXf/EX+OlPf4pt27bhiiuuqPgenH322fjqV7+K22+/HUNDQ7j00ktx6aWX4o477ij72IsuuginnXYavvOd7yCVSuHOO+/E2Wefjf7+/tB299xzDy6//HJ8+9vfxplnnonf/e53uPDCC7Fw4UKcfvrpcBwH55xzDvr7+/H0009jfHy8aL9N0/Ten0cffRSyLOOrX/0qzj77bLz88st1TZnVJ8gQUc3OVNiSg4ODY/o4qBSV2YANGzbAdd1YfwNApk+Pjo5iaGjIu+2MM87A5z//eSxfvhzLly8vesytt96KlStX4pvf/CZWrlyJj370o7jgggsq7ovjOLjzzjtx5JFH4m1vexs+8YlPhAZInnvuuTjnnHNw6KGH4thjj8Xtt9+OV155Ba+//npVfyvzxKxcudK7bd++fWhra/P+fe973wMA/PSnP0WhUMAPf/hDHHnkkTjjjDPw3e9+Fz/60Y+86ds33HADrrrqKnz0ox/FypUr8fWvfx3HHnssvv3tb3vPIQgCfvCDH2D16tV497vfjS984Qtl9/H666/H+eefjyuuuAIrVqzAW97yFtx000344Q9/iEKhUPaxa9aswSGHHIJf/vKXcF0Xd955Jy666KKi7W644QZccMEF+Ju/+RscdthhuPLKK3HOOefghhtuAAD86U9/wp///Gf88Ic/xDHHHINTTz0V1113Xeg57r77bjiOg//4j//AUUcdhVWrVuGOO+7A9u3b8dBDD5Xdz1rh6GQchQCnrs/LwcHBEYeDSlFJKhJev/aslr12LailVHTCCSeUvX/dunU48cQTQ7e96U1vqvi8S5cuRXt7u/f7vHnzsG/fPu/3DRs24JprrsHTTz+N/fv3w3HIhWv79u01GXmD6O3t9cowp512GgzDAAC88cYbOOaYY5BOp71tTznlFDiOg3Xr1iGZTGL37t045ZRTQs93yimn4KWXXgJA3oejjz46lLZa6X146aWX8PLLL+MnP/mJd5vrunAcB1u2bClJKBkuuugi3HHHHVi8eDGy2Sz+4i/+At/97ndD27zxxhu4+OKLi/b7O9/5jnf/okWLMH/+fO/+6HTxl156CRs3bgx9XgBQKBRqKsdVA8cgREVy+ZBPDg6OxuOgIiqCIFRVfmklDj30UAiCgDfeeAMf+tCHiu5/44030N3djblz53q3BS/e9YSiKKHfBUHwyAgAvO9978OSJUvwgx/8APPnz4fjODjyyCM9clEJK1asAEAIxJo1awCQ6b2HHnooANRkBm4UMpkMPvvZz+Kyyy4ruq8aU+z555+PL37xi/inf/onfOITn2jY35TJZHD88ceHCBVD8LtSD7gG8eeI4ESFg4Oj8eClnxmG3t5evPOd78T3vvc95PP50H2Dg4P4yU9+go985CM1DVdcuXIlnnvuudBtzz777LT2c3h4GOvWrcPf//3f4x3veIdXkqoFa9asweGHH44bbrghRIDisGrVKrz00kshE+vjjz8OURSxcuVKdHR0YP78+Xj88cdDj3v88cexevVqAOR9eOWVV6Drund/pffhuOOOw+uvv45DDz206F81vo+enh68//3vx8MPPxxb9mF/W7n9XrVqFXbs2IE9e/Z49z/11FNF+7lhwwb09fUV7WdnZ2fF/awFgkm+lyJXVDg4OJoATlRmIL773e9C13WcddZZeOSRR7Bjxw7ce++9eOc734kFCxZ4ZtZq8dnPfhZ//vOfcdVVV2H9+vX4z//8T8+A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c845+NCHPoSuri784Q9/wObNm3HuuefilFNOwUc+8hHvcd/85jfx5S9/Gf/8z/+M++67D5dffjkOO+wwvPOd7yx6DdM0cdZZZ+Hkk0/Go48+ClmW8dWvfhVnn302Xn75ZaiqCgB44IEHsHDhQjzyyCN4/PHH8alPfQpPPPEETj31VDz99NO4++678dnPfhbvfOc7sXDhwqqf98EHH/RUjI0bN+IjH/kIjj32WHzmM5/Br371KxxzzDG4+OKL8ZnPfMbb502bNuHss8/GV7/6Vdx+++0YGhrCpZdeiksvvdQjSxdccAF2796NBx98EIqi4LLLLsO+ffuq+vwuuugifPGLX8RXvvIVAERNOf/884u2+853voN/+7d/w6233oo1a9bg9ttvx/vf/3689tprWLFiBTKZDN773vfine98J3784x9jy5YtuPzyy0PPMTY2hjPOOAOf/vSnceONNyKfz3uDFx944IGq9rccjHw29Ds303JwNA+2Scr/Cg6u4+7gIiqzCL/73e/Q1tYGy7Kg6zpEUcR3v/tdAICu67juuuvwpz/9CSeffDIA4JBDDsFjjz2GW2+9tSRRMU0Tt9xyC5YvXw4A+PCHP4wf/ehH2Lt3L9ra2rB69WqcfvrpePDBB0NE5ZRTTsGXvvQlAMBhhx2Gxx9/HDfeeGMsUbn77rvhOA7+4z/+w1Ms7rjjDnR1deGhhx7Cu971LgBAT08PbrrpJoiiiJUrV+Ib3/gGcrkcvvzlLwMArr76anzta1/DY489ho9+9KNVP293dze++93vQpIkHH744XjPe96D+++/H5/5zGfQ09MDSZLQ3t6OgYEBb5+vv/56nH/++Z7BdMWKFbjpppvw9re/Hbfccgu2b9+O//mf/8EzzzyDE088EQBw2223YdWqVVV9lu9973vxf//v/8UjjzyC448/Hv/5n/+Jxx57DLfffntouxtuuAFXXXUVPvrRjwIAvv71r+PBBx/Et7/9bdx888346U9/CsdxcNtttyGRSOCII47Azp078dd//dfec3z3u9/FmjVrcN1113m33X777Vi0aBHWr1+Pww47rKp9LgWzwD0qHBytgmOSjjvV5UTlwIWSIspGq167Bpx++um45ZZbkM1mceONN0KWZZx77rkAgI0bNyKXyxURBcMwsGbNmpLPmUqlPJICAP39/Vi6dCna2tpCt0WV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57e//S0DwPbt29epZaaGqakpdvrpp7O9e/ey973vfYFQoeO+fHzxi19kl156adPHfd9no6Oj7Otf/3pw38TEBLMsi33/+99vxxJTyzXXXMM++clP1t330Y9+lF133XWMMTr2cYa2fiLYto39+/fjyiuvDO5TVRVXXnkl9u3b18GVpZ/JyUkAwIoVKwAA+/fvh+M4dZ/F5s2bMTY2Rp/FErB7925cc801dccXoOO+nPzTP/0Ttm/fjmuvvRarVq3Ceeedh7/9278NHn/llVcwPj5ed+zz+TwuvPBCOvaL5OKLL8ajjz6KF198EQDw61//Go8//jg+8IEPAKBjH2cSn5681Lz99tvwPA8jIyN194+MjOCFF17o0KrSj+/7uPXWW3HJJZfg7LPPBgCMj4/DNE0MDAzUPXdkZATj4+MdWGV6ePjhh/Hv//7vePrpp2c8Rsd9+Xj55ZfxrW99C5/97GfxpS99CU8//TQ+85nPwDRNXH/99cHxbfT9Q8d+cdx2220oFArYvHkzNE2D53m46667cN111wEAHfsYQ0KFiAW7d+/GwYMH8fjjj3d6KannyJEjuOWWW7B3715kMplOL6er8H0f27dvx1e/+lUAwHnnnYeDBw/i29/+Nq6//voOry7d/PCHP8RDDz2Ev//7v8dZZ52FAwcO4NZbb8Xq1avp2Mcc2vqJMDw8DE3TZkw4HD9+HKOjox1aVbr59Kc/jZ/+9Kf4l3/5F6xZsya4f3R0FLZtY2Jiou759Fksjv379+PNN9/E+eefD13Xoes6fvnLX+Kb3/wmdF3HyMgIHfdl4pRTTsG73vWuuvu2bNmC119/HQCC40vfP0vP5z//edx222342Mc+hnPOOQd/9Ed/hD/90z/Fnj17ANCxjzMkVCKYpolt27bh0UcfDe7zfR+PPvooduzY0cGVpQ/GGD796U/jH/7hH/DYY49hw4YNdY9v27YNhmHUfRaHDh3C66+/Tp/FIrjiiivw3HPP4cCBA8G/7du347rrrgt+puO+PFxyySUzRvBffPFFrFu3DgCwYcMGjI6O1h37QqGAJ598ko79IimVSlDV+lOepmnwfR8AHftY0+lu3jjy8MMPM8uy2He+8x32m9/8ht10001sYGCAjY+Pd3ppqeJP/uRPWD6fZ7/4xS/YG2+8EfwrlUrBc26++WY2NjbGHnvsMfbMM8+wHTt2sB07dnRw1ekkPPXDGB335eKpp55iuq6zu+66i7300kvsoYceYrlcjn3ve98LnnP33XezgYEB9pOf/IQ9++yz7MMf/jCNyC4B119/PTv11FOD8eQf//jHbHh4mH3hC18InkPHPp6QUGnCfffdx8bGxphpmuyCCy5gTzzxRKeXlDoANPz34IMPBs8pl8vsU5/6FBscHGS5XI595CMfYW+88UbnFp1SokKFjvvy8c///M/s7LPPZpZlsc2bN7P777+/7nHf99mXv/xlNjIywizLYldccQU7dOhQh1abHgqFArvlllvY2NgYy2QybOPGjeyOO+5g1Wo1eA4d+3iiMBay5SMIgiAIgogR1KNCEARBEERsIaFCEARBEERsIaFCEARBEERsIaFCEARBEERsIaFCEARBEERsIaFCEARBEERsIaFCEARBEERsIaFCEARBEERsIaFCEARBEERsIaFCEARBEERsIaFCEARBEERs+f/7Y/qsaZ4WVAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Get original embedding model prediction\n", + "original_embeddings = embedding_model(sample_data)\n", + "\n", + "# Reshape original log-mel inputs from tflite model above and pass to re-implemented model\n", + "reimplemented_embeddings = reimplemented_model(spec.T[None, ..., None])\n", + "\n", + "# Plot final output embeddings for the sample data\n", + "_ = plt.plot(original_embeddings.numpy().flatten(), label=\"Original Google Model\")\n", + "_ = plt.plot(reimplemented_embeddings.numpy().flatten(), label=\"Reimplemented Model\")\n", + "_ = plt.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "ea6f9936", + "metadata": { + "ExecuteTime": { + "end_time": "2024-01-18T00:29:29.894151Z", + "start_time": "2024-01-18T00:29:29.882876Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "0.00010585785" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Check maximum absolute difference in the output embeddings to confirm practical equivalence\n", + "np.abs(original_embeddings.numpy().flatten() - reimplemented_embeddings.numpy().flatten()).max()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "openwakeword_dev", + "language": "python", + "name": "openwakeword_dev" + }, + "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.9.16" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": { + "height": "calc(100% - 180px)", + "left": "10px", + "top": "150px", + "width": "384px" + }, + "toc_section_display": true, + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/training_models.ipynb b/notebooks/training_models.ipynb index 6f118fd..43fed78 100644 --- a/notebooks/training_models.ipynb +++ b/notebooks/training_models.ipynb @@ -43,16 +43,7 @@ "start_time": "2023-02-18T03:26:24.785801Z" } }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/dscripka/anaconda3/envs/torch_gpu/lib/python3.9/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", - " from .autonotebook import tqdm as notebook_tqdm\n" - ] - } - ], + "outputs": [], "source": [ "# Imports\n", "\n", @@ -128,10 +119,8 @@ "name": "stderr", "output_type": "stream", "text": [ - " 0%| | 0/5000 [00:00" ] @@ -776,7 +765,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGiCAYAAAA1LsZRAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAyfklEQVR4nO3df3RU9Z3/8ddMflKEqICBKGC01WpRtGG1waKttrFo3fXUrWzdI9piT1NUxKhr0bNFXb8b1+93WftjQbuC1FNbWQu27rdUSVv5oehWIygCa/lWNNEmpsEagmggmc/3j+TeyWTy496YyWfmc5+Pc3JCZu4kn8u9TF58frw/MWOMEQAAgCVx2w0AAADRRhgBAABWEUYAAIBVhBEAAGAVYQQAAFhFGAEAAFYRRgAAgFWEEQAAYBVhBAAAWEUYAQAAVoUOI5s3b9Yll1yisrIyxWIx/eIXvxjyNZs2bVJFRYWKi4t1wgkn6P777x9OWwEAgINCh5H3339fM2fO1A9/+MNAx+/du1cXXXSR5syZo23btum2227TokWLtHbt2tCNBQAA7ol9lI3yYrGYHn/8cV166aUDHnPrrbfqiSee0O7du/3Hqqur9fLLL+u5554b7o8GAACOyM/0D3juuedUVVWV8tiFF16olStX6vDhwyooKEh7TUdHhzo6OvyvE4mE3n33XU2YMEGxWCzTTQYAACPAGKP29naVlZUpHh94MCbjYaS5uVmlpaUpj5WWlqqzs1Otra2aMmVK2mtqa2t15513ZrppAABgFDQ2Nuq4444b8PmMhxFJab0Z3sjQQL0cS5YsUU1Njf91W1ubpk2bpsbGRo0fPz5zDQUAACNm//79mjp1qsaNGzfocRkPI5MnT1Zzc3PKYy0tLcrPz9eECRP6fU1RUZGKiorSHh8/fjxhBACAHDPUFIuM1xmprKxUXV1dymMbNmzQrFmz+p0vAgAAoiV0GDlw4IC2b9+u7du3S+peurt9+3Y1NDRI6h5imT9/vn98dXW13nzzTdXU1Gj37t1atWqVVq5cqZtvvnlkzgAAgBz31l8O6j9fbNSHh7tsN8WK0GHkxRdf1JlnnqkzzzxTklRTU6MzzzxT3/3udyVJTU1NfjCRpPLycq1fv14bN27UGWecoX/6p3/S97//fV122WUjdAoAAOS22l//j/7h56/oypX/rbaDh9Oe/82ud3TtT19Sy/4PLbQu8z5SnZHRsn//fpWUlKitrY05IwAA51y58r+1ZU+rJOmk0iO0+utnqezIMZKkJ19tVvVP6iVJl886Tvf+7Uxr7Qwr6O9v9qYBAMAyr1sgFpP+8M4BXbZiqza+1qLv/3aPFj5S7x/38/q39NZfDlpqZeYQRgAAsMyoO43ccuHJOnHSWDW1fairH3pBy+r+oISR5s2aqrPLj1bCSGvr37bc2pFHGAEAwLJEovvzsUeO0dpvz9bls45TWUmxPlU2Xv/nqzN1z2Wn6YypR0qSDnSkzynJdaNS9AwAAAzM6xmJxWI68mOFOTUvZCTQMwIAgGX+nJHBDoqlHusSwggAAJZ5+SI+SKXSWE8acTCLEEYAALCu12qagcToGQEAAJnizxkZ5BjvOeNg3whhBAAAyxL0jAAAAJuSxdAH393WVYQRAAAs86PIYD0jDgcVwggAAJZ5HSODrqbxh2ncG6chjAAAYFmQQZrkBFb3EEYAALDM6+0YbJjGe9LBjhHCCAAAtpkAq2n8Yx3sGyGMAABgWbLOyGAVWN1FGAEAwLIgPSPUGQEAABmTDCPsTQMAACwItJqGnhEAAJApQVbTJJ9yL40QRgAAsMwfpnF6murACCMAAFjmr6ZhAisAALAh2Goaip4BAIAMSU5gHXqYhqJnAABgxCWCTGBlmAYAAGSMP4F1YNQZAQAAGeMP0wTZnMZBhBEAACwLVGeEYRoAAJApXr6IByh6xgRWAAAw4pK9HYPsTZNMI84hjAAAYFmg1TRMYAUAAJligqym8eeMuBdHCCMAAGQJVtMAAAArvN6OwSaw+sdmuC02EEYAALAsSDl49qYBAAAZE2wCazcHswhhBAAA24L0djCBFQAAZEyyHHzwY11CGAEAwLLk0t5B5oyMUltsIIwAAGBdz2qaQX4r+8t+HewaIYwAAGBZoJ4RP4u4l0YIIwAAWBZqNY17WYQwAgCAbck6I4OgzggAAMgUf5jG5VmqgyCMAABgmfGHaYZeTcOcEQAAMOKCDNMki55lujWjjzACAIBt/jDNYD0jsd6HOoUwAgCAZf5qmkGOoWcEAABkTJBy8Mmn3EsjhBEAACwLUvTMZYQRAAAs81bIDNozwjANAADIlCB1RpjACgAAMsYEWE0jv2fEvThCGAEAwDJ/mGaQY5JFz9xDGAEAwLJAwzTsTQMAADIlWYGV1TQAAMACbx5IPECdEQc7RggjAADY5geMQEt73YsjhBEAACwLUvRssPkkuY4wAgCARb17OgLVGXGvY4QwAgCATb3DRZDOD+PgrBHCCAAAFvWOFvFBukYYpgEAABkRdJgmeXwGG2PJsMLI8uXLVV5eruLiYlVUVGjLli2DHv/II49o5syZ+tjHPqYpU6bo61//uvbt2zesBgMA4JJEyjDNYD0jzBnxrVmzRosXL9btt9+ubdu2ac6cOZo7d64aGhr6Pf6ZZ57R/PnztWDBAu3cuVOPPfaYXnjhBV1zzTUfufEAAOS6lDkggeqMuJdGQoeRZcuWacGCBbrmmmt0yimn6L777tPUqVO1YsWKfo9//vnndfzxx2vRokUqLy/XZz/7WX3rW9/Siy+++JEbDwBArkuZwBqozkhm22NDqDBy6NAh1dfXq6qqKuXxqqoqbd26td/XzJ49W2+99ZbWr18vY4zeeecd/fznP9fFF1884M/p6OjQ/v37Uz4AAHCdw3NUBxUqjLS2tqqrq0ulpaUpj5eWlqq5ubnf18yePVuPPPKI5s2bp8LCQk2ePFlHHnmkfvCDHwz4c2pra1VSUuJ/TJ06NUwzAQDIGb17OgZdTePVGcl0gywY1gTWWJ+/LGNM2mOeXbt2adGiRfrud7+r+vp6Pfnkk9q7d6+qq6sH/P5LlixRW1ub/9HY2DicZgIAkPV6zwEJMkzjYhrJD3PwxIkTlZeXl9YL0tLSktZb4qmtrdU555yjW265RZJ0+umna+zYsZozZ47uvvtuTZkyJe01RUVFKioqCtM0AAByUuDVND2fIz+BtbCwUBUVFaqrq0t5vK6uTrNnz+73NQcPHlQ8nvpj8vLyJLm52Q8AAGEELgfPBNakmpoaPfjgg1q1apV2796tG2+8UQ0NDf6wy5IlSzR//nz/+EsuuUTr1q3TihUr9Prrr+vZZ5/VokWLdNZZZ6msrGzkzgQAgBwUPFu4O2ck1DCNJM2bN0/79u3TXXfdpaamJs2YMUPr16/X9OnTJUlNTU0pNUeuvvpqtbe364c//KFuuukmHXnkkTr//PP1L//yLyN3FgAA5KigE1hdFjqMSNLChQu1cOHCfp9bvXp12mPXX3+9rr/++uH8KAAA3Ba6zoh7fSPsTQMAgEWJ3nNGBjnO4cU0hBEAAGzqHS4GKpPR+zkHO0YIIwAA2GToGSGMAABgU2rPyMDHJYueuRdHCCMAAFiUulFeNFfTEEYAALDIq6g6VA7xV9NkuD02EEYAALDI6xkZqk/E3yjPwTRCGAEAwCI/jAzZNdJzvIN9I4QRAAAs8odphjjO4fmrhBEAAGxK9ozYbYdNhBEAACzyOjqGGqah6BkAAMiIRCLkME1GW2MHYQQAgCwQeGmvg10jhBEAACxKLu0dYphmyL6T3EUYAQDAotBFz9zrGCGMAABgkxcu4hFeTkMYAQDAIn81zRDHJSewutc1QhgBAMCiRPB68JIYpgEAACMs9N40mW2OFYQRAACs8iawDlX0rOdoB7tGCCMAAFgUtBw8Rc8AAEBGeOGC1TQAAMCKwHNG/HGajDbHCsIIAAAWeatpAhc9y3B7bCCMAABgUXI+6lDl4L3j3YsjhBEAACwKXQ4+w+2xgTACAIBFyXLwQx0ZSzneJYQRAACygMu78g6FMAIAgEXhJ7C61zVCGAEAwKKQW9MwTAMAAEaWv2vvkOXgmTMCAAAyIOhSXZdnlBBGAACwyC8HH+HfyBE+dQAA7EvOGWHXXgAAYIEJuprGqzOS6QZZQBgBAMAifwLrEMcle0Yy2Ro7CCMAAFjkD9MM1TXiHe9g3whhBAAAiwIP09AzAgAAMiHoMI3LCCMAAFiULAc/xGoaJrACAICMCFoOnmEaAACQCcly8IMfl3zevTRCGAEAwKLARc/E3jQAACADvKW6gVfTZLg9NhBGAACwKGydERcRRgAAsMhfTTPEcd7z7E0DAABGVNgJrO5FEcIIAAB2+cM0Qx3IBFYAAJAB/gTWoVbT+HVG3EsjhBEAACzyskV8qGEa7/iMtsYOwggAABYlgk4acRhhBAAAi0zQ1TQOz2AljAAAYFHg1TR9jncJYQQAAItM6I3y3IsjhBEAAKzqDhfxIbpG/L1pMt6e0UcYAQDAIhO4zoi7CCMAAFiUCLprrz9Mk+EGWUAYAQDAIqOAk0b6Hu8QwggAABaFn8Ca0eZYQRgBAMCi4BvlMYEVAABkgLdUd+jVNN4LMtseGwgjAABYxGoawggAAFaF3rXXwa6RYYWR5cuXq7y8XMXFxaqoqNCWLVsGPb6jo0O33367pk+frqKiIp144olatWrVsBoMAIBLgvaM+EXP3Msiyg/7gjVr1mjx4sVavny5zjnnHD3wwAOaO3eudu3apWnTpvX7mssvv1zvvPOOVq5cqY9//ONqaWlRZ2fnR248AAC5Lmi4cHifvPBhZNmyZVqwYIGuueYaSdJ9992np556SitWrFBtbW3a8U8++aQ2bdqk119/XUcffbQk6fjjj/9orQYAwBFeuAg6gTXye9McOnRI9fX1qqqqSnm8qqpKW7du7fc1TzzxhGbNmqV7771Xxx57rE466STdfPPN+uCDDwb8OR0dHdq/f3/KBwAALvLCxZATWOkZ6dba2qquri6VlpamPF5aWqrm5uZ+X/P666/rmWeeUXFxsR5//HG1trZq4cKFevfddwecN1JbW6s777wzTNMAAMhJQYueuWxYE1hjfeKbMSbtMU8ikVAsFtMjjzyis846SxdddJGWLVum1atXD9g7smTJErW1tfkfjY2Nw2kmAABZz19NE3TXXge7RkL1jEycOFF5eXlpvSAtLS1pvSWeKVOm6Nhjj1VJSYn/2CmnnCJjjN566y194hOfSHtNUVGRioqKwjQNAICcFLYcvItC9YwUFhaqoqJCdXV1KY/X1dVp9uzZ/b7mnHPO0Z/+9CcdOHDAf+wPf/iD4vG4jjvuuGE0GQAAdwQuB9/7NY51j4QepqmpqdGDDz6oVatWaffu3brxxhvV0NCg6upqSd1DLPPnz/ePv+KKKzRhwgR9/etf165du7R582bdcsst+sY3vqExY8aM3JkAAJCDknVGhip6lnzesSwSfmnvvHnztG/fPt11111qamrSjBkztH79ek2fPl2S1NTUpIaGBv/4I444QnV1dbr++us1a9YsTZgwQZdffrnuvvvukTsLAAByVMJbTTPEcSk9IxlrjR2hw4gkLVy4UAsXLuz3udWrV6c99slPfjJtaAcAAAQfpnEZe9MAAGCTCbc3TfdL3OobIYwAAGBR8AmsveaMZK45VhBGAACwKOhGeUrpGclYc6wgjAAAYFGyHHyIYRrH+kYIIwAAWJSgHDxhBAAAm5JzRoLt2isxTAMAAEaQCVpnxOG1v4QRAACyQLhy8BltyqgjjAAAYJEXLOJMYAUAADZ4wWLolb3u7k1DGAEAwKKEP4PVajOsIowAAGCRX/QsTDn4DLbHBsIIAAAW+cM0IXpG2JsGAACMGBOw6Bk9IwAAIKOGXE3DBFYAAJAJiUSwYZqU5wkjAABgpCTLwVtthlWEEQAALEoOuYTYm8axrhHCCAAAFgVdTdN7bxrmjAAAgBGTLAc/+HEOTxkhjAAAYFOyAGuIomeOdY0QRgAAsMgLFqGGaTLZIAsIIwAAWBS06JnLCCMAAFiUnMAaPI44NkpDGAEAwKYwwcLLKyztBQAAI8aLFUOVg5d6DeW4lUUIIwAA2JQIOIG1+5jugxzLIoQRAACsYgIrYQQAAJvC7E3jHcIEVgAAMGKSdUYCzBlhAisAABhpfp2RQD0jsZTXuIIwAgCARUHLwfcclPIaVxBGAACwKNRqmp7P7E0DAABGDOXgCSMAAGSFYHVGuj871jFCGAEAwCZ/NU2AvpFA80pyEGEEAACLkuXghz6WnhEAADDiEiHW9voTWB1bT0MYAQDAojATWP29adzKIoQRAABsClMO3lWEEQAALEr2jIQZpnELYQQAAKuCFz3zK7A6Nk5DGAEAwCIvVwRaTeO9JmOtsYMwAgCARYlQu/YygRUAAIywMMHC1UmuhBEAACwa3moat7pGCCMAAFg0rNU0bmURwggAADZ51VSDlYPvmTOSyQZZQBgBAMCiENXg6RkBAAAjL9SuvV6dEcf6RggjAABYRDl4wggAAFaFG3KhzggAABhhyZ6REMM0hBEAADBSvDkj4crBu5VGCCMAAFiUrDMyNHpGAADAiDMKsTdNoMiSewgjACKt7YPDtpuAiAtTZ8RVhBEAkXX/pj/qjLs2aMueP9tuCiKMYRrCCIAI2/Wn/TJGeq253XZTEGHhhmlSX+MKwgiAyEr0/PeyK+HWGztyS6hy8DHqjACAU7w3dLIIbEqE2LXX49otSxgBEFlej0jCtf9mIsd4wzRDH5mcM+LWPUsYARBZXghJ0DUCi8JMYHXVsMLI8uXLVV5eruLiYlVUVGjLli2BXvfss88qPz9fZ5xxxnB+LACMqATDNMgCYTbKS+7a65bQYWTNmjVavHixbr/9dm3btk1z5szR3Llz1dDQMOjr2traNH/+fF1wwQXDbiwAjCSvq5thGtjk3Ydhip65dsuGDiPLli3TggULdM011+iUU07Rfffdp6lTp2rFihWDvu5b3/qWrrjiClVWVg75Mzo6OrR///6UDwAYaQnCCLJAYhh1RlzrGwkVRg4dOqT6+npVVVWlPF5VVaWtW7cO+LqHHnpIf/zjH7V06dJAP6e2tlYlJSX+x9SpU8M0EwAC6fKHadx6Y0duCbVrr/cax27ZUGGktbVVXV1dKi0tTXm8tLRUzc3N/b5mz549+s53vqNHHnlE+fn5gX7OkiVL1NbW5n80NjaGaSYABGL8OiOWG4JI84dpLLfDpmDpoI++6c0Y02+i6+rq0hVXXKE777xTJ510UuDvX1RUpKKiouE0DQAC83pEXFsmidwUquhZhtsy2kKFkYkTJyovLy+tF6SlpSWtt0SS2tvb9eKLL2rbtm267rrrJEmJRELGGOXn52vDhg06//zzP0LzAWD4Ej09IgzTwKZQFVj7vMYVoYZpCgsLVVFRobq6upTH6+rqNHv27LTjx48frx07dmj79u3+R3V1tU4++WRt375dZ5999kdrPQB8BAmGaZAFvH1m4iHSiGu9eaGHaWpqanTllVdq1qxZqqys1I9+9CM1NDSourpaUvd8j7ffflsPP/yw4vG4ZsyYkfL6Y445RsXFxWmPA8BoYzUNskEiRBhObpTnltBhZN68edq3b5/uuusuNTU1acaMGVq/fr2mT58uSWpqahqy5ggAZIMEq2mQBULt2uvoRnnDmsC6cOFCLVy4sN/nVq9ePehr77jjDt1xxx3D+bEAMKLoGUE2oBw8e9MAiDDKwSMbhCoH77/GrZuWMAIgsgwb5SEb9Nx+QSawxhydNEIYARBZXQmGaWBfIkTRM39vmgy2xwbCCIDIYpgG2WBYu/Y6ds8SRgBEFsM0yAbJmiHBp7AyZwQAHMFqGmSDMD0jriKMAIgsr0OkiywCi8Is7XW1zghhBEBkJZjAiizg3X2BVtP0eY0rCCMAIotde5ENvPsv3ARWt+5ZwgiAyPKHaZjACotC7drrhZHMNccKwgiAyEpOYLXcEESavzdNgFkj/jGO3bOEEQCR5f2PlKW9sGkYK3udQxgBEFlUYEU28G6/MOXgqTMCAI5gmAbZIFw5+G6u5WfCCIDISpaDd+ydHTkpUNEz6owAgFsMFViRBZJFz6gzAgCR4w/TJCw3BJHmr6ZhAisARI83gbWLnhFYFK4cvPcat+5ZwgiAyPLez117Y0duSW6UxzANAESON0xDBVbYlAhVDp4JrADglORqGrvtQMSFGabp+yJHEEYARFYXG+UhC4QapvHnjGSuPTYQRgBElhdCmMAKm8Ls2usqwgiAyPKHaVjaC4vCbE3j1SJxLT4TRgBEVoKiZ8gCyQmsQWawdn9y7ZYljACIJGNMctde197ZkVP8OiPBswgb5QGAC3qvoGE1DWwa1q69jt2zhBEAkdS7NyRBGoFF3r2YF6joGXNGAMAZKWHEtf9mIqd4RfdYTQMAEWMYpkGW8HtG4mGGady6aQkjACKpd28I5eBhk3f7hQkjriGMAIik3gHEtf9lIrd492KALJKcM+LYLUsYARBJvTtDqMAKm7xeulCraRybwkoYARBJJmUCq8WGIPISieBhxONafiaMAIik3gGEYRrYFGbOiKsIIwAiiQmsyBbeMGE80ARW5owAgDN6Fzoji8CmRKgJrN1cu2UJIwAiKaUcPGkEFoWqwEqdEQBwBxVYkQ2MMX4wDrJrLz0jAOCQBKtpkAV652AmsAJAxBjqjCAL9L73As0ZSRYacQphBEAkUYEV2aD3fRhoNU3PZ4qeAYADGKZBNkgZpgk1gTVDDbKEMAIgklLKwZNGYEnqME2QOSM9dUYy1B5bCCMAIqnv0AxDNbChdw9dPMBvZHpGAMAhfTtD6B2BDb1r3ITZm8Y1hBEAkdQ3fJBFYEMi7JyRns9MYAUAB/QtdEbhM9gQejUNwzQA4I6+b+aEEdjg3XdB653FmMAKAO5I7xmx1BBEmr8vTcA04o/kOBaeCSMAIolhGmQDb5gmyL403cd1f3btbiWMAIiktDBC1wgs8G7DIJNXXUYYARBJfbMHWQQ2eD0joeeMOHa/EkYARFLfnhDqjMAGfwJr8DQiyb0ifYQRAJHUN3u49uaO3BB6AmvPZ9fuVsIIgEjqGz7oGIENXYnuz0Grr3oTXV3LzoQRAJHU1efdvO/XwGhI1hmhZwQAIidtAitdI7Ag7ARWVxFGAEQSdUaQDfylvSGLnrk2x4kwAiCSmDOCbNA1zGEa1xBGAERSItHna8f+p4nckFzaG+x4JrACgEP6Tlhlzghs8O67oBVYkxNY3bpfCSMAIolhGmSD5ARWVwdgghlWGFm+fLnKy8tVXFysiooKbdmyZcBj161bpy9+8YuaNGmSxo8fr8rKSj311FPDbjAAjIT0cvCkEYw+7z4MX4E1M+2xJXQYWbNmjRYvXqzbb79d27Zt05w5czR37lw1NDT0e/zmzZv1xS9+UevXr1d9fb0+//nP65JLLtG2bds+cuMBYLj6hg/KwcOGZJ2RYMf7e9NkqkGW5Id9wbJly7RgwQJdc801kqT77rtPTz31lFasWKHa2tq04++7776Ur//5n/9Zv/zlL/Vf//VfOvPMM/v9GR0dHero6PC/3r9/f9hmAsCg0svB22kHoi100TN6RqRDhw6pvr5eVVVVKY9XVVVp69atgb5HIpFQe3u7jj766AGPqa2tVUlJif8xderUMM0EgCGlbZTn2rs7coLXIxd+bxq37tdQYaS1tVVdXV0qLS1Neby0tFTNzc2Bvse//uu/6v3339fll18+4DFLlixRW1ub/9HY2BimmQAwJIqeIRt4t13Ue0ZCD9NIyXXOHmNM2mP9+dnPfqY77rhDv/zlL3XMMccMeFxRUZGKioqG0zQACIRde5EN/NU0Ea8HHyqMTJw4UXl5eWm9IC0tLWm9JX2tWbNGCxYs0GOPPaYvfOEL4VsKACMofQKrpYYg0rqGOYHVNaGGaQoLC1VRUaG6urqUx+vq6jR79uwBX/ezn/1MV199tX7605/q4osvHl5LAWAEpdcZoWcEo8+7DwMXPXN0b5rQwzQ1NTW68sorNWvWLFVWVupHP/qRGhoaVF1dLal7vsfbb7+thx9+WFJ3EJk/f76+973v6TOf+YzfqzJmzBiVlJSM4KkAQHB9e0KowAobvPsw6DANc0Z6zJs3T/v27dNdd92lpqYmzZgxQ+vXr9f06dMlSU1NTSk1Rx544AF1dnbq2muv1bXXXus/ftVVV2n16tUf/QwAYBjSJ7BaaggiLWydEVFnJGnhwoVauHBhv8/1DRgbN24czo8AgIximAbZwLvvAi/tdbRnhL1pAERS354Q6ozABvam6UYYARBJfcu/uzYhELkhEbbOSM/nSBc9AwBXpM0ZYWkvLEgkQi7tZZgGANzR982cYRrYEHrOiKMTWAkjACKpb88IwzSwoWuYG+W51jVCGAEQSWkTWBmmgQXDnTPiGsIIgEhiozxkg0TIXXs9rt2thBEAkdS34iphBDZ4q7qCruz1NqV17XYljACIpL7DNIQR2BB2AquHpb0A4ACW9iIbJIa9UV6mWmQHYQRAJPVdPcPSXtjg9dDFAk9gZWkvADijb/hgaS9s6PInsFpuiGURP30AUZU+Z8ROOxBtZph1RlzLzoQRAJHUd85I371qgNHg1beJB67A2o0JrADggL7/s2SYBjYkK7AGOz5ZgTUz7bGFMAIgktLrjFhqCCLNhF5NwwRWAHBG3wmsDNPABu++Cz1M41hPHmEEQCT1fS+n6BlsCLs3jasIIwAiib1pkA1CV2BlNQ0AuCM9jFhqCCItEXZvGoqeAYA72JsG2aCLcvCSCCMAIiptNQ1dI7AgkQg3TEOdEQBwCMM0yAah96ahZwQA3NE3fLC0FzaEHaZxFWEEQCT17RlxrW4DcoMJW4FVboYWwgiASEqvM2KnHYi20EXP/GEat25YwgiASOo7LNO3IiswGsIWPXN0axrCCIBo8oZp8nv+R8rSXtiQXE0T8AXe3jSO3a6EEQCR5L2Z5+e5+eaO3JDctTdcz4hrCCMAIsnrCSmId78NspoGNgx3bxrqjACAA/w9QfIYpoE9oYueUWcEANzRlej+7M8ZoWcEFiSGubTXtbuVMAIgkow/gbX7bZAsAhuGv7Q3Uy2ygzACIJL8OSP53e/unYmEzeYgorwQHHijPP9PbqURwgiASPJ+CYwtzJckfXiYMILRlwi5msZVhBEAkeT9EvhYYZ4k6cPDXTabg4himKYbYQRAJCXDSHfPyAeEEVgQegIrRc8AwB3eFBGvZ+SDQ4QRjD5/iXnQNNKDOiMA4ADvl8DYop45I53MGcHo80Jx4AqsDNMAgDu8N3N/zgg9I7AgfDl46owAgDPSe0YIIxh9oTfKc1TETx9AVHn/Ix1TwJwR2OOF4hjDNAAQPX6dkSKW9sKermEWPWMCKwA4oLNnc5ojigokUfQsG3V0dmnxo9v0ny822m5KxnjbEsQD/jaOJdOIUwgjACLp/Y5OSdLEIwolSYe6En4BKmSHn/53g36x/U/6h5+/YrspGeMXPWMCKwBEzwEvjIwr8h9jqCa7/OGddttNyDh/b5rQFVjdiiOEEQCR5IeRsckwQhXW7PLn9kP+n1375etJhOwZcRVhBEDkdHYl/Dki44rzVZTf/VZIz0h2+fOBDv/PHY4WpQtbZ8TjWjQjjACInPc7kqFjbFG+igtYUZON3mn70P/z/g8PW2xJ5rA3TTfCCIDIae/o/sVWmB9XYX7crzXCiprscfBQp5r3J8PIgQ87LbYmc5JFz8Iu7XULYQRA5Hg9I+N6qq8WF3S/FTJnJHu80Xow5et2V8NIT6qIM4EVAKLlQE/PyFg/jDBMk232tr6f8rU34dg14Zf2uokwAiByDvT0jBzRE0bGFFISPts0tX2Q8nW7o3NGvB6OoBVY/ddlojEWEUYARI43/8ALI8X5PWGEnpGs8U6v+SKStN/RYZouf2+aYMf7e9g4lkYIIwAix6u+ekRxas9IBxNYs8Y7+ztSvnZ1AmvPrgThi545lkYIIwAip72jT88IE1izTkt7d8+Id41cncBqQtYZ8VfTuJVFCCMAosfrGWECa/Zq6ekZOXHSWEnJSceu8YZp8oL+NqbOCAC4wVuZMc4bpilgzki2aWn3wsgRktztGaEcfDfCCIDI8cLI2MK+PSPMGckGBzo6/Wt04jGOhxGvzkjYYRrmjABAbvNX0/TpGWGYJju09KykGVuYp9LxxZKS83xckzAhK7D6Rc8y1SI78m03AABGm7+apqg7hHgTWAkjdm3+w5/1u/9p0dFjCyVJpeOL/aE0V+uMeEXPAi/t7ekbcSyLEEYAJBlj9JvdLZpx7HhNKRljuzkZk1xNUyApOUzDnBF7Egmjmx57WX9uTy7pnTSuyA8jri7tHW7PiBdiXMEwDQDfUzub9c2HX9TXfvS8Ojrd/cWcXE3j9YxQgdW2HW+3pQQRqft//+N6AqPrc0aCVmA9fkL36qJtDX9xKpAMK4wsX75c5eXlKi4uVkVFhbZs2TLo8Zs2bVJFRYWKi4t1wgkn6P777x9WY5H7dv1pv1Y/u9f/ZYDs8uOtb0qS3th3UA9u2Wu5NZkz0GqalvYO5zYgyxW/3f2OJOlLn5qsU6eMlySdc+LElGEaF69NcpgmWBj5q+OPUsmYAv3l4GHVv/mXTDZtVIUeplmzZo0WL16s5cuX65xzztEDDzyguXPnateuXZo2bVra8Xv37tVFF12kb37zm/rJT36iZ599VgsXLtSkSZN02WWXjchJDNeGnc3a03JAsVj3OFz3Z6V+HeseoUsYo86EUVfCqLPL+F1r6nW892cpOeO592SjhFHK63o/3/2aWD+PpX8f43+/nvnUxihhumdXJ4x3TPeBefGY8uMx5cXjPeeQUFeie017PBbzP/Li3btGxmMx5cVigccv+xrovcLIaG/rQT32YqM6E0Y/f+ktXXjqZBXkx1WQF1dM3nmZXudpUs7X+1o9x/X3nPf34TWj+3rGlBePKd5zPXvPWu89I72/tqe2J3lMPNb99+V9374z4d/v6NJv/6f7zfWUyeN13FFjAu/K6RnoGsT6bJWVMEaHuxLqShgd7jLq7EqoM9F9rTu7uv9e8vK8+yB5P6R8nReTMdLze/f53/d/P/Wa9ra+r2lHf6zX9en5e1Hy70VK/r37fx7g2IGeU8pzqd/bE+9pa2HPPVOUHx+wa3uw31mHuxJ+qXGvzsinpx+l/HhM2xvf0//61W6VHZkcour7rQb7hdj3qb4rHvp7aSzW/XjrgQ6NKcjT+DEFSvT8m+5KGHV0JtTR2aWOw92fEwkp3uvfb168+99r99fdn2O9/tz7vk95j/O/9l6fbGPfez0vnvx34/077f0elPD+PfqPe48Z/88J0/1z82LJ+867prGYtPaltyVJXzi1VF8+fYp+u7tF5508SZJUmBfX+4e6dOvaV3TipCP89zvT83fUmTBKJLz36IT/Xu19GOOds6Q+7/Xxnvd4Lwz0/X0Qj/f8ixvg90S854u03x29/p69+6b330VRflyFvYqLBB2myc+L6/xPHqPHt72tH/xuj86YeqQOdxnlxb2/27j/fp4fjw24Sqd3+PH+9LmTJ+mEnqXUoy1mQkbNs88+W5/+9Ke1YsUK/7FTTjlFl156qWpra9OOv/XWW/XEE09o9+7d/mPV1dV6+eWX9dxzz/X7Mzo6OtTRkeyua2tr07Rp09TY2Kjx48eHae6gbnnsZf361eYR+34IpiAvrsNdLKHMVhXTj9JJpUfoZ79vtN2UjJowtlDrb5jjB5L7N/5RP3z6/1luVbQVF8S14cbz/AmsnkdfaNDd/3f3AK/KffnxmLYuOV8fKwzWP7BhZ7Nq/vPlEW/HvX97ui46bcqIfs/9+/dr6tSpeu+991RSUjLwgSaEjo4Ok5eXZ9atW5fy+KJFi8y5557b72vmzJljFi1alPLYunXrTH5+vjl06FC/r1m6dKlRTwDngw8++OCDDz5y+6OxsXHQfBFqmKa1tVVdXV0qLS1Neby0tFTNzf33MDQ3N/d7fGdnp1pbWzVlSnoKW7JkiWpqavyvE4mE3n33XU2YMCHwuFoQXmIb6R6XbBOF8+Qc3RGF84zCOUrROE/OcXDGGLW3t6usrGzQ44a1tLdvIDDGDBoS+ju+v8c9RUVFKioqSnnsyCOPHEZLgxk/fryzN1FvUThPztEdUTjPKJyjFI3z5BwHNujwTI9Qq2kmTpyovLy8tF6QlpaWtN4Pz+TJk/s9Pj8/XxMmTAjz4wEAgINChZHCwkJVVFSorq4u5fG6ujrNnj2739dUVlamHb9hwwbNmjVLBQUFIZsLAABcE7rOSE1NjR588EGtWrVKu3fv1o033qiGhgZVV1dL6p7vMX/+fP/46upqvfnmm6qpqdHu3bu1atUqrVy5UjfffPPIncUwFRUVaenSpWlDQq6Jwnlyju6IwnlG4RylaJwn5zgyQi/tlbqLnt17771qamrSjBkz9G//9m8699xzJUlXX3213njjDW3cuNE/ftOmTbrxxhu1c+dOlZWV6dZbb/XDCwAAiLZhhREAAICRwt40AADAKsIIAACwijACAACsIowAAACrIh1Gli9frvLychUXF6uiokJbtmyx3aRhu+OOO3p24Ux+TJ482X/eGKM77rhDZWVlGjNmjD73uc9p586dFls8tM2bN+uSSy5RWVmZYrGYfvGLX6Q8H+ScOjo6dP3112vixIkaO3as/vqv/1pvvfXWKJ7F0IY6z6uvvjrt2n7mM59JOSbbz7O2tlZ/9Vd/pXHjxumYY47RpZdeqtdeey3lmFy/nkHOMdev5YoVK3T66af7lTgrKyv161//2n8+16+hZ6jzzPXr2J/a2lrFYjEtXrzYf2xUr+cQe+M569FHHzUFBQXmP/7jP8yuXbvMDTfcYMaOHWvefPNN200blqVLl5pPfepTpqmpyf9oaWnxn7/nnnvMuHHjzNq1a82OHTvMvHnzzJQpU8z+/fsttnpw69evN7fffrtZu3atkWQef/zxlOeDnFN1dbU59thjTV1dnXnppZfM5z//eTNz5kzT2dk5ymczsKHO86qrrjJf+tKXUq7tvn37Uo7J9vO88MILzUMPPWReffVVs337dnPxxRebadOmmQMHDvjH5Pr1DHKOuX4tn3jiCfOrX/3KvPbaa+a1114zt912mykoKDCvvvqqMSb3r6FnqPPM9evY1+9//3tz/PHHm9NPP93ccMMN/uOjeT0jG0bOOussU11dnfLYJz/5SfOd73zHUos+mqVLl5qZM2f2+1wikTCTJ08299xzj//Yhx9+aEpKSsz9998/Si38aPr+kg5yTu+9954pKCgwjz76qH/M22+/beLxuHnyySdHre1hDBRG/uZv/mbA1+Tieba0tBhJZtOmTcYYN69n33M0xs1redRRR5kHH3zQyWvYm3eexrh1Hdvb280nPvEJU1dXZ8477zw/jIz29YzkMM2hQ4dUX1+vqqqqlMerqqq0detWS6366Pbs2aOysjKVl5fr7/7u7/T6669Lkvbu3avm5uaU8y0qKtJ5552Xs+cb5Jzq6+t1+PDhlGPKyso0Y8aMnDvvjRs36phjjtFJJ52kb37zm2ppafGfy8XzbGtrkyQdffTRkty8nn3P0ePKtezq6tKjjz6q999/X5WVlU5eQyn9PD2uXMdrr71WF198sb7whS+kPD7a13NYu/bmutbWVnV1daVt7ldaWpq2qV+uOPvss/Xwww/rpJNO0jvvvKO7775bs2fP1s6dO/1z6u9833zzTRvN/ciCnFNzc7MKCwt11FFHpR2TS9d57ty5+upXv6rp06dr7969+sd//Eedf/75qq+vV1FRUc6dpzFGNTU1+uxnP6sZM2ZIcu969neOkhvXcseOHaqsrNSHH36oI444Qo8//rhOPfVU/5ePK9dwoPOU3LiOkvToo4/qpZde0gsvvJD23Gj/m4xkGPHEYrGUr40xaY/lirlz5/p/Pu2001RZWakTTzxRP/7xj/2JVS6dr2c455Rr5z1v3jz/zzNmzNCsWbM0ffp0/epXv9JXvvKVAV+Xred53XXX6ZVXXtEzzzyT9pwr13Ogc3ThWp588snavn273nvvPa1du1ZXXXWVNm3a5D/vyjUc6DxPPfVUJ65jY2OjbrjhBm3YsEHFxcUDHjda1zOSwzQTJ05UXl5eWnJraWlJS4G5auzYsTrttNO0Z88ef1WNS+cb5JwmT56sQ4cO6S9/+cuAx+SiKVOmaPr06dqzZ4+k3DrP66+/Xk888YSefvppHXfccf7jLl3Pgc6xP7l4LQsLC/Xxj39cs2bNUm1trWbOnKnvfe97Tl1DaeDz7E8uXsf6+nq1tLSooqJC+fn5ys/P16ZNm/T9739f+fn5fjtH63pGMowUFhaqoqJCdXV1KY/X1dVp9uzZllo1sjo6OrR7925NmTJF5eXlmjx5csr5Hjp0SJs2bcrZ8w1yThUVFSooKEg5pqmpSa+++mrOnrck7du3T42NjZoyZYqk3DhPY4yuu+46rVu3Tr/73e9UXl6e8rwL13Ooc+xPLl7Lvowx6ujocOIaDsY7z/7k4nW84IILtGPHDm3fvt3/mDVrlv7+7/9e27dv1wknnDC61zPkxFtneEt7V65caXbt2mUWL15sxo4da9544w3bTRuWm266yWzcuNG8/vrr5vnnnzdf/vKXzbhx4/zzueeee0xJSYlZt26d2bFjh/na176W9Ut729vbzbZt28y2bduMJLNs2TKzbds2f/l1kHOqrq42xx13nPnNb35jXnrpJXP++edn3fK6wc6zvb3d3HTTTWbr1q1m79695umnnzaVlZXm2GOPzanz/Pa3v21KSkrMxo0bU5ZDHjx40D8m16/nUOfowrVcsmSJ2bx5s9m7d6955ZVXzG233Wbi8bjZsGGDMSb3r6FnsPN04ToOpPdqGmNG93pGNowYY8y///u/m+nTp5vCwkLz6U9/OmUJXq7x1n8XFBSYsrIy85WvfMXs3LnTfz6RSJilS5eayZMnm6KiInPuueeaHTt2WGzx0J5++mkjKe3jqquuMsYEO6cPPvjAXHfddeboo482Y8aMMV/+8pdNQ0ODhbMZ2GDnefDgQVNVVWUmTZpkCgoKzLRp08xVV12Vdg7Zfp79nZ8k89BDD/nH5Pr1HOocXbiW3/jGN/z3zEmTJpkLLrjADyLG5P419Ax2ni5cx4H0DSOjeT1jxhgTri8FAABg5ERyzggAAMgehBEAAGAVYQQAAFhFGAEAAFYRRgAAgFWEEQAAYBVhBAAAWEUYAQAAVhFGAACAVYQRAABgFWEEAABY9f8B7h6mjcwkwbsAAAAASUVORK5CYII=\n", + "image/png": "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AABcE7rOSE1NjR588EGtWrVKu3fv1o033qiGhgZVV1dL6p7vMX/+fP/46upqvfnmm6qpqdHu3bu1atUqrVy5UjfffPPIncUwFRUVaenSpWlDQq6Jwnlyju6IwnlG4RylaJwn5zgyQi/tlbqLnt17771qamrSjBkz9G//9m8699xzJUlXX3213njjDW3cuNE/ftOmTbrxxhu1c+dOlZWV6dZbb/XDCwAAiLZhhREAAICRwt40AADAKsIIAACwijACAACsIowAAACrIh1Gli9frvLychUXF6uiokJbtmyx3aRhu+OOO3p24Ux+TJ482X/eGKM77rhDZWVlGjNmjD73uc9p586dFls8tM2bN+uSSy5RWVmZYrGYfvGLX6Q8H+ScOjo6dP3112vixIkaO3as/vqv/1pvvfXWKJ7F0IY6z6uvvjrt2n7mM59JOSbbz7O2tlZ/9Vd/pXHjxumYY47RpZdeqtdeey3lmFy/nkHOMdev5YoVK3T66af7lTgrKyv161//2n8+16+hZ6jzzPXr2J/a2lrFYjEtXrzYf2xUr+cQe+M569FHHzUFBQXmP/7jP8yuXbvMDTfcYMaOHWvefPNN200blqVLl5pPfepTpqmpyf9oaWnxn7/nnnvMuHHjzNq1a82OHTvMvHnzzJQpU8z+/fsttnpw69evN7fffrtZu3atkWQef/zxlOeDnFN1dbU59thjTV1dnXnppZfM5z//eTNz5kzT2dk5ymczsKHO86qrrjJf+tKXUq7tvn37Uo7J9vO88MILzUMPPWReffVVs337dnPxxRebadOmmQMHDvjH5Pr1DHKOuX4tn3jiCfOrX/3KvPbaa+a1114zt912mykoKDCvvvqqMSb3r6FnqPPM9evY1+9//3tz/PHHm9NPP93ccMMN/uOjeT0jG0bOOussU11dnfLYJz/5SfOd73zHUos+mqVLl5qZM2f2+1wikTCTJ08299xzj//Yhx9+aEpKSsz9998/Si38aPr+kg5yTu+9954pKCgwjz76qH/M22+/beLxuHnyySdHre1hDBRG/uZv/mbA1+Tieba0tBhJZtOmTcYYN69n33M0xs1redRRR5kHH3zQyWvYm3eexrh1Hdvb280nPvEJU1dXZ8477zw/jIz29YzkMM2hQ4dUX1+vqqqqlMerqqq0detWS6366Pbs2aOysjKVl5fr7/7u7/T6669Lkvbu3avm5uaU8y0qKtJ5552Xs+cb5Jzq6+t1+PDhlGPKyso0Y8aMnDvvjRs36phjjtFJJ52kb37zm2ppafGfy8XzbGtrkyQdffTRkty8nn3P0ePKtezq6tKjjz6q999/X5WVlU5eQyn9PD2uXMdrr71WF198sb7whS+kPD7a13NYu/bmutbWVnV1daVt7ldaWpq2qV+uOPvss/Xwww/rpJNO0jvvvKO7775bs2fP1s6dO/1z6u9833zzTRvN/ciCnFNzc7MKCwt11FFHpR2TS9d57ty5+upXv6rp06dr7969+sd//Eedf/75qq+vV1FRUc6dpzFGNTU1+uxnP6sZM2ZIcu969neOkhvXcseOHaqsrNSHH36oI444Qo8//rhOPfVU/5ePK9dwoPOU3LiOkvToo4/qpZde0gsvvJD23Gj/m4xkGPHEYrGUr40xaY/lirlz5/p/Pu2001RZWakTTzxRP/7xj/2JVS6dr2c455Rr5z1v3jz/zzNmzNCsWbM0ffp0/epXv9JXvvKVAV+Xred53XXX6ZVXXtEzzzyT9pwr13Ogc3ThWp588snavn273nvvPa1du1ZXXXWVNm3a5D/vyjUc6DxPPfVUJ65jY2OjbrjhBm3YsEHFxcUDHjda1zOSwzQTJ05UXl5eWnJraWlJS4G5auzYsTrttNO0Z88ef1WNS+cb5JwmT56sQ4cO6S9/+cuAx+SiKVOmaPr06dqzZ4+k3DrP66+/Xk888YSefvppHXfccf7jLl3Pgc6xP7l4LQsLC/Xxj39cs2bNUm1trWbOnKnvfe97Tl1DaeDz7E8uXsf6+nq1tLSooqJC+fn5ys/P16ZNm/T9739f+fn5fjtH63pGMowUFhaqoqJCdXV1KY/X1dVp9uzZllo1sjo6OrR7925NmTJF5eXlmjx5csr5Hjp0SJs2bcrZ8w1yThUVFSooKEg5pqmpSa+++mrOnrck7du3T42NjZoyZYqk3DhPY4yuu+46rVu3Tr/73e9UXl6e8rwL13Ooc+xPLl7Lvowx6ujocOIaDsY7z/7k4nW84IILtGPHDm3fvt3/mDVrlv7+7/9e27dv1wknnDC61zPkxFtneEt7V65caXbt2mUWL15sxo4da9544w3bTRuWm266yWzcuNG8/vrr5vnnnzdf/vKXzbhx4/zzueeee0xJSYlZt26d2bFjh/na176W9Ut729vbzbZt28y2bduMJLNs2TKzbds2f/l1kHOqrq42xx13nPnNb35jXnrpJXP++edn3fK6wc6zvb3d3HTTTWbr1q1m79695umnnzaVlZXm2GOPzanz/Pa3v21KSkrMxo0bU5ZDHjx40D8m16/nUOfowrVcsmSJ2bx5s9m7d6955ZVXzG233Wbi8bjZsGGDMSb3r6FnsPN04ToOpPdqGmNG93pGNowYY8y///u/m+nTp5vCwkLz6U9/OmUJXq7x1n8XFBSYsrIy85WvfMXs3LnTfz6RSJilS5eayZMnm6KiInPuueeaHTt2WGzx0J5++mkjKe3jqquuMsYEO6cPPvjAXHfddeboo482Y8aMMV/+8pdNQ0ODhbMZ2GDnefDgQVNVVWUmTZpkCgoKzLRp08xVV12Vdg7Zfp79nZ8k89BDD/nH5Pr1HOocXbiW3/jGN/z3zEmTJpkLLrjADyLG5P419Ax2ni5cx4H0DSOjeT1jxhgTri8FAABg5ERyzggAAMgehBEAAGAVYQQAAFhFGAEAAFYRRgAAgFWEEQAAYBVhBAAAWEUYAQAAVhFGAACAVYQRAABgFWEEAABY9f8B7h6mjcwkwbsAAAAASUVORK5CYII=", "text/plain": [ "
" ] @@ -872,7 +861,7 @@ }, { "data": { - "image/png": "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Dx48GHeP1/t57bXXmqeeesq88847pq2tzVx//fVmxowZ5tChQ9F7sv15Hk8fs/1Zbty40bz00kvm3XffNe+++6554IEHTH5+vnnnnXeMMdn/DG3H6me2P8dE//mf/2nOOeccc/HFF5u77747et3J55mzYeSSSy4xDQ0Ncdc+//nPm+985zsutejErFixwsyaNSvle5FIxJSWlppHH300eu3TTz81xcXF5vHHH3eohScm8Yf08fTp448/Nvn5+ea5556L3vPhhx+aQCBgXn75Zcfanol0YeQv//Iv034mG/vZ3d1tJJmtW7caY/z5PBP7aIw/n+Xpp59unnzySV8+w1h2P43x13Ps7+83559/vmlubjZf+cpXomHE6eeZk9M0g4ODamlpUX19fdz1+vp67dixw6VWnbi9e/eqvLxclZWV+uu//mvt27dPkrR//351dXXF9TcUCukrX/lK1vb3ePrU0tKio0ePxt1TXl6uqqqqrOv3li1bdOaZZ2rmzJm67bbb1N3dHX0vG/vZ29srSTrjjDMk+fN5JvbR5pdnGQ6H9dxzz+nw4cOqra315TOUkvtp88tzvPPOO3X99dfrmmuuibvu9PMc16m92a6np0fhcDjpcL+SkpKkQ/2yxaWXXqpnnnlGM2fO1IEDB/TII4+orq5Ou3btivYpVX/ff/99N5p7wo6nT11dXSooKNDpp5+edE82Pec5c+bom9/8pioqKrR//379/d//va666iq1tLQoFAplXT+NMWpsbNTll1+uqqoqSf57nqn6KPnjWe7cuVO1tbX69NNPdcopp+iFF17QhRdeGP3h45dnmK6fkj+eoyQ999xzeuutt/Tb3/426T2n/5vMyTBisywr7mtjTNK1bDFnzpzo7y+66CLV1tbqvPPO07/8y79EC6v81F/bePqUbf2eO3du9PdVVVWqqalRRUWFXnrpJX39619P+zmv9nPRokX63e9+p9deey3pPb88z3R99MOz/NznPqe2tjZ9/PHHev755zV//nxt3bo1+r5fnmG6fl544YW+eI4dHR26++67tXnzZhUWFqa9z6nnmZPTNFOnTlUwGExKbt3d3UkpMFtNnjxZF110kfbu3RtdVeOn/h5Pn0pLSzU4OKj//u//TntPNiorK1NFRYX27t0rKbv6edddd2njxo169dVXdfbZZ0ev++l5putjKtn4LAsKCvTZz35WNTU1ampq0qxZs/T973/fV89QSt/PVLLxOba0tKi7u1vV1dXKy8tTXl6etm7dqh/84AfKy8uLttOp55mTYaSgoEDV1dVqbm6Ou97c3Ky6ujqXWnVyDQwMaM+ePSorK1NlZaVKS0vj+js4OKitW7dmbX+Pp0/V1dXKz8+Pu6ezs1PvvPNO1vZbkg4ePKiOjg6VlZVJyo5+GmO0aNEibdiwQf/xH/+hysrKuPf98DyP1cdUsvFZJjLGaGBgwBfPcCx2P1PJxud49dVXa+fOnWpra4u+ampq9Ld/+7dqa2vTueee6+zzzLDw1jfspb1r1641u3fvNkuWLDGTJ0827733nttNG5d77rnHbNmyxezbt8/85je/MV/72tfMqaeeGu3Po48+aoqLi82GDRvMzp07zd/8zd94fmlvf3+/aW1tNa2trUaSWblypWltbY0uvz6ePjU0NJizzz7b/PrXvzZvvfWWueqqqzy3vG6sfvb395t77rnH7Nixw+zfv9+8+uqrpra21px11llZ1c+/+7u/M8XFxWbLli1xyyGPHDkSvSfbn+ex+uiHZ7ls2TKzbds2s3//fvO73/3OPPDAAyYQCJjNmzcbY7L/GdrG6qcfnmM6satpjHH2eeZsGDHGmB//+MemoqLCFBQUmC9+8YtxS/Cyjb3+Oz8/35SXl5uvf/3rZteuXdH3I5GIWbFihSktLTWhUMhcccUVZufOnS62+NheffVVIynpNX/+fGPM8fXpk08+MYsWLTJnnHGGmTRpkvna175m2tvbXehNemP188iRI6a+vt5MmzbN5OfnmxkzZpj58+cn9cHr/UzVP0nmqaeeit6T7c/zWH30w7P89re/Hf1/5rRp08zVV18dDSLGZP8ztI3VTz88x3QSw4iTz9MyxpjMxlIAAABOnpysGQEAAN5BGAEAAK4ijAAAAFcRRgAAgKsIIwAAwFWEEQAA4CrCCAAAcBVhBAAAuIowAgAAXEUYAQAAriKMAAAAV/1/NEoHiB/UT8gAAAAASUVORK5CYII=\n", + "image/png": "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Dx48GHeP1/t57bXXmqeeesq88847pq2tzVx//fVmxowZ5tChQ9F7sv15Hk8fs/1Zbty40bz00kvm3XffNe+++6554IEHTH5+vnnnnXeMMdn/DG3H6me2P8dE//mf/2nOOeccc/HFF5u77747et3J55mzYeSSSy4xDQ0Ncdc+//nPm+985zsutejErFixwsyaNSvle5FIxJSWlppHH300eu3TTz81xcXF5vHHH3eohScm8Yf08fTp448/Nvn5+ea5556L3vPhhx+aQCBgXn75Zcfanol0YeQv//Iv034mG/vZ3d1tJJmtW7caY/z5PBP7aIw/n+Xpp59unnzySV8+w1h2P43x13Ps7+83559/vmlubjZf+cpXomHE6eeZk9M0g4ODamlpUX19fdz1+vp67dixw6VWnbi9e/eqvLxclZWV+uu//mvt27dPkrR//351dXXF9TcUCukrX/lK1vb3ePrU0tKio0ePxt1TXl6uqqqqrOv3li1bdOaZZ2rmzJm67bbb1N3dHX0vG/vZ29srSTrjjDMk+fN5JvbR5pdnGQ6H9dxzz+nw4cOqra315TOUkvtp88tzvPPOO3X99dfrmmuuibvu9PMc16m92a6np0fhcDjpcL+SkpKkQ/2yxaWXXqpnnnlGM2fO1IEDB/TII4+orq5Ou3btivYpVX/ff/99N5p7wo6nT11dXSooKNDpp5+edE82Pec5c+bom9/8pioqKrR//379/d//va666iq1tLQoFAplXT+NMWpsbNTll1+uqqoqSf57nqn6KPnjWe7cuVO1tbX69NNPdcopp+iFF17QhRdeGP3h45dnmK6fkj+eoyQ999xzeuutt/Tb3/426T2n/5vMyTBisywr7mtjTNK1bDFnzpzo7y+66CLV1tbqvPPO07/8y79EC6v81F/bePqUbf2eO3du9PdVVVWqqalRRUWFXnrpJX39619P+zmv9nPRokX63e9+p9deey3pPb88z3R99MOz/NznPqe2tjZ9/PHHev755zV//nxt3bo1+r5fnmG6fl544YW+eI4dHR26++67tXnzZhUWFqa9z6nnmZPTNFOnTlUwGExKbt3d3UkpMFtNnjxZF110kfbu3RtdVeOn/h5Pn0pLSzU4OKj//u//TntPNiorK1NFRYX27t0rKbv6edddd2njxo169dVXdfbZZ0ev++l5putjKtn4LAsKCvTZz35WNTU1ampq0qxZs/T973/fV89QSt/PVLLxOba0tKi7u1vV1dXKy8tTXl6etm7dqh/84AfKy8uLttOp55mTYaSgoEDV1dVqbm6Ou97c3Ky6ujqXWnVyDQwMaM+ePSorK1NlZaVKS0vj+js4OKitW7dmbX+Pp0/V1dXKz8+Pu6ezs1PvvPNO1vZbkg4ePKiOjg6VlZVJyo5+GmO0aNEibdiwQf/xH/+hysrKuPf98DyP1cdUsvFZJjLGaGBgwBfPcCx2P1PJxud49dVXa+fOnWpra4u+ampq9Ld/+7dqa2vTueee6+zzzLDw1jfspb1r1641u3fvNkuWLDGTJ0827733nttNG5d77rnHbNmyxezbt8/85je/MV/72tfMqaeeGu3Po48+aoqLi82GDRvMzp07zd/8zd94fmlvf3+/aW1tNa2trUaSWblypWltbY0uvz6ePjU0NJizzz7b/PrXvzZvvfWWueqqqzy3vG6sfvb395t77rnH7Nixw+zfv9+8+uqrpra21px11llZ1c+/+7u/M8XFxWbLli1xyyGPHDkSvSfbn+ex+uiHZ7ls2TKzbds2s3//fvO73/3OPPDAAyYQCJjNmzcbY7L/GdrG6qcfnmM6satpjHH2eeZsGDHGmB//+MemoqLCFBQUmC9+8YtxS/Cyjb3+Oz8/35SXl5uvf/3rZteuXdH3I5GIWbFihSktLTWhUMhcccUVZufOnS62+NheffVVIynpNX/+fGPM8fXpk08+MYsWLTJnnHGGmTRpkvna175m2tvbXehNemP188iRI6a+vt5MmzbN5OfnmxkzZpj58+cn9cHr/UzVP0nmqaeeit6T7c/zWH30w7P89re/Hf1/5rRp08zVV18dDSLGZP8ztI3VTz88x3QSw4iTz9MyxpjMxlIAAABOnpysGQEAAN5BGAEAAK4ijAAAAFcRRgAAgKsIIwAAwFWEEQAA4CrCCAAAcBVhBAAAuIowAgAAXEUYAQAAriKMAAAAV/1/NEoHiB/UT8gAAAAASUVORK5CYII=", "text/plain": [ "
" ] @@ -1003,7 +992,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGdCAYAAADAAnMpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAw3UlEQVR4nO3df3BU9b3/8dduNj/4lSAggUDAWH/RcqU1aAsWW380Fq39tuMMfGun2BZmmqIg5Np+RWaqZTqN7bQM2gq0V5BxxquMF+y1t6mS3lZAsVMJSUWhaiuSAAkxCEn4lR+7n+8fm3M2mx+754Sc7IbzfMzsJJz97OazORvyyufzPp9PwBhjBAAAkCLBVHcAAAD4G2EEAACkFGEEAACkFGEEAACkFGEEAACkFGEEAACkFGEEAACkFGEEAACkVCjVHXAiEono2LFjGjNmjAKBQKq7AwAAHDDGqLW1VQUFBQoG+x//GBZh5NixYyosLEx1NwAAwADU1dVp6tSp/d4/LMLImDFjJEVfTG5ubop7AwAAnGhpaVFhYaH9e7w/wyKMWFMzubm5hBEAAIaZZCUWFLACAICUIowAAICUIowAAICUIowAAICUch1Gdu3apbvuuksFBQUKBAL63e9+l/QxO3fuVHFxsXJycnT55Zdr48aNA+krAAC4CLkOI2fOnNGsWbP061//2lH7Q4cO6Y477tC8efNUXV2thx9+WMuXL9e2bdtcdxYAAFx8XF/aO3/+fM2fP99x+40bN2ratGlat26dJGnGjBnau3evfvGLX+juu+92++UBAMBFxvOakTfeeEMlJSVxx26//Xbt3btXHR0dfT6mra1NLS0tcTcAAHBx8jyMNDQ0KD8/P+5Yfn6+Ojs71dTU1OdjysvLlZeXZ99YCh4AgIvXkFxN03PlNWNMn8ctq1atUnNzs32rq6vzvI8AACA1PF8OftKkSWpoaIg71tjYqFAopPHjx/f5mOzsbGVnZ3vdNQAAkAY8HxmZM2eOKisr447t2LFDs2fPVmZmptdfHgAApDnXYeT06dOqqalRTU2NpOiluzU1NaqtrZUUnWJZtGiR3b60tFSHDx9WWVmZDh48qM2bN2vTpk168MEHB+cVAACQxowx+mfjaXWEI73uaz7bod/u+pfqPj6bgp6lD9fTNHv37tXNN99s/7usrEySdO+992rLli2qr6+3g4kkFRUVqaKiQitXrtSTTz6pgoICPfHEE1zWCwC46IUjRg9te0svVB3RrKl5embxZ5U3Ijor0BGO6PM/+7Na2zr14Ymz+unX/y3FvU2dgLGqSdNYS0uL8vLy1NzcrNzc3FR3BwAAR/78j+P67pa99r+tQJIdCmr5c9XaceC4JOm6aWO1femNqeqmZ5z+/va8gBUAAL9qOt0uSZo4Jlsd4Yj+fqRZt63dqayMoI6eOme3m3LJyFR1MS2wUR4AAB77VEGunl3yOU0ZO0Iftbbp6KlzGj8qS1/+1CRJUiT9Jyk8xcgIAABe6coYgUBAnyzI1Y6VN+kP++tljNGtM/JVsb9eL7/TYLfzK8IIAAAeMV0pw1ric1R2SAtmx1YVtxb/9PvICNM0AAB4xNgjI33fbx0mjAAAgJQIdqUUn2cRwggAAF6JZYy+h0aCXYcjhBEAAOCFpNM0Aaudv9MIYQQAAI/0LGDtiQLWKMIIAAAeSZYx7JqRIehLOiOMAADgseRX0wxZV9ISYQQAAI9YGSPQXwFr129hakYAAIA3ukJGfyMjXNobRRgBAMAjyTIGBaxRhBEAADzGCqyJEUYAAPCIvc5Iv4ueMU0jEUYAAPCMiaWRPgXtRc+Gpj/pijACAIBHYlfT9C1gLwfv7zRCGAEAwCPJMkaARc8kEUYAAPBcoJ8K1iBX00gijAAA4Jmk0zRdH1mBFQAAeMIkW/QsaDccmg6lKcIIAAApElv0LMUdSTHCCAAAHks+TePvNEIYAQDAI/YyI0kKWH2eRQgjAAB4xXSVsPY3MsLVNFGEEQAAPGKSXE4TYAVWSYQRAAA8k3zXXqudv9MIYQQAAI8l2yiPq2kAAIAnYgWsfd/P1TRRhBEAADyStIA1yNU0EmEEAADPJAsZQbuA1d9phDACAIDH+pumscZMqBkBAACe6r+ANfqRmhEAAOCJpBvlsQKrJMIIAACeSXo1DTUjkggjAAB4JlnEYJ2RKMIIAACe63tohBVYowgjAAB4JPmiZ4yMSIQRAAA8k3zRs6521IwAAAAvJF/0jKtpJMIIAACeY2+axAgjAAB4xIoY/S16FuBqGkmEEQAAvJN00TOrmb/TCGEEAACPJIsYAWpGJBFGAADwjH1pbz/3szdNFGEEAACPBfqZp7GvphnKzqQhwggAAB5xurIqIyMAAMATyVZgDQa5mkYijAAA4JnkG+V1tWNkBAAAeKm/dUZYgTWKMAIAgEeSb5QXRc0IAADwRLKN8liBNYowAgCAV5JulNetqY9HRwgjAAB4rN9pmm53+DiLEEYAAPCKvVFev4uexT73c90IYQQAAI9YUy/JakYkf6/COqAwsn79ehUVFSknJ0fFxcXavXt3wvbPPvusZs2apZEjR2ry5Mn6zne+oxMnTgyowwAADBf2YEe/0zSxzxkZcWHr1q1asWKFVq9ererqas2bN0/z589XbW1tn+1fe+01LVq0SIsXL9Y777yjF154QW+++aaWLFlywZ0HACCdJV/0jJoRaQBhZO3atVq8eLGWLFmiGTNmaN26dSosLNSGDRv6bP/Xv/5Vl112mZYvX66ioiJ9/vOf1/e+9z3t3bv3gjsPAMBw0P+iZ7HPCSMOtbe3q6qqSiUlJXHHS0pKtGfPnj4fM3fuXB05ckQVFRUyxuj48eP6r//6L9155539fp22tja1tLTE3QAAGG6SL3oWu4NpGoeampoUDoeVn58fdzw/P18NDQ19Pmbu3Ll69tlntXDhQmVlZWnSpEkaO3asfvWrX/X7dcrLy5WXl2ffCgsL3XQTAIC0kHzRs9jnhBGXel6iZIzp97KlAwcOaPny5frRj36kqqoqvfzyyzp06JBKS0v7ff5Vq1apubnZvtXV1Q2kmwAApFSyfBHkahpJUshN4wkTJigjI6PXKEhjY2Ov0RJLeXm5brzxRv3gBz+QJF177bUaNWqU5s2bp5/85CeaPHlyr8dkZ2crOzvbTdcAAEhb/S96FvvcRIamL+nI1chIVlaWiouLVVlZGXe8srJSc+fO7fMxZ8+eVTAY/2UyMjIk+XvpWwCAfyTbtVdimsaVsrIyPfXUU9q8ebMOHjyolStXqra21p52WbVqlRYtWmS3v+uuu7R9+3Zt2LBBH3zwgV5//XUtX75cN9xwgwoKCgbvlQAAkGbsRc/6GRmJu5pmCPqTrlxN00jSwoULdeLECa1Zs0b19fWaOXOmKioqNH36dElSfX193Joj3/72t9Xa2qpf//rX+vd//3eNHTtWt9xyi372s58N3qsAACANJVnzLK7e0s8jI67DiCQtXbpUS5cu7fO+LVu29Dq2bNkyLVu2bCBfCgCAYctJvggEou38HEbYmwYAAK/1N0+jbnUj/s0ihBEAALySbJ2R7vdFCCMAAGCwJVuBVYqNjDBNAwAABp2TeGEFFcIIAADwTH/rjEixMOLjLEIYAQDAK26maQgjAADAA8kLWKkZIYwAAOAZR+uMWG097Ul6I4wAAOARJ9M0FLASRgAA8Fwg0aJnQatmhDACAAAGmXEw+WJP0/g3ixBGAADwirtFz4agQ2mKMAIAgEecLXrG1TSEEQAAPMaiZ4kRRgAA8IizaZroR0ZGAADAoHOyay8rsBJGAADwjqtFz/ybRggjAAB4xIoXiRc942oawggAAB5LVMAa7PpNTM0IAAAYdNaqquzamxhhBAAAjzhaZ8Rq6+M0QhgBAMAjTvIFK7ASRgAA8FyijfJii575N40QRgAA8Ih9NU2CNlxNQxgBAMAzzgpY49v6EWEEAACPOIkX1IwQRgAA8I61N42jpv5NI4QRAAA8lqiAlZERwggAAJ6xN8pLVDPCCqyEEQAAvOIkX9hLxfs3ixBGAADwinFQM2JdTcPICAAA8E7CRc+oGSGMAADgEbtmJEEbVmAljAAA4Bl7msbBrr2MjAAAgEHnbNGzrraMjAAAgMEWK2BNUDPSdZ9/owhhBAAAzyWapglwNQ1hBAAA7yQvYKVmhDACAIBnHC16Rs0IYQQAAK9Y8cLJ1TQ+ziKEEQAAvJawgJWaEcIIAABeMQ7Wgw8wMkIYAQDAK/Y0TYI27E1DGAEAwDNO8gU1I4QRAAA8F0i0UV7XR0ZGAADAoHMyTWPXjHjem/RFGAEAwCNWAWviS3ujHxkZAQAAKRG7tDe1/UglwggAAB6xr+x1sOiZnytYCSMAAHgs0aJn7E1DGAEAwDNGyWtGRM0IYQQAAK+wzogzhBEAADziLIxEPzIyAgAAPJNo0TNGRggjAAB4xq4ZSdDGus/4eNkzwggAAB5xcmlvgKtpCCMAAHjFSb6gZmSAYWT9+vUqKipSTk6OiouLtXv37oTt29ratHr1ak2fPl3Z2dn6xCc+oc2bNw+owwAADBvWyEiCiRrWPJNCbh+wdetWrVixQuvXr9eNN96o3/zmN5o/f74OHDigadOm9fmYBQsW6Pjx49q0aZOuuOIKNTY2qrOz84I7DwDAcOBkBVbj4zTiOoysXbtWixcv1pIlSyRJ69at0yuvvKINGzaovLy8V/uXX35ZO3fu1AcffKBx48ZJki677LIL6zUAAMOAowJWakbcTdO0t7erqqpKJSUlccdLSkq0Z8+ePh/z0ksvafbs2fr5z3+uKVOm6KqrrtKDDz6oc+fODbzXAAAMA04GO5imcTky0tTUpHA4rPz8/Ljj+fn5amho6PMxH3zwgV577TXl5OToxRdfVFNTk5YuXaqPP/6437qRtrY2tbW12f9uaWlx000AANKClS8ST9NEP1LA6lLPxVuMMf0u6BKJRBQIBPTss8/qhhtu0B133KG1a9dqy5Yt/Y6OlJeXKy8vz74VFhYOpJsAAKQJJ4ueEUYcmTBhgjIyMnqNgjQ2NvYaLbFMnjxZU6ZMUV5enn1sxowZMsboyJEjfT5m1apVam5utm91dXVuugkAQFqwAkbCdUastt53J225CiNZWVkqLi5WZWVl3PHKykrNnTu3z8fceOONOnbsmE6fPm0fe++99xQMBjV16tQ+H5Odna3c3Ny4GwAAw409TZOgTayA1b9xxPU0TVlZmZ566ilt3rxZBw8e1MqVK1VbW6vS0lJJ0VGNRYsW2e3vuecejR8/Xt/5znd04MAB7dq1Sz/4wQ/03e9+VyNGjBi8VwIAQJpxs2uvn6+mcX1p78KFC3XixAmtWbNG9fX1mjlzpioqKjR9+nRJUn19vWpra+32o0ePVmVlpZYtW6bZs2dr/PjxWrBggX7yk58M3qsAACANxQpYky965ueREddhRJKWLl2qpUuX9nnfli1beh275pprek3tAADgF4mmaYIUjbA3DQAAnnFQwBqkZoQwAgCAVxzFC3uaxsuepDfCCAAAHrEGO5ztTTMEHUpThBEAADyWaNdeVmAljAAA4Blro7xEFaxWUGEFVgAAMOhM8ixij4z4N4oQRgAA8IyzXXu5moYwAgCAR9wteuZ9f9IVYQQAAI8lnqbhahrCCAAAHnGya69dM+LjNEIYAQAghagZIYwAAOCZ2NU0yWtGfJxFCCMAAHjN2d40Q9SZNEQYAQDAI9aiZ4kKWO1Ne308NEIYAQDAI07yhX01jcd9SWeEEQAAPGIHjETLwbM3DWEEAACv2Jf2Jpyosdp63Zv0RRgBAMBjTgpYfZxFCCMAAHjFXg4+QRumaQgjAAB4x8lGeS7aXqwIIwAAeMTJRnnBoDVN4980QhgBAMBjiWpGrLsikSHpSloijAAA4JHY1TT9CwQYGSGMAADgESfxIlbA6mlX0hphBAAAj9gb5SWcpgnEtfUjwggAAJ5LUMDK5TSEEQAAvGJvlOdoOfgh6FCaIowAAOARe5omQZvYNI1/0whhBAAAjzjJF9bIiH+jCGEEAADPJVr0zLqPaRoAAOCZRNM0VgEr0zQAAGDQ2YueOShg9XEWIYwAAOAVR4ueiRVYCSMAAHgkdjVNopqR+LZ+RBgBAMBjiadprAJW/6YRwggAAB5xMvVi5RQfZxHCCAAAXnGyN03Q3rXXvwgjAAB4xM2uvVzaCwAABp2TAtYgBayEEQAAvJZomsaqGqGAFQAAeMDFomdD0Jt0RRgBAMAjTgY77AJWH6cRwggAAB6x8kXCRc+stj5OI4QRAAA8xjRNYoQRAAA8Ym+Ul6AN0zSEEQAAPOMoX3QlFa6mAQAAg87VCqz+zSKEEQAAvBIrSnVQwOp5b9IXYQQAAI85KmD18dAIYQQAAI8kHxdhmkYijAAA4B0HAcMKKhSwAgCAQWePjCScp4lv60eEEQAAPOZsmsa/cYQwAgCAR+xFz5IPjFAzAgAABp+TfBEMBhy3vVgRRgAA8Ii96Bkb5SVEGAEAwCNGDqZp7OXgh6BDaYowAgBACllX2hgfT9QMKIysX79eRUVFysnJUXFxsXbv3u3oca+//rpCoZA+/elPD+TLAgAwrDjZm8ZeZyTieXfSluswsnXrVq1YsUKrV69WdXW15s2bp/nz56u2tjbh45qbm7Vo0SLdeuutA+4sAADDiZOxjoRrkPiE6zCydu1aLV68WEuWLNGMGTO0bt06FRYWasOGDQkf973vfU/33HOP5syZM+DOAgAwrNgjI/0HjiB707gLI+3t7aqqqlJJSUnc8ZKSEu3Zs6ffxz399NP617/+pUceecTR12lra1NLS0vcDQCA4SrR2Id1pQ0FrA41NTUpHA4rPz8/7nh+fr4aGhr6fMz777+vhx56SM8++6xCoZCjr1NeXq68vDz7VlhY6KabAACkBTdX01DA6lLP4SZjTJ9DUOFwWPfcc49+/OMf66qrrnL8/KtWrVJzc7N9q6urG0g3AQBIKSczL3YY8W8WkbOhii4TJkxQRkZGr1GQxsbGXqMlktTa2qq9e/equrpa999/vyQpEonIGKNQKKQdO3bolltu6fW47OxsZWdnu+kaAABpx94oL+GiZ0zTuBoZycrKUnFxsSorK+OOV1ZWau7cub3a5+bmav/+/aqpqbFvpaWluvrqq1VTU6PPfvazF9Z7AADSmJO9aYL2b2L/phFXIyOSVFZWpm9961uaPXu25syZo9/+9reqra1VaWmppOgUy9GjR/XMM88oGAxq5syZcY+fOHGicnJyeh0HAOBi5aSAlWkaFxYuXKgTJ05ozZo1qq+v18yZM1VRUaHp06dLkurr65OuOQIAgB/Y+cLRcvD+TSMBMwwubG5paVFeXp6am5uVm5ub6u4AAODIZQ/9QZL0t9W3auKYnD7b/LOxVbet3aWxIzNV86OSPtsMV05/f7M3DQAAHktUwGoNm0R8XMFKGAEAwGMJC1jtdUb8izACAIAHuldBJBwXCZBGCCMAAHjAaUWmvWtv+pdweoYwAgCAB7pHi8Qb5QV6tfcbwggAAB5wPk1jtfe2P+mMMAIAgMcSFbBamKYBAACDymm0CAaZpiGMAADgge4DHYk3yrPa+zeOEEYAAPCAUVwa6Rc1I4QRAAA8l3jRM6ZpCCMAAHjAOBsYYZ0REUYAAEgpaw0SH2cRwggAAF6IGxlJME/T/S6/FrESRgAA8JiTaRrJv6MjhBEAADzQ/WoaJwWs0cf4E2EEAAAPON4or1tQ8WsRK2EEAAAPxG2Ul3DRs24jI/7MIoQRAAC8ELdRXqJFz7r9JjY+naghjAAAkEIUsBJGAADwRNw0jdMCVsIIAAAYLAMpYGWaBgAADB7Hu/bG7ov4M4sQRgAA8FrCAlZWYCWMAADghbhFzxK0i5+m8SfCCAAAHnBcM9J9nZGIR51Jc4QRAAA8EH81Tf9jI0EKWAkjAAB4IW7RswTtugcVClgBAIAnEq8zEvucAlYAADBonMaKALv2EkYAAPBC90GORDUj3bFrLwAAGDRuilHtqRp/ZhHCCAAAXnIyKGKNnPg0ixBGAADwRFeycDJBY7VhmgYAAAwaN7HC2rnXp1mEMAIAgBesYOGoeLWrCSMjAABg0FgFrE6maawCVp9mEcIIAABecjYw4uzS34sVYQQAAA+4GeUIME0DAAAGmxUrnIx6UMAKAAAGnb3PjPP6VdYZAQAAg89RNQjTNAAAYLDFLu1N3pZpGgAAkFKxwOLPNEIYAQDAA7GSEecFrBF/ZhHCCAAAXrAXPXNTwEoYAQAAg83RRnkUsAIAgMHmbtEzClgBAMAgsxc9czBPE1tnxJ9phDACAIAHrEXP3EzTMDICAAAGH+uMJEUYAQDAA7G9aZJjmgYA4Fg4YrTgN2/ogeerU90VpLmBFLCyzggAIKm3jpzS3w59rP+uOZbqriDtWeuMOChgtWtG/JlGCCMA4MK5jrD9uV9/ccAZN3vTxNYZ8a4/6YwwAgAutHVG7M/9+osD7jipGQkGYlUjfkQYAQAX2rqNjHRGIglawu/cxAqWgx+A9evXq6ioSDk5OSouLtbu3bv7bbt9+3Z96Utf0qWXXqrc3FzNmTNHr7zyyoA7DACp1H1kJMzQCBKITdM4qRmhgNWVrVu3asWKFVq9erWqq6s1b948zZ8/X7W1tX2237Vrl770pS+poqJCVVVVuvnmm3XXXXepuppKdADDD2EETtkb5TloSwGrS2vXrtXixYu1ZMkSzZgxQ+vWrVNhYaE2bNjQZ/t169bphz/8oa6//npdeeWV+ulPf6orr7xSv//97y+48wAw1AgjcMvVrr2e9iR9uQoj7e3tqqqqUklJSdzxkpIS7dmzx9FzRCIRtba2aty4cf22aWtrU0tLS9wNANJB95oRwggSGdg6I/58T7kKI01NTQqHw8rPz487np+fr4aGBkfP8ctf/lJnzpzRggUL+m1TXl6uvLw8+1ZYWOimmwDgmbPthBE4E8sVyYdGgj4fGhlQAWvPYhxjjKMCneeee06PPvqotm7dqokTJ/bbbtWqVWpubrZvdXV1A+kmAAy6M+2d9udhn/4VC2fsmhFH0zT+LmANuWk8YcIEZWRk9BoFaWxs7DVa0tPWrVu1ePFivfDCC7rtttsSts3OzlZ2drabrgHAkDjXbWSkM+zT3xxwxL6axkFbu4DVp0MjrkZGsrKyVFxcrMrKyrjjlZWVmjt3br+Pe+655/Ttb39b//mf/6k777xzYD0FgDRwpo1pGrjjbAVWf+/a62pkRJLKysr0rW99S7Nnz9acOXP029/+VrW1tSotLZUUnWI5evSonnnmGUnRILJo0SI9/vjj+tznPmePqowYMUJ5eXmD+FIAwHtnmaaBB6y84tcCVtdhZOHChTpx4oTWrFmj+vp6zZw5UxUVFZo+fbokqb6+Pm7Nkd/85jfq7OzUfffdp/vuu88+fu+992rLli0X/goAYAhRwAqnYtM0DgpYu+Yp/PqOch1GJGnp0qVaunRpn/f1DBivvvrqQL4EAKSluJERwggSGEgBq1/TCHvTAIALjIzALTcFrH6dpiGMAIAL3cNIJ2EECQxk0TOfZhHCCAC4caaNaRo4Y707HG2U1+MxfkMYAQAXzjFNA4fcbHoXZJoGAOCEMSZ+BVbCCBxgnZHkCCMA4FBbZyRuuW7CCBKJTdMkb2tP0/g0jRBGAMCh7sWrEoueITE3b4+gNTLiUV/SHWEEABxq6+wRRiKRFPUEw0PXOiNOLu61lhnxaRohjACAQz03xmOjPCRir8DqYpqGAlYAQEId4fiREL/+4oA7ThY9Y5oGAOBIz0XOWPQMibh5dwTsaRp/vqcIIwDgUM+REa6mQSKxaRoHG+VxaS8AwImeNSKEESRijXK42ZvG+HSihjACAA51RhgZwQA4SSNd/HqBFmEEABzqYGQELrh5d1DACgBwpGf4oIAVidg1Iw7aUsAKAHCES3vhhlX/4WrXXp++pQgjAOAQi57BFRcjI7FpGn++pwgjAOBQzwJWRkbghLNde6Mf/fqWIowAgEM9C1ipGUEi7hY9i6YRv76lCCMA4BCX9sKNWAGri5oRpmkAAIlwaS/ciBWwJm/LNA0AwJFeBayEEQyS2HLw/nxPEUYAwKFeBayEESTgJlfEloP3J8IIADhEASvcsN4dztYZ6Spg9el7ijACAA51sugZXBjYRnn+RBgBAId6joSw6BkSiY2MJG8bsGtGvOtPOiOMAIBDPZeDD/t1i1W44iSMBLva+HW0jTACAA71HAkJ+/QXBxxyU8DqXS+GBcIIADjUwaJncMFeZ8TJomdM0wAAnOg1MkIYQQL2CqwuFj1jmgYAkJB1NU1WKPpfJ5f2wglHV9PI2rXXnwgjAOCQFT6yu8KIX9eEgDMDWfSMkREAQELWNE1OZkb034QRJGC/OxzM0wTZmwYA4IRVwGqNjFAzgkRcLXrm8+tpCCMA4FDPkRHCCBJxs+hZsOu3sV+n/ggjAOBQJyMjGABnYx4UsAIAHOjoOTLi1wl+ODKgXXt9+pYijACAQ9alvTmZjIzAia6aERcFrFxNAwBIKHZpLzUjSM5e9MxBW9YZAQA40tFjZIRLe+GEmxVYDSMjAIBErKtpGBmBE27eHUH2pgEAONERsQpYqRlBcrFpGudriBifTtQQRgDAIauAlZEROGEHC1cb5XnXn3RGGAEAh+xpGkZG4ICbAlamaQAAjljLwecwMoJBZgUWpmkAAAn1HBmxVmQF+uJuOXhGRgAADvSsGWFgBInENspLnkbskRGfphHCCAA41GEvesbICJxzMjIiloMHADgRWw6+a2SELOKpi2WUwNE0TVcjv462EUYAwKFORkaGzAPPV+uWX+7UmbbOVHdlwFxtlGc9hgJWAEAinT137SWLeKKtM6z/rjmmQ01ntOu9j1LdnQGzgoWjmhGfT9OEUt0BABgurJGQ2AqspJHB9LOX/6F9h0/qh1++2j528mxHCnt0Yex1RlxM01wsU1NuEUYAwAFjjDp67E3DRnmDJxwx2vDqvyRJj/3xH/bxD0+cSVWXLtjApmn8iWkaAHCg+wJn1shIhDAyaOo+Pmt//uaHJ+3PP/ho+IaRk2fbJUljcpL/3R+wC1j9+Z4ijACAA91HQayRkY6I8e2w+mB773hrn8eH88iI1ffLxo9K2tbvNSOEEQBwoKNbteqkvByFggG1d0Z0rPl8Cnt18Xi/8XSfx2tPnB22y+5/2BQd7Sma4CCMdE3UDM9XeuEGFEbWr1+voqIi5eTkqLi4WLt3707YfufOnSouLlZOTo4uv/xybdy4cUCdBYBUsa6kkaTR2SFdPWmMJOmtulMp6tHFpefIyFX5oyVJ7eGIDg/T0ZFDTdF+OwkjQXtkxJ9xxHUY2bp1q1asWKHVq1erurpa8+bN0/z581VbW9tn+0OHDumOO+7QvHnzVF1drYcffljLly/Xtm3bLrjzAGKoX/DWu12/LMdkh5QRDOjaqXmSpL8faU5lty4KxhgdONYiSfrVNz6j1/7fzXplxU363OXjJEl//kdjKrs3IOc7wjrWfE6SdJmTkRGfT9O4vppm7dq1Wrx4sZYsWSJJWrdunV555RVt2LBB5eXlvdpv3LhR06ZN07p16yRJM2bM0N69e/WLX/xCd99994X1Pg2c7wjr/eOnFTHxS9VY6Tb+mP1Z3DFjfex6juix6B0mrp2xnyMYCCiUEVBmRkAZwaCCgeixQNfH6eNHamRWSE2n23T05Dl1hCNqD0dkTPRNH1CsbV+XnUUiRuGIsefJrXYBRQutrM+DwUDXsa7jPZ6n589V/A+aSXBf/GtP9j3t/t3v+dqCASkjGFRGIKBgMHa/9X1QV/+7P1fsa8aeu3v/+mzbo489z7fpeT77aGu6nfSe5773c8Re9ZGPz+oXO97TFRNHa9Gc6bp0THbc9yL6edfHHue8+zmLfy/E/hEx0fdDpOs9ETaxz40xyggGFQpG35MZwYAyM4LKCAYUCgbU0Hxe/3uwUSfOtOuuWZM19ZKRXe/b6C36vNHLZiPGqDMcff6xI7I0bfxI/b3ulIyJnsdg12OCgYCCgWi/IiZaXBox0eeJmOjjjTGaMnakrp40RvXN5/TWkWZlZQSVHQoqKxRUdihDGcGAfQ67/4xZ5zJ2bow2vXZIkvSVWZMlSddOHavn/lanbfuO6GufKbBfR7jre2XdpGjfA93ej1LAPhYM9H5PBpP8mRgKBnTZ+FE6WN+qpjNtau+MqK0zovbOiDKCUigYVGZGQKFgUKGM6PcrIxj9GiOzQvq3KXnKCMbOb2c4ov1Hm9URNsoIKta+2/tnTE5I0xPUPrR3RnSwvkWdkej/M5Gu97j10Sh2vowx9vc7EpHea2zV+42nlR0Kas4nxmvC6Oj7945/m6y/fvCx/rvmmD53+XgFAwF1RiLqCBt1hCPqDBt1RKIfO8MRXZk/RldMHG336Z+NrXr/+Onoe7Hr/8pQ13vI+hg9u9IVE0crNycz8Te+h8aW8/q4q0i1p7qPz8mY6Pdt/KispM/l9wJWV2Gkvb1dVVVVeuihh+KOl5SUaM+ePX0+5o033lBJSUncsdtvv12bNm1SR0eHMjN7n/y2tja1tbXZ/25paXHTTce2VR3R28cG/leNMVLlgeM6eurcIPZqcFwyMlOfLRqv//3HcftyRFz8qg6fVNXhk8kbpsifDh4f8q859xPjta/2pM53DM6aIP/3+mmSZI+MfNTapi+vSzxVnW5mFY7VddPG2v9+88OP9fbR5P/PfvHqS/udcnj13Y/saYmB+t5Nl9tBRJJu/9QkPfLSO9p/tFlf+dVrSR8fDEh3XzdVo3NCOn2+U9v2HXG8vHreiEz9n08XxIW0RJpOt+t/3jqWdCSjaMIoO2gkYjWprj2lH//+HUd9GGx3XzdVM6fkpeRruwojTU1NCofDys/Pjzuen5+vhoaGPh/T0NDQZ/vOzk41NTVp8uTJvR5TXl6uH//4x266NiA73/tIL/392AU/T25OSGO6Jeq4vzrj/gIN9Hk8aI0odB95UPwIRuxx0fsipusvg66/vky3vw7PdYR18myHXn4nek4m5eYoJzOoUEZ0BCXuL78+fpCMoj/UoWCw27bWJu4vR3skqNvn1vGeP3c9x0v6+6vcen3xj43/JNBHu9ixrv730adwt5Ge7iMW3Uc1Auret75GFOJHUvrsSyB52+6vqedzdO9DX+e+V3+6/pERCGhW4ViFgkHtqz2ps+2dcefZeo3dR9vU7T77fvt4t89lukaVon9NWn81h4LRY8FAwP7+Wu9JewQlYhTKCOiWaybKGOn1fzaprTOiTqudMfbz2beur3Wo6YzCEaNLx2Rr/Kis2OhMt/e61d4aCYv+9W+NmkgH61u0518nJEmXTxilkdkZau8aQWjrjPah589a3Ohfj+Nzr5hgh5BPTs7Vt+depj//o1Fn2jr7/f5Y3+fu5yPSbVRA6nq/xr1vrXdk3063deh8R0RZGUFdmT9a2V0jPZmhoCLdzkNnODqKEPu6RkdOntPf607p7z1qXUZlZSg/N8c+b9Zf6NZ74aPTbXr13Y/06rv9r4g6JiekcaOyoqOm9vcwYI/cquu4NULZfcRo6iUjVfrFT8Q9X35ujr7/hU/of96qV3tnRGFjlBkMKJQRHfHJ7Br5CWUE1dEZ0YH6Fr1QdSTuOT5VkKvsUND++e/+0SpKPtce1okz7XrmjcP9vrb+TBidpf7OVSgY0Dc/O83R81i/Q95vPN1vMa/XPjPtkuERRiw9f2EYYxImv77a93XcsmrVKpWVldn/bmlpUWFh4UC6mtCXPpmvwnEjLug5JozO1sLrCzUyK33Wj+sIR7R93xHVfnxWs6eP0xevvtRRMgfSydtHm7X3w4+14AJ+vl7/Z5P2/KtJ08eP0t3XTXX8V68TgUBAj371U3r0q58atOd06uMz7dq+74huuupSXZU/xtVjj506p+37juhcR9g+NjIrpLuvm6pJeTn9Pu7dhlZV7K/vdz+esSOytPCGQtdTHcn88MvX6IdfviZpO2OMdhw4rreOnLKPXTt1rEo+mZ/0/7+OcETbqo6o7uTZhO26Cyigm666VDcUjXP8mES+/pkpOt8e1qlzfU/7DIUru01xDbWAcVG6297erpEjR+qFF17Q17/+dfv4Aw88oJqaGu3cubPXY2666SZ95jOf0eOPP24fe/HFF7VgwQKdPXu2z2manlpaWpSXl6fm5mbl5uY67S4AAEghp7+/XV1Nk5WVpeLiYlVWVsYdr6ys1Ny5c/t8zJw5c3q137Fjh2bPnu0oiAAAgIub60t7y8rK9NRTT2nz5s06ePCgVq5cqdraWpWWlkqKTrEsWrTIbl9aWqrDhw+rrKxMBw8e1ObNm7Vp0yY9+OCDg/cqAADAsOV6InbhwoU6ceKE1qxZo/r6es2cOVMVFRWaPn26JKm+vj5uzZGioiJVVFRo5cqVevLJJ1VQUKAnnnjiorisFwAAXDhXNSOpQs0IAADDjyc1IwAAAIONMAIAAFKKMAIAAFKKMAIAAFKKMAIAAFKKMAIAAFKKMAIAAFKKMAIAAFKKMAIAAFIqffa9T8BaJLalpSXFPQEAAE5Zv7eTLfY+LMJIa2urJKmwsDDFPQEAAG61trYqLy+v3/uHxd40kUhEx44d05gxYxQIBAbteVtaWlRYWKi6ujr2vEkxzkV64XykD85F+uBcuGeMUWtrqwoKChQM9l8ZMixGRoLBoKZOnerZ8+fm5vLGShOci/TC+UgfnIv0wblwJ9GIiIUCVgAAkFKEEQAAkFK+DiPZ2dl65JFHlJ2dnequ+B7nIr1wPtIH5yJ9cC68MywKWAEAwMXL1yMjAAAg9QgjAAAgpQgjAAAgpQgjAAAgpXwdRtavX6+ioiLl5OSouLhYu3fvTnWXLjq7du3SXXfdpYKCAgUCAf3ud7+Lu98Yo0cffVQFBQUaMWKEvvjFL+qdd96Ja9PW1qZly5ZpwoQJGjVqlL761a/qyJEjQ/gqhr/y8nJdf/31GjNmjCZOnKivfe1revfdd+PacC6GxoYNG3TttdfaC2fNmTNHf/zjH+37OQ+pU15erkAgoBUrVtjHOB9DxPjU888/bzIzM81//Md/mAMHDpgHHnjAjBo1yhw+fDjVXbuoVFRUmNWrV5tt27YZSebFF1+Mu/+xxx4zY8aMMdu2bTP79+83CxcuNJMnTzYtLS12m9LSUjNlyhRTWVlp9u3bZ26++WYza9Ys09nZOcSvZvi6/fbbzdNPP23efvttU1NTY+68804zbdo0c/r0absN52JovPTSS+YPf/iDeffdd827775rHn74YZOZmWnefvttYwznIVX+9re/mcsuu8xce+215oEHHrCPcz6Ghm/DyA033GBKS0vjjl1zzTXmoYceSlGPLn49w0gkEjGTJk0yjz32mH3s/PnzJi8vz2zcuNEYY8ypU6dMZmamef755+02R48eNcFg0Lz88stD1veLTWNjo5Fkdu7caYzhXKTaJZdcYp566inOQ4q0traaK6+80lRWVpovfOELdhjhfAwdX07TtLe3q6qqSiUlJXHHS0pKtGfPnhT1yn8OHTqkhoaGuPOQnZ2tL3zhC/Z5qKqqUkdHR1ybgoICzZw5k3N1AZqbmyVJ48aNk8S5SJVwOKznn39eZ86c0Zw5czgPKXLffffpzjvv1G233RZ3nPMxdIbFRnmDrampSeFwWPn5+XHH8/Pz1dDQkKJe+Y/1ve7rPBw+fNhuk5WVpUsuuaRXG87VwBhjVFZWps9//vOaOXOmJM7FUNu/f7/mzJmj8+fPa/To0XrxxRf1yU9+0v7lxXkYOs8//7z27dunN998s9d9/FwMHV+GEUsgEIj7tzGm1zF4byDngXM1cPfff7/eeustvfbaa73u41wMjauvvlo1NTU6deqUtm3bpnvvvVc7d+607+c8DI26ujo98MAD2rFjh3Jycvptx/nwni+naSZMmKCMjIxeqbWxsbFXAoZ3Jk2aJEkJz8OkSZPU3t6ukydP9tsGzi1btkwvvfSS/vKXv2jq1Kn2cc7F0MrKytIVV1yh2bNnq7y8XLNmzdLjjz/OeRhiVVVVamxsVHFxsUKhkEKhkHbu3KknnnhCoVDI/n5yPrznyzCSlZWl4uJiVVZWxh2vrKzU3LlzU9Qr/ykqKtKkSZPizkN7e7t27txpn4fi4mJlZmbGtamvr9fbb7/NuXLBGKP7779f27dv15///GcVFRXF3c+5SC1jjNra2jgPQ+zWW2/V/v37VVNTY99mz56tb37zm6qpqdHll1/O+RgqqambTT3r0t5NmzaZAwcOmBUrVphRo0aZDz/8MNVdu6i0traa6upqU11dbSSZtWvXmurqavsS6scee8zk5eWZ7du3m/3795tvfOMbfV42N3XqVPOnP/3J7Nu3z9xyyy1cNufS97//fZOXl2deffVVU19fb9/Onj1rt+FcDI1Vq1aZXbt2mUOHDpm33nrLPPzwwyYYDJodO3YYYzgPqdb9ahpjOB9DxbdhxBhjnnzySTN9+nSTlZVlrrvuOvsyRwyev/zlL0ZSr9u9995rjIleOvfII4+YSZMmmezsbHPTTTeZ/fv3xz3HuXPnzP3332/GjRtnRowYYb7yla+Y2traFLya4auvcyDJPP3003YbzsXQ+O53v2v/v3PppZeaW2+91Q4ixnAeUq1nGOF8DI2AMcakZkwGAADApzUjAAAgfRBGAABAShFGAABAShFGAABAShFGAABAShFGAABAShFGAABAShFGAABAShFGAABAShFGAABAShFGAABAShFGAABASv1/mvbc4SbC9sQAAAAASUVORK5CYII=\n", + "image/png": "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", "text/plain": [ "
" ] @@ -1046,7 +1035,7 @@ "outputs": [ { "data": { - "image/png": "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QxDqHPWlvdKZm5796U9/UmFhodLS0vTnP/9ZN9xwgyTpzjvv1L59+7R8+fLG5VesWKF77rlH27ZtU58+fXT//fc3hhcAABBsMYURAAAAq/DbNAAAwFGEEQAA4CjCCAAAcBRhBAAAOCrQYWTGjBnq37+/unbtqvT0dK1a1fpn291o6tSpSkpKavbXq1evxueNMZo6dar69Omjc845R9/5zne0bdu2Zu9RVVWlu+++Wz169NC5556rH/3oRzpw4ECzZY4dO6YRI0YoJSVFKSkpGjFihI4fP25HFbVy5UoNGzZMffr0UVJSkt58881mz9tZx/z8fA0bNkznnnuuevTooQkTJqi6utr2Ot95552ttvt1113n2TpnZmbqm9/8prp166aePXvq1ltv1c6dO5st47ftHEmd/badZ86cqSuvvLLx7qEZGRl69913G5/32zaOpM5+28aWaO/H8fzqtddeM507dzYvvPCC2b59u/nv//5vc+6555r9+/c7XbR2TZkyxXzta18zhYWFjX/FxcWNzz/22GOmW7duZv78+WbLli1m+PDhpnfv3qa8vLxxmbFjx5qLL77YZGVlmQ0bNpgbb7zRXHXVVaa2trZxmR/84AcmLS3NZGdnm+zsbJOWlmZuueUWW+q4aNEi8+CDD5r58+cbSeaNN95o9rxddaytrTVpaWnmxhtvNBs2bDBZWVmmT58+Zvz48bbXedSoUeYHP/hBs+1eWlrabBkv1fn73/++eemll8zWrVvNxo0bzdChQ82ll15qTpw40biM37ZzJHX223ZeuHCheeedd8zOnTvNzp07zQMPPGA6d+5stm7daozx3zaOpM5+28ZWCGwYueaaa8zYsWObPfaVr3zF/OY3v3GoRJGbMmWKueqqq0I+V19fb3r16mUee+yxxscqKytNSkqKefbZZ40xxhw/ftx07tzZvPbaa43LHDx40HTo0MG89957xhhjtm/fbiSZdevWNS6zdu1aI8ns2LEjAbUKr2XHbGcdFy1aZDp06GAOHjzYuMyrr75qkpOTTVlZWULqa0zrOhtzpgH7j//4j7Cv8Xqdi4uLjSSzYsUKY0wwtnPLOhvj/+1sjDEXXHCBmTVrViC2cYOGOhsTjG0crUCepqmurlZOTo4GDx7c7PHBgwcrOzvboVJFZ9euXerTp4/69++v//qv/9KePXskSXv37lVRUVGzuiUnJ+vb3/52Y91ycnJUU1PTbJk+ffooLS2tcZm1a9cqJSVF1157beMy1113nVJSUhxfR3bWce3atUpLS2v2i5Pf//73VVVVpZycnITWM5Tly5erZ8+euuyyy/SLX/xCxcXFjc95vc5lZWWSpAsvvFBSMLZzyzo38Ot2rqur02uvvaaTJ08qIyMjENu4ZZ0b+HUbxyqmX+31upKSEtXV1bX6cb/U1NRWP+rnRtdee61efvllXXbZZTp8+LAeeeQRDRw4UNu2bWssf6i67d+/X5JUVFSkLl266IILLmi1TMPri4qK1LNnz1af3bNnT8fXkZ11LCoqavU5F1xwgbp06WL7ehgyZIj+8z//U/369dPevXv1u9/9TjfddJNycnKUnJzs6TobYzRp0iR961vfUlpaWmM5GsrflF+2c6g6S/7czlu2bFFGRoYqKyv1uc99Tm+88Ya++tWvNnaaftzG4eos+XMbxyuQYaRBUlJSs38bY1o95kZDhgxp/P8rrrhCGRkZ+uIXv6i//vWvjZOgYqlby2VCLe+mdWRXHd2yHoYPH974/2lpaRowYID69eund955Rz/+8Y/Dvs4LdR4/frw2b96s1atXt3rOr9s5XJ39uJ2//OUva+PGjTp+/Ljmz5+vUaNGacWKFWHL4YdtHK7OX/3qV325jeMVyNM0PXr0UMeOHVslw+Li4lYp0gvOPfdcXXHFFdq1a1fjVTVt1a1Xr16qrq7WsWPH2lzm8OHDrT7ryJEjjq8jO+vYq1evVp9z7Ngx1dTUOL4eevfurX79+mnXrl2SvFvnu+++WwsXLtSyZct0ySWXND7u5+0crs6h+GE7d+nSRV/60pc0YMAAZWZm6qqrrtKTTz7p620crs6h+GEbxyuQYaRLly5KT09XVlZWs8ezsrI0cOBAh0oVu6qqKuXl5al3797q37+/evXq1axu1dXVWrFiRWPd0tPT1blz52bLFBYWauvWrY3LZGRkqKysTB999FHjMh9++KHKysocX0d21jEjI0Nbt25VYWFh4zJLlixRcnKy0tPTE1rP9pSWlqqgoEC9e/eW5L06G2M0fvx4LViwQB988IH69+/f7Hk/buf26hyK17dzKMYYVVVV+XIbh9NQ51D8uI2jZsMkWVdquLT3xRdfNNu3bzcTJ0405557rtm3b5/TRWvXvffea5YvX2727Nlj1q1bZ2655RbTrVu3xrI/9thjJiUlxSxYsMBs2bLF/OQnPwl5qdwll1xili5dajZs2GBuuummkJeNXXnllWbt2rVm7dq15oorrrDt0t6KigqTm5trcnNzjSQzbdo0k5ub23jptV11bLg07uabbzYbNmwwS5cuNZdccklCLo1rq84VFRXm3nvvNdnZ2Wbv3r1m2bJlJiMjw1x88cWerfMvf/lLk5KSYpYvX97sEsdTp041LuO37dxenf24nSdPnmxWrlxp9u7dazZv3mweeOAB06FDB7NkyRJjjP+2cXt19uM2tkJgw4gxxjzzzDOmX79+pkuXLuYb3/hGs8vr3KzhOvzOnTubPn36mB//+Mdm27Ztjc/X19ebKVOmmF69epnk5GRzww03mC1btjR7j9OnT5vx48ebCy+80JxzzjnmlltuMfn5+c2WKS0tNT/96U9Nt27dTLdu3cxPf/pTc+zYMTuqaJYtW2YktfobNWqU7XXcv3+/GTp0qDnnnHPMhRdeaMaPH28qKyttrfOpU6fM4MGDzUUXXWQ6d+5sLr30UjNq1KhW9fFSnUPVVZJ56aWXGpfx23Zur85+3M4///nPG9vZiy66yNx8882NQcQY/23j9ursx21shSRjjLFvHAYAAKC5QM4ZAQAA7kEYAQAAjiKMAAAARxFGAACAowgjAADAUYQRAADgKMIIAABwFGEEAAA4ijACAAAcRRgBAACOIowAAABH/T8N5CwyCqzeawAAAABJRU5ErkJggg==\n", + "image/png": "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QxDqHPWlvdKZm5796U9/UmFhodLS0vTnP/9ZN9xwgyTpzjvv1L59+7R8+fLG5VesWKF77rlH27ZtU58+fXT//fc3hhcAABBsMYURAAAAq/DbNAAAwFGEEQAA4CjCCAAAcBRhBAAAOCrQYWTGjBnq37+/unbtqvT0dK1a1fpn291o6tSpSkpKavbXq1evxueNMZo6dar69Omjc845R9/5zne0bdu2Zu9RVVWlu+++Wz169NC5556rH/3oRzpw4ECzZY4dO6YRI0YoJSVFKSkpGjFihI4fP25HFbVy5UoNGzZMffr0UVJSkt58881mz9tZx/z8fA0bNkznnnuuevTooQkTJqi6utr2Ot95552ttvt1113n2TpnZmbqm9/8prp166aePXvq1ltv1c6dO5st47ftHEmd/badZ86cqSuvvLLx7qEZGRl69913G5/32zaOpM5+28aWaO/H8fzqtddeM507dzYvvPCC2b59u/nv//5vc+6555r9+/c7XbR2TZkyxXzta18zhYWFjX/FxcWNzz/22GOmW7duZv78+WbLli1m+PDhpnfv3qa8vLxxmbFjx5qLL77YZGVlmQ0bNpgbb7zRXHXVVaa2trZxmR/84AcmLS3NZGdnm+zsbJOWlmZuueUWW+q4aNEi8+CDD5r58+cbSeaNN95o9rxddaytrTVpaWnmxhtvNBs2bDBZWVmmT58+Zvz48bbXedSoUeYHP/hBs+1eWlrabBkv1fn73/++eemll8zWrVvNxo0bzdChQ82ll15qTpw40biM37ZzJHX223ZeuHCheeedd8zOnTvNzp07zQMPPGA6d+5stm7daozx3zaOpM5+28ZWCGwYueaaa8zYsWObPfaVr3zF/OY3v3GoRJGbMmWKueqqq0I+V19fb3r16mUee+yxxscqKytNSkqKefbZZ40xxhw/ftx07tzZvPbaa43LHDx40HTo0MG89957xhhjtm/fbiSZdevWNS6zdu1aI8ns2LEjAbUKr2XHbGcdFy1aZDp06GAOHjzYuMyrr75qkpOTTVlZWULqa0zrOhtzpgH7j//4j7Cv8Xqdi4uLjSSzYsUKY0wwtnPLOhvj/+1sjDEXXHCBmTVrViC2cYOGOhsTjG0crUCepqmurlZOTo4GDx7c7PHBgwcrOzvboVJFZ9euXerTp4/69++v//qv/9KePXskSXv37lVRUVGzuiUnJ+vb3/52Y91ycnJUU1PTbJk+ffooLS2tcZm1a9cqJSVF1157beMy1113nVJSUhxfR3bWce3atUpLS2v2i5Pf//73VVVVpZycnITWM5Tly5erZ8+euuyyy/SLX/xCxcXFjc95vc5lZWWSpAsvvFBSMLZzyzo38Ot2rqur02uvvaaTJ08qIyMjENu4ZZ0b+HUbxyqmX+31upKSEtXV1bX6cb/U1NRWP+rnRtdee61efvllXXbZZTp8+LAeeeQRDRw4UNu2bWssf6i67d+/X5JUVFSkLl266IILLmi1TMPri4qK1LNnz1af3bNnT8fXkZ11LCoqavU5F1xwgbp06WL7ehgyZIj+8z//U/369dPevXv1u9/9TjfddJNycnKUnJzs6TobYzRp0iR961vfUlpaWmM5GsrflF+2c6g6S/7czlu2bFFGRoYqKyv1uc99Tm+88Ya++tWvNnaaftzG4eos+XMbxyuQYaRBUlJSs38bY1o95kZDhgxp/P8rrrhCGRkZ+uIXv6i//vWvjZOgYqlby2VCLe+mdWRXHd2yHoYPH974/2lpaRowYID69eund955Rz/+8Y/Dvs4LdR4/frw2b96s1atXt3rOr9s5XJ39uJ2//OUva+PGjTp+/Ljmz5+vUaNGacWKFWHL4YdtHK7OX/3qV325jeMVyNM0PXr0UMeOHVslw+Li4lYp0gvOPfdcXXHFFdq1a1fjVTVt1a1Xr16qrq7WsWPH2lzm8OHDrT7ryJEjjq8jO+vYq1evVp9z7Ngx1dTUOL4eevfurX79+mnXrl2SvFvnu+++WwsXLtSyZct0ySWXND7u5+0crs6h+GE7d+nSRV/60pc0YMAAZWZm6qqrrtKTTz7p620crs6h+GEbxyuQYaRLly5KT09XVlZWs8ezsrI0cOBAh0oVu6qqKuXl5al3797q37+/evXq1axu1dXVWrFiRWPd0tPT1blz52bLFBYWauvWrY3LZGRkqKysTB999FHjMh9++KHKysocX0d21jEjI0Nbt25VYWFh4zJLlixRcnKy0tPTE1rP9pSWlqqgoEC9e/eW5L06G2M0fvx4LViwQB988IH69+/f7Hk/buf26hyK17dzKMYYVVVV+XIbh9NQ51D8uI2jZsMkWVdquLT3xRdfNNu3bzcTJ0405557rtm3b5/TRWvXvffea5YvX2727Nlj1q1bZ2655RbTrVu3xrI/9thjJiUlxSxYsMBs2bLF/OQnPwl5qdwll1xili5dajZs2GBuuummkJeNXXnllWbt2rVm7dq15oorrrDt0t6KigqTm5trcnNzjSQzbdo0k5ub23jptV11bLg07uabbzYbNmwwS5cuNZdccklCLo1rq84VFRXm3nvvNdnZ2Wbv3r1m2bJlJiMjw1x88cWerfMvf/lLk5KSYpYvX97sEsdTp041LuO37dxenf24nSdPnmxWrlxp9u7dazZv3mweeOAB06FDB7NkyRJjjP+2cXt19uM2tkJgw4gxxjzzzDOmX79+pkuXLuYb3/hGs8vr3KzhOvzOnTubPn36mB//+Mdm27Ztjc/X19ebKVOmmF69epnk5GRzww03mC1btjR7j9OnT5vx48ebCy+80JxzzjnmlltuMfn5+c2WKS0tNT/96U9Nt27dTLdu3cxPf/pTc+zYMTuqaJYtW2YktfobNWqU7XXcv3+/GTp0qDnnnHPMhRdeaMaPH28qKyttrfOpU6fM4MGDzUUXXWQ6d+5sLr30UjNq1KhW9fFSnUPVVZJ56aWXGpfx23Zur85+3M4///nPG9vZiy66yNx8882NQcQY/23j9ursx21shSRjjLFvHAYAAKC5QM4ZAQAA7kEYAQAAjiKMAAAARxFGAACAowgjAADAUYQRAADgKMIIAABwFGEEAAA4ijACAAAcRRgBAACOIowAAABH/T8N5CwyCqzeawAAAABJRU5ErkJggg==", "text/plain": [ "
" ] @@ -1279,7 +1268,7 @@ "outputs": [ { "data": { - "image/png": "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3ilFesGpp56qCy+8ULt37/Y/VdNV3QYOHKiGhgYdOXKky2EOHjzYaV6HDh2yvoziWceBAwd2ms+RI0fU2NhofTkMGjRIQ4cO1e7duyV5t87333+/3n33XX300Uc699xz/Z8n8noOVudAEmE99+3bV1/4whc0fPhwZWdn6+KLL9bvf//7hF7HweocSCKs4+5KyjDSt29fZWRkKCcnp93nOTk5GjFihKVSRa++vl4FBQUaNGiQhg0bpoEDB7arW0NDg5YtW+avW0ZGhvr06dNumNLSUm3dutU/TGZmpnw+n9atW+cfZu3atfL5fNaXUTzrmJmZqa1bt6q0tNQ/zOLFi5WSkqKMjIyY1jOUyspKlZSUaNCgQZK8V2djjMaNG6f58+frww8/1LBhw9p9n4jrOVSdA/H6eg7EGKP6+vqEXMfBtNY5kERcxxGLw02yrtT6aO+MGTPM9u3bzQMPPGBOPfVUs2/fPttFC+mhhx4yS5cuNXv37jVr1qwxN998sznttNP8ZX/mmWdMamqqmT9/vtmyZYv5/ve/H/BRuXPPPdcsWbLEbNy40Vx33XUBHxu76KKLTG5ursnNzTUXXnhh3B7trampMfn5+SY/P99IMpMnTzb5+fn+R6/jVcfWR+Ouv/56s3HjRrNkyRJz7rnnxuTRuK7qXFNTYx566CGzevVqU1hYaD766COTmZlpzjnnHM/W+cc//rFJTU01S5cubfeIY21trX+YRFvPoeqciOt54sSJZvny5aawsNB8/PHH5tFHHzU9e/Y0ixcvNsYk3joOVedEXMdOSNowYowxL730khk6dKjp27evueSSS9o9Xudmrc/h9+nTxwwePNh8+9vfNtu2bfN/39LSYiZNmmQGDhxoUlJSzNVXX222bNnSbhrHjx8348aNM2eccYY55ZRTzM0332yKi4vbDVNZWWl+8IMfmNNOO82cdtpp5gc/+IE5cuRIPKpoPvroIyOp09/YsWPjXseioiJz0003mVNOOcWcccYZZty4caauri6uda6trTUjR440Z511lunTp48577zzzNixYzvVx0t1DlRXSea1117zD5No6zlUnRNxPd91113+dvass84y119/vT+IGJN46zhUnRNxHTuhhzHGxK8fBgAAoL2kvGcEAAC4B2EEAABYRRgBAABWEUYAAIBVhBEAAGAVYQQAAFhFGAEAAFYRRgAAgFWEEQAAYBVhBAAAWEUYAQAAVv1/syesQD3AFYkAAAAASUVORK5CYII=\n", + "image/png": "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3ilFesGpp56qCy+8ULt37/Y/VdNV3QYOHKiGhgYdOXKky2EOHjzYaV6HDh2yvoziWceBAwd2ms+RI0fU2NhofTkMGjRIQ4cO1e7duyV5t87333+/3n33XX300Uc699xz/Z8n8noOVudAEmE99+3bV1/4whc0fPhwZWdn6+KLL9bvf//7hF7HweocSCKs4+5KyjDSt29fZWRkKCcnp93nOTk5GjFihKVSRa++vl4FBQUaNGiQhg0bpoEDB7arW0NDg5YtW+avW0ZGhvr06dNumNLSUm3dutU/TGZmpnw+n9atW+cfZu3atfL5fNaXUTzrmJmZqa1bt6q0tNQ/zOLFi5WSkqKMjIyY1jOUyspKlZSUaNCgQZK8V2djjMaNG6f58+frww8/1LBhw9p9n4jrOVSdA/H6eg7EGKP6+vqEXMfBtNY5kERcxxGLw02yrtT6aO+MGTPM9u3bzQMPPGBOPfVUs2/fPttFC+mhhx4yS5cuNXv37jVr1qwxN998sznttNP8ZX/mmWdMamqqmT9/vtmyZYv5/ve/H/BRuXPPPdcsWbLEbNy40Vx33XUBHxu76KKLTG5ursnNzTUXXnhh3B7trampMfn5+SY/P99IMpMnTzb5+fn+R6/jVcfWR+Ouv/56s3HjRrNkyRJz7rnnxuTRuK7qXFNTYx566CGzevVqU1hYaD766COTmZlpzjnnHM/W+cc//rFJTU01S5cubfeIY21trX+YRFvPoeqciOt54sSJZvny5aawsNB8/PHH5tFHHzU9e/Y0ixcvNsYk3joOVedEXMdOSNowYowxL730khk6dKjp27evueSSS9o9Xudmrc/h9+nTxwwePNh8+9vfNtu2bfN/39LSYiZNmmQGDhxoUlJSzNVXX222bNnSbhrHjx8348aNM2eccYY55ZRTzM0332yKi4vbDVNZWWl+8IMfmNNOO82cdtpp5gc/+IE5cuRIPKpoPvroIyOp09/YsWPjXseioiJz0003mVNOOcWcccYZZty4caauri6uda6trTUjR440Z511lunTp48577zzzNixYzvVx0t1DlRXSea1117zD5No6zlUnRNxPd91113+dvass84y119/vT+IGJN46zhUnRNxHTuhhzHGxK8fBgAAoL2kvGcEAAC4B2EEAABYRRgBAABWEUYAAIBVhBEAAGAVYQQAAFhFGAEAAFYRRgAAgFWEEQAAYBVhBAAAWEUYAQAAVv1/syesQD3AFYkAAAAASUVORK5CYII=", "text/plain": [ "
" ] diff --git a/openwakeword/__init__.py b/openwakeword/__init__.py index d49e9e2..6ad8f3f 100755 --- a/openwakeword/__init__.py +++ b/openwakeword/__init__.py @@ -5,24 +5,48 @@ __all__ = ['Model', 'VAD', 'train_custom_verifier'] -models = { +FEATURE_MODELS = { + "embedding": { + "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/embedding_model.tflite"), + "download_url": "https://github.com/dscripka/openWakeWord/releases/download/v0.5.1/embedding_model.tflite" + }, + "melspectrogram": { + "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/melspectrogram.tflite"), + "download_url": "https://github.com/dscripka/openWakeWord/releases/download/v0.5.1/melspectrogram.tflite" + } +} + +VAD_MODELS = { + "silero_vad": { + "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/silero_vad.onnx"), + "download_url": "https://github.com/dscripka/openWakeWord/releases/download/v0.5.1/silero_vad.onnx" + } +} + +MODELS = { "alexa": { - "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/alexa_v0.1.tflite") + "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/alexa_v0.1.tflite"), + "download_url": "https://github.com/dscripka/openWakeWord/releases/download/v0.5.1/alexa_v0.1.tflite" }, "hey_mycroft": { - "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/hey_mycroft_v0.1.tflite") + "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/hey_mycroft_v0.1.tflite"), + "download_url": "https://github.com/dscripka/openWakeWord/releases/download/v0.5.1/hey_mycroft_v0.1.tflite" }, "hey_jarvis": { - "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/hey_jarvis_v0.1.tflite") + "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/hey_jarvis_v0.1.tflite"), + "download_url": "https://github.com/dscripka/openWakeWord/releases/download/v0.5.1/hey_jarvis_v0.1.tflite" }, "hey_rhasspy": { - "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/hey_rhasspy_v0.1.tflite") + "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/hey_rhasspy_v0.1.tflite"), + "download_url": "https://github.com/dscripka/openWakeWord/releases/download/v0.5.1/hey_rhasspy_v0.1.tflite" }, "timer": { - "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/timer_v0.1.tflite") + "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/timer_v0.1.tflite"), + "download_url": "https://github.com/dscripka/openWakeWord/releases/download/v0.5.1/timer_v0.1.tflite" }, "weather": { - "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/weather_v0.1.tflite") + "model_path": os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources/models/weather_v0.1.tflite"), + "download_url": "https://github.com/dscripka/openWakeWord/releases/download/v0.5.1/weather_v0.1.tflite" } } @@ -40,6 +64,6 @@ def get_pretrained_model_paths(inference_framework="tflite"): if inference_framework == "tflite": - return [models[i]["model_path"] for i in models.keys()] + return [MODELS[i]["model_path"] for i in MODELS.keys()] elif inference_framework == "onnx": - return [models[i]["model_path"].replace(".tflite", ".onnx") for i in models.keys()] + return [MODELS[i]["model_path"].replace(".tflite", ".onnx") for i in MODELS.keys()] diff --git a/openwakeword/data.py b/openwakeword/data.py index 7c34549..c43da5d 100755 --- a/openwakeword/data.py +++ b/openwakeword/data.py @@ -15,13 +15,19 @@ # imports from multiprocessing.pool import ThreadPool import os +import re +import logging from functools import partial from pathlib import Path import random from tqdm import tqdm from typing import List, Tuple import numpy as np +import itertools +import pronouncing import torch +import audiomentations +import torch_audiomentations from numpy.lib.format import open_memmap from speechbrain.dataio.dataio import read_audio from speechbrain.processing.signal_processing import reverberate @@ -445,7 +451,7 @@ def mix_clips_batch( # Apply volume augmentation if volume_augmentation: volume_levels = np.random.uniform(0.02, 1.0, mixed_clips_batch.shape[0]) - mixed_clips_batch = (volume_levels/mixed_clips_batch.max(axis=1)[0])[..., None]*mixed_clips_batch + mixed_clips_batch = (volume_levels/mixed_clips_batch.max(dim=1)[0])[..., None]*mixed_clips_batch else: # Normalize clips only if max value is outside of [-1, 1] abs_max, _ = torch.max( @@ -457,7 +463,7 @@ def mix_clips_batch( mixed_clips_batch = (mixed_clips_batch.numpy()*32767).astype(np.int16) # Remove any clips that are silent (happens rarely when mixing/reverberating) - error_index = np.where(mixed_clips_batch.max(axis=1) != 0)[0] + error_index = torch.from_numpy(np.where(mixed_clips_batch.max(dim=1) != 0)[0]) mixed_clips_batch = mixed_clips_batch[error_index] labels_batch = labels_batch[error_index] sequence_labels_batch = sequence_labels_batch[error_index] @@ -548,6 +554,181 @@ def apply_reverb(x, rir_files): return reverbed.numpy() +# Alternate data augmentation method using audiomentations library (https://pypi.org/project/audiomentations/) +def augment_clips( + clip_paths: List[str], + total_length: int, + sr: int = 16000, + batch_size: int = 128, + augmentation_probabilities: dict = { + "SevenBandParametricEQ": 0.25, + "TanhDistortion": 0.25, + "PitchShift": 0.25, + "BandStopFilter": 0.25, + "AddColoredNoise": 0.25, + "AddBackgroundNoise": 0.75, + "Gain": 1.0, + "RIR": 0.5 + }, + background_clip_paths: List[str] = [], + RIR_paths: List[str] = [] + ): + """ + Applies audio augmentations to the specified audio clips, returning a generator that applies + the augmentations in batches to support very large quantities of input audio files. + + The augmentations (and probabilities) are chosen from experience based on training openWakeWord models, as well + as for the efficiency of the augmentation. The individual probabilities of each augmentation may be adjusted + with the "augmentation_probabilities" argument. + + Args: + clip_paths (List[str]) = The input audio files (as paths) to augment. Note that these should be shorter + than the "total_length" argument, else they will be truncated. + total_length (int): The total length of audio files (in samples) after augmentation. All input clips + will be left-padded with silence to reach this size, with between 0 and 200 ms + of other audio after the end of the original input clip. + sr (int): The sample size of the input audio files + batch_size (int): The number of audio files to augment at once. + augmentation_probabilities (dict): The individual probabilities of each augmentation. If all probabilities + are zero, the input audio files will simply be padded with silence. THe + default values are: + + { + "SevenBandParametricEQ": 0.25, + "TanhDistortion": 0.25, + "PitchShift": 0.25, + "BandStopFilter": 0.25, + "AddColoredNoise": 0.25, + "AddBackgroundNoise": 0.75, + "Gain": 1.0, + "RIR": 0.5 + } + + background_clip_paths (List[str]) = The paths to background audio files to mix with the input files + RIR_paths (List[str]) = The paths to room impulse response functions (RIRs) to convolve with the input files, + producing a version of the input clip with different acoustic characteristics. + + Returns: + ndarray: A batch of augmented audio clips of size (batch_size, total_length) + """ + # Define augmentations + + # First pass augmentations that can't be done as a batch + augment1 = audiomentations.Compose([ + audiomentations.SevenBandParametricEQ(min_gain_db=-6, max_gain_db=6, p=augmentation_probabilities["SevenBandParametricEQ"]), + audiomentations.TanhDistortion( + min_distortion=0.0001, + max_distortion=0.10, + p=augmentation_probabilities["TanhDistortion"] + ), + ]) + + # Augmentations that can be done as a batch + if background_clip_paths != []: + augment2 = torch_audiomentations.Compose([ + torch_audiomentations.PitchShift( + min_transpose_semitones=-3, + max_transpose_semitones=3, + p=augmentation_probabilities["PitchShift"], + sample_rate=16000, + mode="per_batch" + ), + torch_audiomentations.BandStopFilter(p=augmentation_probabilities["BandStopFilter"], mode="per_batch"), + torch_audiomentations.AddColoredNoise( + min_snr_in_db=10, max_snr_in_db=30, + min_f_decay=-1, max_f_decay=2, p=augmentation_probabilities["AddColoredNoise"], + mode="per_batch" + ), + torch_audiomentations.AddBackgroundNoise( + p=augmentation_probabilities["AddBackgroundNoise"], + background_paths=background_clip_paths, + min_snr_in_db=-10, + max_snr_in_db=15, + mode="per_batch" + ), + torch_audiomentations.Gain(max_gain_in_db=0, p=augmentation_probabilities["Gain"]), + ]) + else: + augment2 = torch_audiomentations.Compose([ + torch_audiomentations.PitchShift( + min_transpose_semitones=-3, + max_transpose_semitones=3, + p=augmentation_probabilities["PitchShift"], + sample_rate=16000, + mode="per_batch" + ), + torch_audiomentations.BandStopFilter(p=augmentation_probabilities["BandStopFilter"], mode="per_batch"), + torch_audiomentations.AddColoredNoise( + min_snr_in_db=10, max_snr_in_db=30, + min_f_decay=-1, max_f_decay=2, p=augmentation_probabilities["AddColoredNoise"], + mode="per_batch" + ), + torch_audiomentations.Gain(max_gain_in_db=0, p=augmentation_probabilities["Gain"]), + ]) + + # Iterate through all clips and augment them + for i in range(0, len(clip_paths), batch_size): + batch = clip_paths[i:i+batch_size] + augmented_clips = [] + for clip in batch: + clip_data, clip_sr = torchaudio.load(clip) + clip_data = clip_data[0] + if clip_data.shape[0] > total_length: + clip_data = clip_data[0:total_length] + + if clip_sr != sr: + raise ValueError("Error! Clip does not have the correct sample rate!") + + clip_data = create_fixed_size_clip(clip_data, total_length, clip_sr) + + # Do first pass augmentations + augmented_clips.append(torch.from_numpy(augment1(samples=clip_data, sample_rate=sr))) + + # Do second pass augmentations + device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') + augmented_batch = augment2(samples=torch.vstack(augmented_clips).unsqueeze(dim=1).to(device), sample_rate=sr).squeeze(axis=1) + + # Do reverberation + if augmentation_probabilities["RIR"] >= np.random.random() and RIR_paths != []: + rir_waveform, sr = torchaudio.load(random.choice(RIR_paths)) + augmented_batch = reverberate(augmented_batch.cpu(), rir_waveform, rescale_amp="avg") + + # yield batch of 16-bit PCM audio data + yield (augmented_batch.cpu().numpy()*32767).astype(np.int16) + + +def create_fixed_size_clip(x, n_samples, sr=16000, start=None, end_jitter=.200): + """ + Create a fixed-length clip of the specified size by padding an input clip with zeros + Optionally specify the start/end position of the input clip, or let it be chosen randomly. + + Args: + x (ndarray): The input audio to pad to a fixed size + n_samples (int): The total number of samples for the fixed length clip + sr (int): The sample rate of the audio + start (int): The start position of the clip in the fixed length output, in samples (default: None) + end_jitter (float): The time (in seconds) from the end of the fixed length output + that the input clip should end, if `start` is None. + + Returns: + ndarray: A new array of audio data of the specified length + """ + dat = np.zeros(n_samples) + end_jitter = int(np.random.uniform(0, end_jitter)*sr) + if start is None: + start = max(0, n_samples - (int(len(x))+end_jitter)) + + if len(x) > n_samples: + if np.random.random() >= 0.5: + dat = x[0:n_samples].numpy() + else: + dat = x[-n_samples:].numpy() + else: + dat[start:start+len(x)] = x + + return dat + + # Load batches of data from mmaped numpy arrays class mmap_batch_generator: """ @@ -645,7 +826,6 @@ def __next__(self): # Restart at zeroth index if an array reaches the end if self.data_counter[label] >= self.shapes[label][0]: self.data_counter[label] = 0 - # self.data[label] = np.load(self.data_files[label], mmap_mode='r') # Get data from mmaped file x = self.data[label][self.data_counter[label]:self.data_counter[label]+n] @@ -697,7 +877,7 @@ def trim_mmap(mmap_path): mmap_file2 = open_memmap(output_file2, mode='w+', dtype=np.float32, shape=(N_new, mmap_file1.shape[1], mmap_file1.shape[2])) - for i in tqdm(range(0, mmap_file1.shape[0], 1024), total=mmap_file1.shape[0]//1024): + for i in tqdm(range(0, mmap_file1.shape[0], 1024), total=mmap_file1.shape[0]//1024, desc="Trimming empty rows"): if i + 1024 > N_new: mmap_file2[i:N_new] = mmap_file1[i:N_new].copy() mmap_file2.flush() @@ -710,3 +890,126 @@ def trim_mmap(mmap_path): # Rename new mmap file to match original os.rename(output_file2, mmap_path) + + +# Generate words that sound similar ("adversarial") to the input phrase using phoneme overlap +def generate_adversarial_texts(input_text: str, N: int, include_partial_phrase: float = 0, include_input_words: float = 0): + """ + Generate adversarial words and phrases based on phoneme overlap. + Currently only works for english texts. + Note that homophones are excluded, as this wouldn't actually be an adversarial example for the input text. + + Args: + input_text (str): The target text for adversarial phrases + N (int): The total number of adversarial texts to return. Uses sampling, + so not all possible combinations will be included and some duplicates + may be present. + include_partial_phrase (float): The probability of returning a number of words less than the input + text (but always between 1 and the number of input words) + include_input_words (float): The probability of including individual input words in the adversarial + texts when the input text consists of multiple words. For example, + if the `input_text` was "ok google", then setting this value > 0.0 + will allow for adversarial texts like "ok noodle", versus the word "ok" + never being present in the adversarial texts. + + Returns: + list: A list of strings corresponding to words and phrases that are phonetically similar (but not identical) + to the input text. + """ + # Get phonemes for english vowels (CMUDICT labels) + vowel_phones = ["AA", "AE", "AH", "AO", "AW", "AX", "AXR", "AY", "EH", "ER", "EY", "IH", "IX", "IY", "OW", "OY", "UH", "UW", "UX"] + + word_phones = [] + input_text_phones = [pronouncing.phones_for_word(i) for i in input_text.split()] + + # Download phonemizer model for OOV words, if needed + if [] in input_text_phones: + phonemizer_mdl_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources", "en_us_cmudict_forward.pt") + if not os.path.exists(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources")): + os.mkdir(os.path.join(os.path.dirname(os.path.abspath(__file__)), "resources")) + if not os.path.exists(phonemizer_mdl_path): + logging.warning("Downloading phonemizer model from DeepPhonemizer library...") + import requests + file_url = "https://public-asai-dl-models.s3.eu-central-1.amazonaws.com/DeepPhonemizer/en_us_cmudict_forward.pt" + r = requests.get(file_url, stream=True) + with open(phonemizer_mdl_path, "wb") as f: + for chunk in r.iter_content(chunk_size=2048): + if chunk: + f.write(chunk) + + # Create phonemizer object + from dp.phonemizer import Phonemizer + phonemizer = Phonemizer.from_checkpoint(phonemizer_mdl_path) + + for phones, word in zip(input_text_phones, input_text.split()): + if phones != []: + word_phones.extend(phones) + elif phones == []: + logging.warning(f"The word '{word}' was not found in the pronunciation dictionary! " + "Using the DeepPhonemizer library to predict the phonemes.") + phones = phonemizer(word, lang='en_us') + logging.warning(f"Phones for '{word}': {phones}") + word_phones.append(re.sub(r"[\]|\[]", "", re.sub(r"\]\[", " ", phones))) + elif isinstance(phones[0], list): + logging.warning(f"There are multiple pronunciations for the word '{word}'.") + word_phones.append(phones[0]) + + # add all possible lexical stresses to vowels + word_phones = [re.sub('|'.join(vowel_phones), lambda x: str(x.group(0)) + '[0|1|2]', re.sub(r'\d+', '', i)) for i in word_phones] + + adversarial_phrases = [] + for phones, word in zip(word_phones, input_text.split()): + query_exps = [] + phones = phones.split() + adversarial_words = [] + if len(phones) <= 2: + query_exps.append(" ".join(phones)) + else: + query_exps.extend(phoneme_replacement(phones, max_replace=max(0, len(phones)-2), replace_char="(.){1,3}")) + + for query in query_exps: + matches = pronouncing.search(query) + matches_phones = [pronouncing.phones_for_word(i)[0] for i in matches] + allowed_matches = [i for i, j in zip(matches, matches_phones) if j != phones] + adversarial_words.extend([i for i in allowed_matches if word.lower() != i]) + + if adversarial_words != []: + adversarial_phrases.append(adversarial_words) + + # Build combinations for final output + adversarial_texts = [] + for i in range(N): + txts = [] + for j, k in zip(adversarial_phrases, input_text.split()): + if np.random.random() > (1 - include_input_words): + txts.append(k) + else: + txts.append(np.random.choice(j)) + + if include_partial_phrase is not None and len(input_text.split()) > 1 and np.random.random() <= include_partial_phrase: + n_words = np.random.randint(1, len(input_text.split())+1) + adversarial_texts.append(" ".join(np.random.choice(txts, size=n_words, replace=False))) + else: + adversarial_texts.append(" ".join(txts)) + + # Remove any exact matches to input phrase + adversarial_texts = [i for i in adversarial_texts if i != input_text] + + return adversarial_texts + + +def phoneme_replacement(input_chars, max_replace, replace_char='"(.){1,3}"'): + results = [] + chars = list(input_chars) + + # iterate over the number of characters to replace (1 to max_replace) + for r in range(1, max_replace+1): + # get all combinations for a fixed r + comb = itertools.combinations(range(len(chars)), r) + for indices in comb: + chars_copy = chars.copy() + for i in indices: + chars_copy[i] = replace_char + results.append(' '.join(chars_copy)) + + return results diff --git a/openwakeword/model.py b/openwakeword/model.py index 46f603a..6029963 100755 --- a/openwakeword/model.py +++ b/openwakeword/model.py @@ -67,7 +67,7 @@ def __init__( with VAD scores above the threshold will be returned. The default value (0), disables voice activity detection entirely. custom_verifier_models (dict): A dictionary of paths to custom verifier models, where - the keys are the model names (corresponding to the openwakeword.models + the keys are the model names (corresponding to the openwakeword.MODELS attribute) and the values are the filepaths of the custom verifier models. custom_verifier_threshold (float): The score threshold to use a custom verifier model. If the score @@ -85,7 +85,7 @@ def __init__( wakeword_model_names = [] if wakeword_models == []: wakeword_models = pretrained_model_paths - wakeword_model_names = list(openwakeword.models.keys()) + wakeword_model_names = list(openwakeword.MODELS.keys()) elif len(wakeword_models) >= 1: for ndx, i in enumerate(wakeword_models): if os.path.exists(i): @@ -224,10 +224,13 @@ def get_parent_model_from_label(self, label): return parent_model def reset(self): - """Reset the prediction buffer""" + """Reset the prediction and audio feature buffers. Useful for re-initializing the model, though may not be efficient + when called too frequently.""" self.prediction_buffer = defaultdict(partial(deque, maxlen=30)) + self.preprocessor.reset() - def predict(self, x: np.ndarray, patience: dict = {}, threshold: dict = {}, timing: bool = False): + def predict(self, x: np.ndarray, patience: dict = {}, + threshold: dict = {}, debounce_time: float = 0.0, timing: bool = False): """Predict with all of the wakeword models on the input audio frames Args: @@ -242,9 +245,11 @@ def predict(self, x: np.ndarray, patience: dict = {}, threshold: dict = {}, timi model names and the values are the number of frames. Can reduce false-positive detections at the cost of a lower true-positive rate. By default, this behavior is disabled. - threshold (dict): The threshold values to use when the `patience` behavior is enabled. + threshold (dict): The threshold values to use when the `patience` or `debounce_time` behavior is enabled. Must be provided as an a dictionary where the keys are the model names and the values are the thresholds. + debounce_time (float): The time (in seconds) to wait before returning another non-zero prediction + after a non-zero prediction. Can preven multiple detections of the same wake-word. timing (bool): Whether to return timing information of the models. Can be useful to debug and assess how efficiently models are running on the current hardware. @@ -322,27 +327,40 @@ def predict(self, x: np.ndarray, patience: dict = {}, threshold: dict = {}, timi )[0][-1] predictions[cls] = verifier_prediction - # Update prediction buffer, and zero predictions for first 5 frames during model initialization + # Zero predictions for first 5 frames during model initialization for cls in predictions.keys(): if len(self.prediction_buffer[cls]) < 5: predictions[cls] = 0.0 - self.prediction_buffer[cls].append(predictions[cls]) # Get timing information if timing: timing_dict["models"][mdl] = time.time() - model_start # Update scores based on thresholds or patience arguments - if patience != {}: + if patience != {} or debounce_time > 0: if threshold == {}: raise ValueError("Error! When using the `patience` argument, threshold " "values must be provided via the `threshold` argument!") + if patience != {} and debounce_time > 0: + raise ValueError("Error! The `patience` and `debounce_time` arguments cannot be used together!") for mdl in predictions.keys(): parent_model = self.get_parent_model_from_label(mdl) - if parent_model in patience.keys(): - scores = np.array(self.prediction_buffer[mdl])[-patience[parent_model]:] - if (scores >= threshold[parent_model]).sum() < patience[parent_model]: - predictions[mdl] = 0.0 + if predictions[mdl] != 0.0: + if parent_model in patience.keys(): + scores = np.array(self.prediction_buffer[mdl])[-patience[parent_model]:] + if (scores >= threshold[parent_model]).sum() < patience[parent_model]: + predictions[mdl] = 0.0 + elif debounce_time > 0: + if parent_model in threshold.keys(): + n_frames = int(np.ceil(debounce_time/(n_prepared_samples/16000))) + recent_predictions = np.array(self.prediction_buffer[mdl])[-n_frames:] + if predictions[mdl] >= threshold[parent_model] and \ + (recent_predictions >= threshold[parent_model]).sum() > 0: + predictions[mdl] = 0.0 + + # Update prediction buffer + for mdl in predictions.keys(): + self.prediction_buffer[mdl].append(predictions[mdl]) # (optionally) get voice activity detection scores and update model scores if self.vad_threshold > 0: diff --git a/openwakeword/resources/models/alexa_v0.1.onnx b/openwakeword/resources/models/alexa_v0.1.onnx deleted file mode 100644 index f52240e..0000000 --- a/openwakeword/resources/models/alexa_v0.1.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6ff566a01d12670e8d9e3c59da32651db1575d17272a601b7f8a39283dfbae3e -size 854246 diff --git a/openwakeword/resources/models/alexa_v0.1.tflite b/openwakeword/resources/models/alexa_v0.1.tflite deleted file mode 100644 index 5d516e2..0000000 --- a/openwakeword/resources/models/alexa_v0.1.tflite +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7333a317a790070a7f3432b81d9439c779481cc4ebd67c73da7174ea3cf48397 -size 855312 diff --git a/openwakeword/resources/models/embedding_model.onnx b/openwakeword/resources/models/embedding_model.onnx deleted file mode 100644 index 2c928ee..0000000 --- a/openwakeword/resources/models/embedding_model.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:70d164290c1d095d1d4ee149bc5e00543250a7316b59f31d056cff7bd3075c1f -size 1326578 diff --git a/openwakeword/resources/models/embedding_model.tflite b/openwakeword/resources/models/embedding_model.tflite deleted file mode 100644 index 52a5336..0000000 --- a/openwakeword/resources/models/embedding_model.tflite +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c0aea21eb84a4ce90a08c870da41b7a7173b45269e6a3207c71d67c40f3a59d8 -size 1330312 diff --git a/openwakeword/resources/models/hey_jarvis_v0.1.onnx b/openwakeword/resources/models/hey_jarvis_v0.1.onnx deleted file mode 100644 index a45f1de..0000000 --- a/openwakeword/resources/models/hey_jarvis_v0.1.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:94a13cfe60075b132f6a472e7e462e8123ee70861bc3fb58434a73712ee0d2cb -size 1271370 diff --git a/openwakeword/resources/models/hey_jarvis_v0.1.tflite b/openwakeword/resources/models/hey_jarvis_v0.1.tflite deleted file mode 100644 index d155242..0000000 --- a/openwakeword/resources/models/hey_jarvis_v0.1.tflite +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:14bff778604985e1b5c19f0f7bbe477a69cf281d8db34b232b3b972411f710e2 -size 1278912 diff --git a/openwakeword/resources/models/hey_mycroft_v0.1.onnx b/openwakeword/resources/models/hey_mycroft_v0.1.onnx deleted file mode 100644 index b9952b3..0000000 --- a/openwakeword/resources/models/hey_mycroft_v0.1.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c2a311e8fa1338de89c31b3b46dc4dffd4af2f9a8d6ddead48893c2d301b1f18 -size 857691 diff --git a/openwakeword/resources/models/hey_mycroft_v0.1.tflite b/openwakeword/resources/models/hey_mycroft_v0.1.tflite deleted file mode 100644 index 53b373c..0000000 --- a/openwakeword/resources/models/hey_mycroft_v0.1.tflite +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bf9e43136afd3ca323698820a6e32a47f885ef4c30a3b8b577ec71688a9d64d8 -size 860300 diff --git a/openwakeword/resources/models/hey_rhasspy_v0.1.onnx b/openwakeword/resources/models/hey_rhasspy_v0.1.onnx deleted file mode 100644 index dea9d9d..0000000 --- a/openwakeword/resources/models/hey_rhasspy_v0.1.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5a9b3ed3be2910e35780e097905aa9f35a9c10038df47914cf2b3ec4d670f6ea -size 204081 diff --git a/openwakeword/resources/models/hey_rhasspy_v0.1.tflite b/openwakeword/resources/models/hey_rhasspy_v0.1.tflite deleted file mode 100644 index 4fb9b6c..0000000 --- a/openwakeword/resources/models/hey_rhasspy_v0.1.tflite +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:01d2526b45068f565aa3849d6ec2b7abae099154fc1b496f9ef20de9ef241fe9 -size 416140 diff --git a/openwakeword/resources/models/melspectrogram.onnx b/openwakeword/resources/models/melspectrogram.onnx deleted file mode 100644 index be0643d..0000000 --- a/openwakeword/resources/models/melspectrogram.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ba2b0e0f8b7b875369a2c89cb13360ff53bac436f2895cced9f479fa65eb176f -size 1087958 diff --git a/openwakeword/resources/models/melspectrogram.tflite b/openwakeword/resources/models/melspectrogram.tflite deleted file mode 100644 index c0f0ab8..0000000 --- a/openwakeword/resources/models/melspectrogram.tflite +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:96fa0adccb6e8cf95cb14465409a1a2898ee4a96a85bb9ed3c7eb0e68bf163e8 -size 1092516 diff --git a/openwakeword/resources/models/silero_vad.onnx b/openwakeword/resources/models/silero_vad.onnx deleted file mode 100755 index 664012e..0000000 --- a/openwakeword/resources/models/silero_vad.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a35ebf52fd3ce5f1469b2a36158dba761bc47b973ea3382b3186ca15b1f5af28 -size 1807522 diff --git a/openwakeword/resources/models/timer_v0.1.onnx b/openwakeword/resources/models/timer_v0.1.onnx deleted file mode 100644 index 5603f7d..0000000 --- a/openwakeword/resources/models/timer_v0.1.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:371e44535470a29248b3b8f1bbbbaf2525c86417fd8f75c67fcf02ae0b9626df -size 1742475 diff --git a/openwakeword/resources/models/timer_v0.1.tflite b/openwakeword/resources/models/timer_v0.1.tflite deleted file mode 100644 index 11a7d50..0000000 --- a/openwakeword/resources/models/timer_v0.1.tflite +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:21d5b0267e97df64870b7aca312e2043ebed248d365698926a115a3694ff9626 -size 1743316 diff --git a/openwakeword/resources/models/weather_v0.1.onnx b/openwakeword/resources/models/weather_v0.1.onnx deleted file mode 100644 index 6c5599e..0000000 --- a/openwakeword/resources/models/weather_v0.1.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8441da8e746899e8d969528d5bad5651cdd563079c05962788f77753041f60e7 -size 1149158 diff --git a/openwakeword/resources/models/weather_v0.1.tflite b/openwakeword/resources/models/weather_v0.1.tflite deleted file mode 100644 index 95dab6e..0000000 --- a/openwakeword/resources/models/weather_v0.1.tflite +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4178991c7aeb76670f5a56559eb4129a6f3ae6207886db8bd8094fea7d362c3f -size 1150224 diff --git a/openwakeword/train.py b/openwakeword/train.py new file mode 100755 index 0000000..7e468bf --- /dev/null +++ b/openwakeword/train.py @@ -0,0 +1,902 @@ +import torch +from torch import optim, nn +import torchinfo +import torchmetrics +import copy +import os +import sys +import tempfile +import uuid +import numpy as np +import scipy +import collections +import argparse +import logging +from tqdm import tqdm +import yaml +from pathlib import Path +import openwakeword +from openwakeword.data import generate_adversarial_texts, augment_clips, mmap_batch_generator +from openwakeword.utils import compute_features_from_generator +from openwakeword.utils import AudioFeatures + + +# Base model class for an openwakeword model +class Model(nn.Module): + def __init__(self, n_classes=1, input_shape=(16, 96), model_type="dnn", + layer_dim=128, n_blocks=1, seconds_per_example=None): + super().__init__() + + # Store inputs as attributes + self.n_classes = n_classes + self.input_shape = input_shape + self.seconds_per_example = seconds_per_example + self.device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') + self.best_models = [] + self.best_model_scores = [] + self.best_val_fp = 1000 + self.best_val_accuracy = 0 + self.best_val_recall = 0 + self.best_train_recall = 0 + + # Define model (currently on fully-connected network supported) + if model_type == "dnn": + # self.model = nn.Sequential( + # nn.Flatten(), + # nn.Linear(input_shape[0]*input_shape[1], layer_dim), + # nn.LayerNorm(layer_dim), + # nn.ReLU(), + # nn.Linear(layer_dim, layer_dim), + # nn.LayerNorm(layer_dim), + # nn.ReLU(), + # nn.Linear(layer_dim, n_classes), + # nn.Sigmoid() if n_classes == 1 else nn.ReLU(), + # ) + + class FCNBlock(nn.Module): + def __init__(self, layer_dim): + super().__init__() + self.fcn_layer = nn.Linear(layer_dim, layer_dim) + self.relu = nn.ReLU() + self.layer_norm = nn.LayerNorm(layer_dim) + + def forward(self, x): + return self.relu(self.layer_norm(self.fcn_layer(x))) + + class Net(nn.Module): + def __init__(self, input_shape, layer_dim, n_blocks=1, n_classes=1): + super().__init__() + self.flatten = nn.Flatten() + self.layer1 = nn.Linear(input_shape[0]*input_shape[1], layer_dim) + self.relu1 = nn.ReLU() + self.layernorm1 = nn.LayerNorm(layer_dim) + self.blocks = nn.ModuleList([FCNBlock(layer_dim) for i in range(n_blocks)]) + self.last_layer = nn.Linear(layer_dim, n_classes) + self.last_act = nn.Sigmoid() if n_classes == 1 else nn.ReLU() + + def forward(self, x): + x = self.relu1(self.layernorm1(self.layer1(self.flatten(x)))) + for block in self.blocks: + x = block(x) + x = self.last_act(self.last_layer(x)) + return x + self.model = Net(input_shape, layer_dim, n_blocks=n_blocks, n_classes=n_classes) + elif model_type == "rnn": + class Net(nn.Module): + def __init__(self, input_shape, n_classes=1): + super().__init__() + self.layer1 = nn.LSTM(input_shape[-1], 64, num_layers=2, bidirectional=True, + batch_first=True, dropout=0.0) + self.layer2 = nn.Linear(64*2, n_classes) + self.layer3 = nn.Sigmoid() if n_classes == 1 else nn.ReLU() + + def forward(self, x): + out, h = self.layer1(x) + return self.layer3(self.layer2(out[:, -1])) + self.model = Net(input_shape, n_classes) + + # Define metrics + if n_classes == 1: + self.fp = lambda pred, y: (y-pred <= -0.5).sum() + self.recall = torchmetrics.Recall(task='binary') + self.accuracy = torchmetrics.Accuracy(task='binary') + else: + def multiclass_fp(p, y, threshold=0.5): + probs = torch.nn.functional.softmax(p, dim=1) + neg_ndcs = y == 0 + fp = (probs[neg_ndcs].argmax(axis=1) != 0 & (probs[neg_ndcs].max(axis=1)[0] > threshold)).sum() + return fp + + def positive_class_recall(p, y, negative_class_label=0, threshold=0.5): + probs = torch.nn.functional.softmax(p, dim=1) + pos_ndcs = y != 0 + rcll = (probs[pos_ndcs].argmax(axis=1) > 0 + & (probs[pos_ndcs].max(axis=1)[0] >= threshold)).sum()/pos_ndcs.sum() + return rcll + + def positive_class_accuracy(p, y, negative_class_label=0): + probs = torch.nn.functional.softmax(p, dim=1) + pos_preds = probs.argmax(axis=1) != negative_class_label + acc = (probs[pos_preds].argmax(axis=1) == y[pos_preds]).sum()/pos_preds.sum() + return acc + + self.fp = multiclass_fp + self.acc = positive_class_accuracy + self.recall = positive_class_recall + + self.n_fp = 0 + self.val_fp = 0 + + # Define logging dict (in-memory) + self.history = collections.defaultdict(list) + + # Define optimizer and loss + self.loss = torch.nn.functional.binary_cross_entropy if n_classes == 1 else nn.functional.cross_entropy + self.optimizer = optim.Adam(self.model.parameters(), lr=0.0001) + + def save_model(self, output_path): + """ + Saves the weights of a trained Pytorch model + """ + if self.n_classes == 1: + torch.save(self.model, output_path) + + def export_to_onnx(self, output_path, class_mapping=""): + obj = self + # Make simple model for export based on model structure + if self.n_classes == 1: + # Save ONNX model + torch.onnx.export(self.model.to("cpu"), torch.rand(self.input_shape)[None, ], output_path, + output_names=[class_mapping]) + + elif self.n_classes >= 1: + class M(nn.Module): + def __init__(self): + super().__init__() + + # Define model + self.model = obj.model.to("cpu") + + def forward(self, x): + return torch.nn.functional.softmax(self.model(x), dim=1) + + # Save ONNX model + torch.onnx.export(M(), torch.rand(self.input_shape)[None, ], output_path, + output_names=[class_mapping]) + + def lr_warmup_cosine_decay(self, + global_step, + warmup_steps=0, + hold=0, + total_steps=0, + start_lr=0.0, + target_lr=1e-3 + ): + # Cosine decay + learning_rate = 0.5 * target_lr * (1 + np.cos(np.pi * (global_step - warmup_steps - hold) + / float(total_steps - warmup_steps - hold))) + + # Target LR * progress of warmup (=1 at the final warmup step) + warmup_lr = target_lr * (global_step / warmup_steps) + + # Choose between `warmup_lr`, `target_lr` and `learning_rate` based on whether + # `global_step < warmup_steps` and we're still holding. + # i.e. warm up if we're still warming up and use cosine decayed lr otherwise + if hold > 0: + learning_rate = np.where(global_step > warmup_steps + hold, + learning_rate, target_lr) + + learning_rate = np.where(global_step < warmup_steps, warmup_lr, learning_rate) + return learning_rate + + def forward(self, x): + return self.model(x) + + def summary(self): + return torchinfo.summary(self.model, input_size=(1,) + self.input_shape, device='cpu') + + def average_models(self, models=None): + """Averages the weights of the provided models together to make a new model""" + + if models is None: + models = self.best_models + + # Clone a model from the list as the base for the averaged model + averaged_model = copy.deepcopy(models[0]) + averaged_model_dict = averaged_model.state_dict() + + # Initialize a running total of the weights + for key in averaged_model_dict: + averaged_model_dict[key] *= 0 # set to 0 + + for model in models: + model_dict = model.state_dict() + for key, value in model_dict.items(): + averaged_model_dict[key] += value + + for key in averaged_model_dict: + averaged_model_dict[key] /= len(models) + + # Load the averaged weights into the model + averaged_model.load_state_dict(averaged_model_dict) + + return averaged_model + + def _select_best_model(self, false_positive_validate_data, val_set_hrs=11.3, max_fp_per_hour=0.5, min_recall=0.20): + """ + Select the top model based on the false positive rate on the validation data + + Args: + false_positive_validate_data (torch.DataLoader): A dataloader with validation data + n (int): The number of models to select + + Returns: + list: A list of the top n models + """ + # Get false positive rates for each model + false_positive_rates = [0]*len(self.best_models) + for batch in false_positive_validate_data: + x_val, y_val = batch[0].to(self.device), batch[1].to(self.device) + for mdl_ndx, model in tqdm(enumerate(self.best_models), total=len(self.best_models), + desc="Find best checkpoints by false positive rate"): + with torch.no_grad(): + val_ps = model(x_val) + false_positive_rates[mdl_ndx] = false_positive_rates[mdl_ndx] + self.fp(val_ps, y_val[..., None]).detach().cpu().numpy() + false_positive_rates = [fp/val_set_hrs for fp in false_positive_rates] + + candidate_model_ndx = [ndx for ndx, fp in enumerate(false_positive_rates) if fp <= max_fp_per_hour] + candidate_model_recall = [self.best_model_scores[ndx]["val_recall"] for ndx in candidate_model_ndx] + if max(candidate_model_recall) <= min_recall: + logging.warning(f"No models with recall >= {min_recall} found!") + return None + else: + best_model = self.best_models[candidate_model_ndx[np.argmax(candidate_model_recall)]] + best_model_training_step = self.best_model_scores[candidate_model_ndx[np.argmax(candidate_model_recall)]]["training_step_ndx"] + logging.info(f"Best model from training step {best_model_training_step} out of {len(candidate_model_ndx)}" + f"models has recall of {np.max(candidate_model_recall)} and false positive rate of" + f" {false_positive_rates[candidate_model_ndx[np.argmax(candidate_model_recall)]]}") + + return best_model + + def auto_train(self, X_train, X_val, false_positive_val_data, steps=50000, max_negative_weight=1000, + target_fp_per_hour=0.2): + """A sequence of training steps that produce relatively strong models + automatically, based on validation data and performance targets provided. + After training merges the best checkpoints and returns a single model. + """ + + # Get false positive validation data duration + val_set_hrs = 11.3 + + # Sequence 1 + logging.info("#"*50 + "\nStarting training sequence 1...\n" + "#"*50) + lr = 0.0001 + weights = np.linspace(1, max_negative_weight, int(steps)).tolist() + val_steps = np.linspace(steps-int(steps*0.25), steps, 20).astype(np.int64) + self.train_model( + X=X_train, + X_val=X_val, + false_positive_val_data=false_positive_val_data, + max_steps=steps, + negative_weight_schedule=weights, + val_steps=val_steps, warmup_steps=steps//5, + hold_steps=steps//3, lr=lr, val_set_hrs=val_set_hrs) + + # Sequence 2 + logging.info("#"*50 + "\nStarting training sequence 2...\n" + "#"*50) + lr = lr/10 + steps = steps/10 + + # Adjust weights as needed based on false positive per hour performance from first sequence + if self.best_val_fp > target_fp_per_hour: + max_negative_weight = max_negative_weight*2 + logging.info("Increasing weight on negative examples to reduce false positives...") + + weights = np.linspace(1, max_negative_weight, int(steps)).tolist() + val_steps = np.linspace(1, steps, 20).astype(np.int16) + self.train_model( + X=X_train, + X_val=X_val, + false_positive_val_data=false_positive_val_data, + max_steps=steps, + negative_weight_schedule=weights, + val_steps=val_steps, warmup_steps=steps//5, + hold_steps=steps//3, lr=lr, val_set_hrs=val_set_hrs) + + # Sequence 3 + logging.info("#"*50 + "\nStarting training sequence 3...\n" + "#"*50) + lr = lr/10 + + # Adjust weights as needed based on false positive per hour performance from second sequence + if self.best_val_fp > target_fp_per_hour: + max_negative_weight = max_negative_weight*2 + logging.info("Increasing weight on negative examples to reduce false positives...") + + weights = np.linspace(1, max_negative_weight, int(steps)).tolist() + val_steps = np.linspace(1, steps, 20).astype(np.int16) + self.train_model( + X=X_train, + X_val=X_val, + false_positive_val_data=false_positive_val_data, + max_steps=steps, + negative_weight_schedule=weights, + val_steps=val_steps, warmup_steps=steps//5, + hold_steps=steps//3, lr=lr, val_set_hrs=val_set_hrs) + + # Merge best models + logging.info("Merging checkpoints above the 90th percentile into single model...") + accuracy_percentile = np.percentile(self.history["val_accuracy"], 90) + recall_percentile = np.percentile(self.history["val_recall"], 90) + fp_percentile = np.percentile(self.history["val_fp_per_hr"], 10) + + # Get models above the 90th percentile + models = [] + for model, score in zip(self.best_models, self.best_model_scores): + if score["val_accuracy"] >= accuracy_percentile and \ + score["val_recall"] >= recall_percentile and \ + score["val_fp_per_hr"] <= fp_percentile: + models.append(model) + + if len(models) > 0: + combined_model = self.average_models(models=models) + else: + combined_model = self.model + + # Report validation metrics for combined model + with torch.no_grad(): + for batch in X_val: + x, y = batch[0].to(self.device), batch[1].to(self.device) + val_ps = combined_model(x) + + combined_model_recall = self.recall(val_ps, y[..., None]).detach().cpu().numpy() + combined_model_accuracy = self.accuracy(val_ps, y[..., None].to(torch.int64)).detach().cpu().numpy() + + combined_model_fp = 0 + for batch in false_positive_val_data: + x_val, y_val = batch[0].to(self.device), batch[1].to(self.device) + val_ps = combined_model(x_val) + combined_model_fp += self.fp(val_ps, y_val[..., None]) + + combined_model_fp_per_hr = (combined_model_fp/val_set_hrs).detach().cpu().numpy() + + logging.info(f"\n################\nFinal Model Accuracy: {combined_model_accuracy}" + f"\nFinal Model Recall: {combined_model_recall}\nFinal Model False Positives per Hour: {combined_model_fp_per_hr}" + "\n################\n") + + return combined_model + + def predict_on_features(self, features, model=None): + """ + Predict on Tensors of openWakeWord features corresponding to single audio clips + + Args: + features (torch.Tensor): A Tensor of openWakeWord features with shape (batch, features) + model (torch.nn.Module): A Pytorch model to use for prediction (default None, which will use self.model) + + Returns: + torch.Tensor: An array of predictions of shape (batch, prediction), where 0 is negative and 1 is positive + """ + if len(features) < 3: + features = features[None, ] + + features = features.to(self.device) + predictions = [] + for x in tqdm(features, desc="Predicting on clips"): + x = x[None, ] + batch = [] + for i in range(0, x.shape[1]-16, 1): # step size of 1 (80 ms) + batch.append(x[:, i:i+16, :]) + batch = torch.vstack(batch) + if model is None: + preds = self.model(batch) + else: + preds = model(batch) + predictions.append(preds.detach().cpu().numpy()[None, ]) + + return np.vstack(predictions) + + def predict_on_clips(self, clips, model=None): + """ + Predict on Tensors of 16-bit 16 khz audio data + + Args: + clips (np.ndarray): A Numpy array of audio clips with shape (batch, samples) + model (torch.nn.Module): A Pytorch model to use for prediction (default None, which will use self.model) + + Returns: + np.ndarray: An array of predictions of shape (batch, prediction), where 0 is negative and 1 is positive + """ + + # Get features from clips + F = AudioFeatures(device='cpu', ncpu=4) + features = F.embed_clips(clips, batch_size=16) + + # Predict on features + preds = self.predict_on_features(torch.from_numpy(features), model=model) + + return preds + + def export_model(self, model, model_name, output_dir): + """Saves the trained openwakeword model to both onnx and tflite formats""" + + if self.n_classes != 1: + raise ValueError("Exporting models to both onnx and tflite with more than one class is currently not supported! " + "Use the `export_to_onnx` function instead.") + + # Save ONNX model + logging.info(f"####\nSaving ONNX mode as '{os.path.join(output_dir, model_name + '.onnx')}'") + model_to_save = copy.deepcopy(model) + torch.onnx.export(model_to_save.to("cpu"), torch.rand(self.input_shape)[None, ], + os.path.join(output_dir, model_name + ".onnx"), opset_version=13) + + return None + + def train_model(self, X, max_steps, warmup_steps, hold_steps, X_val=None, + false_positive_val_data=None, positive_test_clips=None, + negative_weight_schedule=[1], + val_steps=[250], lr=0.0001, val_set_hrs=1): + # Move models and main class to target device + self.to(self.device) + self.model.to(self.device) + + # Train model + accumulation_steps = 1 + accumulated_samples = 0 + accumulated_predictions = torch.Tensor([]).to(self.device) + accumulated_labels = torch.Tensor([]).to(self.device) + for step_ndx, data in tqdm(enumerate(X, 0), total=max_steps, desc="Training"): + # get the inputs; data is a list of [inputs, labels] + x, y = data[0].to(self.device), data[1].to(self.device) + y_ = y[..., None].to(torch.float32) + + # Update learning rates + for g in self.optimizer.param_groups: + g['lr'] = self.lr_warmup_cosine_decay(step_ndx, warmup_steps=warmup_steps, hold=hold_steps, + total_steps=max_steps, target_lr=lr) + + # zero the parameter gradients + self.optimizer.zero_grad() + + # Get predictions for batch + predictions = self.model(x) + + # Construct batch with only samples that have high loss + neg_high_loss = predictions[(y == 0) & (predictions.squeeze() >= 0.001)] # thresholds were chosen arbitrarily but work well + pos_high_loss = predictions[(y == 1) & (predictions.squeeze() < 0.999)] + y = torch.cat((y[(y == 0) & (predictions.squeeze() >= 0.001)], y[(y == 1) & (predictions.squeeze() < 0.999)])) + y_ = y[..., None].to(torch.float32) + predictions = torch.cat((neg_high_loss, pos_high_loss)) + + # Set weights for batch + if len(negative_weight_schedule) == 1: + w = torch.ones(y.shape[0])*negative_weight_schedule[0] + pos_ndcs = y == 1 + w[pos_ndcs] = 1 + w = w[..., None] + else: + if self.n_classes == 1: + w = torch.ones(y.shape[0])*negative_weight_schedule[step_ndx] + pos_ndcs = y == 1 + w[pos_ndcs] = 1 + w = w[..., None] + + if predictions.shape[0] != 0: + # Do backpropagation, with gradient accumulation if the batch-size after selecting high loss examples is too small + loss = self.loss(predictions, y_ if self.n_classes == 1 else y, w.to(self.device)) + loss = loss/accumulation_steps + accumulated_samples += predictions.shape[0] + + if predictions.shape[0] >= 128: + accumulated_predictions = predictions + accumulated_labels = y_ + if accumulated_samples < 128: + accumulation_steps += 1 + accumulated_predictions = torch.cat((accumulated_predictions, predictions)) + accumulated_labels = torch.cat((accumulated_labels, y_)) + else: + loss.backward() + self.optimizer.step() + accumulation_steps = 1 + accumulated_samples = 0 + + self.history["loss"].append(loss.detach().cpu().numpy()) + + # Compute training metrics and log them + fp = self.fp(accumulated_predictions, accumulated_labels if self.n_classes == 1 else y) + self.n_fp += fp + self.history["recall"].append(self.recall(accumulated_predictions, accumulated_labels).detach().cpu().numpy()) + + accumulated_predictions = torch.Tensor([]).to(self.device) + accumulated_labels = torch.Tensor([]).to(self.device) + + # Run validation and log validation metrics + if step_ndx in val_steps and step_ndx > 1 and false_positive_val_data is not None: + # Get false positives per hour with false positive data + val_fp = 0 + for val_step_ndx, data in enumerate(false_positive_val_data): + with torch.no_grad(): + x_val, y_val = data[0].to(self.device), data[1].to(self.device) + val_predictions = self.model(x_val) + val_fp += self.fp(val_predictions, y_val[..., None]) + val_fp_per_hr = (val_fp/val_set_hrs).detach().cpu().numpy() + self.history["val_fp_per_hr"].append(val_fp_per_hr) + + # Get recall on test clips + if step_ndx in val_steps and step_ndx > 1 and positive_test_clips is not None: + tp = 0 + fn = 0 + for val_step_ndx, data in enumerate(positive_test_clips): + with torch.no_grad(): + x_val = data[0].to(self.device) + batch = [] + for i in range(0, x_val.shape[1]-16, 1): + batch.append(x_val[:, i:i+16, :]) + batch = torch.vstack(batch) + preds = self.model(batch) + if any(preds >= 0.5): + tp += 1 + else: + fn += 1 + self.history["positive_test_clips_recall"].append(tp/(tp + fn)) + + if step_ndx in val_steps and step_ndx > 1 and X_val is not None: + # Get metrics for balanced test examples of positive and negative clips + for val_step_ndx, data in enumerate(X_val): + with torch.no_grad(): + x_val, y_val = data[0].to(self.device), data[1].to(self.device) + val_predictions = self.model(x_val) + val_recall = self.recall(val_predictions, y_val[..., None]).detach().cpu().numpy() + val_acc = self.accuracy(val_predictions, y_val[..., None].to(torch.int64)) + val_fp = self.fp(val_predictions, y_val[..., None]) + self.history["val_accuracy"].append(val_acc.detach().cpu().numpy()) + self.history["val_recall"].append(val_recall) + self.history["val_n_fp"].append(val_fp.detach().cpu().numpy()) + + # Save models with a validation score above/below the 90th percentile + # of the validation scores up to that point + if step_ndx in val_steps and step_ndx > 1: + if self.history["val_n_fp"][-1] <= np.percentile(self.history["val_n_fp"], 50) and \ + self.history["val_recall"][-1] >= np.percentile(self.history["val_recall"], 5): + # logging.info("Saving checkpoint with metrics >= to targets!") + self.best_models.append(copy.deepcopy(self.model)) + self.best_model_scores.append({"training_step_ndx": step_ndx, "val_n_fp": self.history["val_n_fp"][-1], + "val_recall": self.history["val_recall"][-1], + "val_accuracy": self.history["val_accuracy"][-1], + "val_fp_per_hr": self.history.get("val_fp_per_hr", [0])[-1]}) + self.best_val_recall = self.history["val_recall"][-1] + self.best_val_accuracy = self.history["val_accuracy"][-1] + + if step_ndx == max_steps-1: + break + + +# Separate function to convert onnx models to tflite format +def convert_onnx_to_tflite(onnx_model_path, output_path): + """Converts an ONNX version of an openwakeword model to the Tensorflow tflite format.""" + # imports + import onnx + from onnx_tf.backend import prepare + import tensorflow as tf + + # Convert to tflite from onnx model + onnx_model = onnx.load(onnx_model_path) + tf_rep = prepare(onnx_model, device="CPU") + with tempfile.TemporaryDirectory() as tmp_dir: + tf_rep.export_graph(os.path.join(tmp_dir, "tf_model")) + converter = tf.lite.TFLiteConverter.from_saved_model(os.path.join(tmp_dir, "tf_model")) + tflite_model = converter.convert() + + logging.info(f"####\nSaving tflite mode to '{output_path}'") + with open(output_path, 'wb') as f: + f.write(tflite_model) + + return None + + +if __name__ == '__main__': + # Get training config file + parser = argparse.ArgumentParser() + parser.add_argument( + "--training_config", + help="The path to the training config file (required)", + type=str, + required=True + ) + parser.add_argument( + "--generate_clips", + help="Execute the synthetic data generation process", + action="https://github.com/store_true", + default="False", + required=False + ) + parser.add_argument( + "--augment_clips", + help="Execute the synthetic data augmentation process", + action="https://github.com/store_true", + default="False", + required=False + ) + parser.add_argument( + "--overwrite", + help="Overwrite existing openwakeword features when the --augment_clips flag is used", + action="https://github.com/store_true", + default="False", + required=False + ) + parser.add_argument( + "--train_model", + help="Execute the model training process", + action="https://github.com/store_true", + default="False", + required=False + ) + + args = parser.parse_args() + config = yaml.load(open(args.training_config, 'r').read(), yaml.Loader) + + # imports Piper for synthetic sample generation + sys.path.insert(0, os.path.abspath(config["piper_sample_generator_path"])) + from generate_samples import generate_samples + + # Define output locations + config["output_dir"] = os.path.abspath(config["output_dir"]) + if not os.path.exists(config["output_dir"]): + os.mkdir(config["output_dir"]) + if not os.path.exists(os.path.join(config["output_dir"], config["model_name"])): + os.mkdir(os.path.join(config["output_dir"], config["model_name"])) + + positive_train_output_dir = os.path.join(config["output_dir"], config["model_name"], "positive_train") + positive_test_output_dir = os.path.join(config["output_dir"], config["model_name"], "positive_test") + negative_train_output_dir = os.path.join(config["output_dir"], config["model_name"], "negative_train") + negative_test_output_dir = os.path.join(config["output_dir"], config["model_name"], "negative_test") + feature_save_dir = os.path.join(config["output_dir"], config["model_name"]) + + # Get paths for impulse response and background audio files + rir_paths = [i.path for j in config["rir_paths"] for i in os.scandir(j)] + background_paths = [] + if len(config["background_paths_duplication_rate"]) != len(config["background_paths"]): + config["background_paths_duplication_rate"] = [1]*len(config["background_paths"]) + for background_path, duplication_rate in zip(config["background_paths"], config["background_paths_duplication_rate"]): + background_paths.extend([i.path for i in os.scandir(background_path)]*duplication_rate) + + if args.generate_clips is True: + # Generate positive clips for training + logging.info("#"*50 + "\nGenerating positive clips for training\n" + "#"*50) + if not os.path.exists(positive_train_output_dir): + os.mkdir(positive_train_output_dir) + n_current_samples = len(os.listdir(positive_train_output_dir)) + if n_current_samples <= 0.95*config["n_samples"]: + generate_samples( + text=config["target_phrase"], max_samples=config["n_samples"]-n_current_samples, + batch_size=config["tts_batch_size"], + noise_scales=[0.98], noise_scale_ws=[0.98], length_scales=[0.75, 1.0, 1.25], + output_dir=positive_train_output_dir, auto_reduce_batch_size=True, + file_names=[uuid.uuid4().hex + ".wav" for i in range(config["n_samples"])] + ) + torch.cuda.empty_cache() + else: + logging.warning(f"Skipping generation of positive clips for training, as ~{config['n_samples']} already exist") + + # Generate positive clips for testing + logging.info("#"*50 + "\nGenerating positive clips for testing\n" + "#"*50) + if not os.path.exists(positive_test_output_dir): + os.mkdir(positive_test_output_dir) + n_current_samples = len(os.listdir(positive_test_output_dir)) + if n_current_samples <= 0.95*config["n_samples_val"]: + generate_samples(text=config["target_phrase"], max_samples=config["n_samples_val"]-n_current_samples, + batch_size=config["tts_batch_size"], + noise_scales=[1.0], noise_scale_ws=[1.0], length_scales=[0.75, 1.0, 1.25], + output_dir=positive_test_output_dir, auto_reduce_batch_size=True) + torch.cuda.empty_cache() + else: + logging.warning(f"Skipping generation of positive clips testing, as ~{config['n_samples_val']} already exist") + + # Generate adversarial negative clips for training + logging.info("#"*50 + "\nGenerating negative clips for training\n" + "#"*50) + if not os.path.exists(negative_train_output_dir): + os.mkdir(negative_train_output_dir) + n_current_samples = len(os.listdir(negative_train_output_dir)) + if n_current_samples <= 0.95*config["n_samples"]: + adversarial_texts = config["custom_negative_phrases"] + for target_phrase in config["target_phrase"]: + adversarial_texts.extend(generate_adversarial_texts( + input_text=target_phrase, + N=config["n_samples"]//len(config["target_phrase"]), + include_partial_phrase=1.0, + include_input_words=0.2)) + generate_samples(text=adversarial_texts, max_samples=config["n_samples"]-n_current_samples, + batch_size=config["tts_batch_size"]//7, + noise_scales=[0.98], noise_scale_ws=[0.98], length_scales=[0.75, 1.0, 1.25], + output_dir=negative_train_output_dir, auto_reduce_batch_size=True, + file_names=[uuid.uuid4().hex + ".wav" for i in range(config["n_samples"])] + ) + torch.cuda.empty_cache() + else: + logging.warning(f"Skipping generation of negative clips for training, as ~{config['n_samples']} already exist") + + # Generate adversarial negative clips for testing + logging.info("#"*50 + "\nGenerating negative clips for testing\n" + "#"*50) + if not os.path.exists(negative_test_output_dir): + os.mkdir(negative_test_output_dir) + n_current_samples = len(os.listdir(negative_test_output_dir)) + if n_current_samples <= 0.95*config["n_samples_val"]: + adversarial_texts = config["custom_negative_phrases"] + for target_phrase in config["target_phrase"]: + adversarial_texts.extend(generate_adversarial_texts( + input_text=target_phrase, + N=config["n_samples_val"]//len(config["target_phrase"]), + include_partial_phrase=1.0, + include_input_words=0.2)) + generate_samples(text=adversarial_texts, max_samples=config["n_samples_val"]-n_current_samples, + batch_size=config["tts_batch_size"]//7, + noise_scales=[1.0], noise_scale_ws=[1.0], length_scales=[0.75, 1.0, 1.25], + output_dir=negative_test_output_dir, auto_reduce_batch_size=True) + torch.cuda.empty_cache() + else: + logging.warning(f"Skipping generation of negative clips for testing, as ~{config['n_samples_val']} already exist") + + # Set the total length of the training clips based on the ~median generated clip duration, rounding to the nearest 1000 samples + # and setting to 32000 when the median + 750 ms is close to that, as it's a good default value + n = 50 # sample size + positive_clips = [str(i) for i in Path(positive_test_output_dir).glob("*.wav")] + duration_in_samples = [] + for i in range(n): + sr, dat = scipy.io.wavfile.read(positive_clips[np.random.randint(0, len(positive_clips))]) + duration_in_samples.append(len(dat)) + + config["total_length"] = int(round(np.median(duration_in_samples)/1000)*1000) + 12000 # add 750 ms to clip duration as buffer + if config["total_length"] < 32000: + config["total_length"] = 32000 # set a minimum of 32000 samples (2 seconds) + elif abs(config["total_length"] - 32000) <= 4000: + config["total_length"] = 32000 + + # Do Data Augmentation + if args.augment_clips is True: + if not os.path.exists(os.path.join(feature_save_dir, "positive_features_train.npy")) or args.overwrite is True: + positive_clips_train = [str(i) for i in Path(positive_train_output_dir).glob("*.wav")]*config["augmentation_rounds"] + positive_clips_train_generator = augment_clips(positive_clips_train, total_length=config["total_length"], + batch_size=config["augmentation_batch_size"], + background_clip_paths=background_paths, + RIR_paths=rir_paths) + + positive_clips_test = [str(i) for i in Path(positive_test_output_dir).glob("*.wav")]*config["augmentation_rounds"] + positive_clips_test_generator = augment_clips(positive_clips_test, total_length=config["total_length"], + batch_size=config["augmentation_batch_size"], + background_clip_paths=background_paths, + RIR_paths=rir_paths) + + negative_clips_train = [str(i) for i in Path(negative_train_output_dir).glob("*.wav")]*config["augmentation_rounds"] + negative_clips_train_generator = augment_clips(negative_clips_train, total_length=config["total_length"], + batch_size=config["augmentation_batch_size"], + background_clip_paths=background_paths, + RIR_paths=rir_paths) + + negative_clips_test = [str(i) for i in Path(negative_test_output_dir).glob("*.wav")]*config["augmentation_rounds"] + negative_clips_test_generator = augment_clips(negative_clips_test, total_length=config["total_length"], + batch_size=config["augmentation_batch_size"], + background_clip_paths=background_paths, + RIR_paths=rir_paths) + + # Compute features and save to disk via memmapped arrays + logging.info("#"*50 + "\nComputing openwakeword features for generated samples\n" + "#"*50) + n_cpus = os.cpu_count() + if n_cpus is None: + n_cpus = 1 + else: + n_cpus = n_cpus//2 + compute_features_from_generator(positive_clips_train_generator, n_total=len(os.listdir(positive_train_output_dir)), + clip_duration=config["total_length"], + output_file=os.path.join(feature_save_dir, "positive_features_train.npy"), + device="gpu" if torch.cuda.is_available() else "cpu", + ncpu=n_cpus if not torch.cuda.is_available() else 1) + + compute_features_from_generator(negative_clips_train_generator, n_total=len(os.listdir(negative_train_output_dir)), + clip_duration=config["total_length"], + output_file=os.path.join(feature_save_dir, "negative_features_train.npy"), + device="gpu" if torch.cuda.is_available() else "cpu", + ncpu=n_cpus if not torch.cuda.is_available() else 1) + + compute_features_from_generator(positive_clips_test_generator, n_total=len(os.listdir(positive_test_output_dir)), + clip_duration=config["total_length"], + output_file=os.path.join(feature_save_dir, "positive_features_test.npy"), + device="gpu" if torch.cuda.is_available() else "cpu", + ncpu=n_cpus if not torch.cuda.is_available() else 1) + + compute_features_from_generator(negative_clips_test_generator, n_total=len(os.listdir(negative_test_output_dir)), + clip_duration=config["total_length"], + output_file=os.path.join(feature_save_dir, "negative_features_test.npy"), + device="gpu" if torch.cuda.is_available() else "cpu", + ncpu=n_cpus if not torch.cuda.is_available() else 1) + else: + logging.warning("Openwakeword features already exist, skipping data augmentation and feature generation") + + # Create openwakeword model + if args.train_model is True: + F = openwakeword.utils.AudioFeatures(device='cpu') + input_shape = F.get_embedding_shape(config["total_length"]//16000) # training data is always 16 khz + + oww = Model(n_classes=1, input_shape=input_shape, model_type=config["model_type"], + layer_dim=config["layer_size"], seconds_per_example=1280*input_shape[0]/16000) + + # Create data transform function for batch generation to handle differ clip lengths (todo: write tests for this) + def f(x, n=16): + """Simple transformation function to ensure negative data is the appropriate shape for the model size""" + if n > x.shape[1] or n < x.shape[1]: + x = np.vstack(x) + new_batch = np.array([x[i:i+n, :] for i in range(0, x.shape[0]-n, n)]) + else: + return x + return new_batch + + # Create label transforms as needed for model (currently only supports binary classification models) + data_transforms = {key: f for key in config["feature_data_files"].keys()} + label_transforms = {} + for key in ["positive"] + list(config["feature_data_files"].keys()) + ["adversarial_negative"]: + if key == "positive": + label_transforms[key] = lambda x: [1 for i in x] + else: + label_transforms[key] = lambda x: [0 for i in x] + + # Add generated positive and adversarial negative clips to the feature data files dictionary + config["feature_data_files"]['positive'] = os.path.join(feature_save_dir, "positive_features_train.npy") + config["feature_data_files"]['adversarial_negative'] = os.path.join(feature_save_dir, "negative_features_train.npy") + + # Make PyTorch data loaders for training and validation data + batch_generator = mmap_batch_generator( + config["feature_data_files"], + n_per_class=config["batch_n_per_class"], + data_transform_funcs=data_transforms, + label_transform_funcs=label_transforms + ) + + class IterDataset(torch.utils.data.IterableDataset): + def __init__(self, generator): + self.generator = generator + + def __iter__(self): + return self.generator + + n_cpus = os.cpu_count() + if n_cpus is None: + n_cpus = 1 + else: + n_cpus = n_cpus//2 + X_train = torch.utils.data.DataLoader(IterDataset(batch_generator), + batch_size=None, num_workers=n_cpus, prefetch_factor=16) + + X_val_fp = np.load(config["false_positive_validation_data_path"]) + X_val_fp = np.array([X_val_fp[i:i+input_shape[0]] for i in range(0, X_val_fp.shape[0]-input_shape[0], 1)]) # reshape to match model + X_val_fp_labels = np.zeros(X_val_fp.shape[0]).astype(np.float32) + X_val_fp = torch.utils.data.DataLoader( + torch.utils.data.TensorDataset(torch.from_numpy(X_val_fp), torch.from_numpy(X_val_fp_labels)), + batch_size=len(X_val_fp_labels) + ) + + X_val_pos = np.load(os.path.join(feature_save_dir, "positive_features_test.npy")) + X_val_neg = np.load(os.path.join(feature_save_dir, "negative_features_test.npy")) + labels = np.hstack((np.ones(X_val_pos.shape[0]), np.zeros(X_val_neg.shape[0]))).astype(np.float32) + + X_val = torch.utils.data.DataLoader( + torch.utils.data.TensorDataset( + torch.from_numpy(np.vstack((X_val_pos, X_val_neg))), + torch.from_numpy(labels) + ), + batch_size=len(labels) + ) + + # Run auto training + best_model = oww.auto_train( + X_train=X_train, + X_val=X_val, + false_positive_val_data=X_val_fp, + steps=config["steps"], + max_negative_weight=config["max_negative_weight"], + target_fp_per_hour=config["target_false_positives_per_hour"], + ) + + # Export the trained model to onnx + oww.export_model(model=best_model, model_name=config["model_name"], output_dir=config["output_dir"]) + + # Convert the model from onnx to tflite format + convert_onnx_to_tflite(os.path.join(config["output_dir"], config["model_name"] + ".onnx"), + os.path.join(config["output_dir"], config["model_name"] + ".tflite")) diff --git a/openwakeword/utils.py b/openwakeword/utils.py index c4f9b15..4964706 100644 --- a/openwakeword/utils.py +++ b/openwakeword/utils.py @@ -21,8 +21,11 @@ from multiprocessing import Process, Queue import time import logging +from tqdm import tqdm import openwakeword +from numpy.lib.format import open_memmap from typing import Union, List, Callable, Deque +import requests # Base class for computing audio features using Google's speech_embedding @@ -157,7 +160,7 @@ def tflite_embedding_predict(x): self.embedding_model_predict = tflite_embedding_predict - # Create databuffers + # Create databuffers with empty/random data self.raw_data_buffer: Deque = deque(maxlen=sr*10) self.melspectrogram_buffer = np.ones((76, 32)) # n_frames x num_features self.melspectrogram_max_len = 10*97 # 97 is the number of frames in 1 second of 16hz audio @@ -166,6 +169,14 @@ def tflite_embedding_predict(x): self.feature_buffer = self._get_embeddings(np.random.randint(-1000, 1000, 16000*4).astype(np.int16)) self.feature_buffer_max_len = 120 # ~10 seconds of feature buffer history + def reset(self): + """Reset the internal buffers""" + self.raw_data_buffer.clear() + self.melspectrogram_buffer = np.ones((76, 32)) + self.accumulated_samples = 0 + self.raw_data_remainder = np.empty(0) + self.feature_buffer = self._get_embeddings(np.random.randint(-1000, 1000, 16000*4).astype(np.int16)) + def _get_melspectrogram(self, x: Union[np.ndarray, List], melspec_transform: Callable = lambda x: x/10 + 2): """ Function to compute the mel-spectrogram of the provided audio samples. @@ -266,8 +277,9 @@ def _get_melspectrogram_batch(self, x, batch_size=128, ncpu=1): result = self._get_melspectrogram(batch) elif pool: + chunksize = batch.shape[0]//ncpu if batch.shape[0] >= ncpu else 1 result = np.array(pool.map(self._get_melspectrogram, - batch, chunksize=batch.shape[0]//ncpu)) + batch, chunksize=chunksize)) melspecs[i:i+batch_size, :, :] = result.squeeze() @@ -327,8 +339,9 @@ def _get_embeddings_batch(self, x, batch_size=128, ncpu=1): result = self.embedding_model_predict(batch) elif pool: + chunksize = batch.shape[0]//ncpu if batch.shape[0] >= ncpu else 1 result = np.array(pool.map(self._get_embeddings_from_melspec, - batch, chunksize=batch.shape[0]//ncpu)) + batch, chunksize=chunksize)) for j, ndx2 in zip(range(0, result.shape[0], n_frames), ndcs): embeddings[ndx2, :, :] = result[j:j+n_frames] @@ -526,6 +539,140 @@ def f(clips): return {list(i.keys())[0]: list(i.values())[0] for i in results} +def compute_features_from_generator(generator, n_total, clip_duration, output_file, device="cpu", ncpu=1): + """ + Computes audio features from a generator that produces Numpy arrays of shape (batch_size, samples) + containing 16-bit PCM audio data. + + Args: + generator (Generator): The generator that process the arrays of audio data + n_total (int): The total number of rows (audio clips) that the generator will produce. + Ideally this is precise, but it can be approximate as well as the output + .npy file will be automatically trimmed to remove empty values. + clip_duration (float): The duration (in samples) of the audio produced by the generator + output_file (str): The output file (.npy) containing the audio features. Note that this file + will be written to using memmap arrays, so it can be substantially larger + than the available system memory. + device (str): The device ("cpu" or "gpu") to use for computing features. + ncpu (int): The number of cores to use when process the audio features (if computing on CPU) + + Returns: + None + """ + # Function specific imports + from openwakeword.data import trim_mmap + + # Create audio features object + F = AudioFeatures(device=device) + + # Determine the output shape and create output file + n_feature_cols = F.get_embedding_shape(clip_duration/16000) + output_shape = (n_total, n_feature_cols[0], n_feature_cols[1]) + fp = open_memmap(output_file, mode='w+', dtype=np.float32, shape=output_shape) + + # Get batch size by pulling one value from the generator and store features + row_counter = 0 + audio_data = next(generator) + batch_size = audio_data.shape[0] + + if batch_size > n_total: + raise ValueError(f"The value of 'n_total' ({n_total}) is less than the batch size ({batch_size})." + " Please increase 'n_total' to be >= batch size.") + + features = F.embed_clips(audio_data, batch_size=batch_size) + fp[row_counter:row_counter+features.shape[0], :, :] = features + row_counter += features.shape[0] + fp.flush() + + # Compute features and add data to output file + for audio_data in tqdm(generator, total=n_total//batch_size, desc="Computing features"): + if row_counter >= n_total: + break + + features = F.embed_clips(audio_data, batch_size=batch_size, ncpu=ncpu) + if row_counter + features.shape[0] > n_total: + features = features[0:n_total-row_counter] + + fp[row_counter:row_counter+features.shape[0], :, :] = features + row_counter += features.shape[0] + fp.flush() + + # Trip empty rows from the mmapped array + trim_mmap(output_file) + + +# Function to download files from a URL with a progress bar +def download_file(url, target_directory, file_size=None): + """A simple function to download a file from a URL with a progress bar using only the requests library""" + local_filename = url.split('/')[-1] + + with requests.get(url, stream=True) as r: + if file_size is not None: + progress_bar = tqdm(total=file_size, unit='iB', unit_scale=True, desc=f"{local_filename}") + else: + total_size = int(r.headers.get('content-length', 0)) + progress_bar = tqdm(total=total_size, unit='iB', unit_scale=True, desc=f"{local_filename}") + + with open(os.path.join(target_directory, local_filename), 'wb') as f: + for chunk in r.iter_content(chunk_size=8192): + f.write(chunk) + progress_bar.update(len(chunk)) + + progress_bar.close() + + +# Function to download models from GitHub release assets +def download_models( + model_names: List[str] = [], + target_directory: str = os.path.join(pathlib.Path(__file__).parent.resolve(), "resources", "models") + ): + """ + Download the specified models from the release assets in the openWakeWord GitHub repository. + Uses the official urls in the MODELS dictionary in openwakeword/__init__.py. + + Args: + model_names (List[str]): The names of the models to download (e.g., hey_jarvis_v0.1). Both ONNX and + tflite models will be downloaded. If not provided (the default), + the latest versions of all models will be downloaded. + target_directory (str): The directory to save the models to. Defaults to the install location + of openWakeWord (i.e., the `resources/models` directory). + Returns: + None + """ + if not isinstance(model_names, list): + raise ValueError("The model_names argument must be a list of strings") + + # Always download melspectrogram and embedding models, if they don't already exist + if not os.path.exists(target_directory): + os.makedirs(target_directory) + for feature_model in openwakeword.FEATURE_MODELS.values(): + if not os.path.exists(os.path.join(target_directory, feature_model["download_url"].split("/")[-1])): + download_file(feature_model["download_url"], target_directory) + download_file(feature_model["download_url"].replace(".tflite", ".onnx"), target_directory) + + # Always download VAD models, if they don't already exist + for vad_model in openwakeword.VAD_MODELS.values(): + if not os.path.exists(os.path.join(target_directory, vad_model["download_url"].split("/")[-1])): + download_file(vad_model["download_url"], target_directory) + + # Get all model urls + official_model_urls = [i["download_url"] for i in openwakeword.MODELS.values()] + official_model_names = [i["download_url"].split("/")[-1] for i in openwakeword.MODELS.values()] + + if model_names != []: + for model_name in model_names: + url = [i for i, j in zip(official_model_urls, official_model_names) if model_name in j] + if url != []: + if not os.path.exists(os.path.join(target_directory, url[0].split("/")[-1])): + download_file(url[0], target_directory) + download_file(url[0].replace(".tflite", ".onnx"), target_directory) + else: + for official_model_url in official_model_urls: + if not os.path.exists(os.path.join(target_directory, official_model_url.split("/")[-1])): + download_file(official_model_url, target_directory) + download_file(official_model_url.replace(".tflite", ".onnx"), target_directory) + + # Handle deprecated arguments and naming (thanks to https://stackoverflow.com/a/74564394) def re_arg(kwarg_map): def decorator(func): diff --git a/openwakeword/vad.py b/openwakeword/vad.py index 18bf5e3..b332ee6 100755 --- a/openwakeword/vad.py +++ b/openwakeword/vad.py @@ -63,18 +63,20 @@ def __init__(self, "resources", "models", "silero_vad.onnx" - ) + ), + n_threads: int = 1 ): """Initialize the VAD model object. Args: model_path (str): The path to the Silero VAD ONNX model. + n_threads (int): The number of threads to use for the VAD model. """ # Initialize the ONNX model sessionOptions = ort.SessionOptions() - sessionOptions.inter_op_num_threads = 1 - sessionOptions.intra_op_num_threads = 1 + sessionOptions.inter_op_num_threads = n_threads + sessionOptions.intra_op_num_threads = n_threads self.model = ort.InferenceSession(model_path, sess_options=sessionOptions, providers=["CPUExecutionProvider"]) diff --git a/pyproject.toml b/pyproject.toml index 23c373c..d420f04 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ testpaths = [ [project] name = "openwakeword" -version = "0.5.1" +version = "0.6.0" authors = [ { name="David Scripka", email="david.scripka@gmail.com" }, ] @@ -24,6 +24,7 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", ] +dynamic = ["dependencies", "optional-dependencies"] [project.urls] "Homepage" = "https://github.com/dscripka/openWakeWord" \ No newline at end of file diff --git a/setup.py b/setup.py index 1c7aecb..df0a666 100644 --- a/setup.py +++ b/setup.py @@ -26,13 +26,14 @@ def build_additional_requires(): setuptools.setup( name="openwakeword", - version="0.5.1", + version="0.6.0", install_requires=[ 'onnxruntime>=1.10.0,<2', 'tflite-runtime>=2.8.0,<3; platform_system == "Linux"', 'tqdm>=4.0,<5.0', 'scipy>=1.3,<2', - 'scikit-learn>=1,<2' + 'scikit-learn>=1,<2', + 'requests>=2.0,<3', ], extras_require={ 'test': [ @@ -41,18 +42,36 @@ def build_additional_requires(): 'pytest-flake8>=1.1.1,<2', 'flake8>=4.0,<4.1', 'pytest-mypy>=0.10.0,<1', + 'types-requests', + 'types-PyYAML', 'mock>=5.1,<6', - 'types-mock>=5.1,<6' + 'types-mock>=5.1,<6', + 'types-requests>=2.0,<3' ], 'full': [ 'mutagen>=1.46.0,<2', - 'speechbrain>=0.5.13,<1', + 'torch>=1.13.1,<3', + 'torchaudio>=0.13.1,<1', + 'torchinfo>=1.8.0,<2', + 'torchmetrics>=0.11.4,<1', + 'speechbrain>=0.5.14,<1', + 'audiomentations>=0.30.0,<1', + 'torch-audiomentations>=0.11.0,<1', + 'tqdm>=4.64.0,<5', 'pytest>=7.2.0,<8', 'pytest-cov>=2.10.1,<3', 'pytest-flake8>=1.1.1,<2', 'pytest-mypy>=0.10.0,<1', - 'plotext>=5.2.7,<6', - 'sounddevice>=0.4.1,<1' + 'acoustics>=0.2.6,<1', + 'pyyaml>=6.0,<7', + 'tensorflow-cpu==2.8.1', + 'tensorflow_probability==0.16.0', + 'protobuf>=3.20,<4', + 'onnx_tf==1.10.0', + 'onnx==1.14.0', + 'pronouncing>=0.2.0,<1', + 'datasets>=2.14.4,<3', + 'deep-phonemizer==0.0.19' ] }, author="David Scripka", diff --git a/tests/test_custom_verifier_model.py b/tests/test_custom_verifier_model.py index d5665e5..53f02ce 100644 --- a/tests/test_custom_verifier_model.py +++ b/tests/test_custom_verifier_model.py @@ -34,6 +34,9 @@ import tempfile import pytest +# Download models needed for tests +openwakeword.utils.download_models(model_names=["alexa_v0.1", "hey_mycroft_v0.1"]) + # Tests class TestModels: diff --git a/tests/test_models.py b/tests/test_models.py index c38ecb8..b3907ff 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -39,6 +39,10 @@ import pickle import tempfile import mock +import wave + +# Download models needed for tests +openwakeword.utils.download_models() # Tests @@ -205,6 +209,48 @@ def test_models_with_speex_noise_cancellation(self): ) assert 1 == 1 + def test_models_with_debounce(self): + # Load model with defaults + owwModel = openwakeword.Model() + + # Predict with chunks of 1280 with and without debounce + predictions = owwModel.predict_clip(os.path.join("tests", "data", "alexa_test.wav"), + debounce_time=0, threshold={"alexa_v0.1": 0.5}) + scores = np.array([i['alexa'] for i in predictions]) + + predictions = owwModel.predict_clip(os.path.join("tests", "data", "alexa_test.wav"), + debounce_time=1.25, threshold={"alexa": 0.5}) + scores_with_debounce = np.array([i['alexa'] for i in predictions]) + print(scores, scores_with_debounce) + assert (scores >= 0.5).sum() > 1 + assert (scores_with_debounce >= 0.5).sum() == 1 + + def test_model_reset(self): + # Load the model + owwModel = openwakeword.Model() + + # Get test clip and load it + clip = os.path.join("tests", "data", "alexa_test.wav") + with wave.open(clip, mode='rb') as f: + data = np.frombuffer(f.readframes(f.getnframes()), dtype=np.int16) + + # Predict frame by frame + for i in range(0, len(data), 1280): + prediction = owwModel.predict(data[i:i+1280]) + if prediction['alexa'] > 0.5: + break + + # Assert that next prediction is still > 0.5 + prediction = owwModel.predict(data[i:i+1280]) + assert prediction['alexa'] > 0.5 + + # Reset the model + owwModel.reset() + + # Assert that next prediction is < 0.5 + prediction = owwModel.predict(data[i:i+1280]) + assert prediction['alexa'] < 0.5 + def test_models_with_vad(self): # Load model with defaults owwModel = openwakeword.Model(vad_threshold=0.5)