PyTorch 是如何实现反向卷积的?
How PyTorch implements Convolution Backward?
看了Pytorch的源码,觉得奇怪的是没有实现convolution_backward
函数,唯一的convolution_backward_overrideable
函数直接报错,应该不会掉这里。
所以我参考了 CuDNN / MKLDNN 实现,它们都实现了 cudnn_convolution_backward
.
这样的功能
我遇到了以下问题:
CUDA/CPU的原生实现是什么?我可以找到类似 thnn_conv2d_backward_out
的内容,但找不到它的调用位置。
为什么 PyTorch 没有把 convolution_backward
函数放在 Convolution.cpp 中?它提供了一个 _convolution_double_backward()
功能。但这是双重倒退,它是渐变的渐变。他们为什么不提供单一的向后功能?
如果我想为我的纯cpu/cuda张量调用原生卷积/convolution_backward函数,我应该如何编写代码?或者哪里可以参考?我找不到这方面的例子。
谢谢!
1- 实现可能会有所不同,具体取决于您使用的后端,它可能使用来自某些库的 CUDA 卷积实现,CPU 来自其他库的卷积实现,或自定义实现,请参见此处:.
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 的位置。
我想到了@unlut post 的补充。
- 卷积方法在不同的文件中用于不同的实现。您可能会轻松找到 cudnn_convoluton_backward 或 mkldnn_convolution_backward。一件棘手的事情是很难找到最终的原生跌落功能。因为目前Pytorch Teams正在将Thnn功能移植到ATen,可以参考PR24507.
可以找到本机函数 thnn_con2d_backward。
反向卷积不是通过autograd计算的,而是必须有一个conv_backward函数,并且必须记录在derivatives.yaml中。如果你想找到具体的反向功能,参考那个文件是一个很好的开始。
关于这段代码,如果想直接调用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);
看了Pytorch的源码,觉得奇怪的是没有实现convolution_backward
函数,唯一的convolution_backward_overrideable
函数直接报错,应该不会掉这里。
所以我参考了 CuDNN / MKLDNN 实现,它们都实现了 cudnn_convolution_backward
.
我遇到了以下问题:
CUDA/CPU的原生实现是什么?我可以找到类似
thnn_conv2d_backward_out
的内容,但找不到它的调用位置。为什么 PyTorch 没有把
convolution_backward
函数放在 Convolution.cpp 中?它提供了一个_convolution_double_backward()
功能。但这是双重倒退,它是渐变的渐变。他们为什么不提供单一的向后功能?如果我想为我的纯cpu/cuda张量调用原生卷积/convolution_backward函数,我应该如何编写代码?或者哪里可以参考?我找不到这方面的例子。
谢谢!
1- 实现可能会有所不同,具体取决于您使用的后端,它可能使用来自某些库的 CUDA 卷积实现,CPU 来自其他库的卷积实现,或自定义实现,请参见此处:
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 的位置。
我想到了@unlut post 的补充。
- 卷积方法在不同的文件中用于不同的实现。您可能会轻松找到 cudnn_convoluton_backward 或 mkldnn_convolution_backward。一件棘手的事情是很难找到最终的原生跌落功能。因为目前Pytorch Teams正在将Thnn功能移植到ATen,可以参考PR24507.
可以找到本机函数 thnn_con2d_backward。
反向卷积不是通过autograd计算的,而是必须有一个conv_backward函数,并且必须记录在derivatives.yaml中。如果你想找到具体的反向功能,参考那个文件是一个很好的开始。
关于这段代码,如果想直接调用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);