未验证 提交 5f2c251c 编写于 作者: C chentianyu03 提交者: GitHub

[Yaml]add conv3d, depthwise_conv2d yaml (#42807)

* add conv3d yaml

* add conv3d_grad, conv3d_double_grad

* add final_state_conv3d test case

* add conv3d double test case

* add depthwise_conv2d grad yaml

* add depthwise_conv2d double grad test case

* modify the order of args

* add depthwise_conv2d_grad_grad config
上级 4b89120b
......@@ -30,7 +30,8 @@ ops_to_fill_zero_for_empty_grads = set([
"divide_double_grad", "log_double_grad", "elu_double_grad",
"leaky_relu_double_grad", "sqrt_double_grad", "rsqrt_double_grad",
"square_double_grad", "celu_double_grad", "pad_double_grad",
"pad3d_double_grad", "squeeze_double_grad", "unsqueeze_double_grad"
"pad3d_double_grad", "squeeze_double_grad", "unsqueeze_double_grad",
"conv3d_double_grad", "depthwise_conv2d_grad_grad"
])
# For API dispatch used at python-level
......
......@@ -531,6 +531,108 @@ Tensor conv2d_impl(const Tensor& input,
return api_output;
}
Tensor conv3d_impl(const Tensor& input,
const Tensor& filter,
const std::vector<int>& strides,
const std::vector<int>& paddings,
const std::string& paddding_algorithm,
int groups,
const std::vector<int>& dilations,
const std::string& data_format,
bool use_addto,
int workspace_size_MB,
bool exhaustive_search) {
Backend kernel_backend = Backend::UNDEFINED;
DataLayout kernel_layout = DataLayout::UNDEFINED;
DataType kernel_data_type = DataType::UNDEFINED;
kernel_data_type = ParseDataType(input);
if (kernel_backend == Backend::UNDEFINED ||
kernel_layout == DataLayout::UNDEFINED ||
kernel_data_type == DataType::UNDEFINED) {
auto kernel_key_set = ParseKernelKeyByInputArgs(input, filter);
auto kernel_key = kernel_key_set.GetHighestPriorityKernelKey();
if (kernel_backend == Backend::UNDEFINED) {
kernel_backend = kernel_key.backend();
}
if (kernel_layout == DataLayout::UNDEFINED) {
kernel_layout = kernel_key.layout();
}
if (kernel_data_type == DataType::UNDEFINED) {
kernel_data_type = kernel_key.dtype();
}
}
VLOG(6) << "conv3d API kernel key: [" << kernel_backend << ", "
<< kernel_layout << ", " << kernel_data_type << "]";
const auto& kernel = phi::KernelFactory::Instance().SelectKernelOrThrowError(
"conv3d", {kernel_backend, kernel_layout, kernel_data_type}, true);
VLOG(6) << "conv3d API kernel: " << kernel;
auto* dev_ctx = GetDeviceContextByBackend(kernel_backend);
phi::TensorArgDef args0 = kernel.InputAt(0);
phi::TensorArgDef args1 = kernel.InputAt(1);
if (kernel_backend == Backend::GPU) {
args0.backend = Backend::GPU;
args1.backend = Backend::GPU;
}
auto input_input = PrepareData(input, args0, {});
auto input_filter = PrepareData(filter, args1, {});
Tensor api_output;
auto kernel_out = SetKernelOutput(kernel_backend, &api_output);
phi::MetaTensor meta_out(kernel_out);
phi::ConvInferMeta(MakeMetaTensor(*input_input),
MakeMetaTensor(*input_filter),
strides,
paddings,
paddding_algorithm,
groups,
dilations,
data_format,
use_addto,
workspace_size_MB,
exhaustive_search,
&meta_out);
using kernel_signature = void (*)(const platform::DeviceContext&,
const phi::DenseTensor&,
const phi::DenseTensor&,
const std::vector<int>&,
const std::vector<int>&,
const std::string&,
int,
const std::vector<int>&,
const std::string&,
bool,
int,
bool,
phi::DenseTensor*);
auto* kernel_fn = kernel.GetVariadicKernelFn<kernel_signature>();
{
(*kernel_fn)(*dev_ctx,
*input_input,
*input_filter,
strides,
paddings,
paddding_algorithm,
groups,
dilations,
data_format,
use_addto,
workspace_size_MB,
exhaustive_search,
kernel_out);
}
return api_output;
}
void conv2d_grad_impl(const Tensor& input,
const Tensor& filter,
const Tensor& out_grad,
......@@ -632,6 +734,107 @@ void conv2d_grad_impl(const Tensor& input,
}
}
void conv3d_grad_impl(const Tensor& input,
const Tensor& filter,
const Tensor& out_grad,
const std::vector<int>& strides,
const std::vector<int>& paddings,
const std::string& paddding_algorithm,
int groups,
const std::vector<int>& dilations,
const std::string& data_format,
bool use_addto,
int workspace_size_MB,
bool exhaustive_search,
Tensor* input_grad,
Tensor* filter_grad) {
Backend kernel_backend = Backend::UNDEFINED;
DataLayout kernel_layout = DataLayout::UNDEFINED;
DataType kernel_data_type = DataType::UNDEFINED;
if (kernel_backend == Backend::UNDEFINED ||
kernel_layout == DataLayout::UNDEFINED ||
kernel_data_type == DataType::UNDEFINED) {
auto kernel_key_set = ParseKernelKeyByInputArgs(input, filter, out_grad);
auto kernel_key = kernel_key_set.GetHighestPriorityKernelKey();
if (kernel_backend == Backend::UNDEFINED) {
kernel_backend = kernel_key.backend();
}
if (kernel_layout == DataLayout::UNDEFINED) {
kernel_layout = kernel_key.layout();
}
if (kernel_data_type == DataType::UNDEFINED) {
kernel_data_type = kernel_key.dtype();
}
}
VLOG(6) << "conv3d_grad API kernel key: [" << kernel_backend << ", "
<< kernel_layout << ", " << kernel_data_type << "]";
const auto& kernel = phi::KernelFactory::Instance().SelectKernelOrThrowError(
"conv3d_grad", {kernel_backend, kernel_layout, kernel_data_type}, true);
VLOG(6) << "conv3d_grad API kernel: " << kernel;
auto* dev_ctx = GetDeviceContextByBackend(kernel_backend);
phi::TensorArgDef args0 = kernel.InputAt(0);
phi::TensorArgDef args1 = kernel.InputAt(1);
phi::TensorArgDef args2 = kernel.InputAt(2);
if (kernel_backend == Backend::GPU) {
args0.backend = Backend::GPU;
args1.backend = Backend::GPU;
args2.backend = Backend::GPU;
}
auto input_input = PrepareData(input, args0, {});
auto input_filter = PrepareData(filter, args1, {});
auto input_out_grad = PrepareData(out_grad, args2, {});
auto kernel_out_0 = SetKernelOutput(kernel_backend, input_grad);
auto kernel_out_1 = SetKernelOutput(kernel_backend, filter_grad);
phi::MetaTensor meta_out_0(kernel_out_0);
phi::MetaTensor meta_out_1(kernel_out_1);
phi::GeneralBinaryGradInferMeta(MakeMetaTensor(*input_input),
MakeMetaTensor(*input_filter),
kernel_out_0 ? &meta_out_0 : nullptr,
kernel_out_1 ? &meta_out_1 : nullptr);
using kernel_signature = void (*)(const platform::DeviceContext&,
const phi::DenseTensor&,
const phi::DenseTensor&,
const phi::DenseTensor&,
const std::vector<int>&,
const std::vector<int>&,
const std::string&,
int,
const std::vector<int>&,
const std::string&,
bool,
int,
bool,
phi::DenseTensor*,
phi::DenseTensor*);
auto* kernel_fn = kernel.GetVariadicKernelFn<kernel_signature>();
{
(*kernel_fn)(*dev_ctx,
*input_input,
*input_filter,
*input_out_grad,
strides,
paddings,
paddding_algorithm,
groups,
dilations,
data_format,
use_addto,
workspace_size_MB,
exhaustive_search,
kernel_out_0,
kernel_out_1);
}
}
Tensor copy_to_impl(const Tensor& x, Place place, bool blocking) {
Tensor out;
copy(x, place, blocking, &out);
......
......@@ -96,6 +96,18 @@ Tensor conv2d_impl(const Tensor& input,
int workspace_size_MB,
bool exhaustive_search);
Tensor conv3d_impl(const Tensor& input,
const Tensor& filter,
const std::vector<int>& strides,
const std::vector<int>& paddings,
const std::string& paddding_algorithm,
int groups,
const std::vector<int>& dilations,
const std::string& data_format,
bool use_addto,
int workspace_size_MB,
bool exhaustive_search);
Tensor copy_to_impl(const Tensor& x, Place place, bool blocking);
Tensor embedding_impl(const Tensor& x,
......@@ -148,6 +160,21 @@ void conv2d_grad_impl(const Tensor& input,
Tensor* input_grad,
Tensor* filter_grad);
void conv3d_grad_impl(const Tensor& input,
const Tensor& filter,
const Tensor& out_grad,
const std::vector<int>& strides,
const std::vector<int>& paddings,
const std::string& paddding_algorithm,
int groups,
const std::vector<int>& dilations,
const std::string& data_format,
bool use_addto,
int workspace_size_MB,
bool exhaustive_search,
Tensor* input_grad,
Tensor* filter_grad);
void imag_grad_impl(const Tensor& out_grad, Tensor* x_grad);
void embedding_grad_impl(const Tensor& x,
......
......@@ -40,11 +40,11 @@ void ConvGradGradKernel(const Context& dev_ctx,
template <typename T, typename Context>
void Conv3DGradGradKernel(const Context& dev_ctx,
const paddle::optional<DenseTensor>& input_grad_grad,
const paddle::optional<DenseTensor>& filter_grad_grad,
const DenseTensor& out_grad,
const DenseTensor& input,
const DenseTensor& filter,
const DenseTensor& out_grad,
const paddle::optional<DenseTensor>& input_grad_grad,
const paddle::optional<DenseTensor>& filter_grad_grad,
const std::vector<int>& strides,
const std::vector<int>& paddings,
const std::string& paddding_algorithm,
......@@ -54,8 +54,8 @@ void Conv3DGradGradKernel(const Context& dev_ctx,
bool use_addto,
int workspace_size_MB,
bool exhaustive_search,
DenseTensor* out_grad_grad,
DenseTensor* input_grad,
DenseTensor* filter_grad);
DenseTensor* filter_grad,
DenseTensor* out_grad_grad);
} // namespace phi
......@@ -21,11 +21,11 @@
namespace phi {
template <typename T, typename Context>
void Conv3DGradGradKernel(const Context& ctx,
const paddle::optional<DenseTensor>& input_grad_grad,
const paddle::optional<DenseTensor>& filter_grad_grad,
const DenseTensor& out_grad,
const DenseTensor& input,
const DenseTensor& filter,
const DenseTensor& out_grad,
const paddle::optional<DenseTensor>& input_grad_grad,
const paddle::optional<DenseTensor>& filter_grad_grad,
const std::vector<int>& strides,
const std::vector<int>& paddings_t,
const std::string& padding_algorithm,
......@@ -35,9 +35,9 @@ void Conv3DGradGradKernel(const Context& ctx,
bool use_addto,
int workspace_size_MB,
bool exhaustive_search_t,
DenseTensor* out_grad_grad,
DenseTensor* input_grad,
DenseTensor* filter_grad) {
DenseTensor* filter_grad,
DenseTensor* out_grad_grad) {
ConvGradGradKernel<T>(ctx,
input,
filter,
......
......@@ -711,11 +711,11 @@ void DepthwiseConvCudnnGradGradKernel(
template <typename T, typename Context>
void Conv3DCudnnGradGradKernel(
const Context& ctx,
const paddle::optional<DenseTensor>& input_grad_grad,
const paddle::optional<DenseTensor>& filter_grad_grad,
const DenseTensor& out_grad,
const DenseTensor& input,
const DenseTensor& filter,
const DenseTensor& out_grad,
const paddle::optional<DenseTensor>& input_grad_grad,
const paddle::optional<DenseTensor>& filter_grad_grad,
const std::vector<int>& strides,
const std::vector<int>& paddings_t,
const std::string& padding_algorithm,
......@@ -725,9 +725,9 @@ void Conv3DCudnnGradGradKernel(
bool use_addto,
int workspace_size_MB,
bool exhaustive_search_t,
DenseTensor* out_grad_grad,
DenseTensor* input_grad,
DenseTensor* filter_grad) {
DenseTensor* filter_grad,
DenseTensor* out_grad_grad) {
ConvCudnnGradGradKernel<T>(ctx,
input,
filter,
......
......@@ -49,7 +49,7 @@ KernelSignature Conv3dGradOpArgumentMapping(const ArgumentMappingContext& ctx) {
KernelSignature Conv3dDoubleGradOpArgumentMapping(
const ArgumentMappingContext& ctx) {
return KernelSignature("conv3d_grad_grad",
{"DDInput", "DDFilter", "DOutput", "Input", "Filter"},
{"Input", "Filter", "DOutput", "DDInput", "DDFilter"},
{"strides",
"paddings",
"padding_algorithm",
......@@ -59,7 +59,7 @@ KernelSignature Conv3dDoubleGradOpArgumentMapping(
"use_addto",
"workspace_size_MB",
"exhaustive_search"},
{"DDOutput", "DInput", "DFilter"});
{"DInput", "DFilter", "DDOutput"});
}
} // namespace phi
......
......@@ -17,6 +17,8 @@ from paddle import fluid, nn
import paddle.fluid.dygraph as dg
import paddle.nn.functional as F
import paddle.fluid.initializer as I
import paddle
from paddle.fluid.framework import _test_eager_guard
import unittest
......@@ -134,7 +136,8 @@ class Conv3DTestCase(unittest.TestCase):
return y_np
def paddle_nn_layer(self):
x_var = dg.to_variable(self.input)
x_var = paddle.to_tensor(self.input)
x_var.stop_gradient = False
conv = nn.Conv3D(
self.num_channels,
self.num_filters,
......@@ -148,17 +151,23 @@ class Conv3DTestCase(unittest.TestCase):
if not self.no_bias:
conv.bias.set_value(self.bias)
y_var = conv(x_var)
y_var.backward()
y_np = y_var.numpy()
return y_np
t1 = x_var.gradient()
return y_np, t1
def _test_equivalence(self, place):
place = fluid.CPUPlace()
result1 = self.fluid_layer(place)
result2 = self.functional(place)
with dg.guard(place):
result3 = self.paddle_nn_layer()
result3, g1 = self.paddle_nn_layer()
with _test_eager_guard():
res_eager, g2 = self.paddle_nn_layer()
np.testing.assert_array_almost_equal(result1, result2)
np.testing.assert_array_almost_equal(result2, result3)
self.assertTrue(np.allclose(result3, res_eager))
self.assertTrue(np.allclose(g1, g2))
def runTest(self):
place = fluid.CPUPlace()
......
......@@ -503,6 +503,75 @@ class TestDepthWiseConvDoubleGradCheck(unittest.TestCase):
self.func(p)
class TestDepthWiseConvDoubleGradCheckCase1(unittest.TestCase):
def depthwise_conv2d_wrapper(self, x):
return paddle.nn.functional.conv2d(x[0], x[1], groups=4)
@prog_scope()
def func(self, place):
x_shape = [2, 4, 3, 3]
w_shape = [4, 1, 3, 3]
eps = 0.005
dtype = np.float32 if fluid.core.is_compiled_with_rocm() else np.float64
x = layers.data('x', x_shape, False, dtype)
w = layers.data('w', w_shape, False, dtype)
# condition of depthwise conv:
# use_cudnn == False
# groups == filters
# num_filters % num_channels == 0
y = paddle.nn.functional.conv2d(x, w, groups=4)
x_arr = np.random.uniform(-1, 1, x_shape).astype(dtype)
w_arr = np.random.uniform(-1, 1, w_shape).astype(dtype)
gradient_checker.double_grad_check(
[x, w], y, x_init=[x_arr, w_arr], place=place, eps=eps)
gradient_checker.double_grad_check_for_dygraph(
self.depthwise_conv2d_wrapper, [x, w],
y,
x_init=[x_arr, w_arr],
place=place)
def test_grad(self):
places = []
if core.is_compiled_with_cuda():
places.append(fluid.CUDAPlace(0))
for p in places:
self.func(p)
class TestConv3DDoubleGradCheck_NN(unittest.TestCase):
def conv3d_wrapper(self, x):
return paddle.nn.functional.conv3d(x[0], x[1])
@prog_scope()
def func(self, place):
x_shape = [2, 3, 8, 8, 8]
w_shape = [6, 3, 3, 3, 3]
eps = 0.005
dtype = np.float32 if fluid.core.is_compiled_with_rocm() else np.float64
x = layers.data('x', x_shape, False, dtype)
w = layers.data('w', w_shape, False, dtype)
x.persistable = True
w.persistable = True
y = paddle.nn.functional.conv3d(x, w)
x_arr = np.random.uniform(-1, 1, x_shape).astype(dtype)
w_arr = np.random.uniform(-1, 1, w_shape).astype(dtype)
gradient_checker.double_grad_check(
[x, w], y, x_init=[x_arr, w_arr], place=place, eps=eps)
gradient_checker.double_grad_check_for_dygraph(
self.conv3d_wrapper, [x, w], y, x_init=[x_arr, w_arr], place=place)
def test_grad(self):
places = []
if core.is_compiled_with_cuda():
places.append(fluid.CUDAPlace(0))
for p in places:
self.func(p)
if __name__ == "__main__":
paddle.enable_static()
unittest.main()
......@@ -138,6 +138,35 @@ def _conv_nd(x,
return _C_ops.final_state_add(pre_bias, bias)
else:
return pre_bias
if in_dygraph_mode() and op_type == "depthwise_conv2d":
pre_bias = _C_ops.final_state_depthwise_conv2d(
x, weight, stride, padding, padding_algorithm, groups, dilation,
data_format, False, -1, False, False)
if bias is not None:
channel_dim = channel_dim + len(
x.shape) if channel_dim < 0 else channel_dim
tmp_bias = _C_ops.final_state_reshape(
bias, bias.shape +
[1 for i in range(len(x.shape) - channel_dim - 1)])
return _C_ops.final_state_add(pre_bias, tmp_bias)
else:
return pre_bias
if in_dygraph_mode() and op_type == "conv3d":
pre_bias = _C_ops.final_state_conv3d(
x, weight, stride, padding, padding_algorithm, groups, dilation,
data_format, False, -1, False)
if bias is not None:
channel_dim = channel_dim + len(
x.shape) if channel_dim < 0 else channel_dim
tmp_bias = _C_ops.final_state_reshape(
bias, bias.shape +
[1 for i in range(len(x.shape) - channel_dim - 1)])
return _C_ops.final_state_add(pre_bias, tmp_bias)
else:
return pre_bias
if in_dynamic_mode():
attrs = ('strides', stride, 'paddings', padding, 'dilations', dilation,
'groups', groups, 'use_cudnn', use_cudnn, 'use_mkldnn',
......
......@@ -407,6 +407,12 @@
use_gpudnn : true
backward : conv2d_transpose_grad
- api : conv3d
args : (Tensor input, Tensor filter, int[] strides, int[] paddings, str paddding_algorithm, int groups, int[] dilations, str data_format, bool use_addto, int workspace_size_MB, bool exhaustive_search)
output : Tensor
invoke : conv3d_impl(input, filter, strides, paddings, paddding_algorithm, groups, dilations, data_format, use_addto, workspace_size_MB, exhaustive_search)
backward : conv3d_grad
- api : conv3d_transpose
args : (Tensor x, Tensor filter, int[] strides, int[] paddings, int[] output_padding, int[] output_size, str padding_algorithm, int groups, int[] dilations, str data_format)
output : Tensor(out)
......@@ -492,6 +498,17 @@
optional : mask
backward : deformable_conv_grad
- api : depthwise_conv2d
args : (Tensor x, Tensor filter, int[] strides, int[] paddings, str padding_algorithm, int groups, int[] dilations, str data_format, bool use_addto, int workspace_size_MB, bool exhaustive_search, bool fuse_relu)
output : Tensor(out)
invoke : conv2d_impl(x, filter, strides, paddings, padding_algorithm, groups, dilations, data_format, use_addto, workspace_size_MB, exhaustive_search)
backward : depthwise_conv2d_grad
# infer_meta :
# func : ConvTransposeInferMeta
# prams: [x, filter, strides, paddings, padding_algorithm, groups, dilations, data_format, use_addto, workspace_size_MB, exhaustive_search]
# kernel :
# func : depthwise_conv2d
- api : depthwise_conv2d_transpose
args : (Tensor x, Tensor filter, int[] strides, int[] paddings, int[] output_padding, int[] output_size, str padding_algorithm, int groups, int[] dilations, str data_format)
output : Tensor(out)
......
......@@ -392,6 +392,25 @@
use_gpudnn : true
backward : conv2d_transpose_double_grad
- backward_api : conv3d_grad
forward : conv3d (Tensor input, Tensor filter, int[] strides, int[] paddings, str paddding_algorithm, int groups, int[] dilations, str data_format, bool use_addto, int workspace_size_MB, bool exhaustive_search) -> Tensor(out)
args : (Tensor input, Tensor filter, Tensor out_grad, int[] strides, int[] paddings, str paddding_algorithm, int groups, int[] dilations, str data_format, bool use_addto, int workspace_size_MB, bool exhaustive_search)
output : Tensor(input_grad), Tensor(filter_grad)
invoke : conv3d_grad_impl(input, filter, out_grad, strides, paddings, paddding_algorithm, groups, dilations, data_format, use_addto, workspace_size_MB, exhaustive_search, input_grad, filter_grad)
backward : conv3d_grad_grad
- backward_api : conv3d_grad_grad
forward : conv3d_grad (Tensor input, Tensor filter, Tensor grad_out, int[] strides, int[] paddings, str paddding_algorithm, int groups, int[] dilations, str data_format, bool use_addto, int workspace_size_MB, bool exhaustive_search) -> Tensor(grad_input), Tensor(grad_filter)
args : (Tensor input, Tensor filter, Tensor grad_out, Tensor grad_input_grad, Tensor grad_filter_grad, int[] strides, int[] paddings, str paddding_algorithm, int groups, int[] dilations, str data_format, bool use_addto, int workspace_size_MB, bool exhaustive_search)
output : Tensor(input_grad), Tensor(filter_grad), Tensor(grad_out_grad)
infer_meta :
func : GeneralTernaryGradInferMeta
param: [input, filter, grad_out]
kernel :
func : conv3d_grad_grad
use_gpudnn : true
optional : grad_input_grad, grad_filter_grad
- backward_api : conv3d_transpose_grad
forward : conv3d_transpose(Tensor x, Tensor filter, int[] strides, int[] paddings, int[] output_padding, int[] output_size, str padding_algorithm, int groups, int[] dilations, str data_format) -> Tensor(out)
args : (Tensor x, Tensor filter, Tensor out_grad, int[] strides, int[] paddings, int[] output_padding, int[] output_size, str padding_algorithm, int groups, int[] dilations, str data_format)
......@@ -475,6 +494,25 @@
data_type : x
optional : mask
- backward_api : depthwise_conv2d_grad
forward : depthwise_conv2d (Tensor input, Tensor filter, int[] strides, int[] paddings, str paddding_algorithm, int groups, int[] dilations, str data_format, bool use_addto, int workspace_size_MB, bool exhaustive_search, bool fuse_relu) -> Tensor(out)
args : (Tensor input, Tensor filter, Tensor out_grad, int[] strides, int[] paddings, str paddding_algorithm, int groups, int[] dilations, str data_format, bool use_addto, int workspace_size_MB, bool exhaustive_search, bool fuse_relu)
output : Tensor(input_grad), Tensor(filter_grad)
invoke : conv2d_grad_impl(input, filter, out_grad, strides, paddings, paddding_algorithm, groups, dilations, data_format, use_addto, workspace_size_MB, exhaustive_search, input_grad, filter_grad)
backward : depthwise_conv2d_grad_grad
- backward_api : depthwise_conv2d_grad_grad
forward : depthwise_conv2d_grad (Tensor input, Tensor filter, Tensor grad_out, int[] strides, int[] paddings, str paddding_algorithm, int groups, int[] dilations, str data_format, bool use_addto, int workspace_size_MB, bool exhaustive_search, bool fuse_relu) -> Tensor(grad_input), Tensor(grad_filter)
args : (Tensor input, Tensor filter, Tensor grad_out, Tensor grad_input_grad, Tensor grad_filter_grad, int[] strides, int[] paddings, str paddding_algorithm, int groups, int[] dilations, str data_format, bool use_addto, int workspace_size_MB, bool exhaustive_search)
output : Tensor(input_grad), Tensor(filter_grad), Tensor(grad_out_grad)
infer_meta :
func : GeneralTernaryGradInferMeta
param: [input, filter, grad_out]
kernel :
func : conv2d_grad_grad
use_gpudnn : true
optional : grad_input_grad, grad_filter_grad
- backward_api : depthwise_conv2d_transpose_grad
forward : depthwise_conv2d_transpose(Tensor x, Tensor filter, int[] strides, int[] paddings, int[] output_padding, int[] output_size, str padding_algorithm, int groups, int[] dilations, str data_format) -> Tensor(out)
args : (Tensor x, Tensor filter, Tensor out_grad, int[] strides, int[] paddings, int[] output_padding, int[] output_size, str padding_algorithm, int groups, int[] dilations, str data_format)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册