| @@ -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: | ||||