web-dev-qa-db-ja.com

「インタプリタの内部データへの参照が派手な配列またはスライスの形式で少なくとも1つある」を修正し、tf.liteで推論を実行する方法

this に従ってトレーニング後の量子化を実行することで最適化したmnistケラスモデルでtf.liteを使用して推論を実行しようとしています

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.

これは、画像のサイズを4次元に変更した後、またはコメント行に表示されているインタープリター自体のサイズを変更した後に発生します。これの前のエラーは、「4次元が予期されていましたが、3次元が見つかりました」のようなものでした。これがコードです:

import tensorflow as tf
tf.enable_eager_execution()
import numpy as np
from tensorflow.keras.datasets import mnist
import matplotlib.pyplot as plt
%matplotlib inline

mnist_train, mnist_test = tf.keras.datasets.mnist.load_data()
images, labels = tf.cast(mnist_test[0], tf.float32)/255.0, mnist_test[1]
images = np.reshape(images,[images.shape[0],images.shape[1],images.shape[2],1])
mnist_ds = tf.data.Dataset.from_tensor_slices((images, labels)).batch(1, drop_remainder = True)

interpreter = tf.lite.Interpreter(model_path="C:\\Users\\USER\\Documents\\python\\converted_quant_model_cnn_5_100.tflite")
#tf.lite.Interpreter.resize_tensor_input(interpreter, input_index="index" , tensor_size=([1,28,28,1]) )

interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
input_index = interpreter.get_input_details()[0]["index"]
output_index = interpreter.get_output_details()[0]["index"]

for img, label in mnist_ds.take(1):
  break
#print(img.get_shape)
interpreter.set_tensor(input_index, img)
interpreter.invoke()
predictions = interpreter.get_tensor(output_index)
8
theroguecode

Tfliteモデルで推論を実行しているときに同じ問題に直面していました。さかのぼると、このランタイムエラーが発生する関数を読み取ってしまいました。

このエラーを発生させる原因となる関数は次のとおりです。

_def _ensure_safe(self)
_

そして

_def _safe_to_run(self)
_

関数「_safe_to_run()」は、関数「_ensure_safe()」内から呼び出されます。 _safe_to_run()関数は、TrueまたはFalseを返します。 Falseを返すと、上記のランタイムエラーが発生します。

Numpy配列バッファーが存在する場合は、Falseを返します。つまり、内部的に割り当てられたメモリを破壊(または変更)する可能性のあるtflite呼び出しを実行することは安全ではありません。

したがって、「_ ensure_safe()」関数がこの実行時エラーを発生させないようにするには、内部バッファーを指す派手な配列がアクティブになっていないことを確認する必要があります。

また、より明確にするために、関数「_ensure_safe()」は、メモリを再割り当てする可能性がある_interpreterの関数を呼び出すすべての関数から呼び出す必要があることに注意してください。したがって、関数を呼び出すとき

interpreter.allocate_tensors()

上記のコードで述べたように、この "interpreter.allocate_tensors()"関数が内部的に行う最初のことは、 "_ ensure_safe()"関数を呼び出すことです。この場合の変更とは、名前が示すように「割り当てる」ことを意味します。 「_ensure_safe()」も呼び出されるもう1つの例は、「invoke()」関数が呼び出されたときです。そして、そのような関数はたくさんありますが、あなたはそのアイデアを思いつきます。

根本的な原因と動作がわかったので、このランタイムエラーを克服するには、内部バッファーを指す派手な配列がないように、それらをクリアする必要があります。

それらをクリアするには:

a)。すべてのnumpy配列/スライスをクリアするため、jupyterノートブックをシャットダウンしてカーネルを再起動します

b)。または、単にモデルをもう一度ロードします。つまり、jupyterノートブックでこの行をもう一度実行します。

_interpreter = tf.lite.Interpreter(model_path="C:\\Users\\USER\\Documents\\python\\converted_quant_model_cnn_5_100.tflite")
_

これで問題が解決することを願っています。

これらのオプションが両方ともない場合、上記の説明で「why」と指摘したので、このエラーが発生します。したがって、「内部バッファを指す派手な配列がない」他の方法を見つけた場合は、共有してください。

リファレンス: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/python/interpreter.py

4
Sushanth

私のためにそれを解決したものを追加するだけです。私はスクリプトを使用しているため、Jupyter Notebooksとは関係ありません。

私の問題は、predictions = interpreter.tensor(output_index)の代わりにpredictions = interpreter.get_tensor(output_index)を使用していたことでした。

ただし、問題はこのスレッドでコメントされた同じエラーとして表示されました。

0
BCJuan