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

【Hackathon 5th No.38】为 Paddle 新增 FractionalMaxPool2d / FractionalMaxPool3d API #698

Merged
merged 4 commits into from
Nov 20, 2023

Conversation

megemini
Copy link
Contributor

PR types

Others

PR changes

Docs

Description

【Hackathon 5th No.38】为 Paddle 新增 FractionalMaxPool2d / FractionalMaxPool3d API

请评审!

@paddle-bot
Copy link

paddle-bot bot commented Oct 12, 2023

你的PR提交成功,感谢你对开源项目的贡献!
请检查PR提交格式和内容是否完备,具体请参考示例模版
Your PR has been submitted. Thanks for your contribution!
Please check its format and content. For this, you can refer to Template and Demo.


## 底层 OP 设计

由于赛题要求直接实现 python 接口,所以此处直接使用 python API 实现,无需设计底层 c++ 相关 OP。

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个算子组合实现的话调用kernel数量会跟batch_size有关系,导致launch大量kernel,考虑到性能问题,这边要求最好是用c++ 底层op去实现该算子。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

嗯,所以最后我写了个补充说明 ~ 看看补充说明里面的实现方式是否可行?

- `paddle.nn.FractionalMaxPool2d`

``` python
paddle.nn.functional.fractional_max_pool2d(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这儿是否需要和maxpooling2D一样加一个data_format参数?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

嗯 应该有!我记一下~

@megemini
Copy link
Contributor Author

@Charles-hit

根据之前的讨论,此次更新,使用 c++ 实现底层算子:

  • 共用 max pooling Nd 底层算子的方式,而不是共用 pooling Nd 算子(参考 adaptive max pooling)
  • 分析底层 c++ 算子相关实现,cpu/gpu
  • 分析 python api/layer 相关接口

另外,之前讨论的 data_format 参数,仔细分析了一下目前 pooling 的实现方式,此次方案可能加不进去 ~ 方案里面有具体的分析,请评审!

非常感谢!

@megemini megemini requested a review from Charles-hit October 28, 2023 11:25

``` yaml
- op : max_pool2d_with_index
args : (Tensor x, int[] kernel_size, int[] strides= {1, 1}, int[] paddings = {0, 0}, bool global_pooling = false, bool adaptive = false, bool fractional = false)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这些参数比如kernel_size是在api内部进行推导的吗,如果是的话方便加一下推导过程吗.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fractional max pooling 与 adaptive max pooling 应该一样,不需要 kernel_size 参数,只需要 output_sizekernel_size 是自动推导的,使用 ksize 代为接受 output_size 这个参数。

python 接口:

def adaptive_max_pool2d(x, output_size, return_mask=False, name=None):
    ...
    if in_dygraph_mode():
    ...
    else:
        l_type = 'max_pool2d_with_index'
        ...

        helper.append_op(
            type=l_type,
            inputs={"X": x},
            outputs=outputs,
            attrs={
                "pooling_type": 'max',
                "ksize": output_size,
                "adaptive": True,
            },
        )
        return (pool_out, mask) if return_mask else pool_out

c++ 算子:

    if (adaptive || fractional) {
        output_shape.insert(
            output_shape.end(), kernel_size_.begin(), kernel_size_.end());
    } else {
        ...
    }

fractional max pooling 与 adaptive max pooling 最重要的是生成池化序列的方法,也就是一系列的 ksize,如 fractional max pooling 的 1222111212...。之前版本有用 python 写过伪序列的生成方法:

def pseudo(input_size, output_size, sample):
    cum_seq = [0] * (output_size + 1)
    diff = [0] * output_size

    alpha = input_size / output_size
    base = input_size // output_size

    u_max1 = (base + 2) / alpha - 1
    u_max2 = (input_size + 1 - base) / alpha - (output_size - 1)
    max_u = min(u_max1, u_max2)

    u = sample * max_u

    cum_seq[0] = 1
    cum_seq[output_size] = input_size + 1

    for i in range(1, output_size):
        cum_seq[i] = math.ceil(alpha * (i + u))

    for i in range(output_size):
        diff[i] = cum_seq[i + 1] - cum_seq[i]

    return diff

这里需要用 c++ 重新写一下 ~ 是需要这个推导过程是吧?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好的 我看你是复用adaptive_max_poolNd的实现,但是yaml以及函数命名记得与这个进行区分,文档中我看写的都是max_poolNd

Copy link

@Charles-hit Charles-hit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

设计文档写得非常详细认真!

@megemini
Copy link
Contributor Author

Update 20231114

  • 已增加池化序列生成方式的简易程序用于演示与验证

我看你是复用adaptive_max_poolNd的实现,但是yaml以及函数命名记得与这个进行区分,文档中我看写的都是max_poolNd

由于 adaptive_max_poolNd 也是复用 max_poolNd_with_index,所以,实际上是 adaptive_max_poolNd 和 fractional_max_poolNd 共同复用了 max_poolNd_with_index,所以文档中基本上都是 max_poolNd_xxx。

@Charles-hit 请评审~ 谢谢!

@megemini megemini requested a review from Charles-hit November 14, 2023 11:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants