我正面临着坦索弗莱的问题。我知道这个错误:
不支持
类型的INT32 (2)。节点STRIDED_SLICE (编号2)未能在状态1调用
我所做的是:
我用MNIST数据训练了一个模型。
model = tf.keras.Sequential([
tf.keras.layers.InputLayer(input_shape=(28, 28)),
tf.keras.layers.Reshape(target_shape=(28, 28, 1)),
tf.keras.layers.Conv2D(filters=12, kernel_size=(3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(10)
])
我使用整数量化来转换模型.但是,当我调用模型时,它会抛出该错误。
我在看striced_slice.cc时发现了这个:
switch (output->type) {
case kTfLiteFloat32:
reference_ops::StridedSlice(op_params,
tflite::micro::GetTensorShape(input),
tflite::micro::GetTensorData<float>(input),
tflite::micro::GetTensorShape(output),
tflite::micro::GetTensorData<float>(output));
break;
case kTfLiteUInt8:
reference_ops::StridedSlice(
op_params, tflite::micro::GetTensorShape(input),
tflite::micro::GetTensorData<uint8_t>(input),
tflite::micro::GetTensorShape(output),
tflite::micro::GetTensorData<uint8_t>(output));
break;
case kTfLiteInt8:
reference_ops::StridedSlice(op_params,
tflite::micro::GetTensorShape(input),
tflite::micro::GetTensorData<int8_t>(input),
tflite::micro::GetTensorShape(output),
tflite::micro::GetTensorData<int8_t>(output));
break;
default:
TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.",
TfLiteTypeGetName(input->type), input->type);
因此,不支持int32。我真不知道该如何处理这种问题。有任何方法来改变这个节点上的行为吗?我应该在量化步骤中做一些不同的事情吗?
我所做的是:
def representative_data_gen():
for input_value in tf.data.Dataset.from_tensor_slices(train_images).batch(1).take(100):
yield [input_value]
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_data_gen
# Ensure that if any ops can't be quantized, the converter throws an error
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.int8
converter.inference_output_type = tf.int8
tflite_model = converter.convert()
open("model_int8.tflite", "wb").write(tflite_model)
PD:我正在使用stm32中的tensorflow-lite。
提前谢谢。
发布于 2020-11-16 04:43:01
当您执行全整数量化时,您的输入和输出应该是1字节长(在您的例子中是int8)。给出输入的int8值,您将能够调用模型。
发布于 2021-02-16 03:52:17
我只是简单地将INT32支持添加到striced_slice.cc中来解决这个问题。
case kTfLiteFloat32:
reference_ops::StridedSlice(op_params,
tflite::micro::GetTensorShape(input),
tflite::micro::GetTensorData<float>(input),
tflite::micro::GetTensorShape(output),
tflite::micro::GetTensorData<float>(output));
break;
case kTfLiteUInt8:
reference_ops::StridedSlice(
op_params, tflite::micro::GetTensorShape(input),
tflite::micro::GetTensorData<uint8_t>(input),
tflite::micro::GetTensorShape(output),
tflite::micro::GetTensorData<uint8_t>(output));
break;
case kTfLiteInt8:
reference_ops::StridedSlice(op_params,
tflite::micro::GetTensorShape(input),
tflite::micro::GetTensorData<int8_t>(input),
tflite::micro::GetTensorShape(output),
tflite::micro::GetTensorData<int8_t>(output));
break;
case kTfLiteInt32:
reference_ops::StridedSlice(op_params,
tflite::micro::GetTensorShape(input),
tflite::micro::GetTensorData<int8_t>(input),
tflite::micro::GetTensorShape(output),
tflite::micro::GetTensorData<int8_t>(output));
break;
default:
TF_LITE_KERNEL_LOG(context, "Type %s (%d) not supported.",
TfLiteTypeGetName(input->type), input->type);
return kTfLiteError;
我复制了kTfLiteInt8案例并创建了kTfLiteInt32案例。
因为我知道输入数据实际上是int8类型,所以我只是将其转换为int8。
我已经在ESP32微控制器上测试过它。我没有运行一套完整的测试,但有几个样本,它发挥了预期的作用。
这是个解决办法。真正的修复应该在转换器中完成,在那里它使用TFLITE_BUILTINS_INT8完全量化模型。不知何故,它量化了float32类型,但int32停留在其中一个层中。
https://stackoverflow.com/questions/64850356
复制