AssertionError: feed_list should be set when return_list=False
场景描述
我正在量化paddle里面的关键点检测模型,我参考的量化文档,但是我还是不是很懂sample_generator这个参数要怎么传?然后我看代码里面的加载数据集的方式是先调用self.dataset = cfg['{}Dataset'.format(self.mode.capitalize())]来构造一个对象,然后使用self.loader = create('{}Reader'.format(self.mode.capitalize()))( self.dataset, cfg.worker_num)来构造一个loader,
最后推理的方式为
for step_id, data in enumerate(self.loader):
self.status['data_time'].update(time.time() - iter_tic)
self.status['step_id'] = step_id
profiler.add_profiler_step(profiler_options)
self._compose_callback.on_step_begin(self.status)
data['epoch_id'] = epoch_id
if self.cfg.get('amp', False):
with amp.auto_cast(enable=self.cfg.use_gpu):
# model forward
outputs = model(data)
loss = outputs['loss']
我以为是把这个loader传到sample_generator参数就好了,于是我的量化代码就写成了下面的样子:
if __name__ == "__main__":
image_path = r"./images/100"
save_path = r"./images/all_anns_100.json"
if os.path.exists(save_path):
convert(image_path, save_path, image_path)
# gt_db = load_coco_keypoint_annotations(save_path, image_path)
cfg = load_config('/data/liyy/QuantPoseDemo/other/PaddleDetection/configs/keypoint/tiny_pose/tinypose_128x96.yml')
# 开启静态图模式
paddle.enable_static()
image = paddle.static.data(
name='image', shape=[None, 1, 128, 96], dtype='float32')
label = paddle.static.data(name='label', shape=[None, 1], dtype='int64')
dataset = cfg['{}Dataset'.format("eval".capitalize())]
eval_reader = create('{}Reader'.format("eval".capitalize()))
loader = eval_reader(dataset, cfg.worker_num)
slim.quant.quant_post_static(
executor=paddle.static.Executor(),
feed_list=[image, label],
model_dir='./inference_model',
quantize_model_path='./quant_post_static_model',
sample_generator=loader,
model_filename='fp32.pdmodel',
params_filename='fp32.pdiparams',
batch_nums=10)
于是就有下面的报错:

问题
- 请问我这里的sample_generator是直接传loader就行了吗?还是要把loader里面的data取出来,然后组成一个列表再传给sample_generator呢?
- 请问静态图中这个feed_list我这里应该怎么传呢? 感谢帮忙解答一下哈!谢谢了!
https://github.com/PaddlePaddle/PaddleSlim/blob/develop/demo/quant/quant_post/quant_post.py#L75 如果有已经写好的dataloader的话,可以直接传入dataloader,不用写 sample_generator 了
https://github.com/PaddlePaddle/PaddleSlim/blob/develop/demo/quant/quant_post/quant_post.py#L75 如果有已经写好的dataloader的话,可以直接传入dataloader,不用写 sample_generator 了
好的,谢谢哈!我试试
-
我调用这个API接口出现了这个错误,是版本不对吗?我得paddleSlim是2.1.1的

-
请问这个支持动态图量化吗?静态图量化需要给data_loader传一个feed_list进去,我直接传了image进去,不知道要不要传label,这个feed_list该怎么传是需要看哪里呢?

我将paddleslim的版本更新为了2.2.2后,可以使用dataloader的选项,但是现在报错feed_list的数量不匹配
错误信息:ValueError: (InvalidArgument) The sample number of reader's input data and the input number of feed list are not equal.

