diff --git a/src/TensorFlowNET.Core/Gradients/Tape.ComputeGradient.cs b/src/TensorFlowNET.Core/Gradients/Tape.ComputeGradient.cs index 0d0ecbe25..73c9e501e 100644 --- a/src/TensorFlowNET.Core/Gradients/Tape.ComputeGradient.cs +++ b/src/TensorFlowNET.Core/Gradients/Tape.ComputeGradient.cs @@ -90,7 +90,7 @@ public Tensor[] ComputeGradient(Tensor[] target_tensor_ids, in_gradients = trace.backward_function(out_gradients.ToArray(), unneeded_gradients.ToArray()); - if (in_gradients.Count() != trace.input_tensor_id.Count()) + if (in_gradients.Length != trace.input_tensor_id.Length && in_gradients.Length + unneeded_gradients.Count != trace.input_tensor_id.Length) throw new RuntimeError($"Recorded operation '{trace.op_type}' returned too few gradients. Expected {trace.input_tensor_id.Length} but received {in_gradients.Count()}"); if (!_persistent) { @@ -103,9 +103,11 @@ public Tensor[] ComputeGradient(Tensor[] target_tensor_ids, in_gradients = new Tensor[trace.input_tensor_id.Length]; } - for (int i = 0; i < in_gradients.Length; ++i) + bool skip_unneeded_id = trace.input_tensor_id.Length > in_gradients.Length; + for (int i = 0, k = 0; i < in_gradients.Length && k < trace.input_tensor_id.Count(); ++i, ++k) { - var id = trace.input_tensor_id[i]; + if (skip_unneeded_id && unneeded_gradients.Contains(k)) ++k; + var id = trace.input_tensor_id[k]; if (in_gradients[i] != null) { var unaggregated_grads = gradients[id]; diff --git a/src/TensorFlowNET.Core/Gradients/math_grad.cs b/src/TensorFlowNET.Core/Gradients/math_grad.cs index d9bc9b228..22d3c641b 100644 --- a/src/TensorFlowNET.Core/Gradients/math_grad.cs +++ b/src/TensorFlowNET.Core/Gradients/math_grad.cs @@ -639,6 +639,20 @@ public static Tensor[] _SqrtGrad(Operation op, Tensor[] grads) }); } + [RegisterGradient("Rsqrt")] + public static Tensor[] _RsqrtGrad(Operation op, Tensor[] grads) + { + var grad = grads[0]; + var y = op.outputs[0]; + + return tf_with(ops.control_dependencies(grads), delegate + { + y = math_ops.conj(y); + var factor = constant_op.constant(-0.5f, dtype: y.dtype); + return new Tensor[] { grad * (factor * math_ops.square(y) * y) }; + }); + } + [RegisterGradient("Asin")] public static Tensor[] _ASinGrad(Operation op, Tensor[] grads) { diff --git a/src/TensorFlowNET.Core/Keras/Layers/ILayersApi.cs b/src/TensorFlowNET.Core/Keras/Layers/ILayersApi.cs index 525bfd354..f1860da1b 100644 --- a/src/TensorFlowNET.Core/Keras/Layers/ILayersApi.cs +++ b/src/TensorFlowNET.Core/Keras/Layers/ILayersApi.cs @@ -55,6 +55,20 @@ public ILayer Conv2D(int filters, IRegularizer bias_regularizer = null, IRegularizer activity_regularizer = null); + public ILayer Conv2DTranspose(int filters, + Shape kernel_size = null, + Shape strides = null, + string output_padding = "valid", + string data_format = null, + Shape dilation_rate = null, + string activation = null, + bool use_bias = true, + string kernel_initializer = null, + string bias_initializer = null, + string kernel_regularizer = null, + string bias_regularizer = null, + string activity_regularizer = null); + public ILayer Conv2D(int filters, Shape kernel_size = null, Shape strides = null,