@@ -364,8 +364,8 @@ namespace Tensorflow | |||||
public Tensor divide<T>(Tensor x, T[] y, string name = null) where T : struct | public Tensor divide<T>(Tensor x, T[] y, string name = null) where T : struct | ||||
=> x / ops.convert_to_tensor(y, dtype: x.dtype.as_base_dtype(), name: "y"); | => x / ops.convert_to_tensor(y, dtype: x.dtype.as_base_dtype(), name: "y"); | ||||
public Tensor pow<T1, T2>(T1 x, T2 y) | |||||
=> gen_math_ops.pow(x, y); | |||||
public Tensor pow<T1, T2>(T1 x, T2 y, string name = "pow") | |||||
=> gen_math_ops.pow(x, y, name: name); | |||||
/// <summary> | /// <summary> | ||||
/// Divides `x / y` elementwise, rounding toward the most negative integer. | /// Divides `x / y` elementwise, rounding toward the most negative integer. | ||||
@@ -33,10 +33,14 @@ namespace Tensorflow.Gradients | |||||
var x = op.inputs[0]; | var x = op.inputs[0]; | ||||
var grad = grads[0]; | var grad = grads[0]; | ||||
return new Tensor[] { gen_ops.mul(grad, gen_math_ops.sign(x)) }; | |||||
return new Tensor[] { grad * math_ops.sign(x) }; | |||||
} | } | ||||
[RegisterGradient("AddV2")] | [RegisterGradient("AddV2")] | ||||
public static Tensor[] _AddV2Grad(Operation op, Tensor[] grads) | |||||
=> _AddGrad(op, grads); | |||||
[RegisterGradient("Add")] | |||||
public static Tensor[] _AddGrad(Operation op, Tensor[] grads) | public static Tensor[] _AddGrad(Operation op, Tensor[] grads) | ||||
{ | { | ||||
var x = op.inputs[0]; | var x = op.inputs[0]; | ||||
@@ -65,10 +65,6 @@ namespace Tensorflow | |||||
var base_types = new List<TF_DataType>(); | var base_types = new List<TF_DataType>(); | ||||
var types = new List<TF_DataType>(); | var types = new List<TF_DataType>(); | ||||
#if DEBUG | |||||
if (op_type_name == "FusedBatchNormGradV3") | |||||
; | |||||
#endif | |||||
// Perform input type inference | // Perform input type inference | ||||
foreach (var input_arg in op_def.InputArg) | foreach (var input_arg in op_def.InputArg) | ||||
{ | { | ||||
@@ -40,13 +40,11 @@ namespace Tensorflow | |||||
} | } | ||||
return num; | return num; | ||||
} | } | ||||
#if SERIALIZABLE | |||||
[JsonIgnore] | |||||
#endif | |||||
public int NumInputs => c_api.TF_OperationNumInputs(_handle); | public int NumInputs => c_api.TF_OperationNumInputs(_handle); | ||||
private TF_DataType[] _input_types => _inputs_val._inputs.Select(x => x.dtype).ToArray(); | private TF_DataType[] _input_types => _inputs_val._inputs.Select(x => x.dtype).ToArray(); | ||||
private InputList _inputs_val; | private InputList _inputs_val; | ||||
public InputList inputs | public InputList inputs | ||||
{ | { | ||||
get | get | ||||
@@ -69,8 +67,10 @@ namespace Tensorflow | |||||
} | } | ||||
} | } | ||||
public int NumControlInputs => c_api.TF_OperationNumControlInputs(_handle); | |||||
public int NumControlInputs | |||||
=> _handle == IntPtr.Zero ? 0 : c_api.TF_OperationNumControlInputs(_handle); | |||||
Operation[] _control_inputs; | |||||
/// <summary> | /// <summary> | ||||
/// The `Operation` objects on which this op has a control dependency. | /// The `Operation` objects on which this op has a control dependency. | ||||
/// | /// | ||||
@@ -87,7 +87,9 @@ namespace Tensorflow | |||||
{ | { | ||||
get | get | ||||
{ | { | ||||
return GetControlInputs(); | |||||
if (_control_inputs == null || _control_inputs.Length == 0) | |||||
_control_inputs = GetControlInputs(); | |||||
return _control_inputs; | |||||
} | } | ||||
} | } | ||||
@@ -26,9 +26,6 @@ namespace Tensorflow | |||||
{ | { | ||||
public partial class Operation | public partial class Operation | ||||
{ | { | ||||
#if SERIALIZABLE | |||||
[JsonIgnore] | |||||
#endif | |||||
public int NumOutputs => c_api.TF_OperationNumOutputs(_handle); | public int NumOutputs => c_api.TF_OperationNumOutputs(_handle); | ||||
public TF_DataType OutputType(int index) => c_api.TF_OperationOutputType(_tf_output(index)); | public TF_DataType OutputType(int index) => c_api.TF_OperationOutputType(_tf_output(index)); | ||||
@@ -154,11 +154,6 @@ namespace Tensorflow | |||||
public Operation(NodeDef node_def, Graph g, Tensor[] inputs = null, TF_DataType[] output_types = null, ITensorOrOperation[] control_inputs = null, TF_DataType[] input_types = null, string original_op = "", OpDef op_def = null) | public Operation(NodeDef node_def, Graph g, Tensor[] inputs = null, TF_DataType[] output_types = null, ITensorOrOperation[] control_inputs = null, TF_DataType[] input_types = null, string original_op = "", OpDef op_def = null) | ||||
{ | { | ||||
_graph = g; | _graph = g; | ||||
#if DEBUG | |||||
if (node_def.Name == "define_second_stage_train/gradients/define_loss/conv_lobj_branch/batch_normalization/cond/FusedBatchNormV3_1_grad/FusedBatchNormGradV3") | |||||
; | |||||
#endif | |||||
// Build the list of control inputs. | // Build the list of control inputs. | ||||
var control_input_ops = new List<Operation>(); | var control_input_ops = new List<Operation>(); | ||||
if (control_inputs != null) | if (control_inputs != null) | ||||
@@ -140,6 +140,14 @@ namespace Tensorflow | |||||
} | } | ||||
public static Tensor add<Tx, Ty>(Tx x, Ty y, string name = null) | public static Tensor add<Tx, Ty>(Tx x, Ty y, string name = null) | ||||
{ | |||||
// forward_compatible(2019, 6, 25): | |||||
var _op = _op_def_lib._apply_op_helper("Add", name, args: new { x, y }); | |||||
return _op.output; | |||||
} | |||||
public static Tensor add_v2<Tx, Ty>(Tx x, Ty y, string name = null) | |||||
{ | { | ||||
// forward_compatible(2019, 6, 25): | // forward_compatible(2019, 6, 25): | ||||
var _op = _op_def_lib._apply_op_helper("AddV2", name, args: new { x, y }); | var _op = _op_def_lib._apply_op_helper("AddV2", name, args: new { x, y }); | ||||
@@ -213,7 +221,7 @@ namespace Tensorflow | |||||
return op.outputs[0]; | return op.outputs[0]; | ||||
} | } | ||||
public static Tensor sign(Tensor x, string name = "Sign") | |||||
public static Tensor sign<T>(T x, string name = "Sign") | |||||
{ | { | ||||
var op = _op_def_lib._apply_op_helper("Sign", name: name, args: new {x}); | var op = _op_def_lib._apply_op_helper("Sign", name: name, args: new {x}); | ||||
@@ -448,7 +456,7 @@ namespace Tensorflow | |||||
return _op.outputs[0]; | return _op.outputs[0]; | ||||
} | } | ||||
public static Tensor cast(Tensor x, TF_DataType DstT, bool Truncate= false, string name= "") | |||||
public static Tensor cast(Tensor x, TF_DataType DstT, bool Truncate= false, string name= null) | |||||
{ | { | ||||
var _op = _op_def_lib._apply_op_helper("Cast", name, args: new { x, DstT, Truncate }); | var _op = _op_def_lib._apply_op_helper("Cast", name, args: new { x, DstT, Truncate }); | ||||
@@ -35,14 +35,17 @@ namespace Tensorflow | |||||
x = ops.convert_to_tensor(x, name: "x"); | x = ops.convert_to_tensor(x, name: "x"); | ||||
if (x.dtype.is_complex()) | if (x.dtype.is_complex()) | ||||
throw new NotImplementedException("math_ops.abs for dtype.is_complex"); | throw new NotImplementedException("math_ops.abs for dtype.is_complex"); | ||||
//return gen_math_ops.complex_abs(x, Tout: x.dtype.real_dtype, name: name); | |||||
//return gen_math_ops.complex_abs(x, Tout: x.dtype.real_dtype, name: name); | |||||
return gen_math_ops._abs(x, name: name); | return gen_math_ops._abs(x, name: name); | ||||
}); | }); | ||||
} | } | ||||
public static Tensor add<Tx, Ty>(Tx x, Ty y, string name = null) | |||||
public static Tensor add<Tx, Ty>(Tx x, Ty y, string name = null) | |||||
=> gen_math_ops.add(x, y, name); | => gen_math_ops.add(x, y, name); | ||||
public static Tensor add_v2<Tx, Ty>(Tx x, Ty y, string name = null) | |||||
=> gen_math_ops.add_v2(x, y, name); | |||||
/// <summary> | /// <summary> | ||||
/// Adds all input tensors element-wise. | /// Adds all input tensors element-wise. | ||||
/// </summary> | /// </summary> | ||||
@@ -53,21 +56,38 @@ namespace Tensorflow | |||||
{ | { | ||||
inputs = ops.convert_n_to_tensor_or_indexed_slices(inputs); | inputs = ops.convert_n_to_tensor_or_indexed_slices(inputs); | ||||
if(inputs.Length == 1) | |||||
if (inputs.Length == 1) | |||||
{ | { | ||||
var values = inputs[0]; | var values = inputs[0]; | ||||
if (name != null) | if (name != null) | ||||
return array_ops.identity(values, name: name); | return array_ops.identity(values, name: name); | ||||
return values; | return values; | ||||
} | } | ||||
return gen_math_ops.add_n(inputs, name: name); | return gen_math_ops.add_n(inputs, name: name); | ||||
} | } | ||||
public static Tensor cast(RefVariable x, TF_DataType dtype = TF_DataType.DtInvalid, string name = null) | |||||
{ | |||||
var base_type = dtype.as_base_dtype(); | |||||
if (base_type == x.dtype) | |||||
return x; | |||||
return tf_with(ops.name_scope(name, "Cast", new { x }), scope => | |||||
{ | |||||
name = scope; | |||||
var t_x = ops.convert_to_tensor(x, name: "x"); | |||||
if (t_x.dtype.as_base_dtype() != base_type) | |||||
t_x = gen_math_ops.cast(t_x, base_type, name: name); | |||||
return x; | |||||
}); | |||||
} | |||||
public static Tensor cast(Tensor x, TF_DataType dtype = TF_DataType.DtInvalid, string name = null) | public static Tensor cast(Tensor x, TF_DataType dtype = TF_DataType.DtInvalid, string name = null) | ||||
{ | { | ||||
var base_type = dtype.as_base_dtype(); | var base_type = dtype.as_base_dtype(); | ||||
if(base_type == x.dtype) | |||||
if (base_type == x.dtype) | |||||
return x; | return x; | ||||
return tf_with(ops.name_scope(name, "Cast", new { x }), scope => | return tf_with(ops.name_scope(name, "Cast", new { x }), scope => | ||||
@@ -98,13 +118,13 @@ namespace Tensorflow | |||||
public static Tensor cumsum<T>(Tensor x, T axis = default, bool exclusive = false, bool reverse = false, string name = null) | public static Tensor cumsum<T>(Tensor x, T axis = default, bool exclusive = false, bool reverse = false, string name = null) | ||||
{ | { | ||||
return tf_with(ops.name_scope(name, "Cumsum", new {x}), scope => | |||||
{ | |||||
name = scope; | |||||
x = ops.convert_to_tensor(x, name: "x"); | |||||
return tf_with(ops.name_scope(name, "Cumsum", new { x }), scope => | |||||
{ | |||||
name = scope; | |||||
x = ops.convert_to_tensor(x, name: "x"); | |||||
return gen_math_ops.cumsum(x, axis: axis, exclusive: exclusive, reverse: reverse, name: name); | |||||
}); | |||||
return gen_math_ops.cumsum(x, axis: axis, exclusive: exclusive, reverse: reverse, name: name); | |||||
}); | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
@@ -221,7 +241,7 @@ namespace Tensorflow | |||||
public static Tensor reduce_mean(Tensor[] input_tensors, int? axis = null, bool keepdims = false, string name = null) | public static Tensor reduce_mean(Tensor[] input_tensors, int? axis = null, bool keepdims = false, string name = null) | ||||
{ | { | ||||
if(axis == null) | |||||
if (axis == null) | |||||
{ | { | ||||
var r = _ReductionDims(input_tensors, axis); | var r = _ReductionDims(input_tensors, axis); | ||||
var m = gen_math_ops.mean(input_tensors, r, keepdims, name); | var m = gen_math_ops.mean(input_tensors, r, keepdims, name); | ||||
@@ -263,14 +283,8 @@ namespace Tensorflow | |||||
return gen_math_ops.sigmoid(x_tensor, name: name); | return gen_math_ops.sigmoid(x_tensor, name: name); | ||||
} | } | ||||
public static Tensor sign(Tensor x, string name = null) | |||||
{ | |||||
return tf_with(ops.name_scope(name, "Sign", new {x}), scope => | |||||
{ | |||||
x = ops.convert_to_tensor(x, name: "x"); | |||||
return gen_math_ops.sign(x); | |||||
}); | |||||
} | |||||
public static Tensor sign<T>(T x, string name = null) | |||||
=> gen_math_ops.sign(x, name: name); | |||||
/// <summary> | /// <summary> | ||||
/// Returns (x - y)(x - y) element-wise. | /// Returns (x - y)(x - y) element-wise. | ||||
@@ -328,7 +328,7 @@ namespace Tensorflow | |||||
switch (name.ToLowerInvariant()) | switch (name.ToLowerInvariant()) | ||||
{ | { | ||||
case "add": | case "add": | ||||
result = math_ops.add(x1, y1, name: scope); | |||||
result = math_ops.add_v2(x1, y1, name: scope); | |||||
break; | break; | ||||
case "div": | case "div": | ||||
result = math_ops.div(x1, y1, name: scope); | result = math_ops.div(x1, y1, name: scope); | ||||