| @@ -24,6 +24,6 @@ namespace Tensorflow | |||||
| /// <param name="dy">TF_Output*</param> | /// <param name="dy">TF_Output*</param> | ||||
| [DllImport(TensorFlowLibName)] | [DllImport(TensorFlowLibName)] | ||||
| public static extern void TF_AddGradientsWithPrefix(IntPtr g, string prefix, TF_Output[] y, int ny, | public static extern void TF_AddGradientsWithPrefix(IntPtr g, string prefix, TF_Output[] y, int ny, | ||||
| TF_Output[] x, int nx, TF_Output[] dx, IntPtr status, ref IntPtr dy); | |||||
| TF_Output[] x, int nx, TF_Output[] dx, IntPtr status, IntPtr[] dy); | |||||
| } | } | ||||
| } | } | ||||
| @@ -37,6 +37,8 @@ namespace Tensorflow | |||||
| // ancestor graphs. This is necessary for correctly handling captured values. | // ancestor graphs. This is necessary for correctly handling captured values. | ||||
| var curr_graph = src_graph; | var curr_graph = src_graph; | ||||
| if (stop_gradients == null) | |||||
| stop_gradients = new Tensor[0]; | |||||
| if (grad_ys == null) | if (grad_ys == null) | ||||
| grad_ys = new Tensor[ys.Length]; | grad_ys = new Tensor[ys.Length]; | ||||
| @@ -45,7 +47,7 @@ namespace Tensorflow | |||||
| all.AddRange(xs); | all.AddRange(xs); | ||||
| all.AddRange(stop_gradients); | all.AddRange(stop_gradients); | ||||
| all.AddRange(grad_ys); | all.AddRange(grad_ys); | ||||
| // Iterate over the collected ops. | // Iterate over the collected ops. | ||||
| /** | /** | ||||
| * grads: op => list of gradients received on each output endpoint of the | * grads: op => list of gradients received on each output endpoint of the | ||||
| @@ -16,5 +16,17 @@ namespace Tensorflow | |||||
| return (grad, grad); | return (grad, grad); | ||||
| } | } | ||||
| public static (Tensor, Tensor) _RealDivGrad(Operation op, Tensor grad) | |||||
| { | |||||
| var x = op.inputs[0]; | |||||
| var y = op.inputs[1]; | |||||
| var sx = array_ops.shape(x); | |||||
| var sy = array_ops.shape(y); | |||||
| // rx, ry = gen_array_ops.broadcast_gradient_args(sx, sy) | |||||
| return (grad, grad); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -59,5 +59,10 @@ namespace Tensorflow | |||||
| return _op.outputs[0]; | return _op.outputs[0]; | ||||
| } | } | ||||
| public static (Tensor, Tensor) broadcast_gradient_args(Tensor s0, Tensor s1, string name = "") | |||||
| { | |||||
| return (null, null); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -42,7 +42,7 @@ namespace Tensorflow | |||||
| { | { | ||||
| get | get | ||||
| { | { | ||||
| var dims = new long[rank]; | |||||
| var dims = new long[rank < 0 ? 0 : rank]; | |||||
| if (_handle == IntPtr.Zero) | if (_handle == IntPtr.Zero) | ||||
| { | { | ||||
| @@ -14,6 +14,11 @@ namespace Tensorflow | |||||
| /// </summary> | /// </summary> | ||||
| public abstract class Optimizer | public abstract class Optimizer | ||||
| { | { | ||||
| // Values for gate_gradients. | |||||
| public static int GATE_NONE = 0; | |||||
| public static int GATE_OP = 1; | |||||
| public static int GATE_GRAPH = 2; | |||||
| public string Name { get; set; } | public string Name { get; set; } | ||||
| public double LearningRate { get; set; } | public double LearningRate { get; set; } | ||||
| public Tensor LearningRateTensor { get; set; } | public Tensor LearningRateTensor { get; set; } | ||||
| @@ -87,11 +92,15 @@ namespace Tensorflow | |||||
| var processors = var_list.Select(v => optimizer._get_processor(v)).ToList(); | var processors = var_list.Select(v => optimizer._get_processor(v)).ToList(); | ||||
| var var_refs = processors.Select(x => x.target()).ToArray(); | var var_refs = processors.Select(x => x.target()).ToArray(); | ||||
| gradients_impl.gradients(new Tensor[] { loss }, var_refs, grad_ys: grad_loss, | |||||
| var grads = gradients_impl.gradients(new Tensor[] { loss }, var_refs, grad_ys: grad_loss, | |||||
| gate_gradients: (gate_gradients == GateGradientType.GATE_OP), | gate_gradients: (gate_gradients == GateGradientType.GATE_OP), | ||||
| aggregation_method: aggregation_method, | aggregation_method: aggregation_method, | ||||
| colocate_gradients_with_ops: colocate_gradients_with_ops); | colocate_gradients_with_ops: colocate_gradients_with_ops); | ||||
| //if ((int)gate_gradients == Optimizer.GATE_GRAPH) | |||||
| //grads = control_flow_ops.tuple(grads); | |||||
| return null; | return null; | ||||
| } | } | ||||
| } | } | ||||
| @@ -8,6 +8,7 @@ using node_def_pb2 = Tensorflow; | |||||
| using Google.Protobuf; | using Google.Protobuf; | ||||
| using System.Linq; | using System.Linq; | ||||
| using NumSharp.Core; | using NumSharp.Core; | ||||
| using System.ComponentModel; | |||||
| namespace Tensorflow | namespace Tensorflow | ||||
| { | { | ||||
| @@ -285,7 +286,20 @@ namespace Tensorflow | |||||
| return (oper, out_grads) => | return (oper, out_grads) => | ||||
| { | { | ||||
| return math_grad._AddGrad(op, out_grads); | |||||
| switch (oper.type) | |||||
| { | |||||
| case "Add": | |||||
| return math_grad._AddGrad(op, out_grads); | |||||
| case "RealDiv": | |||||
| return math_grad._RealDivGrad(op, out_grads); | |||||
| default: | |||||
| throw new NotImplementedException("get_gradient_function"); | |||||
| } | |||||
| /*var result = typeof(math_grad).GetMethod($"_{op.type}Grad").Invoke(null, new object[] { op, out_grads }); | |||||
| var p1 = result.GetType().GetProperty("Item1"); | |||||
| var p2 = result.GetType().GetProperty("Item2"); | |||||
| return (p1.GetValue(result, null) as Tensor, p2.GetValue(result, null) as Tensor);*/ | |||||
| }; | }; | ||||
| } | } | ||||
| } | } | ||||
| @@ -36,8 +36,8 @@ namespace TensorFlowNET.Examples | |||||
| var W = tf.Variable(rng.randn<double>(), name: "weight"); | var W = tf.Variable(rng.randn<double>(), name: "weight"); | ||||
| var b = tf.Variable(rng.randn<double>(), name: "bias"); | var b = tf.Variable(rng.randn<double>(), name: "bias"); | ||||
| var part1 = tf.multiply(X, W); | |||||
| var pred = tf.add(part1, b); | |||||
| var mul = tf.multiply(X, W); | |||||
| var pred = tf.add(mul, b); | |||||
| // Mean squared error | // Mean squared error | ||||
| var sub = pred - Y; | var sub = pred - Y; | ||||
| @@ -111,12 +111,11 @@ namespace TensorFlowNET.UnitTest | |||||
| var grad_inputs_op = FloatConst2x2(graph_, s_, grad_inputs_val, "GradInputs"); | var grad_inputs_op = FloatConst2x2(graph_, s_, grad_inputs_val, "GradInputs"); | ||||
| grad_inputs[0] = new TF_Output(grad_inputs_op, 0); | grad_inputs[0] = new TF_Output(grad_inputs_op, 0); | ||||
| IntPtr handle = IntPtr.Zero; | |||||
| IntPtr[] handles = new IntPtr[2] { IntPtr.Zero, IntPtr.Zero }; | |||||
| c_api.TF_AddGradientsWithPrefix(graph_, prefix, outputs, noutputs, inputs, | c_api.TF_AddGradientsWithPrefix(graph_, prefix, outputs, noutputs, inputs, | ||||
| ninputs, grad_inputs, s_, ref handle); | |||||
| grad_outputs[0] = Marshal.PtrToStructure<TF_Output>(handle); | |||||
| var op = new Operation(handle); | |||||
| ninputs, grad_inputs, s_, handles); | |||||
| var op = new Operation(handles[0]); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||