Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KeyError: 'multiclass_nms3_0.tmp_2.lod' #1635

Closed
wjplove8 opened this issue Feb 16, 2022 · 7 comments
Closed

KeyError: 'multiclass_nms3_0.tmp_2.lod' #1635

wjplove8 opened this issue Feb 16, 2022 · 7 comments

Comments

@wjplove8
Copy link

wjplove8 commented Feb 16, 2022

部署fasterrcnn模型时,预测出错
预测的代码

import sys
import numpy as np
from paddle_serving_client import Client
from paddle_serving_app.reader import *
import cv2

preprocess = DetectionSequential([
DetectionFile2Image(),
DetectionNormalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225], True),
DetectionResize(
(800, 1333), True, interpolation=cv2.INTER_LINEAR),
DetectionTranspose((2,0,1)),
DetectionPadStride(128)
])

postprocess = RCNNPostprocess("label_list.txt", "output")
client = Client()

client.load_client_config("serving_client/serving_client_conf.prototxt")
client.connect(['127.0.0.1:9292'])

im, im_info = preprocess(sys.argv[1])
fetch_map = client.predict(
feed={
"image": im,
"im_shape": np.array(list(im.shape[1:])).reshape(-1),
"scale_factor": im_info['scale_factor'],
},
#fetch=["save_infer_model/scale_0.tmp_1"],#multiclass_nms3_0.tmp_2
fetch=["multiclass_nms3_0.tmp_2"],
batch=False)
fetch_map["image"] = sys.argv[1]
postprocess(fetch_map)

serving_client_conf.prototxt:
feed_var {
name: "im_shape"
alias_name: "im_shape"
is_lod_tensor: false
feed_type: 1
shape: 2
}
feed_var {
name: "image"
alias_name: "image"
is_lod_tensor: false
feed_type: 1
shape: 3
}
feed_var {
name: "scale_factor"
alias_name: "scale_factor"
is_lod_tensor: false
feed_type: 1
shape: 2
}
fetch_var {
name: "concat_12.tmp_0"
alias_name: "concat_12.tmp_0"
is_lod_tensor: false
fetch_type: 1
shape: 6
}
fetch_var {
name: "multiclass_nms3_0.tmp_2"
alias_name: "multiclass_nms3_0.tmp_2"
is_lod_tensor: false
fetch_type: 2
}

client报错信息
Traceback (most recent call last):
File "test_client.py", line 47, in
postprocess(fetch_map)
File "/usr/local/lib/python3.6/site-packages/paddle_serving_app/reader/image_reader.py", line 427, in call
self.clsid2catid)
File "/usr/local/lib/python3.6/site-packages/paddle_serving_app/reader/image_reader.py", line 344, in _get_bbox_result
lod = [fetch_map[fetch_name + '.lod']]
KeyError: 'multiclass_nms3_0.tmp_2.lod'

