在量化中使用代表性数据集生成器时,“无法将值转换为可读张量”

问题描述 投票:0回答:2

我正在量化一个模型。该模型采用 224x224 输入。

我使用内置函数

preprocess_input()
对数据进行预处理,该函数减去一些中心像素。

现在,当在

representative_dataset_gen()
中使用具有此预处理功能的简单图像时,一切正常

def representative_dataset_gen():
        pfad='./000001.jpg'
        img = cv2.imread(pfad)
        img = np.expand_dims(img,0).astype(np.float32) 
        img = preprocess_input(img) 
        yield [img]

但是当我使用生成器函数来使用多个图像时

def prepare(img):
    img = np.expand_dims(img,0).astype(np.float32)
    img = preprocess_input(img)
    return arg
      
    
repDatagen=tf.keras.preprocessing.image.ImageDataGenerator(preprocessing_function=prepare)
datagen=repDatagen.flow_from_directory(folderpath,target_size=size,batch_size=1)


def representative_dataset_gen():
  for _ in range(10):
    img = datagen.next()
    yield [img]

我收到以下错误:

ValueError:无法将值转换为可读的张量。

我的猜测:这是由于

ImageDataGenerator(preprocessing_function=prepare)
。在张量流描述中它说:

将应用于每个输入的函数。该函数将运行 调整图像大小并增强后。该函数应该取一个 参数:一张图像(等级为 3 的 Numpy 张量),并且应该输出 具有相同形状的 Numpy 张量。

我尝试在不使用和使用 np.squeez() 的情况下调整“prepare”函数的 img 输出的形状。 结果是 (1,244,244,3) 或 (224,224,3)。但我仍然收到错误。我也尝试了

tf.convert_to_tensor()
,但出现了同样的错误。

def prepare(img):
    img = np.expand_dims(img,0).astype(np.float32)
    img = preprocess_input(img, version=2)
    img = np.squeeze(img)
    arg = tf.convert_to_tensor(img, dtype=tf.float32)
    return arg

有谁知道我必须如何准备输出才能获得正确的张量?

谢谢

python tensorflow generator tf.keras quantization
2个回答
1
投票

问题实际上是发电机的输出。 输出不是

np.array()
。无法使用 np.asarray() 进行转换,因为它会引发错误。

所以答案很简单:

data_generator 输出是一个元组

enter image description here

所以只产生第一个元素

img[0]


代码总计:

size=(224,224)

def prepare(img):
    img = np.expand_dims(img,0).astype(np.float32)
    img = preprocess_input(img, version=2)
    return img
      
repDatagen=tf.keras.preprocessing.image.ImageDataGenerator(preprocessing_function=prepare)
datagen=repDatagen.flow_from_directory(folderpath,target_size=size,batch_size=1)

def representative_dataset_gen():
  for _ in range(10):
    img = datagen.next()
    yield [img[0]]
    #yield [np.array(img[0], dtype=np.float32)] # also possible

0
投票

谢谢你,你太棒了,你的帖子救了我的命,我在 YOLO 模型上应用了量化,代码:

#https://github.com/ultralytics/ultralytics/issues/6676
#https://github.com/onnx/onnx-tensorflow
#https://github.com/onnx/onnx-tensorflow/blob/main/example/onnx_to_tf.py
#https://docs.ultralytics.com/modes/export/#usage-examples
#https://coral.ai/docs/edgetpu/models-intro/#compatibility-overview

import tensorflow as tf
import numpy as np
import os 
import cv2

def representative_data_gen():
  image_paths = "/..../images/"
  op_ = 0

  for image_path in os.listdir(image_paths):
    op_ = op_ + 1 
    image = cv2.imread("/home/at-am/datasets/VisDrone/VisDrone2019-DET-train/images/"+image_path)    
    print("------111-------", image.shape)  
    image = cv2.resize(image, (640, 640))
    print("------222-------", image.shape)  
    image = np.array(image).astype(np.float32) / 255.0 
    print("------333-------", image.shape)  
    image = np.transpose(image, (2, 0, 1))  # (H, W, C) -> (C, H, W)
    print("------444-------", image.shape)  
    image = np.expand_dims(image, axis=0)  # Add batch dimension

    print("------555-------", image.shape)  
    if op_ == 100:
      break
  
    print(len(image), len(image[0]), len(image[0][0]), len(image[0][0][0]))
    yield [image] #[np.array(image[0][0], dtype=np.float32)]# [image]
    print(" what next ")
   


# ... (Load your TensorFlow model)
converter = tf.lite.TFLiteConverter.from_saved_model('/..../teston')

converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.int8  
converter.inference_output_type = tf.int8  
converter.representative_dataset = representative_data_gen  # Provide a data generator function

tflite_quant_model = converter.convert()

# Save the quantized model
with open('/..../teston/quantized_model2.tflite', 'wb') as f:
    f.write(tflite_quant_model)
© www.soinside.com 2019 - 2024. All rights reserved.