Changes some filenames, started to work on docs, added a function

This commit is contained in:
dscripka 2022-10-09 23:45:09 -04:00
parent 623e86f505
commit c1466374ba
8 changed files with 160 additions and 3 deletions

View file

@ -0,0 +1,31 @@
# openWakeWord
openWakeWord is a fully open-source wakeword library that can be used to create voice-enabled applications and interfaces. It comes with a (growing!) set of pre-trained models, and new models can be easily trained as well for different wake words & phrases. The overall goal of the library is to provide a simple framework for wakeword/phrase detection, while also providing pre-built models (and the ability to train new models) that perform well enough to be useable in the real-word.
More specifically, openWakeWord aims to:
1) Be fast & accurate *enough* for real-world usage. The models can easily run in real-time using ~x% of a single core on a Raspberry Pi3 (see the see the [Performance & Evaluation]() section for more details), but are likely too big for less powerful systems or microcontrollers. The models should have false-accept and false-reject rates of that are below the annoyance threshold for the average user. This is obviously subjective, by a false-accept rate of <0.5 per hour and a false-reject rate of <5% seems reasonable in practice.
2) Have a simple interface for model inference. Models process a stream of audio data in 80 ms frames, and return a prediction for each frame indicated whether the wake word/phrase has been detected.
3) Have a shared feature extraction backbone for all models so that many separate models can be run with minimal additional resource requirements. See the [Model Architecture]() section for more details.
4) Require *little to no manual data collection* to train new models. The included models (see the [Pre-trained Models]() section for more details) were all trained with *100% synthetic* speech generated from text-to-speech models. Training new models is a simple as generating new clips for the target wake word/phrase and training a small head-model on top of of the frozen common backbone. See the [Training New Models]() section for more details.
# Pre-Trained Models
# Model Architecture
# Performance and Evaluation
- Mention 0.5/hour false accept rate for near continuous speech (e.g., dinner party corpus)
- False-reject rate of 5% means that the chanced of missing two activations is only 0.25%. E.g., if a user on average intentially speaks a wake word/phrase 20 times per day, they would expect to have to try two times once per day, and try three times only once every 20 days (assuming the failed activations aren't correlated and the environmental conditions are such that an activation is expected).
# Training New Models
# Language Support
Currently, openWakeWord only supports English, primarily because the pre-trained text-to-speech models used to generate training data are all english. It's likely that speech-to-text models trained on other languages would also work well, but non-english models & datasets are less commonly available.
Future release roadmaps may have non-english support. In particular, [Mycroft.AIs Mimic 3](https://github.com/MycroftAI/mimic3-voices) TTS engine could work well.

0
docs/models/alexa.md Executable file
View file

View file

@ -17,7 +17,7 @@ import os
import plotext as plt
import sounddevice
import numpy as np
from openwakeword.detect import Model
from openwakeword.model import Model
# Get microphone stream
mic_stream = sounddevice.InputStream(

View file

@ -1 +1 @@
from openwakeword.detect import Model
from openwakeword.model import Model

66
openwakeword/metrics.py Normal file
View file

@ -0,0 +1,66 @@
# Copyright 2022 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.
## Define metric utility functions specific to the wakeword detection use-case
from time import time
import matplotlib.pyplot as plt
import re
from tqdm import tqdm
import numpy as np
def generate_roc_curve_fprs(scores, n_points=25, time_per_prediction=.08, **kwargs):
"""
Generates the false positive rate (fpr) per hour for the given predictions
over a range of score thresholds. Assumes that all predictions should be less than the threshold,
else the prediction is a false positive.
Args:
predictions (List): A list of predicted scores, between 0 and 1
labels (List): A list of ground-truth labels
thresholds (List[float]): A list of threshold values to plot curves for
time_per_prediction: The time (in seconds) that each prediction represents
Returns:
list: A list of fprs per hour
"""
# Determine total time
total_hours = time_per_prediction*len(scores)/3600 # convert to hours
# Calculate true positive rate
fprs = []
for threshold in tqdm(np.linspace(0.05,0.95,num=n_points)):
# Remove repeated predictions from data to not overcount false positives
bin_pred = ''.join(["1" if i else "0" for i in np.array(scores) >= threshold])
bin_pred = re.sub("1(0){1,5}1", "1", bin_pred)
bin_pred = re.sub("0(1){1,50}0", "1", bin_pred)
fprs.append(len(re.findall('1', bin_pred))/total_hours)
return fprs
def generate_roc_curve_tprs(scores, n_points=25):
"""
Generates the true positive rate (true accept rate) for the given predictions
over a range score thresholds. Assumes that all predictions are supposed to be equal to 1.
Args:
scores (list): A list of scores for each prediction
"""
tprs = []
for threshold in tqdm(np.linspace(0.05,0.95,num=n_points)):
tprs.append(sum(scores >= threshold)/len(scores))
return tprs

View file

@ -20,6 +20,9 @@ import numpy as np
import pathlib
from collections import deque
from multiprocessing.pool import ThreadPool
from multiprocessing import Process, Queue
import time
import openwakeword
# Base class for computing audio features using Google's speech_embedding model (https://tfhub.dev/google/speech_embedding/1)
class AudioFeatures():
@ -257,3 +260,57 @@ class AudioFeatures():
def __call__(self, x):
self._streaming_features(x)
# Bulk prediction function
def bulk_predict(file_paths, wakeword_model_paths, ncpu=1):
"""
Bulk predict on the provided input files in parallel using multiprocessing using the specified model.
Args:
input_paths (List[str]): The list of input file to predict
wakeword_model_path (List(str)): The paths to the wakeword ONNX model files
ncpu (int): How many processes to create (up to max of available CPUs)
Returns:
dict: A dictionary containing the predictions for each file, with the filepath as the key
"""
# Create openWakeWord model objects
n_batches = len(file_paths)//ncpu
remainder = len(file_paths) % ncpu
chunks = [file_paths[i:i+n_batches] for i in range(0, len(file_paths)-remainder, n_batches)]
for i in range(1, remainder+1):
chunks[i-1].append(file_paths[-1*i])
# Create jobs
ps = []
mdls = []
q = Queue()
for chunk in chunks:
oww = openwakeword.Model(
wakeword_model_paths=wakeword_model_paths,
input_sizes=[16]
)
mdls.append(oww)
def f(clips):
results = []
for clip in clips:
results.append({clip: mdls[-1].predict_clip(clip)})
q.put(results)
ps.append(Process(target=f, args=(chunk,)))
# Submit jobs
for p in ps:
p.start()
# Collection results
results = []
for p in ps:
while q.empty():
time.sleep(1)
results.extend(q.get())
# Consolidate results and return
return {list(i.keys())[0]:list(i.values())[0] for i in results}

View file

@ -6,9 +6,12 @@ with open("README.md", "r", encoding="utf-8") as fh:
setuptools.setup(
name="openwakeword",
version="0.0.1",
install_requires=[
'onnxruntime>=1.10.0,<2'
],
author="David Scripka",
author_email="david.scripka@gmail.com",
description="An open-source audio wake word (or phrase) detection framework with a focus on accuracy and customizability",
description="An open-source audio wake word (or phrase) detection framework with a focus on performance and simplicity",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/pypa/sampleproject",