server log:
W0216 10:07:18.747469 2563 infer.cpp:287] Succ reload version engine: 18446744073709551615
I0216 10:07:18.747480 2563 manager.h:131] Finish reload 1 workflow(s)
I0216 10:07:28.747581 2563 server.cpp:151] Begin reload framework...
W0216 10:07:28.747633 2563 infer.cpp:287] Succ reload version engine: 18446744073709551615
I0216 10:07:28.747643 2563 manager.h:131] Finish reload 1 workflow(s)
I0216 10:07:38.747742 2563 server.cpp:151] Begin reload framework...
W0216 10:07:38.747807 2563 infer.cpp:287] Succ reload version engine: 18446744073709551615
I0216 10:07:38.747819 2563 manager.h:131] Finish reload 1 workflow(s)
I0216 10:07:44.068684 2572 general_model_service.pb.cc:3319] (logid=0) remote_side=[127.0.0.1:46034]
I0216 10:07:44.068742 2572 general_model_service.pb.cc:3320] (logid=0) local_side=[127.0.0.1:9292]
I0216 10:07:44.068750 2572 general_model_service.pb.cc:3321] (logid=0) service_name=[GeneralModelService]
I0216 10:07:44.068750 2572 op_repository.h:68] RAW: Succ regist op: GeneralReaderOp
I0216 10:07:44.068750 2572 op_repository.h:68] RAW: Succ regist op: GeneralInferOp
I0216 10:07:44.068750 2572 op_repository.h:68] RAW: Succ regist op: GeneralResponseOp
I0216 10:07:44.079159 2572 op.cpp:164] (logid=0) general_reader_0_time=[10296]
I0216 10:07:44.326128 2572 op.cpp:164] (logid=0) general_infer_0_time=[246925]
I0216 10:07:44.326174 2572 op.cpp:164] (logid=0) general_response_0_time=[8]
I0216 10:07:44.326189 2572 service.cpp:263] (logid=0) workflow total time: 257421
I0216 10:07:44.326215 2572 general_model_service.pb.cc:3343] [serving]logid=0,cost=257.534ms.
I0216 10:07:48.747907 2563 server.cpp:151] Begin reload framework...
W0216 10:07:48.747962 2563 infer.cpp:287] Succ reload version engine: 18446744073709551615
I0216 10:07:48.747973 2563 manager.h:131] Finish reload 1 workflow(s)
I0216 10:07:58.748062 2563 server.cpp:151] Begin reload framework...
W0216 10:07:58.748112 2563 infer.cpp:287] Succ reload version engine: 18446744073709551615
I0216 10:07:58.748121 2563 manager.h:131] Finish reload 1 workflow(s)
I0216 10:08:08.748234 2563 server.cpp:151] Begin reload framework...
W0216 10:08:08.748302 2563 infer.cpp:287] Succ reload version engine: 18446744073709551615
I0216 10:08:08.748315 2563 manager.h:131] Finish reload 1 workflow(s)
I0216 10:08:18.748411 2563 server.cpp:151] Begin reload framework...
处理
fetch_var {
name: "multiclass_nms3_0.tmp_2"
alias_name: "multiclass_nms3_0.tmp_2"
is_lod_tensor: false
fetch_type: 2
}
修改为
fetch_var {
name: "multiclass_nms3_0.tmp_2"
alias_name: "multiclass_nms3_0.tmp_2"
is_lod_tensor: true
fetch_type: 2
}
也不行

@github-actions
Copy link

Message that will be displayed on users' first issue

@felixhjh
Copy link
Collaborator

您好,我看这边您应该是使用自己训练的模型对嘛?postprocess针对不同模型处理上并不一样,这边还需要自己去做一下模型的后处理工作。Paddle Serving提供的postprocess方法只针对,Paddle Serving示例代码,并不具有通用性。因此还需要开发者参照示例的postprocess进行一定的修改。除此之外,并不是每个模型都会返回lod信息,因此报错。

@wjplove8
Copy link
Author

您好,我看这边您应该是使用自己训练的模型对嘛?postprocess针对不同模型处理上并不一样,这边还需要自己去做一下模型的后处理工作。Paddle Serving提供的postprocess方法只针对,Paddle Serving示例代码,并不具有通用性。因此还需要开发者参照示例的postprocess进行一定的修改。除此之外,并不是每个模型都会返回lod信息,因此报错。

谢谢解决了,文档还是不够全面呀。希望能增加更多系列文档。

@ChiTaoGIS
Copy link

我也是使用的fasterrcnn,遇到同样的问题,
def _get_bbox_result(self, fetch_map, fetch_name, clsid2catid): result = {} is_bbox_normalized = False output = fetch_map[fetch_name] lod = [fetch_map[fetch_name + '.lod']] lengths = self._offset_to_lengths(lod) np_data = np.array(output)
问题出现在这里,不是很清楚后续如何处理,希望可以支持一下~!

@zhiqiangohuo
Copy link

除此之外,并不是每个模型都会返回lod信息,因此报错。

使用自己训练的yolov3

feed_var {
  name: "im_shape"
  alias_name: "im_shape"
  is_lod_tensor: false
  feed_type: 1
  shape: 2
}
feed_var {
  name: "image"
  alias_name: "image"
  is_lod_tensor: false
  feed_type: 1
  shape: 3
  shape: 608
  shape: 608
}
feed_var {
  name: "scale_factor"
  alias_name: "scale_factor"
  is_lod_tensor: false
  feed_type: 1
  shape: 2
}
fetch_var {
  name: "multiclass_nms3_0.tmp_0"
  alias_name: "multiclass_nms3_0.tmp_0"
  is_lod_tensor: true
  fetch_type: 1
  shape: -1
}
fetch_var {
  name: "multiclass_nms3_0.tmp_2"
  alias_name: "multiclass_nms3_0.tmp_2"
  is_lod_tensor: false
  fetch_type: 2
}

遇见了同样的问题,想问一下是什么原因造成的?

@wjplove8
Copy link
Author

wjplove8 commented Feb 22, 2023

