DTLN example: (#2012)
Adding DTLN example to demonstrates LSTM layers on HiFi DSP and NOT for evaluating noise suppression quality.
BUG=none
diff --git a/tensorflow/lite/micro/examples/dtln/Makefile.inc b/tensorflow/lite/micro/examples/dtln/Makefile.inc
new file mode 100644
index 0000000..a64686e
--- /dev/null
+++ b/tensorflow/lite/micro/examples/dtln/Makefile.inc
@@ -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)))
diff --git a/tensorflow/lite/micro/examples/dtln/README.md b/tensorflow/lite/micro/examples/dtln/README.md
new file mode 100644
index 0000000..eb96b0c
--- /dev/null
+++ b/tensorflow/lite/micro/examples/dtln/README.md
@@ -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.
diff --git a/tensorflow/lite/micro/examples/dtln/dtln_inout_data.cc b/tensorflow/lite/micro/examples/dtln/dtln_inout_data.cc
new file mode 100644
index 0000000..a4652a7
--- /dev/null
+++ b/tensorflow/lite/micro/examples/dtln/dtln_inout_data.cc
@@ -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};
diff --git a/tensorflow/lite/micro/examples/dtln/dtln_inout_data.h b/tensorflow/lite/micro/examples/dtln/dtln_inout_data.h
new file mode 100644
index 0000000..c5fde46
--- /dev/null
+++ b/tensorflow/lite/micro/examples/dtln/dtln_inout_data.h
@@ -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[];
diff --git a/tensorflow/lite/micro/examples/dtln/dtln_noise_suppression.tflite b/tensorflow/lite/micro/examples/dtln/dtln_noise_suppression.tflite
new file mode 100644
index 0000000..143ef8d
--- /dev/null
+++ b/tensorflow/lite/micro/examples/dtln/dtln_noise_suppression.tflite
Binary files differ
diff --git a/tensorflow/lite/micro/examples/dtln/dtln_test.cc b/tensorflow/lite/micro/examples/dtln/dtln_test.cc
new file mode 100644
index 0000000..1077195
--- /dev/null
+++ b/tensorflow/lite/micro/examples/dtln/dtln_test.cc
@@ -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