使用C++预测库对应的Python接口对yolov3物体检测模型预测结果有误
Created by: tracyCzf
- 标题:使用C++预测库对应的Python接口对yolov3物体检测模型预测结果有误,参考接口文档https://paddlepaddle.org.cn/documentation/docs/zh/advanced_usage/deploy/inference/python_infer_cn.html
- 版本、环境信息: 1)PaddlePaddle版本:1.5.2源码编译, -DWITH_GPU=OFF -DON_INFER=ON 2)CPU:Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz 3)GPU:无 4)系统环境:镜像paddle:1.5.2-gpu-cuda9.0-cudnn7,Python2.7 -预测信息 1)yolov3模型训练方式参考https://github.com/PaddlePaddle/models/tree/develop/PaddleCV/yolov3 2)python API预测代码如下:
import argparse
import numpy as np
import cv2
from paddle.fluid.core import PaddleBuf
from paddle.fluid.core import PaddleDType
from paddle.fluid.core import PaddleTensor
from paddle.fluid.core import AnalysisConfig
from paddle.fluid.core import create_paddle_predictor
def main():
args = parse_args()
# Set config
config = AnalysisConfig(args.prog_file, args.params_file)
config.disable_gpu()
config.set_cpu_math_library_num_threads(10)
config.enable_mkldnn()
# Create PaddlePredictor
predictor = create_paddle_predictor(config)
# Set inputs
inputs = input_gen(args.image_path)
# Infer
outputs = predictor.run(inputs)
# parse outputs
print outputs
output = outputs[0]
print(output.name)
output_data = output.data.float_data()
output = np.array(output_data).reshape((-1, 6))
output = output[np.flip(output[:,1].argsort())]
for box in output[:10, :].tolist():
print box
def input_gen(filename, resize=(800, 800), img_mean=[0.485, 0.456, 0.406], img_std=[0.229, 0.224, 0.225]):
im = cv2.imread(filename).astype('float32')
im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
h, w, _ = im.shape
out_img = cv2.resize(im, resize, interpolation=3)
mean = np.array(img_mean).reshape((1, 1, -1))
std = np.array(img_std).reshape((1, 1, -1))
out_img = (out_img / 255.0 - mean) / std
out_img = out_img.transpose((2, 0, 1))
image = PaddleTensor()
image.name = "image"
image.shape = [1, out_img.shape[0], out_img.shape[1], out_img.shape[2]]
image.dtype = PaddleDType.FLOAT32
image.data = PaddleBuf(
out_img.flatten().astype("float32").tolist())
image_info = PaddleTensor()
image_info.name = "im_shape"
image_info.shape = [1, 2]
image_info.dtype = PaddleDType.INT32
image_info.data = PaddleBuf(
np.array([h, w]).flatten().astype("int32").tolist())
# return [image, ]
return [image, image_info]
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("--model_dir", type=str, help="model dir")
parser.add_argument("--prog_file", type=str, help="program filename")
parser.add_argument("--params_file", type=str, help="parameter filename")
parser.add_argument("--image_path", type=str, help="image path")
return parser.parse_args()
if __name__ == "__main__":
main()
- 问题描述:开始使用fluid.Executor(place).run的方式对训练好的yolov3模型进行预测,时间较长,所以选择使用C++预测库对应的Python接口来使用多核进行预测(预测代码如上)。通过可视化和对比两种方式的infer结果,发现第一种方式的结果是正确的,但C++预测库的预测结果有些问题(没有错误或者警告日志)。两者的top10结果如下,每行是一个物体检测框[label, score, x1, y1, x2, y2]: fluid.Executor.run: C++预测库python API: 对比结果可以发现,两种方式的预测结果中,label, score, y1, y2的结果都是非常接近的,只有x1,x2的结果存在异常。