@@ -20,6 +20,7 @@ namespace Tensorflow.Gradients | |||||
public static int[] OpGradientUnusedOutputIndices(string op_name) | public static int[] OpGradientUnusedOutputIndices(string op_name) | ||||
=> op_name switch | => op_name switch | ||||
{ | { | ||||
"FusedBatchNormV3" => new[] { 0, 1, 2 }, | |||||
"ReadVariableOp" => new int[0], | "ReadVariableOp" => new int[0], | ||||
"SoftmaxCrossEntropyWithLogits" => new[] { 0 }, | "SoftmaxCrossEntropyWithLogits" => new[] { 0 }, | ||||
"TensorArrayConcat" => new[] { 0 }, | "TensorArrayConcat" => new[] { 0 }, | ||||
@@ -21,7 +21,7 @@ namespace Tensorflow.Keras.Engine | |||||
_channels_first = args.DataFormat == "channels_first"; | _channels_first = args.DataFormat == "channels_first"; | ||||
} | } | ||||
protected override Tensors CallFn(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
{ | { | ||||
if (_channels_first) | if (_channels_first) | ||||
{ | { | ||||
@@ -268,7 +268,7 @@ namespace Tensorflow.Keras.Engine | |||||
nodes_in_decreasing_depth.Insert(nodes_in_decreasing_depth.Count, node); | nodes_in_decreasing_depth.Insert(nodes_in_decreasing_depth.Count, node); | ||||
} | } | ||||
protected override Tensors CallFn(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
{ | { | ||||
return run_internal_graph(inputs, is_training); | return run_internal_graph(inputs, is_training); | ||||
} | } | ||||
@@ -305,6 +305,7 @@ namespace Tensorflow.Keras.Engine | |||||
tensor_dict[node.FlatInputIds[0]] = new Tensor[0]; | tensor_dict[node.FlatInputIds[0]] = new Tensor[0]; | ||||
var outputs = node.Layer.Apply(layer_inputs, is_training: training); | var outputs = node.Layer.Apply(layer_inputs, is_training: training); | ||||
// Update tensor_dict. | // Update tensor_dict. | ||||
foreach (var (x_id, y) in zip(node.FlatOutputIds, outputs)) | foreach (var (x_id, y) in zip(node.FlatOutputIds, outputs)) | ||||
tensor_dict[x_id] = Enumerable.Range(0, tensor_usage_count[x_id]).Select(x => y).ToArray(); | tensor_dict[x_id] = Enumerable.Range(0, tensor_usage_count[x_id]).Select(x => y).ToArray(); | ||||
@@ -46,7 +46,7 @@ namespace Tensorflow.Keras.Engine | |||||
if (!built) | if (!built) | ||||
MaybeBuild(inputs); | MaybeBuild(inputs); | ||||
outputs = CallFn(inputs, state: state, is_training: is_training); | |||||
outputs = Call(inputs, state: state, is_training: is_training); | |||||
outputs = _set_connectivity_metadata_(inputs, outputs); | outputs = _set_connectivity_metadata_(inputs, outputs); | ||||
_handle_activity_regularization(inputs, outputs); | _handle_activity_regularization(inputs, outputs); | ||||
@@ -42,7 +42,7 @@ namespace Tensorflow.Keras.Engine | |||||
if (!dynamic) | if (!dynamic) | ||||
throw new NotImplementedException(""); | throw new NotImplementedException(""); | ||||
outputs = CallFn(inputs); | |||||
outputs = Call(inputs); | |||||
outputs = _set_connectivity_metadata_(inputs, outputs); | outputs = _set_connectivity_metadata_(inputs, outputs); | ||||
_handle_activity_regularization(inputs, outputs); | _handle_activity_regularization(inputs, outputs); | ||||
@@ -162,7 +162,7 @@ namespace Tensorflow.Keras.Engine | |||||
/// <param name="state"></param> | /// <param name="state"></param> | ||||
/// <param name="is_training"></param> | /// <param name="is_training"></param> | ||||
/// <returns></returns> | /// <returns></returns> | ||||
protected virtual Tensors CallFn(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
protected virtual Tensors Call(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
{ | { | ||||
throw new NotImplementedException(""); | throw new NotImplementedException(""); | ||||
} | } | ||||
@@ -23,9 +23,9 @@ namespace Tensorflow.Keras.Engine | |||||
built = true; | built = true; | ||||
} | } | ||||
protected override Tensors CallFn(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
{ | { | ||||
return base.CallFn(inputs, state, is_training); | |||||
return base.Call(inputs, state, is_training); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -119,7 +119,7 @@ namespace Tensorflow.Keras.Layers | |||||
built = true; | built = true; | ||||
} | } | ||||
protected override Tensors CallFn(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
{ | { | ||||
Tensor outputs = null; | Tensor outputs = null; | ||||
@@ -98,7 +98,7 @@ namespace Tensorflow.Keras.Layers | |||||
built = true; | built = true; | ||||
} | } | ||||
protected override Tensors CallFn(Tensors inputs, Tensor state = null, bool training = false) | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool training = false) | |||||
{ | { | ||||
var outputs = _convolution_op.Apply(inputs, kernel); | var outputs = _convolution_op.Apply(inputs, kernel); | ||||
if (use_bias) | if (use_bias) | ||||
@@ -65,7 +65,7 @@ namespace Tensorflow.Keras.Layers | |||||
built = true; | built = true; | ||||
} | } | ||||
protected override Tensors CallFn(Tensors inputs, Tensor state = null, bool training = false) | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool training = false) | |||||
{ | { | ||||
Tensor outputs = null; | Tensor outputs = null; | ||||
var rank = inputs.rank; | var rank = inputs.rank; | ||||
@@ -18,7 +18,7 @@ namespace Tensorflow.Keras.Layers | |||||
this.args = args; | this.args = args; | ||||
} | } | ||||
protected override Tensors CallFn(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
{ | { | ||||
var output = tf_utils.smart_cond(is_training, | var output = tf_utils.smart_cond(is_training, | ||||
() => tf.nn.dropout(inputs, | () => tf.nn.dropout(inputs, | ||||
@@ -62,7 +62,7 @@ namespace Tensorflow.Keras.Layers | |||||
built = true; | built = true; | ||||
} | } | ||||
protected override Tensors CallFn(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
{ | { | ||||
var dtype = inputs.dtype; | var dtype = inputs.dtype; | ||||
if (dtype != tf.int32 && dtype != tf.int64) | if (dtype != tf.int32 && dtype != tf.int64) | ||||
@@ -29,9 +29,9 @@ namespace Tensorflow.Keras.Layers | |||||
.ToArray(); | .ToArray(); | ||||
} | } | ||||
protected override Tensors CallFn(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
{ | { | ||||
return base.CallFn(inputs, state: state, is_training: is_training); | |||||
return base.Call(inputs, state: state, is_training: is_training); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -36,7 +36,7 @@ namespace Tensorflow.Keras.Layers | |||||
input_spec = new InputSpec(ndim: 4); | input_spec = new InputSpec(ndim: 4); | ||||
} | } | ||||
protected override Tensors CallFn(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
{ | { | ||||
int[] pool_shape; | int[] pool_shape; | ||||
int[] strides; | int[] strides; | ||||
@@ -20,7 +20,7 @@ namespace Tensorflow.Keras.Layers | |||||
this.args = args; | this.args = args; | ||||
} | } | ||||
protected override Tensors CallFn(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
{ | { | ||||
scale = math_ops.cast(args.Scale, args.DType); | scale = math_ops.cast(args.Scale, args.DType); | ||||
offset = math_ops.cast(args.Offset, args.DType); | offset = math_ops.cast(args.Offset, args.DType); | ||||
@@ -29,7 +29,7 @@ namespace Tensorflow.Keras.Layers | |||||
this.input_spec = new InputSpec(ndim: 4); | this.input_spec = new InputSpec(ndim: 4); | ||||
} | } | ||||
protected override Tensors CallFn(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
{ | { | ||||
return tf.keras.backend.spatial_2d_padding(inputs, | return tf.keras.backend.spatial_2d_padding(inputs, | ||||
padding: padding, | padding: padding, | ||||
@@ -74,7 +74,7 @@ namespace Tensorflow | |||||
/// <param name="training"></param> | /// <param name="training"></param> | ||||
/// <param name="state"></param> | /// <param name="state"></param> | ||||
/// <returns></returns> | /// <returns></returns> | ||||
protected override Tensors CallFn(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
{ | { | ||||
var one = constant_op.constant(1, dtype: dtypes.int32); | var one = constant_op.constant(1, dtype: dtypes.int32); | ||||
// Parameters of gates are concatenated into one multiply for efficiency. | // Parameters of gates are concatenated into one multiply for efficiency. | ||||
@@ -67,7 +67,7 @@ namespace Tensorflow | |||||
built = true; | built = true; | ||||
} | } | ||||
protected override Tensors CallFn(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool is_training = false) | |||||
{ | { | ||||
// Most basic RNN: output = new_state = act(W * input + U * state + B). | // Most basic RNN: output = new_state = act(W * input + U * state + B). | ||||
var concat = array_ops.concat(new Tensor[] { inputs, state }, 1); | var concat = array_ops.concat(new Tensor[] { inputs, state }, 1); | ||||
@@ -321,6 +321,23 @@ namespace Tensorflow.Operations | |||||
bool is_training = true, | bool is_training = true, | ||||
string name = null) | string name = null) | ||||
{ | { | ||||
if (tf.executing_eagerly()) | |||||
{ | |||||
var results = tf.Runner.TFE_FastPathExecute(tf.Context, tf.Context.DeviceName, | |||||
"FusedBatchNormV3", name, | |||||
null, | |||||
x, | |||||
scale, | |||||
offset, | |||||
mean, | |||||
variance, | |||||
"epsilon", epsilon, | |||||
"data_format", data_format, | |||||
"is_training", is_training); | |||||
return results; | |||||
} | |||||
var _op = tf.OpDefLib._apply_op_helper("FusedBatchNormV3", name: name, args: new | var _op = tf.OpDefLib._apply_op_helper("FusedBatchNormV3", name: name, args: new | ||||
{ | { | ||||
x, | x, | ||||
@@ -79,7 +79,7 @@ https://tensorflownet.readthedocs.io</Description> | |||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Google.Protobuf" Version="3.11.4" /> | <PackageReference Include="Google.Protobuf" Version="3.11.4" /> | ||||
<PackageReference Include="NumSharp.Lite" Version="0.1.8" /> | |||||
<PackageReference Include="NumSharp.Lite" Version="0.1.9" /> | |||||
<PackageReference Include="Protobuf.Text" Version="0.4.0" /> | <PackageReference Include="Protobuf.Text" Version="0.4.0" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
@@ -158,6 +158,9 @@ namespace Tensorflow | |||||
UnmanagedStorage storage; | UnmanagedStorage storage; | ||||
switch (dtype) | switch (dtype) | ||||
{ | { | ||||
case TF_DataType.TF_BOOL: | |||||
storage = new UnmanagedStorage(NPTypeCode.Boolean); | |||||
break; | |||||
case TF_DataType.TF_STRING: | case TF_DataType.TF_STRING: | ||||
return np.array(StringBytes()[0]); | return np.array(StringBytes()[0]); | ||||
case TF_DataType.TF_INT32: | case TF_DataType.TF_INT32: | ||||