From 13189451f7b685241c3c49414e2bfd3d5b659d55 Mon Sep 17 00:00:00 2001 From: Oceania2018 Date: Sun, 9 Jun 2019 14:19:33 -0500 Subject: [PATCH] Gradient function for Conv2D --- src/TensorFlowNET.Core/Gradients/nn_grad.cs | 44 ++++++++++++++++++ .../Operations/NnOps/Conv2dParams.cs | 16 +++++++ .../Operations/NnOps/gen_nn_ops.cs | 46 +++++++++++++++++++ .../Operations/gen_array_ops.cs | 13 ++++++ .../TensorFlowNET.Core.csproj | 5 +- 5 files changed, 122 insertions(+), 2 deletions(-) diff --git a/src/TensorFlowNET.Core/Gradients/nn_grad.cs b/src/TensorFlowNET.Core/Gradients/nn_grad.cs index b7d46b2c..19cdac36 100644 --- a/src/TensorFlowNET.Core/Gradients/nn_grad.cs +++ b/src/TensorFlowNET.Core/Gradients/nn_grad.cs @@ -97,6 +97,50 @@ namespace Tensorflow.Gradients }; } + /// + /// Gradient function for Conv2D. + /// + /// + /// + /// + [RegisterGradient("Conv2D")] + public static Tensor[] _Conv2DGrad(Operation op, Tensor[] grads) + { + var dilations = op.get_attr("dilations"); + var strides = op.get_attr("strides"); + var padding = op.get_attr("padding"); + var explicit_paddings = op.get_attr("explicit_paddings"); + var use_cudnn_on_gpu = op.get_attr("use_cudnn_on_gpu"); + var data_format = op.get_attr("data_format"); + var shape = gen_array_ops.shape_n(new Tensor[] { op.inputs[0], op.inputs[1] }); + + return new Tensor[] + { + gen_nn_ops.conv2d_backprop_input(new Conv2dParams + { + InputSizes = shape[0], + Filter = op.inputs[1], + Dilations = dilations == null ? null : dilations as int[], + Strides = strides == null ? null : strides as int[], + Padding = padding.ToString(), + ExplicitPaddings = explicit_paddings == null ? null : explicit_paddings as int[], + UseCudnnOnGpu = (bool)use_cudnn_on_gpu, + DataFormat = data_format.ToString() + }), + gen_nn_ops.conv2d_backprop_filter(new Conv2dParams + { + Input = op.inputs[0], + FilterSizes = shape[1], + Dilations = dilations == null ? null : dilations as int[], + Strides = strides == null ? null : strides as int[], + Padding = padding.ToString(), + ExplicitPaddings = explicit_paddings == null ? null : explicit_paddings as int[], + UseCudnnOnGpu = (bool)use_cudnn_on_gpu, + DataFormat = data_format.ToString() + }) + }; + } + private static bool IsZero(Tensor g) { if (new string[] { "ZerosLike", "Zeros" }.Contains(g.op.type)) diff --git a/src/TensorFlowNET.Core/Operations/NnOps/Conv2dParams.cs b/src/TensorFlowNET.Core/Operations/NnOps/Conv2dParams.cs index de480692..37380a2b 100644 --- a/src/TensorFlowNET.Core/Operations/NnOps/Conv2dParams.cs +++ b/src/TensorFlowNET.Core/Operations/NnOps/Conv2dParams.cs @@ -22,11 +22,27 @@ namespace Tensorflow.Operations /// public Tensor Input { get; set; } + /// + /// An integer vector representing the shape of `input` + /// + public Tensor InputSizes { get; set; } + /// /// A 4-D tensor of shape /// public Tensor Filter { get; set; } + /// + /// An integer vector representing the tensor shape of `filter` + /// + public Tensor FilterSizes { get; set; } + + /// + /// A `Tensor`. Must have the same type as `filter`. + /// 4-D with shape `[batch, out_height, out_width, out_channels]`. + /// + public Tensor OutBackProp { get; set; } + /// /// The stride of the sliding window for each /// dimension of `input`. The dimension order is determined by the value of diff --git a/src/TensorFlowNET.Core/Operations/NnOps/gen_nn_ops.cs b/src/TensorFlowNET.Core/Operations/NnOps/gen_nn_ops.cs index 7e985a01..86d19bbf 100644 --- a/src/TensorFlowNET.Core/Operations/NnOps/gen_nn_ops.cs +++ b/src/TensorFlowNET.Core/Operations/NnOps/gen_nn_ops.cs @@ -43,6 +43,52 @@ namespace Tensorflow.Operations }); return _op.outputs[0]; + } + + /// + /// Computes the gradients of convolution with respect to the filter. + /// + /// + /// + public static Tensor conv2d_backprop_filter(Conv2dParams parameters) + { + var _op = _op_def_lib._apply_op_helper("Conv2DBackpropFilter", name: parameters.Name, args: new + { + input = parameters.Input, + filter_sizes = parameters.FilterSizes, + out_backprop = parameters.OutBackProp, + strides = parameters.Strides, + padding = parameters.Padding, + use_cudnn_on_gpu = parameters.UseCudnnOnGpu, + explicit_paddings = parameters.ExplicitPaddings, + data_format = parameters.DataFormat, + dilations = parameters.Dilations + }); + + return _op.outputs[0]; + } + + /// + /// Computes the gradients of convolution with respect to the input. + /// + /// + /// + public static Tensor conv2d_backprop_input(Conv2dParams parameters) + { + var _op = _op_def_lib._apply_op_helper("Conv2DBackpropInput", name: parameters.Name, args: new + { + input_sizes = parameters.InputSizes, + filter = parameters.Filter, + out_backprop = parameters.OutBackProp, + strides = parameters.Strides, + padding = parameters.Padding, + use_cudnn_on_gpu = parameters.UseCudnnOnGpu, + explicit_paddings = parameters.ExplicitPaddings, + data_format = parameters.DataFormat, + dilations = parameters.Dilations + }); + + return _op.outputs[0]; } public static Tensor bias_add(Tensor value, diff --git a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs index 0a49233c..fb980259 100644 --- a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs +++ b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs @@ -252,6 +252,19 @@ namespace Tensorflow return _op.outputs[0]; } + /// + /// Returns shape of tensors. + /// + /// + /// + /// + /// + public static Tensor[] shape_n(Tensor[] input, TF_DataType out_type = TF_DataType.TF_INT32, string name = null) + { + var _op = _op_def_lib._apply_op_helper("ShapeN", name, new { input, out_type }); + return _op.outputs; + } + public static Tensor size(Tensor input, TF_DataType out_type = TF_DataType.TF_INT32, string name = null) { var _op = _op_def_lib._apply_op_helper("Size", name, new { input, out_type }); diff --git a/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj b/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj index eef35f50..1cca840f 100644 --- a/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj +++ b/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj @@ -20,8 +20,9 @@ Docs: https://tensorflownet.readthedocs.io 0.8.1.0 Changes since v0.8: -1. Removed global static graph instance. -2. Provide custom gradient function. +1. Remove global static graph instance. +2. Provide custom gradient function. +3. Add gradient function for Conv2D. 7.2 0.8.1.0