keras 节点号X(RESHAPE)准备失败,使用tflite v2.2调整Tensor大小

bkhjykvo  于 2023-05-23  发布在  其他
关注(0)|答案(3)|浏览(158)

下面是一个简单的代码来重现错误:

import os
os.environ["CUDA_VISIBLE_DEVICES"]="-1"

import numpy as np
from keras.models import Sequential
from keras.layers import Conv1D, Flatten, Dense
import tensorflow as tf

model_path = 'test.h5'

model = Sequential()
model.add(Conv1D(8,(5,), input_shape=(100,1)))
model.add(Flatten())
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
model.save(model_path)

model = tf.keras.models.load_model(model_path, compile=False)
converter = tf.lite.TFLiteConverter.from_keras_model(model)

tflite_model = converter.convert()

interpreter = tf.lite.Interpreter(model_content=tflite_model)

interpreter.resize_tensor_input(interpreter.get_input_details()[0]['index'], (2,100,1))
interpreter.resize_tensor_input(interpreter.get_output_details()[0]['index'], (2,1))

interpreter.allocate_tensors()
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-3-ad8e2eea467f> in <module>
     27 interpreter.resize_tensor_input(interpreter.get_output_details()[0]['index'], (2,1))
     28 
---> 29 interpreter.allocate_tensors()

<>/tensorflow/lite/python/interpreter.py in allocate_tensors(self)
    240   def allocate_tensors(self):
    241     self._ensure_safe()
--> 242     return self._interpreter.AllocateTensors()
    243 
    244   def _safe_to_run(self):

<>/tensorflow/lite/python/interpreter_wrapper/tensorflow_wrap_interpreter_wrapper.py in AllocateTensors(self)
    108 
    109     def AllocateTensors(self):
--> 110         return _tensorflow_wrap_interpreter_wrapper.InterpreterWrapper_AllocateTensors(self)
    111 
    112     def Invoke(self):

RuntimeError: tensorflow/lite/kernels/reshape.cc:66 num_input_elements != num_output_elements (1536 != 768)Node number 3 (RESHAPE) failed to prepare.

问题似乎来自flatten层中的reshapes函数。我已经能够用tensorflow 1.5执行这种调整大小,但不能用2.2版本。
下面是重塑层的信息:

{'name': 'sequential_1/flatten_1/Reshape',
  'index': 8,
  'shape': array([  1, 768], dtype=int32),
  'shape_signature': array([  1, 768], dtype=int32),
  'dtype': numpy.float32,
  'quantization': (0.0, 0),
  'quantization_parameters': {'scales': array([], dtype=float32),
   'zero_points': array([], dtype=int32),
   'quantized_dimension': 0},
  'sparsity_parameters': {}},

我想也许我也应该调整这个层的大小,所以我添加了:
interpreter.resize_tensor_input(8, (2,768))
但我也犯了同样的错误
RuntimeError: tensorflow/lite/kernels/reshape.cc:66 num_input_elements != num_output_elements (1536 != 768)Node number 3 (RESHAPE) failed to prepare.

uyhoqukh

uyhoqukh1#

我已经想出了一个解决方案,在转换为tflite之前重塑模型,重塑keras模型,然后将其转换为具体函数,并使用from_concrete_function而不是from_keras_model。

import os
os.environ["CUDA_VISIBLE_DEVICES"]="-1"

import numpy as np
from keras.models import Sequential
from keras.layers import Conv1D, Flatten, Dense
import tensorflow as tf

model_path = 'test.h5'

model = Sequential()
model.add(Conv1D(8,(5,), input_shape=(100,1)))
model.add(Flatten())
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
model.save(model_path)

model = tf.keras.models.load_model(model_path, compile=False)

batch_size = 2
input_shape = model.inputs[0].shape.as_list()
input_shape[0] = batch_size
func = tf.function(model).get_concrete_function(
    tf.TensorSpec(input_shape, model.inputs[0].dtype))
converter = tf.lite.TFLiteConverter.from_concrete_functions([func])

tflite_model = converter.convert()

interpreter = tf.lite.Interpreter(model_content=tflite_model)

interpreter.allocate_tensors()
qcuzuvrc

qcuzuvrc2#

resize_tensor_input将批量大小更改为2,这似乎是触发此问题的原因。
TFL对批处理大小= 1(大多数情况下)有很好的支持,但对更大的批处理大小的支持偶尔会出现错误。在某些地方,此批处理大小参数可能会被忽略。你可以尝试批量大小= 1,看看它是否有效?
调用resize_tensor_input时,TFL将使用Prepare方法重新计算计算图中所有节点的输入/输出形状。对中间层的任何更改都将被覆盖,因此interpreter.resize_tensor_input(8, (2,768))没有帮助。

n6lpvg4x

n6lpvg4x3#

此问题与生成器项数据形状和要将模型转换为的预期输入形状之间的形状不匹配有关。我通过确保批量大小在input_shape和生成器项大小之间对齐来解决这个问题。示例:如果生成器项形状为(50,255,255),则将输入形状声明为(50,255,255)

相关问题