去年就遇到了此问题,当时搞定了,今年又遇到了,来查,看到答案想抽自己俩耳光,写一下具体解决办法。
需要重写一下paddle_serving_app.reader模块的RCNNPostprocess类

class RCNNPostprocess(object):
def init(self, label_file, output_dir, resize_shape=None):
self.output_dir = output_dir
self.label_file = label_file
self.label_list = []
self.resize_shape = resize_shape
with open(label_file) as fin:
for line in fin:
self.label_list.append(line.strip())
self.clsid2catid = {i: i for i in range(len(self.label_list))}
self.catid2name = {i: name for i, name in enumerate(self.label_list)}

def _offset_to_lengths(self, lod):
    offset = lod[0]
    #lengths = [offset[i + 1] - offset[i] for i in range(len(offset) - 1)]
    lengths = [6 for i in range(len(offset) - 1)]
    return [lengths]

def _bbox2out(self, results, clsid2catid, is_bbox_normalized=False):
    xywh_res = []
    for t in results:
        bboxes = t['bbox'][0]
        lengths = t['bbox'][1]#[0]
        if bboxes.shape == (1, 1) or bboxes is None:
            continue

        k = 0
        for i in range(len(lengths)):
            num = lengths[i]
            if k==len(bboxes):
                break
            for j in range(num):               
                dt = bboxes[k]
                clsid, score, xmin, ymin, xmax, ymax = dt.tolist()
                catid = (clsid2catid[int(clsid)])
                catname=(self.catid2name[int(catid)])
                if is_bbox_normalized:
                    xmin, ymin, xmax, ymax = \
                        self.clip_bbox([xmin, ymin, xmax, ymax])
                    w = xmax - xmin
                    h = ymax - ymin
                    im_shape = t['im_shape'].tolist()
                    im_height, im_width = int(im_shape[0]), int(im_shape[1])
                    xmin *= im_width
                    ymin *= im_height
                    w *= im_width
                    h *= im_height
                else:
                    w = xmax - xmin + 1
                    h = ymax - ymin + 1

                bbox = [xmin, ymin, w, h]
                coco_res = {
                    'category_id': catid,
                    'cat_name':catname,
                    'bbox': bbox,
                    'score': score
                }
                xywh_res.append(coco_res)
                k += 1
    return xywh_res

def _get_bbox_result(self, fetch_map, fetch_name, clsid2catid):
    result = {}
    is_bbox_normalized = False
    output = fetch_map[fetch_name]
    
    # lod = [fetch_map[fetch_name + '.lod']]
    lod = [fetch_map[fetch_name ]]
    
    lengths = self._offset_to_lengths(lod)
    np_data = np.array(output)
    result['bbox'] = (np_data,[6] * (len(np_data)))#np.ones(10) * 6      np.ones(len(np_data.shape))*6
    result['im_id'] = np.array([[0]])

    bbox_results = self._bbox2out([result], clsid2catid, is_bbox_normalized)
    return bbox_results

def color_map(self, num_classes):
    color_map = num_classes * [0, 0, 0]
    for i in range(0, num_classes):
        j = 0
        lab = i
        while lab:
            color_map[i * 3] |= (((lab >> 0) & 1) << (7 - j))
            color_map[i * 3 + 1] |= (((lab >> 1) & 1) << (7 - j))
            color_map[i * 3 + 2] |= (((lab >> 2) & 1) << (7 - j))
            j += 1
            lab >>= 3
    color_map = np.array(color_map).reshape(-1, 3)
    return color_map

def draw_bbox(self, image, catid2name, bboxes, threshold, color_list):
    """
    draw bbox on image
    """
    draw = ImageDraw.Draw(image)

    for dt in np.array(bboxes):
        catid, bbox, score = dt['category_id'], dt['bbox'], dt['score']
        if score < threshold:
            continue

        xmin, ymin, w, h = bbox
        xmax = xmin + w
        ymax = ymin + h

        img_w, img_h = image.size
        if self.resize_shape is not None:
            xmin = xmin * img_w / self.resize_shape[0]
            xmax = xmax * img_w / self.resize_shape[0]
            ymin = ymin * img_h / self.resize_shape[1]
            ymax = ymax * img_h / self.resize_shape[1]

        color = tuple(color_list[catid])

        # draw bbox
        draw.line(
            [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin),
             (xmin, ymin)],
            width=2,
            fill=color)

        # draw label
        text = "{} {:.2f}".format(catid2name[catid], score)
        tw, th = draw.textsize(text)
        draw.rectangle(
            [(xmin + 1, ymin - th), (xmin + tw + 1, ymin)], fill=color)
        draw.text((xmin + 1, ymin - th), text, fill=(255, 255, 255))
    return image

