There is at least 1 reference to internal data in the interpreter in the form of a numpy array or slice. Be sure to only hold the function returned from tensor() if you are using raw data access.

Raise code
""" nterpreter that may reallocate memory e.g. invoke(), ...
Raises:
RuntimeError: If there exist numpy objects pointing to internal memory
then we throw.
"""
if not self._safe_to_run():
raise RuntimeError("""There is at least 1 reference to internal data
in the interpreter in the form of a numpy array or slice. Be sure to
only hold the function returned from tensor() if you are using raw
data access.""")
# Experimental and subject to change
def _get_op_details(self, op_index):
"""Gets a dictionary with arrays of ids for tensors involved with an op.
A """
Links to the raise (1)
https://github.com/tensorflow/tensorflow/blob/ae722be2e5eecc64e3eb45cafc57309e282debb3/tensorflow/lite/python/interpreter.py#L448Ways to fix
The interpreter makes the TensorFlow Lite interpreter accessible in Python. It is possible to use this interpreter in a multithreaded Python environment, but you must be sure to call functions of a particular instance from only one thread at a time.
Simply, create tflite model.
import tensorflow as tf
import numpy as np
with tf.Graph().as_default():
img = tf.compat.v1.placeholder(name="img", dtype=tf.float32, shape=(1, 3))
const = tf.constant([1., 2., 3.])
val = img + const
out = tf.identity(val, name='output')
with tf.compat.v1.Session() as sess:
converter = tf.compat.v1.lite.TFLiteConverter.from_session(sess, [img], [out])
converter.inference_type = tf.compat.v1.lite.constants.QUANTIZED_UINT8
input_arrays = converter.get_input_arrays()
converter.quantized_input_stats = {input_arrays[0] : np.array([2,6])} # mean, std_dev
converter.default_ranges_stats = (0, 3)
tflite_model = converter.convert()
open("example1.tflite", "wb").write(tflite_model)
and our interpreter
itp_full2 = tf.lite.Interpreter(model_path="example1.tflite")
itp_full2.allocate_tensors()
imgx = np.array([[2,1,0]]).astype(np.uint8) # cast to uint8
itp_full2.set_tensor(1, imgx)
itp_full2.invoke()
res = itp_full2.tensor(2)
print(res)
The error arises from:
def _ensure_safe():
if not self._safe_to_run():
raise RuntimeError("""There is at least 1 reference to internal data
in the interpreter in the form of a numpy array or slice. Be sure to
only hold the function returned from tensor() if you are using raw
data access.""")
which means it is safe to run tflite calls that may destroy internally allocated memory.
def _safe_to_run(self):
return sys.getrefcount(self._interpreter) == 2
It returns False when there exist NumPy array buffers. This means it is not safe to run tflite calls that may destroy (or alter) internally allocated memory. So for _ensure_safe() function to not raise this runtime error we have to make sure that no NumPy arrays pointing to internal buffers are active.
sys.getrefcount tells us the reference count of an object.
Also, for more clarity note that the function _ensure_safe() should be called from any function that will call a function on _interpreter that may reallocate memory. Thus when we call the function
interpreter.allocate_tensors()
Now that the root cause and working is known, to overcome this runtime error i.e to have no numpy arrays pointing to internal buffers, we have to clear them.
To clear them:
a) Either shutdown your Jupiter notebook and restart the kernel, as this will clear all NumPy arrays/slices
b) Or simply load the model again
Reference: link