TfLiteKerasInterpreter(model_content: str, input_name: str | None = None, output_name: str | None = None, signature_key: str | None = None)
TFLite model interpreter that takes care of I/O conversion and prediction.
Parameters:
-
model_content
(str
)
–
-
input_name
(str | None
, default:
None
)
–
Input layer name. Defaults to None.
-
output_name
(str | None
, default:
None
)
–
Output layer name. Defaults to None.
-
signature_key
(str | None
, default:
None
)
–
Signature key. Defaults to None
Example:
# Create simple dataset
test_x = np.random.rand(1000, 64).astype(np.float32)
test_y = np.random.randint(0, 10, 1000).astype(np.int32)
# Create a dense model and train
model = keras.Sequential([
keras.layers.Dense(64, activation="relu", input_shape=(64,)),
keras.layers.Dense(32, activation="relu"),
keras.layers.Dense(10, activation="softmax"),
])
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.fit(test_x, test_y, epochs=1, validation_split=0.2)
# Create converter and convert to TFLite w/ FP32 quantization
converter = nse.converters.tflite.TfLiteKerasConverter(model=model)
tflite_content = converter.convert(
test_x,
quantization=nse.converters.tflite.QuantizationType.FP32,
io_type="float32"
)
interpreter = nse.interpreters.tflite.TfLiteKerasInterpreter(model_content=tflite_content)
interpreter.compile()
y_pred_tfl = interpreter.predict(test_x)
y_pred_tf = model.predict(test_x)
print(np.allclose(y_pred_tf, y_pred_tfl, atol=1e-3))
Source code in neuralspot_edge/interpreters/tflite/interpreter.py
| def __init__(
self,
model_content: str,
input_name: str | None = None,
output_name: str | None = None,
signature_key: str | None = None,
):
"""TFLite model interpreter that takes care of I/O conversion and prediction.
Args:
model_content (str): TFLite model content
input_name (str | None, optional): Input layer name. Defaults to None.
output_name (str | None, optional): Output layer name. Defaults to None.
signature_key (str | None, optional): Signature key. Defaults to None
Example:
```python
# Create simple dataset
test_x = np.random.rand(1000, 64).astype(np.float32)
test_y = np.random.randint(0, 10, 1000).astype(np.int32)
# Create a dense model and train
model = keras.Sequential([
keras.layers.Dense(64, activation="relu", input_shape=(64,)),
keras.layers.Dense(32, activation="relu"),
keras.layers.Dense(10, activation="softmax"),
])
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
model.fit(test_x, test_y, epochs=1, validation_split=0.2)
# Create converter and convert to TFLite w/ FP32 quantization
converter = nse.converters.tflite.TfLiteKerasConverter(model=model)
tflite_content = converter.convert(
test_x,
quantization=nse.converters.tflite.QuantizationType.FP32,
io_type="float32"
)
interpreter = nse.interpreters.tflite.TfLiteKerasInterpreter(model_content=tflite_content)
interpreter.compile()
y_pred_tfl = interpreter.predict(test_x)
y_pred_tf = model.predict(test_x)
print(np.allclose(y_pred_tf, y_pred_tfl, atol=1e-3))
```
"""
self.model_content = model_content
self.interpreter = tf.lite.Interpreter(model_content=model_content)
self.interpreter.allocate_tensors()
self.signature_key = signature_key
self._has_signature = False
self._input_name = input_name
self._input_shape = None
self._input_scale = None
self._input_zero_point = None
self._input_dtype = "float32"
self._output_name = output_name
self._output_scale = None
self._output_zero_point = None
self._output_dtype = "float32"
|
Functions
compile
Compile model and extract input/output details.
Source code in neuralspot_edge/interpreters/tflite/interpreter.py
| def compile(self):
"""Compile model and extract input/output details."""
# Some models may lose signature after converting to tflite due to TF issues.
# Most prevalent for models lowered to concrete functions.
self._has_signature = len(self.interpreter.get_signature_list()) > 0
if not self._has_signature:
input_details = self.interpreter.get_input_details()[0]
output_details = self.interpreter.get_output_details()[0]
self._input_shape = input_details["shape_signature"].tolist()
self._input_name = input_details["index"]
self._output_name = output_details["index"]
else:
model_sig = self.interpreter.get_signature_runner(self.signature_key)
inputs_details = model_sig.get_input_details()
outputs_details = model_sig.get_output_details()
if self._input_name is None:
self._input_name = list(inputs_details.keys())[0]
if self._output_name is None:
self._output_name = list(outputs_details.keys())[0]
input_details = inputs_details[self._input_name]
output_details = outputs_details[self._output_name]
self._input_shape = input_details["shape_signature"].tolist()[1:]
# END IF
input_scale: list[float] = input_details["quantization_parameters"]["scales"]
input_zero_point: list[int] = input_details["quantization_parameters"]["zero_points"]
output_scale: list[float] = output_details["quantization_parameters"]["scales"]
output_zero_point: list[int] = output_details["quantization_parameters"]["zero_points"]
self._input_dtype = input_details["dtype"]
if len(input_scale) and len(input_zero_point):
self._input_scale = input_scale[0]
self._input_zero_point = input_zero_point[0]
# END IF
self._output_dtype = output_details["dtype"]
if len(output_scale) and len(output_zero_point):
self._output_scale = output_scale[0]
self._output_zero_point = output_zero_point[0]
|
convert_input(x: npt.NDArray) -> npt.NDArray
Convert input data based on quantization.
NOTE: predict() will call this method internally.
Parameters:
Returns:
-
NDArray
–
npt.NDArray: Prepared input samples
Source code in neuralspot_edge/interpreters/tflite/interpreter.py
| def convert_input(self, x: npt.NDArray) -> npt.NDArray:
"""Convert input data based on quantization.
NOTE: predict() will call this method internally.
Args:
x (npt.NDArray): Input samples
Returns:
npt.NDArray: Prepared input samples
"""
inputs = x.copy()
inputs = inputs.reshape([-1] + self._input_shape)
if self._input_scale and self._input_zero_point:
inputs = inputs / self._input_scale + self._input_zero_point
inputs = inputs.astype(self._input_dtype)
return inputs
|
convert_output
convert_output(outputs: npt.NDArray) -> npt.NDArray
Convert output data based on quantization.
NOTE: predict() will call this method internally.
Parameters:
Returns:
-
NDArray
–
npt.NDArray: Prepared output samples
Source code in neuralspot_edge/interpreters/tflite/interpreter.py
| def convert_output(self, outputs: npt.NDArray) -> npt.NDArray:
"""Convert output data based on quantization.
NOTE: predict() will call this method internally.
Args:
outputs (npt.NDArray): Output samples
Returns:
npt.NDArray: Prepared output samples
"""
outputs = outputs.astype(np.float32)
if self._output_scale and self._output_zero_point:
outputs = (outputs - self._output_zero_point) * self._output_scale
return outputs
|
predict
predict(x: npt.NDArray) -> npt.NDArray
Predict using TFLite model
Parameters:
Returns:
-
NDArray
–
npt.NDArray: Predicted values
Source code in neuralspot_edge/interpreters/tflite/interpreter.py
| def predict(
self,
x: npt.NDArray,
) -> npt.NDArray:
"""Predict using TFLite model
Args:
x (npt.NDArray): Input samples
Returns:
npt.NDArray: Predicted values
"""
inputs = self.convert_input(x)
if not self._has_signature:
outputs = []
for sample in inputs:
self.interpreter.set_tensor(self._input_name, sample)
self.interpreter.invoke()
y = self.interpreter.get_tensor(self._output_name)
outputs.append(y)
outputs = np.concatenate(outputs, axis=0)
else:
model_sig = self.interpreter.get_signature_runner(self.signature_key)
outputs = np.array(
[
model_sig(**{self._input_name: inputs[i : i + 1]})[self._output_name][0]
for i in range(inputs.shape[0])
],
dtype=self._output_dtype,
)
# END IF
outputs = self.convert_output(outputs)
return outputs
|