def visualize(self, infer_img, bbox_results, catid2name, num_classes):
    image = Image.open(infer_img).convert('RGB')
    color_list = self.color_map(num_classes)
    image = self.draw_bbox(image, self.catid2name, bbox_results, 0.5,
                           color_list)
    image_path = os.path.split(infer_img)[-1]
    if not os.path.exists(self.output_dir):
        os.makedirs(self.output_dir)
    out_path = os.path.join(self.output_dir, image_path)
    image.save(out_path, quality=95)

def __call__(self, image_with_bbox, visualize=False):
    fetch_name = ""
    for key in image_with_bbox:
        if key == "image":
            continue
        if ".lod" in key or "im_shape" in key:
            continue
        fetch_name = key
    bbox_result = self._get_bbox_result(image_with_bbox, fetch_name,
                                        self.clsid2catid)
    if os.path.isdir(self.output_dir) is False:
        os.mkdir(self.output_dir)
    if visualize is False:
        return bbox_result
    self.visualize(image_with_bbox["image"], bbox_result, self.catid2name,
                   len(self.label_list))
    if os.path.isdir(self.output_dir) is False:
        os.mkdir(self.output_dir)
    bbox_file = os.path.join(self.output_dir, 'bbox.json')
    with open(bbox_file, 'w') as f:
        json.dump(bbox_result, f, indent=4)
    return bbox_result

def __repr__(self):
    return self.__class__.__name__ + "label_file: {1}, output_dir: {2}".format(
        self.label_file, self.output_dir)

我也是使用的fasterrcnn,遇到同样的问题, def _get_bbox_result(self, fetch_map, fetch_name, clsid2catid): result = {} is_bbox_normalized = False output = fetch_map[fetch_name] lod = [fetch_map[fetch_name + '.lod']] lengths = self._offset_to_lengths(lod) np_data = np.array(output) 问题出现在这里,不是很清楚后续如何处理,希望可以支持一下~!

@wjplove8
Copy link
Author

去年就遇到了此问题,当时搞定了,今年又遇到了,来查,看到答案想抽自己俩耳光,写一下具体解决办法。 需要重写一下paddle_serving_app.reader模块的RCNNPostprocess类

class RCNNPostprocess(object): def init(self, label_file, output_dir, resize_shape=None): self.output_dir = output_dir self.label_file = label_file self.label_list = [] self.resize_shape = resize_shape with open(label_file) as fin: for line in fin: self.label_list.append(line.strip()) self.clsid2catid = {i: i for i in range(len(self.label_list))} self.catid2name = {i: name for i, name in enumerate(self.label_list)}

def _offset_to_lengths(self, lod):
    offset = lod[0]
    #lengths = [offset[i + 1] - offset[i] for i in range(len(offset) - 1)]
    lengths = [6 for i in range(len(offset) - 1)]
    return [lengths]

def _bbox2out(self, results, clsid2catid, is_bbox_normalized=False):
    xywh_res = []
    for t in results:
        bboxes = t['bbox'][0]
        lengths = t['bbox'][1]#[0]
        if bboxes.shape == (1, 1) or bboxes is None:
            continue

        k = 0
        for i in range(len(lengths)):
            num = lengths[i]
            if k==len(bboxes):
                break
            for j in range(num):               
                dt = bboxes[k]
                clsid, score, xmin, ymin, xmax, ymax = dt.tolist()
                catid = (clsid2catid[int(clsid)])
                catname=(self.catid2name[int(catid)])
                if is_bbox_normalized:
                    xmin, ymin, xmax, ymax = \
                        self.clip_bbox([xmin, ymin, xmax, ymax])
                    w = xmax - xmin
                    h = ymax - ymin
                    im_shape = t['im_shape'].tolist()
                    im_height, im_width = int(im_shape[0]), int(im_shape[1])
                    xmin *= im_width
                    ymin *= im_height
                    w *= im_width
                    h *= im_height
                else:
                    w = xmax - xmin + 1
                    h = ymax - ymin + 1

                bbox = [xmin, ymin, w, h]
                coco_res = {
                    'category_id': catid,
                    'cat_name':catname,
                    'bbox': bbox,
                    'score': score
                }
                xywh_res.append(coco_res)
                k += 1
    return xywh_res

