Skip to content

Commit

Permalink
DTLN example: (#2012)
Browse files Browse the repository at this point in the history
Adding DTLN example to demonstrates LSTM layers on HiFi DSP and NOT for evaluating noise suppression quality.

BUG=none
  • Loading branch information
cad-audio authored Jan 10, 2024
1 parent 85e19dd commit ca5358f
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 0 deletions.
27 changes: 27 additions & 0 deletions tensorflow/lite/micro/examples/dtln/Makefile.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

DTLN_TEST_SRCS := \
$(TENSORFLOW_ROOT)tensorflow/lite/micro/examples/dtln/dtln_test.cc \
$(TENSORFLOW_ROOT)tensorflow/lite/micro/examples/dtln/dtln_inout_data.cc

DTLN_TEST_HDRS := \
$(TENSORFLOW_ROOT)tensorflow/lite/micro/examples/dtln/dtln_inout_data.h

DTLN_GENERATOR_INPUTS := \
$(TENSORFLOW_ROOT)tensorflow/lite/micro/examples/dtln/dtln_noise_suppression.tflite

DTLN_GENERATED_SRCS := \
$(GENERATED_SRCS_DIR)$(TENSORFLOW_ROOT)tensorflow/lite/micro/examples/dtln/dtln_noise_suppression_model_data.cc

DTLN_GENERATED_HDRS := \
$(GENERATED_SRCS_DIR)$(TENSORFLOW_ROOT)tensorflow/lite/micro/examples/dtln/dtln_noise_suppression_model_data.h

#Find any platform - specific rules for this example.
include $(wildcard $(TENSORFLOW_ROOT)tensorflow/lite/micro/examples/dtln/*/Makefile.inc)

# TODO(b/161489252): Disabling warnings for this example until we have a better
# way to build third_party code with a reduced list of CFLAGS.
CCFLAGS := $(filter-out $(CC_WARNINGS),$(CCFLAGS))

# Tests loading and running a dtln model.
$(eval $(call microlite_test,dtln_test,\
$(DTLN_TEST_SRCS),$(DTLN_TEST_HDRS),$(DTLN_GENERATOR_INPUTS)))
23 changes: 23 additions & 0 deletions tensorflow/lite/micro/examples/dtln/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# DTLN example
The DTLN example is a demonstration of DTLN network running on HiFi DSP for Noise suppression in speech.
It uses feature_data as input and provides noise suppressed speech as output.
It is based on the paper(https://github.com/breizhn/DTLN).
While paper presents 2 parts, one for noise suppression and the other for speech enhancement,
the example presented here follows the noise suppression part only.
The model was re-trained by Cadence using the DNS challenge data (https://github.com/microsoft/DNS-Challenge)
and the noise suppression part was 8-bit quantized.
This example is not to be used to evaluate the network quality or quality of noise suppression, but only as a demonstration as stated above.

## Run the tests on a development machine

```
make -f tensorflow/lite/micro/tools/make/Makefile third_party_downloads
make -f tensorflow/lite/micro/tools/make/Makefile test_dtln_test
```

You should see a series of files get compiled, followed by some logging output
from a test, which should conclude with `~~~ALL TESTS PASSED~~~`. If you see
this, it means that a small program has been built and run that loads a trained
TensorFlow model, runs with features data, and got the expected
outputs. This particular test runs with a feature data as input,
and validate the output with golden reference output.
60 changes: 60 additions & 0 deletions tensorflow/lite/micro/examples/dtln/dtln_inout_data.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/* Copyright 2020 The TensorFlow Authors. 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.
==============================================================================*/

#include "tensorflow/lite/c/common.h"

int8_t feature_data[] = {
-127, -126, -115, -82, -90, -113, -15, 13, -87, -105, -77, -106,
-113, -81, -90, -123, -113, -112, -124, -120, -114, -123, -123, -112,
-115, -125, -120, -120, -126, -126, -126, -127, -128, -127, -128, -128,
-127, -127, -128, -126, -125, -126, -127, -127, -127, -128, -126, -127,
-128, -127, -127, -128, -127, -126, -127, -128, -127, -127, -127, -124,
-124, -127, -126, -126, -127, -126, -124, -125, -128, -126, -125, -127,
-126, -126, -127, -127, -126, -126, -127, -126, -126, -127, -126, -125,
-127, -126, -123, -124, -126, -126, -126, -128, -127, -127, -127, -128,
-127, -127, -128, -128, -128, -128, -128, -127, -128, -128, -127, -128,
-128, -127, -127, -128, -128, -128, -128, -128, -128, -128, -128, -128,
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
-128, -128, -128, -128, -128, -128, -128, -127, -127, -127, -127, -127,
-127, -127, -127, -128, -127, -127, -127, -127, -126, -127, -127, -127,
-127, -127, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
-128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128,
-128, -127, -128, -128, -127, -127, -128, -128, -128, -128, -128, -128,
-128, -128, -128, -128, -128};

int8_t golden_ref[] = {
119, 82, 72, 116, -5, 10, -2, 0, -2, 36, 116, 125, 123, 124, 126,
124, 115, 116, 124, 126, 121, 124, 121, 104, 104, 113, 113, 110, 115, 101,
96, 119, 120, 117, 118, 114, 104, 110, 118, 119, 111, 114, 119, 117, 114,
110, 117, 112, 115, 120, 119, 118, 119, 116, 117, 120, 121, 121, 121, 119,
117, 120, 121, 120, 118, 115, 114, 114, 117, 119, 113, 108, 108, 111, 112,
114, 114, 116, 115, 112, 110, 113, 113, 110, 107, 98, 102, 101, 101, 103,
92, 98, 101, 102, 102, 101, 104, 102, 101, 101, 100, 102, 98, 104, 100,
99, 92, 96, 87, 97, 96, 96, 96, 95, 92, 98, 95, 90, 85, 82,
87, 82, 82, 89, 90, 83, 86, 85, 80, 86, 87, 91, 89, 87, 87,
85, 82, 74, 80, 80, 72, 79, 74, 79, 82, 83, 77, 85, 71, 76,
72, 76, 76, 77, 56, 74, 74, 69, 69, 69, 65, 56, 60, 67, 71,
69, 74, 67, 71, 65, 77, 76, 79, 67, 72, 61, 60, 67, 69, 71,
77, 63, 63, 60, 63, 71, 80, 80, 74, 76, 67, 74, 63, 67, 69,
72, 77, 71, 72, 82, 65, 49, 67, 58, 71, 65, 63, 69, 61, 77,
63, 65, 65, 69, 69, 65, 72, 77, 80, 60, 79, 77, 71, 67, 79,
69, 67, 65, 74, 69, 71, 67, 76, 77, 77, 77, 83, 67, 65, 79,
77, 60, 71, 86, 86, 63, 74, 63, 63, 63, 69, 79, 63, 52, 85,
87, 86};
19 changes: 19 additions & 0 deletions tensorflow/lite/micro/examples/dtln/dtln_inout_data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* Copyright 2020 The TensorFlow Authors. 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.
==============================================================================*/

#include "tensorflow/lite/c/common.h"

extern int8_t feature_data[];
extern int8_t golden_ref[];
Binary file not shown.
100 changes: 100 additions & 0 deletions tensorflow/lite/micro/examples/dtln/dtln_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* Copyright 2020 The TensorFlow Authors. 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.
==============================================================================*/

#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/micro/examples/dtln/dtln_inout_data.h"
#include "tensorflow/lite/micro/examples/dtln/dtln_noise_suppression_model_data.h"
#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/micro/micro_log.h"
#include "tensorflow/lite/micro/micro_mutable_op_resolver.h"
#include "tensorflow/lite/micro/testing/micro_test.h"
#include "tensorflow/lite/schema/schema_generated.h"

TF_LITE_MICRO_TESTS_BEGIN

MicroPrintf(
"\nThis example demonstrates LSTM layers on HiFi DSP, NOT for evaluating "
"noise suppression quality.\n");
TF_LITE_MICRO_TEST(TestInvoke) {
// Map the model into a usable data structure. This doesn't involve any
// copying or parsing, it's a very lightweight operation.
const tflite::Model* model =
::tflite::GetModel(g_dtln_noise_suppression_model_data);
if (model->version() != TFLITE_SCHEMA_VERSION) {
MicroPrintf(
"Model provided is schema version %d not equal "
"to supported version %d.\n",
model->version(), TFLITE_SCHEMA_VERSION);
}

// Pull in only the operation implementations we need.
// This relies on a complete list of all the ops needed by this graph.

tflite::MicroMutableOpResolver<3> micro_op_resolver;
micro_op_resolver.AddUnidirectionalSequenceLSTM();
micro_op_resolver.AddFullyConnected();
micro_op_resolver.AddLogistic();

// Create an area of memory to use for input, output, and intermediate arrays.
constexpr int tensor_arena_size = 16 * 1024;
alignas(16) uint8_t tensor_arena[tensor_arena_size];

// Build an interpreter to run the model with.
tflite::MicroInterpreter interpreter(model, micro_op_resolver, tensor_arena,
tensor_arena_size);
interpreter.AllocateTensors();

// Get information about the memory area to use for the model's input.
TfLiteTensor* input = interpreter.input(0);

// Make sure the input has the properties we expect.
TF_LITE_MICRO_EXPECT(input != nullptr);
TF_LITE_MICRO_EXPECT_EQ(3, input->dims->size);
TF_LITE_MICRO_EXPECT_EQ(1, input->dims->data[0]);
TF_LITE_MICRO_EXPECT_EQ(1, input->dims->data[1]);
TF_LITE_MICRO_EXPECT_EQ(257, input->dims->data[2]);
TF_LITE_MICRO_EXPECT_EQ(kTfLiteInt8, input->type);

// Copy a spectrogram created from a noisy.wav audio file,
// into the memory area used for the input.
for (size_t i = 0; i < input->bytes; ++i) {
input->data.int8[i] = feature_data[i];
}

// Run the model on this input and make sure it succeeds.
TfLiteStatus invoke_status = interpreter.Invoke();
if (invoke_status != kTfLiteOk) {
MicroPrintf("Invoke failed\n");
}
TF_LITE_MICRO_EXPECT_EQ(kTfLiteOk, invoke_status);

// Get the output from the model, and make sure it's the expected size and
// type.
TfLiteTensor* output = interpreter.output(0);
TF_LITE_MICRO_EXPECT_EQ(3, output->dims->size);
TF_LITE_MICRO_EXPECT_EQ(1, output->dims->data[0]);
TF_LITE_MICRO_EXPECT_EQ(1, output->dims->data[1]);
TF_LITE_MICRO_EXPECT_EQ(257, output->dims->data[2]);
TF_LITE_MICRO_EXPECT_EQ(kTfLiteInt8, output->type);

int output_size =
output->dims->data[0] * output->dims->data[1] * output->dims->data[2];
for (int i = 0; i < output_size; i++)
TF_LITE_MICRO_EXPECT_EQ(output->data.int8[i], golden_ref[i]);

MicroPrintf("Ran successfully\n");
}

TF_LITE_MICRO_TESTS_END

0 comments on commit ca5358f

Please sign in to comment.