Fixed bugs in handling of variable input data sizes and adjusted tests

This commit is contained in:
dscripka 2023-08-25 22:07:12 -04:00
parent 3dbc16e11e
commit 7056d28a3e
3 changed files with 37 additions and 25 deletions

View file

@ -97,7 +97,7 @@ class Model():
raise ValueError("Could not find pretrained model for model name '{}'".format(i))
else:
wakeword_models[ndx] = matching_model[0]
wakeword_model_names.append(matching_model[0].split(os.path.sep)[-1])
wakeword_model_names.append(i)
# Create attributes to store models and metadata
self.models = {}

View file

@ -396,23 +396,28 @@ class AudioFeatures():
def _streaming_features(self, x):
# Add raw audio data to buffer, temporarily storing extra frames if not an even number of 80 ms chunks
processed_samples = 0
if self.raw_data_remainder.shape[0] != 0:
x = np.concatenate((self.raw_data_remainder, x))
self.raw_data_remainder = np.empty(0)
if x.shape[0] < 1280 and self.accumulated_samples == 0:
self._buffer_raw_data(x)
self.accumulated_samples += len(x)
elif (x.shape[0] >= 1280 and self.accumulated_samples == 0) or \
(self.accumulated_samples != 0 and self.accumulated_samples + x.shape[0] >= 1280):
if self.accumulated_samples + x.shape[0] >= 1280:
remainder = (self.accumulated_samples + x.shape[0]) % 1280
x_even_chunks = x[0:x.shape[0] - remainder]
self._buffer_raw_data(x_even_chunks)
self.accumulated_samples += len(x_even_chunks)
self.raw_data_remainder = x[x.shape[0] - remainder:]
if remainder != 0:
x_even_chunks = x[0:-remainder]
self._buffer_raw_data(x_even_chunks)
self.accumulated_samples += len(x_even_chunks)
self.raw_data_remainder = x[-remainder:]
elif remainder == 0:
self._buffer_raw_data(x)
self.accumulated_samples += x.shape[0]
self.raw_data_remainder = np.empty(0)
else:
self.accumulated_samples += x.shape[0]
self._buffer_raw_data(x)
# Only calculate melspectrogram once minimum samples area accumulated
if self.accumulated_samples >= 1280:
# Only calculate melspectrogram once minimum samples are accumulated
if self.accumulated_samples >= 1280 and self.accumulated_samples % 1280 == 0:
self._streaming_melspectrogram(self.accumulated_samples)
# Calculate new audio embeddings/features based on update melspectrograms

View file

@ -57,30 +57,37 @@ class TestModels:
def test_predict_with_different_frame_sizes(self):
# Test with binary model
owwModel = openwakeword.Model(wakeword_models=[
owwModel1 = openwakeword.Model(wakeword_models=[
os.path.join("openwakeword", "resources", "models", "alexa_v0.1.onnx")
], inference_framework="onnx")
owwModel2 = openwakeword.Model(wakeword_models=[
os.path.join("openwakeword", "resources", "models", "alexa_v0.1.onnx")
], inference_framework="onnx")
# Prediction on random data with integer multiples of standard chunk size (1280 samples)
owwModel.predict(np.random.randint(-1000, 1000, 1280).astype(np.int16))
owwModel.predict(np.random.randint(-1000, 1000, 1280*2).astype(np.int16))
predictions1 = owwModel1.predict_clip(os.path.join("tests", "data", "alexa_test.wav"), chunk_size=1280)
predictions2 = owwModel2.predict_clip(os.path.join("tests", "data", "alexa_test.wav"), chunk_size=1280*2)
np.testing.assert_approx_equal(max([i['alexa_v0.1'] for i in predictions1]), max([i['alexa_v0.1'] for i in predictions2]), 5)
# Prediction on data with a chunk size not an integer multiple of 1280
owwModel.predict(np.random.randint(-1000, 1000, 1024).astype(np.int16))
owwModel.predict(np.random.randint(-1000, 1000, 1024*2).astype(np.int16))
predictions1 = owwModel1.predict_clip(os.path.join("tests", "data", "alexa_test.wav"), chunk_size=1024)
predictions2 = owwModel2.predict_clip(os.path.join("tests", "data", "alexa_test.wav"), chunk_size=1024*2)
np.testing.assert_approx_equal(max([i['alexa_v0.1'] for i in predictions1]), max([i['alexa_v0.1'] for i in predictions2]), 5)
# Test with multiclass model
owwModel = openwakeword.Model(wakeword_models=[
os.path.join("openwakeword", "resources", "models", "timer_v0.1.onnx")
], inference_framework="onnx")
owwModel1 = openwakeword.Model(wakeword_models=["timer"], inference_framework="onnx")
owwModel2 = openwakeword.Model(wakeword_models=["timer"], inference_framework="onnx")
# Prediction on random data with integer multiples of standard chunk size (1280 samples)
owwModel.predict(np.random.randint(-1000, 1000, 1280).astype(np.int16))
owwModel.predict(np.random.randint(-1000, 1000, 1280*2).astype(np.int16))
predictions1 = owwModel1.predict_clip(os.path.join("tests", "data", "alexa_test.wav"), chunk_size=1280)
predictions2 = owwModel2.predict_clip(os.path.join("tests", "data", "alexa_test.wav"), chunk_size=1280*2)
assert abs(max([i['1_minute_timer'] for i in predictions1]) - max([i['1_minute_timer'] for i in predictions2])) < 0.00001
# Prediction on data with a chunk size not an integer multiple of 1280
owwModel.predict(np.random.randint(-1000, 1000, 1024).astype(np.int16))
owwModel.predict(np.random.randint(-1000, 1000, 1024*2).astype(np.int16))
predictions1 = owwModel1.predict_clip(os.path.join("tests", "data", "alexa_test.wav"), chunk_size=1024)
predictions2 = owwModel2.predict_clip(os.path.join("tests", "data", "alexa_test.wav"), chunk_size=1024*2)
assert abs(max([i['1_minute_timer'] for i in predictions1]) - max([i['1_minute_timer'] for i in predictions2])) < 0.00001
def test_exception_handling_for_inference_framework(self):
with mock.patch.dict(sys.modules, {'onnxruntime': None}):