@@ -11,7 +11,7 @@ namespace Tensorflow.Eager | |||||
Tensor[] inputs, | Tensor[] inputs, | ||||
object[] attrs, | object[] attrs, | ||||
Tensor[] results, | Tensor[] results, | ||||
Func<BackwardFunction> getBackwardFunction = null) | |||||
BackwardFunction backwardFunction = null) | |||||
{ | { | ||||
bool should_record = ShouldRecord(inputs); | bool should_record = ShouldRecord(inputs); | ||||
@@ -28,9 +28,9 @@ namespace Tensorflow.Eager | |||||
} | } | ||||
if (!should_record) return should_record; | if (!should_record) return should_record; | ||||
tf.Logger.Debug($"RecordGradient: op_name={op_name}"); | |||||
// tf.Logger.Debug($"RecordGradient: op_name={op_name}"); | |||||
Tensor[] op_outputs; | |||||
/*Tensor[] op_outputs = null; | |||||
var unused_output_indices = gradient_exclustions.OpGradientUnusedOutputIndices(op_name); | var unused_output_indices = gradient_exclustions.OpGradientUnusedOutputIndices(op_name); | ||||
if (unused_output_indices != null) | if (unused_output_indices != null) | ||||
{ | { | ||||
@@ -44,7 +44,7 @@ namespace Tensorflow.Eager | |||||
else | else | ||||
op_outputs = results; | op_outputs = results; | ||||
Tensor[] op_inputs; | |||||
Tensor[] op_inputs = null; | |||||
var unused_input_indices = gradient_exclustions.OpGradientUnusedInputIndices(op_name); | var unused_input_indices = gradient_exclustions.OpGradientUnusedInputIndices(op_name); | ||||
if (unused_input_indices != null) | if (unused_input_indices != null) | ||||
{ | { | ||||
@@ -56,22 +56,14 @@ namespace Tensorflow.Eager | |||||
} | } | ||||
} | } | ||||
else | else | ||||
op_inputs = inputs; | |||||
op_inputs = inputs;*/ | |||||
TapeSetRecordOperation(op_name, inputs, results, | |||||
getBackwardFunction ?? GetBackwradFunction(op_name, inputs, attrs, results)); | |||||
backwardFunction = backwardFunction ?? GetGradientFunction(op_name, inputs, attrs, results); | |||||
TapeSetRecordOperation(op_name, inputs, results, backwardFunction); | |||||
return true; | return true; | ||||
} | } | ||||
Func<BackwardFunction> GetBackwradFunction(string op_name, | |||||
Tensor[] op_inputs, | |||||
object[] attrs, | |||||
Tensor[] op_outputs) | |||||
{ | |||||
return () => GetGradientFunction(op_name, op_inputs, attrs, op_outputs); | |||||
} | |||||
BackwardFunction GetGradientFunction(string op_name, | BackwardFunction GetGradientFunction(string op_name, | ||||
Tensor[] op_inputs, | Tensor[] op_inputs, | ||||
object[] attrs, | object[] attrs, | ||||
@@ -1,7 +1,6 @@ | |||||
using System; | using System; | ||||
using Tensorflow.Gradients; | using Tensorflow.Gradients; | ||||
using static Tensorflow.Binding; | using static Tensorflow.Binding; | ||||
using static Tensorflow.tensorflow; | |||||
namespace Tensorflow.Eager | namespace Tensorflow.Eager | ||||
{ | { | ||||
@@ -10,7 +9,7 @@ namespace Tensorflow.Eager | |||||
void TapeSetRecordBackprop(string op_type, | void TapeSetRecordBackprop(string op_type, | ||||
Tensor[] input_tensors, | Tensor[] input_tensors, | ||||
TapeTensor[] output_tensors, | TapeTensor[] output_tensors, | ||||
Func<BackwardFunction> backward_function_getter) | |||||
BackwardFunction backward_function) | |||||
{ | { | ||||
if (!CouldBackprop()) | if (!CouldBackprop()) | ||||
{ | { | ||||
@@ -19,8 +18,7 @@ namespace Tensorflow.Eager | |||||
foreach (var tape in tf.GetTapeSet()) | foreach (var tape in tf.GetTapeSet()) | ||||
{ | { | ||||
tape.RecordOperation(op_type, input_tensors, output_tensors, | |||||
backward_function_getter); | |||||
tape.RecordOperation(op_type, input_tensors, output_tensors, backward_function); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -9,7 +9,7 @@ namespace Tensorflow.Eager | |||||
bool TapeSetRecordForwardprop(string op_type, | bool TapeSetRecordForwardprop(string op_type, | ||||
Tensor[] input_tensors, | Tensor[] input_tensors, | ||||
TapeTensor[] output_tensors, | TapeTensor[] output_tensors, | ||||
Func<BackwardFunction> backward_function_getter) | |||||
BackwardFunction backward_function_getter) | |||||
{ | { | ||||
if (!CouldForwardprop()) | if (!CouldForwardprop()) | ||||
{ | { | ||||
@@ -10,16 +10,16 @@ namespace Tensorflow.Eager | |||||
public bool TapeSetRecordOperation(string op_type, | public bool TapeSetRecordOperation(string op_type, | ||||
Tensor[] input_tensors, | Tensor[] input_tensors, | ||||
Tensor[] output_tensors, | Tensor[] output_tensors, | ||||
Func<BackwardFunction> backward_function_getter) | |||||
BackwardFunction backward_function) | |||||
{ | { | ||||
var output_info = output_tensors.Select(x => new TapeTensor(x)).ToArray(); | var output_info = output_tensors.Select(x => new TapeTensor(x)).ToArray(); | ||||
if (!TapeSetRecordForwardprop(op_type, input_tensors, output_info, | if (!TapeSetRecordForwardprop(op_type, input_tensors, output_info, | ||||
backward_function_getter)) | |||||
backward_function)) | |||||
return false; | return false; | ||||
TapeSetRecordBackprop(op_type, input_tensors, output_info, | TapeSetRecordBackprop(op_type, input_tensors, output_info, | ||||
backward_function_getter); | |||||
backward_function); | |||||
return true; | return true; | ||||
} | } | ||||
@@ -9,7 +9,8 @@ namespace Tensorflow.Eager | |||||
{ | { | ||||
Tensor[] Execute(Context ctx, string op_name, | Tensor[] Execute(Context ctx, string op_name, | ||||
int num_outputs, | int num_outputs, | ||||
Tensor[] inputs, object[] attrs, | |||||
Tensor[] inputs, | |||||
object[] attrs, | |||||
string name = null); | string name = null); | ||||
(TF_DataType, Tensor[]) ArgsToMatchingEager(Context ctx, | (TF_DataType, Tensor[]) ArgsToMatchingEager(Context ctx, | ||||
@@ -34,7 +35,7 @@ namespace Tensorflow.Eager | |||||
Tensor[] inputs, | Tensor[] inputs, | ||||
object[] attrs, | object[] attrs, | ||||
Tensor[] results, | Tensor[] results, | ||||
Func<BackwardFunction> getBackwardFunction = null); | |||||
BackwardFunction getBackwardFunction = null); | |||||
bool MustRecordGradient(); | bool MustRecordGradient(); | ||||
@@ -47,7 +47,7 @@ namespace Tensorflow.Functions | |||||
{ | { | ||||
var (backward_function, to_record) = _wrap_backward_function(_forward_graph, _backward, flat_outputs); | var (backward_function, to_record) = _wrap_backward_function(_forward_graph, _backward, flat_outputs); | ||||
tf.Runner.RecordGradient(_forward.Name, inference_args, new object[0], to_record, | tf.Runner.RecordGradient(_forward.Name, inference_args, new object[0], to_record, | ||||
getBackwardFunction: () => backward_function); | |||||
getBackwardFunction: backward_function); | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
@@ -5,7 +5,7 @@ namespace Tensorflow.Gradients | |||||
{ | { | ||||
public class BackpropInitialState | public class BackpropInitialState | ||||
{ | { | ||||
public OpTape<BackwardFunction, TapeTensor> op_tape { get; set; } | |||||
public OpTape op_tape { get; set; } | |||||
/// <summary> | /// <summary> | ||||
/// Map from tensor to how many references still exist for this tensor in | /// Map from tensor to how many references still exist for this tensor in | ||||
/// the tape. | /// the tape. | ||||
@@ -19,7 +19,7 @@ namespace Tensorflow.Gradients | |||||
public BackpropInitialState() | public BackpropInitialState() | ||||
{ | { | ||||
op_tape = new OpTape<BackwardFunction, TapeTensor>(); | |||||
op_tape = new OpTape(); | |||||
tensor_usage_counts = new UnorderedMap<Tensor, long>(); | tensor_usage_counts = new UnorderedMap<Tensor, long>(); | ||||
op_missing_tensor = new UnorderedMap<Tensor, long>(); | op_missing_tensor = new UnorderedMap<Tensor, long>(); | ||||
} | } | ||||
@@ -13,7 +13,7 @@ namespace Tensorflow.Gradients | |||||
void RecordOperation(string op_type, | void RecordOperation(string op_type, | ||||
Tensor[] input_tensors, | Tensor[] input_tensors, | ||||
TapeTensor[] output_tensors, | TapeTensor[] output_tensors, | ||||
Func<BackwardFunction> backward_function_getter); | |||||
BackwardFunction backward_function); | |||||
void VariableAccessed(ResourceVariable variable); | void VariableAccessed(ResourceVariable variable); | ||||
@@ -5,10 +5,7 @@ namespace Tensorflow.Gradients | |||||
/// <summary> | /// <summary> | ||||
/// Map from operation-id to tape entry. | /// Map from operation-id to tape entry. | ||||
/// </summary> | /// </summary> | ||||
/// <typeparam name="BackwardFunction"></typeparam> | |||||
/// <typeparam name="TapeTensor"></typeparam> | |||||
public class OpTape<BackwardFunction, TapeTensor> : | |||||
UnorderedMap<Tensor, OpTapeEntry<BackwardFunction, TapeTensor>> | |||||
public class OpTape : UnorderedMap<Tensor, OpTapeEntry> | |||||
{ | { | ||||
} | } | ||||
@@ -5,9 +5,7 @@ namespace Tensorflow.Gradients | |||||
/// <summary> | /// <summary> | ||||
/// Represents an entry in the tape. | /// Represents an entry in the tape. | ||||
/// </summary> | /// </summary> | ||||
/// <typeparam name="BackwardFunction"></typeparam> | |||||
/// <typeparam name="TapeTensor"></typeparam> | |||||
public class OpTapeEntry<BackwardFunction, TapeTensor> | |||||
public class OpTapeEntry | |||||
{ | { | ||||
public string op_type { get; set; } | public string op_type { get; set; } | ||||
public TapeTensor[] output_tensor_info { get; set; } | public TapeTensor[] output_tensor_info { get; set; } | ||||
@@ -1,5 +1,4 @@ | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using static Tensorflow.tensorflow; | |||||
namespace Tensorflow.Gradients | namespace Tensorflow.Gradients | ||||
{ | { | ||||
@@ -9,7 +8,7 @@ namespace Tensorflow.Gradients | |||||
List<long> unneeded_gradients, | List<long> unneeded_gradients, | ||||
List<Tensor> output_gradients) | List<Tensor> output_gradients) | ||||
{ | { | ||||
var grads = new Tensor[output_gradients.Count]; | |||||
// var grads = new Tensor[output_gradients.Count]; | |||||
var result = backward_function(output_gradients.ToArray(), | var result = backward_function(output_gradients.ToArray(), | ||||
unneeded_gradients.ToArray()); | unneeded_gradients.ToArray()); | ||||
@@ -2,24 +2,22 @@ | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Linq; | using System.Linq; | ||||
using Tensorflow.Util; | using Tensorflow.Util; | ||||
using static Tensorflow.tensorflow; | |||||
namespace Tensorflow.Gradients | namespace Tensorflow.Gradients | ||||
{ | { | ||||
public partial class Tape | public partial class Tape | ||||
{ | { | ||||
int kMinAggregateCount = 4; | |||||
int kMinAggregateBytes = 128 * 1024 * 1024; | |||||
// int kMinAggregateCount = 4; | |||||
// int kMinAggregateBytes = 128 * 1024 * 1024; | |||||
public Tensor[] ComputeGradient(Tensor[] target_tensor_ids, | public Tensor[] ComputeGradient(Tensor[] target_tensor_ids, | ||||
Tensor[] source_tensor_ids, | Tensor[] source_tensor_ids, | ||||
UnorderedMap<Tensor, TapeTensor> sources_that_are_targets, | UnorderedMap<Tensor, TapeTensor> sources_that_are_targets, | ||||
Tensor[] output_gradients) | Tensor[] output_gradients) | ||||
{ | { | ||||
var result = new List<Tensor>(source_tensor_ids.Length); | |||||
var sources_set = new UnorderedSet<Tensor>(source_tensor_ids); | var sources_set = new UnorderedSet<Tensor>(source_tensor_ids); | ||||
var gradients_size = new UnorderedMap<Tensor, long>(); | |||||
// var gradients_size = new UnorderedMap<Tensor, long>(); | |||||
var functionsAcceptingNoneForIndicesMap = FunctionsAcceptingNoneForIndicesMap(); | |||||
var state = PrepareBackprop( | var state = PrepareBackprop( | ||||
target_tensor_ids, tensor_tape_, op_tape_, sources_set, _persistent); | target_tensor_ids, tensor_tape_, op_tape_, sources_set, _persistent); | ||||
var op_stack = InitialStack(state.op_tape, state.op_missing_tensor); | var op_stack = InitialStack(state.op_tape, state.op_missing_tensor); | ||||
@@ -54,7 +52,7 @@ namespace Tensorflow.Gradients | |||||
var id = trace.output_tensor_info[i].GetTensor(); | var id = trace.output_tensor_info[i].GetTensor(); | ||||
if (!gradients.find(id, out var grad_it)) | if (!gradients.find(id, out var grad_it)) | ||||
{ | { | ||||
if (FunctionsAcceptingNoneForIndicesMap().find(trace.op_type, out var func_name_it) && | |||||
if (functionsAcceptingNoneForIndicesMap.find(trace.op_type, out var func_name_it) && | |||||
func_name_it.find(i)) | func_name_it.find(i)) | ||||
{ | { | ||||
out_gradients.Add(null); | out_gradients.Add(null); | ||||
@@ -76,8 +74,8 @@ namespace Tensorflow.Gradients | |||||
gradients.Remove(id); | gradients.Remove(id); | ||||
else | else | ||||
{ | { | ||||
grad_it.Clear(); | |||||
grad_it.Add(new_gradients); | |||||
// grad_it.Clear(); | |||||
// grad_it.Add(new_gradients); | |||||
// vspace.MarkAsResult(new_gradients); | // vspace.MarkAsResult(new_gradients); | ||||
} | } | ||||
out_gradients.Add(new_gradients); | out_gradients.Add(new_gradients); | ||||
@@ -87,18 +85,17 @@ namespace Tensorflow.Gradients | |||||
Tensor[] in_gradients; | Tensor[] in_gradients; | ||||
if (any_gradient_nonzero) | if (any_gradient_nonzero) | ||||
{ | { | ||||
foreach (var i in zero_indices) | |||||
out_gradients[i] = trace.output_tensor_info[i].ZerosLike(); | |||||
// foreach (var i in zero_indices) | |||||
// out_gradients[i] = trace.output_tensor_info[i].ZerosLike(); | |||||
in_gradients = CallBackwardFunction(trace.backward_function, | |||||
unneeded_gradients, | |||||
out_gradients); | |||||
in_gradients = trace.backward_function(out_gradients.ToArray(), unneeded_gradients.ToArray()); | |||||
if (in_gradients.Count() != trace.input_tensor_id.Count()) | if (in_gradients.Count() != trace.input_tensor_id.Count()) | ||||
throw new RuntimeError($"Recorded operation '{trace.op_type}' returned too few gradients. Expected {trace.input_tensor_id.Length} but received {in_gradients.Count()}"); | 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) | if (!_persistent) | ||||
{ | { | ||||
// trace.backward_function_deleter(trace.backward_function); | // trace.backward_function_deleter(trace.backward_function); | ||||
trace.backward_function = null; | |||||
} | } | ||||
} | } | ||||
else | else | ||||
@@ -113,7 +110,7 @@ namespace Tensorflow.Gradients | |||||
{ | { | ||||
var unaggregated_grads = gradients[id]; | var unaggregated_grads = gradients[id]; | ||||
unaggregated_grads.Add(in_gradients[i]); | unaggregated_grads.Add(in_gradients[i]); | ||||
if (unaggregated_grads.Count > kMinAggregateCount) | |||||
/*if (unaggregated_grads.Count > kMinAggregateCount) | |||||
{ | { | ||||
if (!gradients_size.find(id, out var size)) | if (!gradients_size.find(id, out var size)) | ||||
{ | { | ||||
@@ -125,7 +122,7 @@ namespace Tensorflow.Gradients | |||||
{ | { | ||||
throw new NotImplementedException(""); | throw new NotImplementedException(""); | ||||
} | } | ||||
} | |||||
}*/ | |||||
} | } | ||||
if (!state.tensor_usage_counts.find(id)) | if (!state.tensor_usage_counts.find(id)) | ||||
@@ -162,36 +159,21 @@ namespace Tensorflow.Gradients | |||||
if (state.op_tape.Count > 0) | if (state.op_tape.Count > 0) | ||||
throw new RuntimeError("Invalid tape state."); | throw new RuntimeError("Invalid tape state."); | ||||
var used_gradient_ids = new List<Tensor>(source_tensor_ids.Length); | |||||
var result = new Tensor[source_tensor_ids.Length]; | |||||
var j = 0; | |||||
foreach (var id in source_tensor_ids) | foreach (var id in source_tensor_ids) | ||||
{ | { | ||||
if (!gradients.find(id, out var grad_it)) | |||||
result.Add(null); | |||||
else | |||||
if (gradients.find(id, out var grad_it)) | |||||
{ | { | ||||
if (grad_it.Count > 1) | if (grad_it.Count > 1) | ||||
{ | |||||
var grad = gen_math_ops.add_n(grad_it.ToArray()); | |||||
grad_it.Clear(); | |||||
grad_it.Add(grad); | |||||
} | |||||
result.Add(grad_it[0]); | |||||
used_gradient_ids.Add(id); | |||||
result[j] = gen_math_ops.add_n(grad_it.ToArray()); | |||||
else | |||||
result[j] = grad_it[0]; | |||||
} | } | ||||
j++; | |||||
} | } | ||||
/*foreach(var grad_pair in gradients) | |||||
{ | |||||
if(!used_gradient_ids.Contains(grad_pair.Key)) | |||||
{ | |||||
foreach(var g in grad_pair.Value) | |||||
{ | |||||
vspace.DeleteGradient(g); | |||||
} | |||||
} | |||||
}*/ | |||||
return result.ToArray(); | |||||
return result; | |||||
} | } | ||||
UnorderedMap<string, UnorderedSet<int>> FunctionsAcceptingNoneForIndicesMap() | UnorderedMap<string, UnorderedSet<int>> FunctionsAcceptingNoneForIndicesMap() | ||||
@@ -207,7 +189,7 @@ namespace Tensorflow.Gradients | |||||
UnorderedMap<Tensor, TapeTensor> sources_that_are_targets, | UnorderedMap<Tensor, TapeTensor> sources_that_are_targets, | ||||
Tensor[] output_gradients, | Tensor[] output_gradients, | ||||
TensorTape tensor_tape, | TensorTape tensor_tape, | ||||
OpTape<BackwardFunction, TapeTensor> op_tape) | |||||
OpTape op_tape) | |||||
{ | { | ||||
var result = new UnorderedMapEnumerable<Tensor, List<Tensor>>(); | var result = new UnorderedMapEnumerable<Tensor, List<Tensor>>(); | ||||
for (int i = 0; i < target_tensor_ids.Length; ++i) | for (int i = 0; i < target_tensor_ids.Length; ++i) | ||||
@@ -253,7 +235,7 @@ namespace Tensorflow.Gradients | |||||
return result; | return result; | ||||
} | } | ||||
Queue<Tensor> InitialStack(OpTape<BackwardFunction, TapeTensor> op_tape, | |||||
Queue<Tensor> InitialStack(OpTape op_tape, | |||||
UnorderedMap<Tensor, long> op_missing_tensor) | UnorderedMap<Tensor, long> op_missing_tensor) | ||||
{ | { | ||||
var result = new Queue<Tensor>(); | var result = new Queue<Tensor>(); | ||||
@@ -8,7 +8,7 @@ namespace Tensorflow.Gradients | |||||
{ | { | ||||
public BackpropInitialState PrepareBackprop(Tensor[] target, | public BackpropInitialState PrepareBackprop(Tensor[] target, | ||||
TensorTape tensor_tape, | TensorTape tensor_tape, | ||||
OpTape<BackwardFunction, TapeTensor> op_tape, | |||||
OpTape op_tape, | |||||
UnorderedSet<Tensor> sources_set, | UnorderedSet<Tensor> sources_set, | ||||
bool persistent_tape) | bool persistent_tape) | ||||
{ | { | ||||
@@ -16,7 +16,7 @@ namespace Tensorflow.Gradients | |||||
public void RecordOperation(string op_type, | public void RecordOperation(string op_type, | ||||
Tensor[] input_tensors, | Tensor[] input_tensors, | ||||
TapeTensor[] output_tensors, | TapeTensor[] output_tensors, | ||||
Func<BackwardFunction> backward_function_getter) | |||||
BackwardFunction backward_function) | |||||
{ | { | ||||
if (!ShouldRecord(input_tensors)) | if (!ShouldRecord(input_tensors)) | ||||
return; | return; | ||||
@@ -32,12 +32,12 @@ namespace Tensorflow.Gradients | |||||
tensor_usage_[o.GetTensor()] = 1; | tensor_usage_[o.GetTensor()] = 1; | ||||
} | } | ||||
op_tape_[op_id] = new OpTapeEntry<BackwardFunction, TapeTensor> | |||||
op_tape_[op_id] = new OpTapeEntry | |||||
{ | { | ||||
op_type = op_type, | op_type = op_type, | ||||
output_tensor_info = output_tensors, | output_tensor_info = output_tensors, | ||||
input_tensor_id = input_tensors, | input_tensor_id = input_tensors, | ||||
backward_function = backward_function_getter() | |||||
backward_function = backward_function | |||||
}; | }; | ||||
} | } | ||||
} | } | ||||
@@ -15,7 +15,7 @@ namespace Tensorflow.Gradients | |||||
bool _recording; | bool _recording; | ||||
bool _created_eagerly; | bool _created_eagerly; | ||||
TensorTape tensor_tape_; | TensorTape tensor_tape_; | ||||
OpTape<BackwardFunction, TapeTensor> op_tape_; | |||||
OpTape op_tape_; | |||||
/// <summary> | /// <summary> | ||||
/// A deque-backed stack, whose element references are not invalidated by | /// A deque-backed stack, whose element references are not invalidated by | ||||
@@ -28,7 +28,7 @@ namespace Tensorflow.Gradients | |||||
_persistent = persistent; | _persistent = persistent; | ||||
_created_eagerly = tf.Context.executing_eagerly(); | _created_eagerly = tf.Context.executing_eagerly(); | ||||
tensor_tape_ = new TensorTape(); | tensor_tape_ = new TensorTape(); | ||||
op_tape_ = new OpTape<BackwardFunction, TapeTensor>(); | |||||
op_tape_ = new OpTape(); | |||||
tensor_usage_ = new UnorderedMap<Tensor, long>(); | tensor_usage_ = new UnorderedMap<Tensor, long>(); | ||||
if(_created_eagerly) | if(_created_eagerly) | ||||
tf.Context.start_step(); | tf.Context.start_step(); | ||||
@@ -161,7 +161,7 @@ namespace Tensorflow.Graphs | |||||
tf.Runner.RecordGradient("captured_value", | tf.Runner.RecordGradient("captured_value", | ||||
new[] { graph_const }, null, | new[] { graph_const }, null, | ||||
new[] { tensor }, | new[] { tensor }, | ||||
getBackwardFunction: () => _backward_function_wrapper | |||||
getBackwardFunction: _backward_function_wrapper | |||||
/*getForwardFunction: forward_function*/); | /*getForwardFunction: forward_function*/); | ||||
return graph_const; | return graph_const; | ||||
@@ -191,7 +191,7 @@ namespace Tensorflow.Graphs | |||||
tf.Runner.RecordGradient("captured_value", | tf.Runner.RecordGradient("captured_value", | ||||
new[] { placeholder }, null, | new[] { placeholder }, null, | ||||
new[] { tensor }, | new[] { tensor }, | ||||
getBackwardFunction: () => _backward_function_wrapper | |||||
getBackwardFunction: _backward_function_wrapper | |||||
/*getForwardFunction: forward_function*/); | /*getForwardFunction: forward_function*/); | ||||
return placeholder; | return placeholder; | ||||
@@ -15,6 +15,8 @@ | |||||
******************************************************************************/ | ******************************************************************************/ | ||||
using System; | using System; | ||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | using System.Linq; | ||||
using Tensorflow.Contexts; | using Tensorflow.Contexts; | ||||
using static Tensorflow.Binding; | using static Tensorflow.Binding; | ||||
@@ -215,7 +215,7 @@ namespace Tensorflow | |||||
/// Evaluates this tensor in a `Session`. | /// Evaluates this tensor in a `Session`. | ||||
/// </summary> | /// </summary> | ||||
/// <param name="feed_dict">A dictionary that maps `Tensor` objects to feed values.</param> | /// <param name="feed_dict">A dictionary that maps `Tensor` objects to feed values.</param> | ||||
/// <returns>A <see cref="NumSharp"/> array corresponding to the value of this tensor.</returns> | |||||
/// <returns>A <see cref="NumPy"/> array corresponding to the value of this tensor.</returns> | |||||
public NDArray eval(params FeedItem[] feed_dict) | public NDArray eval(params FeedItem[] feed_dict) | ||||
{ | { | ||||
return ops._eval_using_default_session(this, feed_dict, graph); | return ops._eval_using_default_session(this, feed_dict, graph); | ||||
@@ -226,7 +226,7 @@ namespace Tensorflow | |||||
/// </summary> | /// </summary> | ||||
/// <param name="feed_dict">A dictionary that maps `Tensor` objects to feed values.</param> | /// <param name="feed_dict">A dictionary that maps `Tensor` objects to feed values.</param> | ||||
/// <param name="session">The `Session` to be used to evaluate this tensor.</param> | /// <param name="session">The `Session` to be used to evaluate this tensor.</param> | ||||
/// <returns>A <see cref="NumSharp"/> array corresponding to the value of this tensor.</returns> | |||||
/// <returns>A <see cref="NumPy"/> array corresponding to the value of this tensor.</returns> | |||||
public NDArray eval(Session session, params FeedItem[] feed_dict) | public NDArray eval(Session session, params FeedItem[] feed_dict) | ||||
{ | { | ||||
return ops._eval_using_default_session(this, feed_dict, graph, session); | return ops._eval_using_default_session(this, feed_dict, graph, session); | ||||
@@ -14,7 +14,6 @@ | |||||
limitations under the License. | limitations under the License. | ||||
******************************************************************************/ | ******************************************************************************/ | ||||
using System.Collections.Generic; | |||||
using Serilog; | using Serilog; | ||||
using Serilog.Core; | using Serilog.Core; | ||||
using Tensorflow.Contexts; | using Tensorflow.Contexts; | ||||