def _get_bbox_result(self, fetch_map, fetch_name, clsid2catid):
    result = {}
    is_bbox_normalized = False
    output = fetch_map[fetch_name]
    
    # lod = [fetch_map[fetch_name + '.lod']]
    lod = [fetch_map[fetch_name ]]
    
    lengths = self._offset_to_lengths(lod)
    np_data = np.array(output)
    result['bbox'] = (np_data,[6] * (len(np_data)))#np.ones(10) * 6      np.ones(len(np_data.shape))*6
    result['im_id'] = np.array([[0]])

    bbox_results = self._bbox2out([result], clsid2catid, is_bbox_normalized)
    return bbox_results

def color_map(self, num_classes):
    color_map = num_classes * [0, 0, 0]
    for i in range(0, num_classes):
        j = 0
        lab = i
        while lab:
            color_map[i * 3] |= (((lab >> 0) & 1) << (7 - j))
            color_map[i * 3 + 1] |= (((lab >> 1) & 1) << (7 - j))
            color_map[i * 3 + 2] |= (((lab >> 2) & 1) << (7 - j))
            j += 1
            lab >>= 3
    color_map = np.array(color_map).reshape(-1, 3)
    return color_map

def draw_bbox(self, image, catid2name, bboxes, threshold, color_list):
    """
    draw bbox on image
    """
    draw = ImageDraw.Draw(image)

    for dt in np.array(bboxes):
        catid, bbox, score = dt['category_id'], dt['bbox'], dt['score']
        if score < threshold:
            continue

        xmin, ymin, w, h = bbox
        xmax = xmin + w
        ymax = ymin + h

        img_w, img_h = image.size
        if self.resize_shape is not None:
            xmin = xmin * img_w / self.resize_shape[0]
            xmax = xmax * img_w / self.resize_shape[0]
            ymin = ymin * img_h / self.resize_shape[1]
            ymax = ymax * img_h / self.resize_shape[1]

        color = tuple(color_list[catid])

        # draw bbox
        draw.line(
            [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin),
             (xmin, ymin)],
            width=2,
            fill=color)

        # draw label
        text = "{} {:.2f}".format(catid2name[catid], score)
        tw, th = draw.textsize(text)
        draw.rectangle(
            [(xmin + 1, ymin - th), (xmin + tw + 1, ymin)], fill=color)
        draw.text((xmin + 1, ymin - th), text, fill=(255, 255, 255))
    return image

def visualize(self, infer_img, bbox_results, catid2name, num_classes):
    image = Image.open(infer_img).convert('RGB')
    color_list = self.color_map(num_classes)
    image = self.draw_bbox(image, self.catid2name, bbox_results, 0.5,
                           color_list)
    image_path = os.path.split(infer_img)[-1]
    if not os.path.exists(self.output_dir):
        os.makedirs(self.output_dir)
    out_path = os.path.join(self.output_dir, image_path)
    image.save(out_path, quality=95)

def __call__(self, image_with_bbox, visualize=False):
    fetch_name = ""
    for key in image_with_bbox:
        if key == "image":
            continue
        if ".lod" in key or "im_shape" in key:
            continue
        fetch_name = key
    bbox_result = self._get_bbox_result(image_with_bbox, fetch_name,
                                        self.clsid2catid)
    if os.path.isdir(self.output_dir) is False:
        os.mkdir(self.output_dir)
    if visualize is False:
        return bbox_result
    self.visualize(image_with_bbox["image"], bbox_result, self.catid2name,
                   len(self.label_list))
    if os.path.isdir(self.output_dir) is False:
        os.mkdir(self.output_dir)
    bbox_file = os.path.join(self.output_dir, 'bbox.json')
    with open(bbox_file, 'w') as f:
        json.dump(bbox_result, f, indent=4)
    return bbox_result

def __repr__(self):
    return self.__class__.__name__ + "label_file: {1}, output_dir: {2}".format(
        self.label_file, self.output_dir)

我也是使用的fasterrcnn,遇到同样的问题, def _get_bbox_result(self, fetch_map, fetch_name, clsid2catid): result = {} is_bbox_normalized = False output = fetch_map[fetch_name] lod = [fetch_map[fetch_name + '.lod']] lengths = self._offset_to_lengths(lod) np_data = np.array(output) 问题出现在这里,不是很清楚后续如何处理,希望可以支持一下~!

其实就是官方写的后处理计算不能兼容lod数据和定长数据两种情况。我没有找到带lod数据的模型,不能完善代码,这只是应急处理,希望官方后续更新一下。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants