首页 Paddle框架 帖子详情
py_func使用问题
收藏
快速回复
Paddle框架 问答深度学习 816 9
py_func使用问题
收藏
快速回复
Paddle框架 问答深度学习 816 9

   1)PaddlePaddle版本:1.4.1
   2)CPU/GPU:如果您使用GPU训练,请提供GPU驱动版本、CUDA和cuDNN版本号
   3)系统环境:请您描述系统类型、版本,例如Mac OS 10.14
   4)Python 3.6
   5)显存信息
运行下面代码

import paddle.fluid as fluid
import numpy as np
def _bbox_overlaps(roi_boxes:np.ndarray, gt_boxes:np.ndarray):
    lt = np.maximum(roi_boxes[:,np.newaxis, :2], gt_boxes[:, :2])
    rb = np.minimum(roi_boxes[:,np.newaxis, 2:], gt_boxes[:, 2:])
    wh=np.clip((rb-lt+1),a_min=0,a_max=None)
    inter=wh[:,:,0]*wh[:,:,1]
    w1 = np.maximum(roi_boxes[:, 2] - roi_boxes[:, 0] + 1, 0)
    h1 = np.maximum(roi_boxes[:, 3] - roi_boxes[:, 1] + 1, 0)
    w2 = np.maximum(gt_boxes[:, 2] - gt_boxes[:, 0] + 1, 0)
    h2 = np.maximum(gt_boxes[:, 3] - gt_boxes[:, 1] + 1, 0)
    area1 = w1 * h1
    area2 = w2 * h2
    overlap=inter/(area1[:,np.newaxis]+area2-inter)
    return overlap
def create_tmp_var(name, dtype, shape):
    return fluid.default_main_program().current_block().create_var(
        name=name, dtype=dtype, shape=shape)
def py_func():
    main=fluid.Program()
    start=fluid.Program()
    with fluid.program_guard(main,start):
        roi=fluid.layers.data('roi',[3,4],append_batch_size=False)
        gt=fluid.layers.data('gt',[2,4],append_batch_size=False)
        overlap=create_tmp_var('overlap','float32',[3,2])
        out=fluid.layers.py_func(_bbox_overlaps,[roi,gt],overlap)
    exe=fluid.Executor(fluid.CPUPlace())
    exe.run(start)
    out=exe.run(main,feed={'roi':np.ones([3,4]),'gt':np.ones([2,4])},fetch_list=[out])
    print(out)
py_func()

报错信息如下

---------------------------------------------------------------------------ValueError                                Traceback (most recent call last)<ipython-input-2-b318fada9f02> in <module>
     29     out=exe.run(main,feed={'roi':np.ones([3,4]),'gt':np.ones([2,4])},fetch_list=[out])
     30     print(out)
---> 31 py_func()
<ipython-input-2-b318fada9f02> in py_func()
     24         gt=fluid.layers.data('gt',[2,4],append_batch_size=False)
     25         overlap=create_tmp_var('overlap','float32',[3,2])
---> 26         out=fluid.layers.py_func(_bbox_overlaps,[roi,gt],overlap)
     27     exe=fluid.Executor(fluid.CPUPlace())
     28     exe.run(start)
/opt/conda/envs/python35-paddle120-env/lib/python3.5/site-packages/paddle/fluid/layers/nn.py in py_func(func, x, out, backward_func, skip_vars_in_backward_input)
  10634             'Output must be Variable/list(Variable)/tuple(Variable)')
  10635 
> 10636     fwd_func_id = PyFuncRegistry(func).id
  10637     bwd_func_id = PyFuncRegistry(
  10638         backward_func).id if backward_func is not None else -1
/opt/conda/envs/python35-paddle120-env/lib/python3.5/site-packages/paddle/fluid/layers/nn.py in __init__(self, func)
  10468         self._func = func
  10469         # find named args using reflection
> 10470         args = inspect.getargspec(self._func)
  10471         if len(args[0]) == 0 and args[1] is None and args[2] is None:
  10472             # Function with no inputs
/opt/conda/envs/python35-paddle120-env/lib/python3.5/inspect.py in getargspec(func)
   1048         getfullargspec(func)
   1049     if kwonlyargs or ann:
-> 1050         raise ValueError("Function has keyword-only arguments or annotations"
   1051                          ", use getfullargspec() API which can support them")
   1052     return ArgSpec(args, varargs, varkw, defaults)
ValueError: Function has keyword-only arguments or annotations, use getfullargspec() API which can support them
0
收藏
回复
全部评论(9)
时间顺序
AIStudio792074
#2 回复于2019-11
@liuwei1031

老师,请帮忙看一下,用户代码用到了python 3.5的一个语法叫function annotation

代码是这一行:

def _bbox_overlaps(roi_boxes:np.ndarray, gt_boxes:np.ndarray):

咱们的PyFuncRegistry处理这个函数的时候应该是没有兼容这个语法,要改成getfullargspec()才行

麻烦您看一下哈

0
回复
AIStudio792105
#3 回复于2019-11

我换了一种写法,还是报错

import paddle.fluid as fluid
import numpy as np
def bbox_overlaps(roi_boxes, gt_boxes):
    w1 = np.maximum(roi_boxes[:, 2] - roi_boxes[:, 0] + 1, 0)
    h1 = np.maximum(roi_boxes[:, 3] - roi_boxes[:, 1] + 1, 0)
    w2 = np.maximum(gt_boxes[:, 2] - gt_boxes[:, 0] + 1, 0)
    h2 = np.maximum(gt_boxes[:, 3] - gt_boxes[:, 1] + 1, 0)
    area1 = w1 * h1
    area2 = w2 * h2

    overlaps = np.zeros((roi_boxes.shape[0], gt_boxes.shape[0]))
    for ind1 in range(roi_boxes.shape[0]):
        for ind2 in range(gt_boxes.shape[0]):
            inter_x1 = np.maximum(roi_boxes[ind1, 0], gt_boxes[ind2, 0])
            inter_y1 = np.maximum(roi_boxes[ind1, 1], gt_boxes[ind2, 1])
            inter_x2 = np.minimum(roi_boxes[ind1, 2], gt_boxes[ind2, 2])
            inter_y2 = np.minimum(roi_boxes[ind1, 3], gt_boxes[ind2, 3])
            inter_w = np.maximum(inter_x2 - inter_x1 + 1, 0)
            inter_h = np.maximum(inter_y2 - inter_y1 + 1, 0)
            inter_area = inter_w * inter_h
            iou = inter_area / (area1[ind1] + area2[ind2] - inter_area)
            overlaps[ind1, ind2] = iou
    return overlaps
def create_tmp_var(name, dtype, shape):
    return fluid.default_main_program().current_block().create_var(
        name=name, dtype=dtype, shape=shape)
def py_func():
    main=fluid.Program()
    start=fluid.Program()
    with fluid.program_guard(main,start):
        roi=fluid.layers.data('roi',[3,4],append_batch_size=False)
        gt=fluid.layers.data('gt',[2,4],append_batch_size=False)
        overlap=create_tmp_var('overlap','float32',[3,2])
        out=fluid.layers.py_func(bbox_overlaps,[roi,gt],overlap)
    exe=fluid.Executor(fluid.CPUPlace())
    exe.run(start)
    out=exe.run(main,feed={'roi':np.ones([3,4]),'gt':np.ones([2,4])},fetch_list=[out])
    print(out)
py_func()

报错信息

---------------------------------------------------------------------------TypeError                                 Traceback (most recent call last)<ipython-input-11-d1585aa8c677> in <module>
     51     out=exe.run(main,feed={'roi':np.ones([3,4]),'gt':np.ones([2,4])},fetch_list=[out])
     52     print(out)
---> 53 py_func()
<ipython-input-11-d1585aa8c677> in py_func()
     49     exe=fluid.Executor(fluid.CPUPlace())
     50     exe.run(start)
