@@ -9,11 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Benchmark", "src | |||||
EndProject | EndProject | ||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.UnitTest", "test\TensorFlowNET.UnitTest\Tensorflow.UnitTest.csproj", "{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.UnitTest", "test\TensorFlowNET.UnitTest\Tensorflow.UnitTest.csproj", "{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}" | ||||
EndProject | EndProject | ||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Keras", "src\TensorFlowNET.Keras\Tensorflow.Keras.csproj", "{6268B461-486A-460B-9B3C-86493CBBAAF7}" | |||||
EndProject | |||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tensorflow.Keras.UnitTest", "test\Tensorflow.Keras.UnitTest\Tensorflow.Keras.UnitTest.csproj", "{EB92DD90-6346-41FB-B967-2B33A860AD98}" | |||||
EndProject | |||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TensorFlowNET.Console", "src\TensorFlowNET.Console\TensorFlowNET.Console.csproj", "{03F06299-3F4B-4449-A709-3A647657BC0C}" | |||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Console", "src\TensorFlowNET.Console\TensorFlowNET.Console.csproj", "{03F06299-3F4B-4449-A709-3A647657BC0C}" | |||||
EndProject | EndProject | ||||
Global | Global | ||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
@@ -103,54 +99,6 @@ Global | |||||
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|x64.Build.0 = Release|x64 | {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|x64.Build.0 = Release|x64 | ||||
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|x86.ActiveCfg = Release|Any CPU | {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|x86.ActiveCfg = Release|Any CPU | ||||
{23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|x86.Build.0 = Release|Any CPU | {23C28035-2FCE-41F3-9A12-E73CE8A5AE32}.Release|x86.Build.0 = Release|Any CPU | ||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug|x64.ActiveCfg = Debug|x64 | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug|x64.Build.0 = Debug|x64 | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug|x86.ActiveCfg = Debug|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug|x86.Build.0 = Debug|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug-Minimal|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug-Minimal|Any CPU.Build.0 = Debug|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug-Minimal|x64.ActiveCfg = Debug|x64 | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug-Minimal|x64.Build.0 = Debug|x64 | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug-Minimal|x86.ActiveCfg = Debug|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Debug-Minimal|x86.Build.0 = Debug|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Publish|Any CPU.ActiveCfg = Release|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Publish|Any CPU.Build.0 = Release|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Publish|x64.ActiveCfg = Release|x64 | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Publish|x64.Build.0 = Release|x64 | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Publish|x86.ActiveCfg = Release|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Publish|x86.Build.0 = Release|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Release|x64.ActiveCfg = Release|x64 | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Release|x64.Build.0 = Release|x64 | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Release|x86.ActiveCfg = Release|Any CPU | |||||
{6268B461-486A-460B-9B3C-86493CBBAAF7}.Release|x86.Build.0 = Release|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug|x64.ActiveCfg = Debug|x64 | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug|x64.Build.0 = Debug|x64 | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug|x86.ActiveCfg = Debug|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug|x86.Build.0 = Debug|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug-Minimal|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug-Minimal|Any CPU.Build.0 = Debug|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug-Minimal|x64.ActiveCfg = Debug|x64 | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug-Minimal|x64.Build.0 = Debug|x64 | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug-Minimal|x86.ActiveCfg = Debug|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Debug-Minimal|x86.Build.0 = Debug|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Publish|Any CPU.ActiveCfg = Release|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Publish|Any CPU.Build.0 = Release|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Publish|x64.ActiveCfg = Release|x64 | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Publish|x64.Build.0 = Release|x64 | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Publish|x86.ActiveCfg = Release|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Publish|x86.Build.0 = Release|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Release|x64.ActiveCfg = Release|x64 | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Release|x64.Build.0 = Release|x64 | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Release|x86.ActiveCfg = Release|Any CPU | |||||
{EB92DD90-6346-41FB-B967-2B33A860AD98}.Release|x86.Build.0 = Release|Any CPU | |||||
{03F06299-3F4B-4449-A709-3A647657BC0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||
{03F06299-3F4B-4449-A709-3A647657BC0C}.Debug|Any CPU.Build.0 = Debug|Any CPU | {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
{03F06299-3F4B-4449-A709-3A647657BC0C}.Debug|x64.ActiveCfg = Debug|Any CPU | {03F06299-3F4B-4449-A709-3A647657BC0C}.Debug|x64.ActiveCfg = Debug|Any CPU | ||||
@@ -14,9 +14,11 @@ | |||||
limitations under the License. | limitations under the License. | ||||
******************************************************************************/ | ******************************************************************************/ | ||||
using System; | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Linq; | using System.Linq; | ||||
using NumSharp; | using NumSharp; | ||||
using Tensorflow.Keras.ArgsDefinition; | |||||
using Tensorflow.Keras.Layers; | using Tensorflow.Keras.Layers; | ||||
using Tensorflow.Operations.Activation; | using Tensorflow.Operations.Activation; | ||||
using static Tensorflow.Binding; | using static Tensorflow.Binding; | ||||
@@ -173,14 +175,19 @@ namespace Tensorflow | |||||
if (bias_initializer == null) | if (bias_initializer == null) | ||||
bias_initializer = tf.zeros_initializer; | bias_initializer = tf.zeros_initializer; | ||||
var layer = new Dense(units, activation, | |||||
use_bias: use_bias, | |||||
bias_initializer: bias_initializer, | |||||
kernel_initializer: kernel_initializer, | |||||
trainable: trainable, | |||||
name: name); | |||||
return layer.apply(inputs).Item1; | |||||
var layer = new Dense(new DenseArgs | |||||
{ | |||||
Units = units, | |||||
Activation = activation, | |||||
UseBias = use_bias, | |||||
BiasInitializer = bias_initializer, | |||||
KernelInitializer = kernel_initializer, | |||||
Trainable = trainable, | |||||
Name = name | |||||
}); | |||||
throw new NotImplementedException(""); | |||||
//return layer.apply(inputs).Item1; | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
@@ -515,6 +515,9 @@ namespace Tensorflow | |||||
public Tensor sum(Tensor input, int axis, bool keep_dims = false, string name = null) | public Tensor sum(Tensor input, int axis, bool keep_dims = false, string name = null) | ||||
=> gen_math_ops._sum(input, axis, keep_dims: keep_dims, name: name); | => gen_math_ops._sum(input, axis, keep_dims: keep_dims, name: name); | ||||
public Tensor reduce_mean(Tensor input_tensors, int axis, bool keepdims = false, string name = null) | |||||
=> math_ops.reduce_mean(input_tensors, axis: new[] { axis }, keepdims: keepdims, name: name); | |||||
public Tensor reduce_mean(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null, int? reduction_indices = null) | public Tensor reduce_mean(Tensor input_tensor, int[] axis = null, bool keepdims = false, string name = null, int? reduction_indices = null) | ||||
=> math_ops.reduce_mean(input_tensor, axis: axis, keepdims: keepdims, name: name, reduction_indices: reduction_indices); | => math_ops.reduce_mean(input_tensor, axis: axis, keepdims: keepdims, name: name, reduction_indices: reduction_indices); | ||||
@@ -7,7 +7,7 @@ namespace Tensorflow | |||||
{ | { | ||||
public class DatasetManager | public class DatasetManager | ||||
{ | { | ||||
public IDatasetV2 from_tensor_slices(NDArray features, NDArray labels) | |||||
public IDatasetV2 from_tensor_slices(Tensor features, Tensor labels) | |||||
=> new TensorSliceDataset(features, labels); | => new TensorSliceDataset(features, labels); | ||||
} | } | ||||
} | } |
@@ -11,9 +11,9 @@ namespace Tensorflow | |||||
{ | { | ||||
public class TensorSliceDataset : DatasetSource | public class TensorSliceDataset : DatasetSource | ||||
{ | { | ||||
public TensorSliceDataset(NDArray features, NDArray labels) | |||||
public TensorSliceDataset(Tensor features, Tensor labels) | |||||
{ | { | ||||
_tensors = new[] { tf.convert_to_tensor(features), tf.convert_to_tensor(labels) }; | |||||
_tensors = new[] { features, labels }; | |||||
var batched_spec = _tensors.Select(x => x.ToTensorSpec()).ToArray(); | var batched_spec = _tensors.Select(x => x.ToTensorSpec()).ToArray(); | ||||
structure = batched_spec.Select(x => x._unbatch()).ToArray(); | structure = batched_spec.Select(x => x._unbatch()).ToArray(); | ||||
@@ -0,0 +1,17 @@ | |||||
using System; | |||||
namespace Tensorflow | |||||
{ | |||||
public class InvalidArgumentError : TensorflowException | |||||
{ | |||||
public InvalidArgumentError() : base() | |||||
{ | |||||
} | |||||
public InvalidArgumentError(string message) : base(message) | |||||
{ | |||||
} | |||||
} | |||||
} |
@@ -119,7 +119,7 @@ namespace Tensorflow.Gradients | |||||
return (results[0], results[1]); | return (results[0], results[1]); | ||||
} | } | ||||
public Tensor[] gradient(Tensor target, ResourceVariable[] sources) | |||||
public Tensor[] gradient(Tensor target, IEnumerable<IVariableV1> sources) | |||||
{ | { | ||||
if (_recording) | if (_recording) | ||||
{ | { | ||||
@@ -0,0 +1,56 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using Tensorflow.Operations.Activation; | |||||
using static Tensorflow.Binding; | |||||
namespace Tensorflow.Keras.ArgsDefinition | |||||
{ | |||||
public class DenseArgs : LayerArgs | |||||
{ | |||||
/// <summary> | |||||
/// Positive integer, dimensionality of the output space. | |||||
/// </summary> | |||||
public int Units { get; set; } | |||||
/// <summary> | |||||
/// Activation function to use. | |||||
/// </summary> | |||||
public IActivation Activation { get; set; } | |||||
/// <summary> | |||||
/// Whether the layer uses a bias vector. | |||||
/// </summary> | |||||
public bool UseBias { get; set; } = true; | |||||
/// <summary> | |||||
/// Initializer for the `kernel` weights matrix. | |||||
/// </summary> | |||||
public IInitializer KernelInitializer { get; set; } = tf.glorot_uniform_initializer; | |||||
/// <summary> | |||||
/// Initializer for the bias vector. | |||||
/// </summary> | |||||
public IInitializer BiasInitializer { get; set; } = tf.zeros_initializer; | |||||
/// <summary> | |||||
/// Regularizer function applied to the `kernel` weights matrix. | |||||
/// </summary> | |||||
public IInitializer KernelRegularizer { get; set; } | |||||
/// <summary> | |||||
/// Regularizer function applied to the bias vector. | |||||
/// </summary> | |||||
public IInitializer BiasRegularizer { get; set; } | |||||
/// <summary> | |||||
/// Constraint function applied to the `kernel` weights matrix. | |||||
/// </summary> | |||||
public Action KernelConstraint { get; set; } | |||||
/// <summary> | |||||
/// Constraint function applied to the bias vector. | |||||
/// </summary> | |||||
public Action BiasConstraint { get; set; } | |||||
} | |||||
} |
@@ -0,0 +1,51 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace Tensorflow.Keras.ArgsDefinition | |||||
{ | |||||
public class LayerArgs | |||||
{ | |||||
/// <summary> | |||||
/// Indicates whether the layer's weights are updated during training | |||||
/// and whether the layer's updates are run during training. | |||||
/// </summary> | |||||
public bool Trainable { get; set; } = true; | |||||
public string Name { get; set; } | |||||
/// <summary> | |||||
/// Only applicable to input layers. | |||||
/// </summary> | |||||
public TF_DataType DType { get; set; } | |||||
/// <summary> | |||||
/// Whether the `call` method can be used to build a TF graph without issues. | |||||
/// This attribute has no effect if the model is created using the Functional | |||||
/// API. Instead, `model.dynamic` is determined based on the internal layers. | |||||
/// </summary> | |||||
public bool Dynamic { get; set; } = false; | |||||
/// <summary> | |||||
/// Only applicable to input layers. | |||||
/// </summary> | |||||
public TensorShape InputShape { get; set; } | |||||
/// <summary> | |||||
/// Only applicable to input layers. | |||||
/// </summary> | |||||
public TensorShape BatchInputShape { get; set; } | |||||
/// <summary> | |||||
/// Initial weight values. | |||||
/// </summary> | |||||
public float[] Weights { get; set; } | |||||
/// <summary> | |||||
/// Regularizer function applied to the output of the layer(its "activation"). | |||||
/// </summary> | |||||
public IInitializer ActivityRegularizer { get; set; } | |||||
public bool Autocast { get; set; } | |||||
} | |||||
} |
@@ -0,0 +1,10 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace Tensorflow.Keras.ArgsDefinition | |||||
{ | |||||
public class ModelArgs : LayerArgs | |||||
{ | |||||
} | |||||
} |
@@ -0,0 +1,14 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace Tensorflow.Keras.Engine | |||||
{ | |||||
public class CallContext | |||||
{ | |||||
public CallContextManager enter() | |||||
{ | |||||
return new CallContextManager(); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,14 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace Tensorflow.Keras.Engine | |||||
{ | |||||
public class CallContextManager : IDisposable | |||||
{ | |||||
public void Dispose() | |||||
{ | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,15 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace Tensorflow.Keras.Engine | |||||
{ | |||||
/// <summary> | |||||
/// A layer is a callable object that takes as input one or more tensors and | |||||
/// that outputs one or more tensors. | |||||
/// </summary> | |||||
public interface ILayer | |||||
{ | |||||
Tensor Apply(Tensor inputs, bool is_training = false); | |||||
} | |||||
} |
@@ -17,12 +17,14 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Linq; | using System.Linq; | ||||
using Tensorflow.Keras.Engine; | |||||
using System.Threading; | |||||
using Tensorflow.Keras.ArgsDefinition; | |||||
using Tensorflow.Keras.Layers; | |||||
using Tensorflow.Keras.Utils; | using Tensorflow.Keras.Utils; | ||||
using Tensorflow.Train; | using Tensorflow.Train; | ||||
using static Tensorflow.Binding; | using static Tensorflow.Binding; | ||||
namespace Tensorflow.Keras.Layers | |||||
namespace Tensorflow.Keras.Engine | |||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// Base layer class. | /// Base layer class. | ||||
@@ -32,8 +34,10 @@ namespace Tensorflow.Keras.Layers | |||||
/// | /// | ||||
/// tensorflow\python\keras\engine\base_layer.py | /// tensorflow\python\keras\engine\base_layer.py | ||||
/// </summary> | /// </summary> | ||||
public class Layer : AutoTrackable | |||||
public class Layer : AutoTrackable, ILayer | |||||
{ | { | ||||
protected LayerArgs _args; | |||||
/// <summary> | /// <summary> | ||||
/// Indicates whether `build` needs to be called upon layer call, to create | /// Indicates whether `build` needs to be called upon layer call, to create | ||||
/// the layer's weights. | /// the layer's weights. | ||||
@@ -52,6 +56,7 @@ namespace Tensorflow.Keras.Layers | |||||
protected InputSpec input_spec; | protected InputSpec input_spec; | ||||
protected bool supports_masking; | protected bool supports_masking; | ||||
protected List<IVariableV1> _trainable_weights; | protected List<IVariableV1> _trainable_weights; | ||||
public List<IVariableV1> trainable_variables => _trainable_weights; | |||||
protected List<IVariableV1> _non_trainable_weights; | protected List<IVariableV1> _non_trainable_weights; | ||||
private string _name; | private string _name; | ||||
public string name => _name; | public string name => _name; | ||||
@@ -72,13 +77,12 @@ namespace Tensorflow.Keras.Layers | |||||
float _initial_weights; | float _initial_weights; | ||||
#pragma warning restore CS0169 // The field 'Layer._initial_weights' is never used | #pragma warning restore CS0169 // The field 'Layer._initial_weights' is never used | ||||
public Layer(bool trainable = true, | |||||
string name = null, | |||||
TF_DataType dtype = TF_DataType.DtInvalid, | |||||
int[] input_shape = null) | |||||
ThreadLocal<CallContext> _call_context; | |||||
public CallContext CallContext => _call_context.Value; | |||||
public Layer(LayerArgs args) | |||||
{ | { | ||||
this.trainable = trainable; | |||||
this._dtype = dtype; | |||||
_args = args; | |||||
// A stateful layer is a layer whose updates are run during inference too, | // A stateful layer is a layer whose updates are run during inference too, | ||||
// for instance stateful RNNs. | // for instance stateful RNNs. | ||||
stateful = false; | stateful = false; | ||||
@@ -94,17 +98,47 @@ namespace Tensorflow.Keras.Layers | |||||
_updates = new List<Operation>(); | _updates = new List<Operation>(); | ||||
// Manage input shape information if passed. | // Manage input shape information if passed. | ||||
if(input_shape != null) | |||||
_inbound_nodes = new List<Node>(); | |||||
} | |||||
/// <summary> | |||||
/// Wraps `call`, applying pre- and post-processing steps. | |||||
/// </summary> | |||||
/// <param name="input"></param> | |||||
/// <param name="is_training"></param> | |||||
/// <returns></returns> | |||||
public Tensor Apply(Tensor input, bool is_training = false) | |||||
{ | |||||
var input_list = new Tensor[] { input }; | |||||
if (_call_context == null) | |||||
_call_context = new ThreadLocal<CallContext>() | |||||
{ | |||||
Value = new CallContext() | |||||
}; | |||||
using var ctxManager = CallContext.enter(); | |||||
string name_scope = ""; | |||||
if (tf.context.executing_eagerly()) | |||||
{ | { | ||||
var shapes = new List<int> { -1 }; | |||||
shapes.AddRange(input_shape); | |||||
_batch_input_shape = shapes.ToArray(); | |||||
name_scope = _name; | |||||
} | |||||
else | |||||
{ | |||||
throw new NotImplementedException(""); | |||||
} | } | ||||
_dtype = dtype; | |||||
tf_with(ops.name_scope(name_scope), scope => | |||||
{ | |||||
if (!built) | |||||
_maybe_build(input); | |||||
_inbound_nodes = new List<Node>(); | |||||
call(input, is_training: is_training); | |||||
}); | |||||
throw new NotImplementedException(""); | |||||
} | } | ||||
public Tensor[] __call__(Tensor[] inputs, | public Tensor[] __call__(Tensor[] inputs, | ||||
@@ -147,7 +181,7 @@ namespace Tensorflow.Keras.Layers | |||||
_maybe_build(inputs[0]); | _maybe_build(inputs[0]); | ||||
outputs = call(inputs[0], | outputs = call(inputs[0], | ||||
training: training, | |||||
// training: training, | |||||
state: state); | state: state); | ||||
(input, outputs) = _set_connectivity_metadata_(input, outputs); | (input, outputs) = _set_connectivity_metadata_(input, outputs); | ||||
@@ -183,7 +217,7 @@ namespace Tensorflow.Keras.Layers | |||||
return null; | return null; | ||||
} | } | ||||
protected virtual Tensor[] call(Tensor inputs, Tensor training = null, Tensor state = null) | |||||
protected virtual Tensor[] call(Tensor inputs, bool is_training = false, Tensor state = null) | |||||
{ | { | ||||
throw new NotImplementedException(""); | throw new NotImplementedException(""); | ||||
} | } |
@@ -1,8 +1,12 @@ | |||||
using Tensorflow.Keras.Optimizers; | |||||
using Tensorflow.Keras.ArgsDefinition; | |||||
using Tensorflow.Keras.Optimizers; | |||||
namespace Tensorflow.Keras.Engine | namespace Tensorflow.Keras.Engine | ||||
{ | { | ||||
public class Model : Network | |||||
/// <summary> | |||||
/// `Model` groups layers into an object with training and inference features. | |||||
/// </summary> | |||||
public class Model : Layer | |||||
{ | { | ||||
#pragma warning disable CS0169 // The field 'Model._cloning' is never used | #pragma warning disable CS0169 // The field 'Model._cloning' is never used | ||||
bool _cloning; | bool _cloning; | ||||
@@ -15,8 +19,8 @@ namespace Tensorflow.Keras.Engine | |||||
string loss; | string loss; | ||||
IOptimizer optimizer; | IOptimizer optimizer; | ||||
public Model(string name = null) | |||||
: base(name: name) | |||||
public Model(ModelArgs args) | |||||
: base(args) | |||||
{ | { | ||||
} | } | ||||
@@ -1,55 +0,0 @@ | |||||
/***************************************************************************** | |||||
Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved. | |||||
Licensed under the Apache License, Version 2.0 (the "License"); | |||||
you may not use this file except in compliance with the License. | |||||
You may obtain a copy of the License at | |||||
http://www.apache.org/licenses/LICENSE-2.0 | |||||
Unless required by applicable law or agreed to in writing, software | |||||
distributed under the License is distributed on an "AS IS" BASIS, | |||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
See the License for the specific language governing permissions and | |||||
limitations under the License. | |||||
******************************************************************************/ | |||||
using System.Collections.Generic; | |||||
using Tensorflow.Keras.Layers; | |||||
namespace Tensorflow.Keras.Engine | |||||
{ | |||||
public class Network : Layer | |||||
{ | |||||
protected bool _is_compiled; | |||||
protected bool _expects_training_arg; | |||||
protected bool _compute_output_and_mask_jointly; | |||||
/// <summary> | |||||
/// All layers in order of horizontal graph traversal. | |||||
/// Entries are unique. Includes input and output layers. | |||||
/// </summary> | |||||
protected List<Layer> _layers; | |||||
public Network(string name = null) | |||||
: base(name: name) | |||||
{ | |||||
_init_subclassed_network(name); | |||||
} | |||||
protected virtual void _init_subclassed_network(string name = null) | |||||
{ | |||||
_base_init(name: name); | |||||
} | |||||
protected virtual void _base_init(string name = null) | |||||
{ | |||||
_init_set_name(name); | |||||
trainable = true; | |||||
_is_compiled = false; | |||||
_expects_training_arg = false; | |||||
_compute_output_and_mask_jointly = false; | |||||
supports_masking = false; | |||||
_layers = new List<Layer>(); | |||||
} | |||||
} | |||||
} |
@@ -14,6 +14,7 @@ | |||||
limitations under the License. | limitations under the License. | ||||
******************************************************************************/ | ******************************************************************************/ | ||||
using Tensorflow.Keras.ArgsDefinition; | |||||
using Tensorflow.Keras.Layers; | using Tensorflow.Keras.Layers; | ||||
namespace Tensorflow.Keras.Engine | namespace Tensorflow.Keras.Engine | ||||
@@ -28,10 +29,10 @@ namespace Tensorflow.Keras.Engine | |||||
#pragma warning restore CS0169 // The field 'Sequential.outputs' is never used | #pragma warning restore CS0169 // The field 'Sequential.outputs' is never used | ||||
public Sequential(string name = null) | public Sequential(string name = null) | ||||
: base(name: name) | |||||
: base(new ModelArgs { Name = name}) | |||||
{ | { | ||||
supports_masking = true; | supports_masking = true; | ||||
_compute_output_and_mask_jointly = true; | |||||
// _compute_output_and_mask_jointly = true; | |||||
} | } | ||||
public void __enter__() | public void __enter__() | ||||
@@ -47,7 +48,7 @@ namespace Tensorflow.Keras.Engine | |||||
{ | { | ||||
built = false; | built = false; | ||||
var set_inputs = false; | var set_inputs = false; | ||||
if(_layers.Count == 0) | |||||
//if(_layers.Count == 0) | |||||
{ | { | ||||
if(layer is InputLayer) | if(layer is InputLayer) | ||||
{ | { | ||||
@@ -1,6 +1,11 @@ | |||||
using System.Data; | |||||
using System; | |||||
using System.Data; | |||||
using Tensorflow.Keras; | using Tensorflow.Keras; | ||||
using Tensorflow.Keras.ArgsDefinition; | |||||
using Tensorflow.Keras.Datasets; | using Tensorflow.Keras.Datasets; | ||||
using Tensorflow.Keras.Engine; | |||||
using Tensorflow.Keras.Layers; | |||||
using Tensorflow.Operations.Activation; | |||||
namespace Tensorflow | namespace Tensorflow | ||||
{ | { | ||||
@@ -8,5 +13,17 @@ namespace Tensorflow | |||||
{ | { | ||||
public KerasDataset datasets { get; } = new KerasDataset(); | public KerasDataset datasets { get; } = new KerasDataset(); | ||||
public Initializers initializers { get; } = new Initializers(); | public Initializers initializers { get; } = new Initializers(); | ||||
public Layers layers { get; } = new Layers(); | |||||
public class Layers | |||||
{ | |||||
public ILayer Dense(int units, | |||||
IActivation activation = null) | |||||
=> new Dense(new DenseArgs | |||||
{ | |||||
Units = units, | |||||
Activation = activation | |||||
}); | |||||
} | |||||
} | } | ||||
} | } |
@@ -143,12 +143,13 @@ namespace Tensorflow.Keras.Layers | |||||
built = true; | built = true; | ||||
} | } | ||||
protected override Tensor[] call(Tensor inputs, Tensor training = null, Tensor state = null) | |||||
protected override Tensor[] call(Tensor inputs, bool is_training = false, Tensor state = null) | |||||
{ | { | ||||
Tensor outputs = null; | Tensor outputs = null; | ||||
if (fused) | if (fused) | ||||
{ | { | ||||
Tensor training = tf.convert_to_tensor(is_training); | |||||
outputs = _fused_batch_norm(inputs, training: training); | outputs = _fused_batch_norm(inputs, training: training); | ||||
return new[] { outputs, outputs }; | return new[] { outputs, outputs }; | ||||
} | } | ||||
@@ -108,7 +108,7 @@ namespace Tensorflow.Keras.Layers | |||||
built = true; | built = true; | ||||
} | } | ||||
protected override Tensor[] call(Tensor inputs, Tensor training = null, Tensor state = null) | |||||
protected override Tensor[] call(Tensor inputs, bool training = false, Tensor state = null) | |||||
{ | { | ||||
var outputs = _convolution_op.__call__(inputs, kernel); | var outputs = _convolution_op.__call__(inputs, kernel); | ||||
if (use_bias) | if (use_bias) | ||||
@@ -17,35 +17,29 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Linq; | using System.Linq; | ||||
using Tensorflow.Keras.ArgsDefinition; | |||||
using Tensorflow.Keras.Engine; | using Tensorflow.Keras.Engine; | ||||
using Tensorflow.Operations.Activation; | using Tensorflow.Operations.Activation; | ||||
using static Tensorflow.Binding; | using static Tensorflow.Binding; | ||||
namespace Tensorflow.Keras.Layers | namespace Tensorflow.Keras.Layers | ||||
{ | { | ||||
public class Dense : Tensorflow.Layers.Layer | |||||
/// <summary> | |||||
/// Just your regular densely-connected NN layer. | |||||
/// </summary> | |||||
public class Dense : Layer | |||||
{ | { | ||||
protected int units; | protected int units; | ||||
protected IActivation activation; | protected IActivation activation; | ||||
protected bool use_bias; | protected bool use_bias; | ||||
protected IInitializer kernel_initializer; | protected IInitializer kernel_initializer; | ||||
protected IInitializer bias_initializer; | protected IInitializer bias_initializer; | ||||
protected RefVariable kernel; | |||||
protected RefVariable bias; | |||||
protected IVariableV1 kernel; | |||||
protected IVariableV1 bias; | |||||
public Dense(int units, | |||||
IActivation activation, | |||||
string name = null, | |||||
bool use_bias = true, | |||||
bool trainable = false, | |||||
IInitializer kernel_initializer = null, | |||||
IInitializer bias_initializer = null) : base(trainable: trainable, name: name) | |||||
public Dense(DenseArgs args) : | |||||
base(args) | |||||
{ | { | ||||
this.units = units; | |||||
this.activation = activation; | |||||
this.use_bias = use_bias; | |||||
this.kernel_initializer = kernel_initializer; | |||||
this.bias_initializer = bias_initializer; | |||||
this.supports_masking = true; | this.supports_masking = true; | ||||
this.input_spec = new InputSpec(min_ndim: 2); | this.input_spec = new InputSpec(min_ndim: 2); | ||||
} | } | ||||
@@ -56,14 +50,14 @@ namespace Tensorflow.Keras.Layers | |||||
var axes = new Dictionary<int, int>(); | var axes = new Dictionary<int, int>(); | ||||
axes[-1] = last_dim; | axes[-1] = last_dim; | ||||
input_spec = new InputSpec(min_ndim: 2, axes: axes); | input_spec = new InputSpec(min_ndim: 2, axes: axes); | ||||
kernel = (RefVariable)add_weight( | |||||
kernel = add_weight( | |||||
"kernel", | "kernel", | ||||
shape: new int[] { last_dim, units }, | shape: new int[] { last_dim, units }, | ||||
initializer: kernel_initializer, | initializer: kernel_initializer, | ||||
dtype: _dtype, | dtype: _dtype, | ||||
trainable: true); | trainable: true); | ||||
if (use_bias) | if (use_bias) | ||||
bias = (RefVariable)add_weight( | |||||
bias = add_weight( | |||||
"bias", | "bias", | ||||
shape: new int[] { units }, | shape: new int[] { units }, | ||||
initializer: bias_initializer, | initializer: bias_initializer, | ||||
@@ -73,7 +67,7 @@ namespace Tensorflow.Keras.Layers | |||||
built = true; | built = true; | ||||
} | } | ||||
protected override Tensor[] call(Tensor inputs, Tensor training = null, Tensor state = null) | |||||
protected override Tensor[] call(Tensor inputs, bool training = false, Tensor state = null) | |||||
{ | { | ||||
Tensor outputs = null; | Tensor outputs = null; | ||||
var rank = inputs.rank; | var rank = inputs.rank; | ||||
@@ -83,7 +77,7 @@ namespace Tensorflow.Keras.Layers | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
outputs = gen_math_ops.mat_mul(inputs, kernel); | |||||
outputs = gen_math_ops.mat_mul(inputs, kernel.Handle); | |||||
} | } | ||||
if (use_bias) | if (use_bias) | ||||
@@ -14,6 +14,8 @@ | |||||
limitations under the License. | limitations under the License. | ||||
******************************************************************************/ | ******************************************************************************/ | ||||
using Tensorflow.Keras.ArgsDefinition; | |||||
using Tensorflow.Keras.Engine; | |||||
using static Tensorflow.Binding; | using static Tensorflow.Binding; | ||||
namespace Tensorflow.Keras.Layers | namespace Tensorflow.Keras.Layers | ||||
@@ -32,7 +34,12 @@ namespace Tensorflow.Keras.Layers | |||||
bool mask_zero = false, | bool mask_zero = false, | ||||
TF_DataType dtype = TF_DataType.TF_FLOAT, | TF_DataType dtype = TF_DataType.TF_FLOAT, | ||||
int[] input_shape = null, | int[] input_shape = null, | ||||
int input_length = -1) : base(dtype: dtype, input_shape: input_shape ?? new[] { input_length }) | |||||
int input_length = -1) : | |||||
base(new LayerArgs | |||||
{ | |||||
DType = dtype, | |||||
InputShape = input_shape ?? new[] { input_length } | |||||
}) | |||||
{ | { | ||||
this.input_dim = input_dim; | this.input_dim = input_dim; | ||||
this.output_dim = output_dim; | this.output_dim = output_dim; | ||||
@@ -50,7 +57,7 @@ namespace Tensorflow.Keras.Layers | |||||
built = true; | built = true; | ||||
} | } | ||||
protected override Tensor[] call(Tensor inputs, Tensor training = null, Tensor state = null) | |||||
protected override Tensor[] call(Tensor inputs, bool is_training = false, Tensor state = null) | |||||
{ | { | ||||
var dtype = inputs.dtype; | var dtype = inputs.dtype; | ||||
if (dtype != tf.int32 && dtype != tf.int64) | if (dtype != tf.int32 && dtype != tf.int64) | ||||
@@ -17,6 +17,8 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Linq; | using System.Linq; | ||||
using Tensorflow.Keras.ArgsDefinition; | |||||
using Tensorflow.Keras.Engine; | |||||
namespace Tensorflow.Keras.Layers | namespace Tensorflow.Keras.Layers | ||||
{ | { | ||||
@@ -35,7 +37,11 @@ namespace Tensorflow.Keras.Layers | |||||
TF_DataType dtype = TF_DataType.DtInvalid, | TF_DataType dtype = TF_DataType.DtInvalid, | ||||
string name = null, | string name = null, | ||||
bool sparse = false, | bool sparse = false, | ||||
Tensor input_tensor = null) : base(dtype: dtype, name: name) | |||||
Tensor input_tensor = null) : | |||||
base(new LayerArgs | |||||
{ | |||||
DType = dtype, Name = name | |||||
}) | |||||
{ | { | ||||
built = true; | built = true; | ||||
this.sparse = sparse; | this.sparse = sparse; | ||||
@@ -15,6 +15,7 @@ | |||||
******************************************************************************/ | ******************************************************************************/ | ||||
using System.Linq; | using System.Linq; | ||||
using Tensorflow.Keras.Engine; | |||||
namespace Tensorflow.Keras.Layers | namespace Tensorflow.Keras.Layers | ||||
{ | { | ||||
@@ -45,7 +45,7 @@ namespace Tensorflow.Keras.Layers | |||||
this.input_spec = new InputSpec(ndim: 4); | this.input_spec = new InputSpec(ndim: 4); | ||||
} | } | ||||
protected override Tensor[] call(Tensor inputs, Tensor training = null, Tensor state = null) | |||||
protected override Tensor[] call(Tensor inputs, bool is_training = false, Tensor state = null) | |||||
{ | { | ||||
int[] pool_shape; | int[] pool_shape; | ||||
if (data_format == "channels_last") | if (data_format == "channels_last") | ||||
@@ -1,20 +0,0 @@ | |||||
using Tensorflow.Operations.Activation; | |||||
namespace Tensorflow.Layers | |||||
{ | |||||
public class Dense : Keras.Layers.Dense | |||||
{ | |||||
public Dense(int units, | |||||
IActivation activation, | |||||
bool use_bias = true, | |||||
bool trainable = false, | |||||
IInitializer kernel_initializer = null) : base(units, | |||||
activation, | |||||
use_bias: use_bias, | |||||
trainable: trainable, | |||||
kernel_initializer: kernel_initializer) | |||||
{ | |||||
} | |||||
} | |||||
} |
@@ -16,11 +16,12 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using Tensorflow.Keras.ArgsDefinition; | |||||
using static Tensorflow.Binding; | using static Tensorflow.Binding; | ||||
namespace Tensorflow.Layers | namespace Tensorflow.Layers | ||||
{ | { | ||||
public class Layer : Keras.Layers.Layer | |||||
public class Layer : Keras.Engine.Layer | |||||
{ | { | ||||
protected Graph _graph; | protected Graph _graph; | ||||
@@ -34,7 +35,13 @@ namespace Tensorflow.Layers | |||||
public Layer(bool trainable = true, | public Layer(bool trainable = true, | ||||
string name = null, | string name = null, | ||||
TF_DataType dtype = TF_DataType.DtInvalid, | TF_DataType dtype = TF_DataType.DtInvalid, | ||||
bool? _reuse = null) : base(trainable: trainable, name: name, dtype: dtype) | |||||
bool? _reuse = null) : | |||||
base(new LayerArgs | |||||
{ | |||||
Trainable = trainable, | |||||
Name = name, | |||||
DType = dtype | |||||
}) | |||||
{ | { | ||||
// For backwards compatibility, legacy layers do not use `ResourceVariable` | // For backwards compatibility, legacy layers do not use `ResourceVariable` | ||||
// by default. | // by default. | ||||
@@ -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 Tensor[] call(Tensor inputs, Tensor training = null, Tensor state = null) | |||||
protected override Tensor[] call(Tensor inputs, bool is_training = false, Tensor state = null) | |||||
{ | { | ||||
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 Tensor[] call(Tensor inputs, Tensor training = null, Tensor state = null) | |||||
protected override Tensor[] call(Tensor inputs, bool is_training = false, Tensor state = null) | |||||
{ | { | ||||
// 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[] { inputs, state }, 1); | var concat = array_ops.concat(new[] { inputs, state }, 1); | ||||
@@ -85,8 +85,9 @@ namespace Tensorflow | |||||
{ | { | ||||
case TF_Code.TF_OUT_OF_RANGE: | case TF_Code.TF_OUT_OF_RANGE: | ||||
throw new OutOfRangeError(message); | throw new OutOfRangeError(message); | ||||
case TF_Code.TF_INVALID_ARGUMENT: | |||||
throw new InvalidArgumentError(message); | |||||
default: | default: | ||||
Console.WriteLine(message); | |||||
throw new TensorflowException(message); | throw new TensorflowException(message); | ||||
} | } | ||||
} | } | ||||