我将paddleslim的版本更新为了2.2.2后,可以使用dataloader的选项,但是现在报错feed_list的数量不匹配 错误信息:ValueError: (InvalidArgument) The sample number of reader's input data and the input number of feed list are not equal.
应该是dataloader返回的输入的数量和模型里面的输入的数量不匹配,可以用netron可视化模型看下输入叫什么,然后在dataloader里相应的改一下就可以了~
我将paddleslim的版本更新为了2.2.2后,可以使用dataloader的选项,但是现在报错feed_list的数量不匹配 错误信息:ValueError: (InvalidArgument) The sample number of reader's input data and the input number of feed list are not equal.
应该是dataloader返回的输入的数量和模型里面的输入的数量不匹配,可以用netron可视化模型看下输入叫什么,然后在dataloader里相应的改一下就可以了~
好的,我检查一下,前几天请假了!回的有点慢,谢谢哈
终于量化成功了 参考文档见:https://aistudio.baidu.com/aistudio/projectdetail/3924444 关键点检测模型量化代码如下:
# quant.py
import os
import paddle
import paddleslim as slim
import numpy as np
import warnings
from pycocotools.coco import COCO
import json
import tqdm
from PIL import Image
import traceback
from ppdet.core.workspace import load_config
from ppdet.core.workspace import create
from ppdet.data import transform
warnings.simplefilter('ignore', ResourceWarning)
USE_GPU = True
place = paddle.CUDAPlace(0) if USE_GPU else paddle.CPUPlace()
executor = paddle.static.Executor(place)
import yaml
def load_config(file_path):
"""
Load config from file.
Args:
file_path (str): Path of the config file to be loaded.
Returns: global config
"""
_, ext = os.path.splitext(file_path)
assert ext in ['.yml', '.yaml'], "only support yaml files for now"
# load config
with open(file_path) as f:
file_cfg = yaml.load(f, Loader=yaml.Loader)
return file_cfg
class Compose(object):
def __init__(self, transforms, num_classes=80):
self.transforms = transforms
self.transforms_cls = []
for t in self.transforms:
for k, v in t.items():
op_cls = getattr(transform, k)
f = op_cls(**v)
if hasattr(f, 'num_classes'):
f.num_classes = num_classes
self.transforms_cls.append(f)
def __call__(self, data):
for f in self.transforms_cls:
try:
data = f(data)
except Exception as e:
stack_info = traceback.format_exc()
print("err ", stack_info)
# logger.warning("fail to map sample transform [{}] "
# "with error: {} and stack:\n{}".format(
# f, e, str(stack_info)))
raise e
return data
if __name__ == "__main__":
# 开启静态图模式
paddle.enable_static()
# 配置参数
image_path = r"/data/liyy/QuantPoseDemo-20220531/other/PaddleDetection/tools/images/100"
model_dir = '/data/liyy/QuantPoseDemo-20220531/other/PaddleDetection/tools/tinypose_128x96'
quantize_model_path = '/data/liyy/QuantPoseDemo-20220531/other/PaddleDetection/tools/quant_post_static_model'
model_filename = 'model.pdmodel'
params_filename = 'model.pdiparams'
model_dir_quant_static = "./"
save_path = r"./images"
# 加载config文件
cfg = load_config(
'/data/liyy/QuantPoseDemo-20220531/other/PaddleDetection/configs/keypoint/tiny_pose/tinypose_128x96.yml')
# 构建sample_transforms
sample_transforms = cfg["TestReader"]["sample_transforms"]
sample_transforms = Compose(
sample_transforms, num_classes=1)
# 构建dataset,主要用于获取roidbs的规范化数据字典用于输入sample_transforms
dataset = cfg['{}Dataset'.format("test".capitalize())]
dataset.check_or_download_dataset()
dataset.parse_dataset()
dataset.set_transform(sample_transforms)
# 注意datas返回的图片需要经过reshape到输入尺寸
datas = iter([
sample_transforms(
info
)["image"].reshape(-1, 3, 128, 96) for info in dataset.roidbs
])
# 静态量化
slim.quant.quant_post_static(
executor=paddle.static.Executor(), # Paddle 静态图执行器
model_dir=model_dir, # 输入模型路径
model_filename=model_filename, # 输入模型计算图文件名称
params_filename=params_filename, # 输入模型参数文件名称
quantize_model_path=model_dir_quant_static, # 输出模型路径
save_model_filename=model_filename, # 输出模型计算图文件名称
save_params_filename=params_filename, # 输出模型参数文件名称
batch_generator=None, # 数据批次生成器,需传入一个可调用对象,返回一个 Generator
sample_generator=lambda: datas, # 数据采样生成器,需传入一个可调用对象,返回一个 Generator
data_loader=None, # Paddle DataLoader
batch_size=1, # 数据批次大小
batch_nums=100, # 数据批次数量,默认为使用全部数据
weight_bits=8, # 参数量化比特数 8/16 对应 INT8/16 类型
activation_bits=8, # 激活值量化比特数 8/16 对应 INT8/16 类型
weight_quantize_type='channel_wise_abs_max',
# 参数量化方法,目前支持 'range_abs_max', 'moving_average_abs_max' 和 'abs_max'
activation_quantize_type='range_abs_max', # 激活值量化方法,目前支持 'range_abs_max', 'moving_average_abs_max' 和 'abs_max'
algo='mse', # 校准方法,目前支持 'KL', 'hist', 'mse', 'avg', 'abs_max'
)
print("ok!")
@liyuyuan6969 哈喽,大佬,使用您最后提供的这部分代码,出现如下的错误
File "/root/PaddleDetection/quant.py", line 86, in