---> 51     out=exe.run(main,feed={'roi':np.ones([3,4]),'gt':np.ones([2,4])},fetch_list=[out])
     52     print(out)
     53 py_func()
/opt/conda/envs/python35-paddle120-env/lib/python3.5/site-packages/paddle/fluid/executor.py in run(self, program, feed, fetch_list, feed_var_name, fetch_var_name, scope, return_numpy, use_program_cache)
    563                 scope=scope,
    564                 return_numpy=return_numpy,
--> 565                 use_program_cache=use_program_cache)
    566         else:
    567             if fetch_list and program._is_data_parallel and program._program and (
/opt/conda/envs/python35-paddle120-env/lib/python3.5/site-packages/paddle/fluid/executor.py in _run(self, program, exe, feed, fetch_list, feed_var_name, fetch_var_name, scope, return_numpy, use_program_cache)
    640 
    641         self._feed_data(program, feed, feed_var_name, scope)
--> 642         exe.run(program.desc, scope, 0, True, True, fetch_var_name)
    643         outs = self._fetch_data(fetch_list, fetch_var_name, scope)
    644         if return_numpy:
/opt/conda/envs/python35-paddle120-env/lib/python3.5/site-packages/paddle/fluid/layers/nn.py in __call__(self, *args)
  10512                 kwargs[arg] = args[idx]
  10513                 idx += 1
> 10514             func_ret = self._func(*args[idx:], **kwargs)
  10515 
  10516         if not isinstance(func_ret, (list, tuple)):
<ipython-input-11-d1585aa8c677> in bbox_overlaps(roi_boxes, gt_boxes)
      2 import numpy as np
      3 def bbox_overlaps(roi_boxes, gt_boxes):
----> 4     w1 = np.maximum(roi_boxes[:, 2] - roi_boxes[:, 0] + 1, 0)
      5     h1 = np.maximum(roi_boxes[:, 3] - roi_boxes[:, 1] + 1, 0)
      6     w2 = np.maximum(gt_boxes[:, 2] - gt_boxes[:, 0] + 1, 0)
TypeError: unsupported operand type(s) for -: 'paddle.fluid.core.Tensor' and 'paddle.fluid.core.Tensor'
0
回复
AIStudio792074
#4 回复于2019-11

我换了一种写法,还是报错

这个错误比较明显,py_func的2个输入是Tensor,2个Tensor如果要做elementwise减法,可以用paddle提供的数学操作,比如layers.elementwise_sub

参考https://www.paddlepaddle.org.cn/documentation/docs/zh/api_guides/low_level/layers/math.html

0
回复
AIStudio792105
#5 回复于2019-11

这个函数不是可以支持所有的python操作吗,我只是测试一下,这个都不支持,那这个函数到底支持啥操作啊?官网上的例子太简单了,看不出来到底支持啥操作啊

0
回复
AIStudio792074
#6 回复于2019-11
@liuwei1031

这个也请 老师解答一下?

0
回复
AIStudio791346
#7 回复于2019-11

py_func的主要思路是基于Paddle的LoDTensor和numpy array可以方便的互转来设计的,使用的主要思路是把传入的LoDTensor转换为numpy array,然后利用numpy的相关接口来进行计算。

0
回复
AIStudio792105
#8 回复于2019-11
@liuwei1031

既然支持numpy的接口,那我那个为什么会报错啊,麻烦您帮忙看一下

我换了一种写法,还是报错

import paddle.fluid as fluid
import numpy as np
def bbox_overlaps(roi_boxes, gt_boxes):
    w1 = np.maximum(roi_boxes[:, 2] - roi_boxes[:, 0] + 1, 0)
    h1 = np.maximum(roi_boxes[:, 3] - roi_boxes[:, 1] + 1, 0)
    w2 = np.maximum(gt_boxes[:, 2] - gt_boxes[:, 0] + 1, 0)
    h2 = np.maximum(gt_boxes[:, 3] - gt_boxes[:, 1] + 1, 0)
    area1 = w1 * h1
    area2 = w2 * h2

    overlaps = np.zeros((roi_boxes.shape[0], gt_boxes.shape[0]))
    for ind1 in range(roi_boxes.shape[0]):
        for ind2 in range(gt_boxes.shape[0]):
            inter_x1 = np.maximum(roi_boxes[ind1, 0], gt_boxes[ind2, 0])
            inter_y1 = np.maximum(roi_boxes[ind1, 1], gt_boxes[ind2, 1])
            inter_x2 = np.minimum(roi_boxes[ind1, 2], gt_boxes[ind2, 2])
            inter_y2 = np.minimum(roi_boxes[ind1, 3], gt_boxes[ind2, 3])
            inter_w = np.maximum(inter_x2 - inter_x1 + 1, 0)
            inter_h = np.maximum(inter_y2 - inter_y1 + 1, 0)
            inter_area = inter_w * inter_h
            iou = inter_area / (area1[ind1] + area2[ind2] - inter_area)
            overlaps[ind1, ind2] = iou
    return overlaps
def create_tmp_var(name, dtype, shape):
    return fluid.default_main_program().current_block().create_var(
        name=name, dtype=dtype, shape=shape)
def py_func():
    main=fluid.Program()
    start=fluid.Program()
    with fluid.program_guard(main,start):
        roi=fluid.layers.data('roi',[3,4],append_batch_size=False)
        gt=fluid.layers.data('gt',[2,4],append_batch_size=False)
        overlap=create_tmp_var('overlap','float32',[3,2])
        out=fluid.layers.py_func(bbox_overlaps,[roi,gt],overlap)
    exe=fluid.Executor(fluid.CPUPlace())
    exe.run(start)
    out=exe.run(main,feed={'roi':np.ones([3,4]),'gt':np.ones([2,4])},fetch_list=[out])
    print(out)
py_func()

报错信息

---------------------------------------------------------------------------TypeError                                 Traceback (most recent call last)<ipython-input-11-d1585aa8c677> in <module>
     51     out=exe.run(main,feed={'roi':np.ones([3,4]),'gt':np.ones([2,4])},fetch_list=[out])
     52     print(out)
---> 53 py_func()
<ipython-input-11-d1585aa8c677> in py_func()
     49     exe=fluid.Executor(fluid.CPUPlace())
     50     exe.run(start)
---> 51     out=exe.run(main,feed={'roi':np.ones([3,4]),'gt':np.ones([2,4])},fetch_list=[out])
     52     print(out)
     53 py_func()
/opt/conda/envs/python35-paddle120-env/lib/python3.5/site-packages/paddle/fluid/executor.py in run(self, program, feed, fetch_list, feed_var_name, fetch_var_name, scope, return_numpy, use_program_cache)
    563                 scope=scope,
    564                 return_numpy=return_numpy,
--> 565                 use_program_cache=use_program_cache)
    566         else:
    567             if fetch_list and program._is_data_parallel and program._program and (
/opt/conda/envs/python35-paddle120-env/lib/python3.5/site-packages/paddle/fluid/executor.py in _run(self, program, exe, feed, fetch_list, feed_var_name, fetch_var_name, scope, return_numpy, use_program_cache)
    640 
    641         self._feed_data(program, feed, feed_var_name, scope)
--> 642         exe.run(program.desc, scope, 0, True, True, fetch_var_name)
    643         outs = self._fetch_data(fetch_list, fetch_var_name, scope)
    644         if return_numpy:
/opt/conda/envs/python35-paddle120-env/lib/python3.5/site-packages/paddle/fluid/layers/nn.py in __call__(self, *args)
  10512                 kwargs[arg] = args[idx]
  10513                 idx += 1
> 10514             func_ret = self._func(*args[idx:], **kwargs)
  10515 
  10516         if not isinstance(func_ret, (list, tuple)):
<ipython-input-11-d1585aa8c677> in bbox_overlaps(roi_boxes, gt_boxes)
      2 import numpy as np
      3 def bbox_overlaps(roi_boxes, gt_boxes):
----> 4     w1 = np.maximum(roi_boxes[:, 2] - roi_boxes[:, 0] + 1, 0)
      5     h1 = np.maximum(roi_boxes[:, 3] - roi_boxes[:, 1] + 1, 0)
      6     w2 = np.maximum(gt_boxes[:, 2] - gt_boxes[:, 0] + 1, 0)
TypeError: unsupported operand type(s) for -: 'paddle.fluid.core.Tensor' and 'paddle.fluid.core.Tensor'
0
回复
AIStudio792105
#9 回复于2019-11
@wangguibao
import paddle.fluid as fluid
import numpy as np
def bbox_overlaps(roi_boxes, gt_boxes):
    roi_boxes=np.array(roi_boxes)#手动转换成numpy
    gt_boxes=np.array(gt_boxes)
    w1 = np.maximum(roi_boxes[:, 2] - roi_boxes[:, 0] + 1, 0)
    h1 = np.maximum(roi_boxes[:, 3] - roi_boxes[:, 1] + 1, 0)
    w2 = np.maximum(gt_boxes[:, 2] - gt_boxes[:, 0] + 1, 0)
    h2 = np.maximum(gt_boxes[:, 3] - gt_boxes[:, 1] + 1, 0)
    area1 = w1 * h1
    area2 = w2 * h2

    overlaps = np.zeros((roi_boxes.shape[0], gt_boxes.shape[0]))
    for ind1 in range(roi_boxes.shape[0]):
        for ind2 in range(gt_boxes.shape[0]):
            inter_x1 = np.maximum(roi_boxes[ind1, 0], gt_boxes[ind2, 0])
            inter_y1 = np.maximum(roi_boxes[ind1, 1], gt_boxes[ind2, 1])
            inter_x2 = np.minimum(roi_boxes[ind1, 2], gt_boxes[ind2, 2])
            inter_y2 = np.minimum(roi_boxes[ind1, 3], gt_boxes[ind2, 3])
            inter_w = np.maximum(inter_x2 - inter_x1 + 1, 0)
            inter_h = np.maximum(inter_y2 - inter_y1 + 1, 0)
            inter_area = inter_w * inter_h
            iou = inter_area / (area1[ind1] + area2[ind2] - inter_area)
            overlaps[ind1, ind2] = iou
    return overlaps
def create_tmp_var(name, dtype, shape):
    return fluid.default_main_program().current_block().create_var(
        name=name, dtype=dtype, shape=shape)
def py_func():
    main=fluid.Program()
    start=fluid.Program()
    with fluid.program_guard(main,start):
        roi=fluid.layers.data('roi',[3,4],append_batch_size=False)
        gt=fluid.layers.data('gt',[2,4],append_batch_size=False)
        overlap=create_tmp_var('overlap','float32',[3,2])
        out=fluid.layers.py_func(bbox_overlaps,[roi,gt],overlap)
    exe=fluid.Executor(fluid.CPUPlace())
    exe.run(start)
    out=exe.run(main,feed={'roi':np.ones([3,4]),'gt':np.ones([2,4])},fetch_list=[out])
    print(out)
py_func()

py_func好像是会把输入直接传进去,不会自动把输入变量变成numpy,需要手动转换一下,转换之后就不报错了

0
回复
AIStudio791346
#10 回复于2019-11

是的,传入的LoDTensor需要主动转换为numpy array,具体的解释可以参考一下这个链接https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_usage/development/new_op/new_python_op.html#py-func
我们的API示例写的的确有些简单,我会找相关同事优化一下

0
回复
需求/bug反馈?一键提issue告诉我们
发现bug?如果您知道修复办法,欢迎提pr直接参与建设飞桨~
在@后输入用户全名并按空格结束,可艾特全站任一用户