【问题标题】:How PyTorch implements Convolution Backward?PyTorch 如何实现反向卷积?
【发布时间】:2021-01-05 21:21:23
【问题描述】:

我阅读了Pytorch的源代码,发现它没有实现convolution_backward函数很奇怪,唯一的convolution_backward_overrideable函数是直接引发错误,应该不会落在这里。

所以我提到了 CuDNN / MKLDNN 的实现,它们都实现了像cudnn_convolution_backward 这样的功能。

我有以下问题:

  1. CUDA/CPU 的原生实现是什么?我可以找到类似thnn_conv2d_backward_out 的东西,但我找不到它在哪里调用。

  2. 为什么 PyTorch 没有将 convolution_backward 函数放在 Convolution.cpp 中?它提供了_convolution_double_backward() 功能。但这是双后退,是梯度的梯度。为什么他们不提供单一的后向功能?

  3. 如果我想为我的纯 cpu/cuda 张量调用原生卷积/convolution_backward 函数,我应该如何编写代码?或者我可以参考哪里?我找不到这方面的例子。

谢谢!

【问题讨论】:

    标签: pytorch convolution


    【解决方案1】:

    1- 实现可能因您使用的后端而异,它可能使用来自某个库的 CUDA 卷积实现、来自某个其他库的 CPU 卷积实现或自定义实现,请参见此处:pytorch - Where is “conv1d” implemented?

    2- 我不确定当前版本,但单次后退是通过 autograd 计算的,这就是为什么它没有明确的不同函数的原因。我不知道 autograd 的基本细节,但你可以查看https://github.com/pytorch/pytorch/blob/master/torch/csrc/autograd/autograd.cpp。只有当您需要高阶导数时,该 double_backward 函数才存在。

    3- 如果您想在 C 中执行此操作,您链接的文件 (convolution.cpp) 将向您展示如何执行此操作(函数 at::Tensor _convolution...)。如果你检查你看到的函数,它只是检查使用哪个实现(params.use_something...)并使用它。如果您想在 python 中执行此操作,您应该从 conv 开始跟踪,直到调用此文件 convolution.cpp。

    【讨论】:

    • 谢谢,但如果我想使用grad_inputgrad_weightgrad_bias 应该由 **_convolution_backward() 函数计算。我应该如何从 Native 实现中得到这三个?我的意思是,我知道 cudnn 得到了 cudnn_convolution_backward(),但是 CPU/CUDA 呢?
    • @Sut cudnn 是一个用 cuda(字面意思是 CUDA 深度神经网络)编写的深度学习库,对于 CPU,你可以使用 mkldnn,github.com/pytorch/pytorch/blob/…。你可以在 ATen -> Native in the repository 查看其他人。
    • 对不起,我的陈述不完整。我的意思是,比如在做卷积的时候,会落入_convolution(),这个函数会判断使用cudnn/mkldnn,如果以上都不起作用,会落入at::convolution_overrideable。我还想像 _convolution() 那样提及向后功能,但是 cudnn_convolution_backward() 的入口点在哪里? cudnn_convolution_backward_overrideable() 等后向函数什么时候调用?
    • @Sut 正如我在第二点中所说,没有向后的入口点,因为它不是直接调用的,它是通过 autograd 计算的。如果您想了解如何执行映射,则需要查看计算图如何计算的详细信息。不幸的是,我不知道细节,但每个张量(更准确地说是变量)对象都应该保存有关它所涉及的函数的信息,以及当你在图中开始反向传播时,它们各自的反向函数被调用。也许从 autograd/variable.h 中的 grad_fn 或 tools/autograd 中的derived.yaml 开始寻找。
    【解决方案2】:

    我在@unlut 的帖子中找到了一些补充。

    1. 卷积方法在不同的文件中用于不同的实现。您可以轻松找到 cudnn_convoluton_backward 或 mkldnn_convolution_backward。一件棘手的事情是,最终的原生 fall 函数很难找到。这是因为目前 Pytorch Teams 正在将 Thnn 功能移植到 ATen,您可以参考PR24507

    原生函数可以找到thnn_con2d_backward

    1. 后向卷积不是通过 autograd 计算的,而是必须有一个 conv_backward 函数,并且必须记录在 derived.yaml 中。如果你想找到具体的后向函数,参考那个文件是一个好的开始。

    2. 关于这段代码,如果要直接调用thnn_backward函数,需要显式构造finput和fgrad_input。这是两个作为缓冲区的空张量。

    at::Tensor finput = at::empty({0},input.options()); 
    at::Tensor fgrad_input = at::empty({0}, input.options());
    auto kernel_size = weight.sizes().slice(2);
    auto &&result = at::thnn_conv2d_backward(grad_output, input, weight,kernel_size , stride, padding, 
    finput, fgrad_input, output_mask);
    

    【讨论】:

      猜你喜欢
      • 2020-12-10
      • 2019-12-09
      • 1970-01-01
      • 2016-11-11
      • 2021-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多