| @@ -150,7 +150,7 @@ namespace Tensorflow | |||
| var variables = graph.get_collection<IVariableV1>(tf.GraphKeys.GLOBAL_VARIABLES, | |||
| scope: scope_to_prepend_to_names); | |||
| var var_list = new Dictionary<string, IVariableV1>(); | |||
| variables.ForEach(v => var_list[ops.strip_name_scope(v.Name, scope_to_prepend_to_names)] = v); | |||
| // variables.ForEach(v => var_list[ops.strip_name_scope(v.Name, scope_to_prepend_to_names)] = v); | |||
| return (var_list, imported_return_elements); | |||
| } | |||
| @@ -1,6 +1,7 @@ | |||
| using NumSharp; | |||
| using System; | |||
| using Tensorflow.Keras.ArgsDefinition; | |||
| using Tensorflow.Keras.Losses; | |||
| using Tensorflow.Keras.Optimizers; | |||
| namespace Tensorflow.Keras.Engine | |||
| @@ -42,6 +43,11 @@ namespace Tensorflow.Keras.Engine | |||
| // Prepare list of loss functions, same size of model outputs. | |||
| } | |||
| public void compile(string optimizerName, ILossFunc lossName) | |||
| { | |||
| throw new NotImplementedException(""); | |||
| } | |||
| /// <summary> | |||
| /// Generates output predictions for the input samples. | |||
| /// </summary> | |||
| @@ -7,6 +7,7 @@ using Tensorflow.Keras.ArgsDefinition; | |||
| using Tensorflow.Keras.Datasets; | |||
| using Tensorflow.Keras.Engine; | |||
| using Tensorflow.Keras.Layers; | |||
| using Tensorflow.Keras.Losses; | |||
| using static Tensorflow.Binding; | |||
| namespace Tensorflow | |||
| @@ -16,6 +17,7 @@ namespace Tensorflow | |||
| public KerasDataset datasets { get; } = new KerasDataset(); | |||
| public Initializers initializers { get; } = new Initializers(); | |||
| public LayersApi layers { get; } = new LayersApi(); | |||
| public LossesApi losses { get; } = new LossesApi(); | |||
| public Activations activations { get; } = new Activations(); | |||
| public Preprocessing preprocessing { get; } = new Preprocessing(); | |||
| public BackendImpl backend { get; } = new BackendImpl(); | |||
| @@ -69,52 +71,5 @@ namespace Tensorflow | |||
| return layer.InboundNodes[0].Outputs; | |||
| } | |||
| public class LayersApi | |||
| { | |||
| public Rescaling Rescaling(float scale, | |||
| float offset = 0, | |||
| TensorShape input_shape = null) | |||
| => new Rescaling(new RescalingArgs | |||
| { | |||
| Scale = scale, | |||
| Offset = offset, | |||
| InputShape = input_shape | |||
| }); | |||
| public Dense Dense(int units, | |||
| Activation activation = null, | |||
| TensorShape input_shape = null) | |||
| => new Dense(new DenseArgs | |||
| { | |||
| Units = units, | |||
| Activation = activation ?? tf.keras.activations.Linear, | |||
| InputShape = input_shape | |||
| }); | |||
| /// <summary> | |||
| /// Turns positive integers (indexes) into dense vectors of fixed size. | |||
| /// </summary> | |||
| /// <param name="input_dim"></param> | |||
| /// <param name="output_dim"></param> | |||
| /// <param name="embeddings_initializer"></param> | |||
| /// <param name="mask_zero"></param> | |||
| /// <returns></returns> | |||
| public Embedding Embedding(int input_dim, | |||
| int output_dim, | |||
| IInitializer embeddings_initializer = null, | |||
| bool mask_zero = false, | |||
| TensorShape input_shape = null, | |||
| int input_length = -1) | |||
| => new Embedding(new EmbeddingArgs | |||
| { | |||
| InputDim = input_dim, | |||
| OutputDim = output_dim, | |||
| MaskZero = mask_zero, | |||
| InputShape = input_shape ?? input_length, | |||
| InputLength = input_length, | |||
| EmbeddingsInitializer = embeddings_initializer | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,95 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using Tensorflow.Keras.ArgsDefinition; | |||
| using Tensorflow.Keras.Engine; | |||
| using static Tensorflow.Binding; | |||
| namespace Tensorflow.Keras.Layers | |||
| { | |||
| public class LayersApi | |||
| { | |||
| public Conv2D Conv2D(int filters, | |||
| TensorShape kernel_size = null, | |||
| string padding = "valid", | |||
| string activation = "relu") | |||
| => new Conv2D(new Conv2DArgs | |||
| { | |||
| Filters = filters, | |||
| KernelSize = kernel_size, | |||
| Padding = padding, | |||
| Activation = GetActivationByName(activation) | |||
| }); | |||
| public Dense Dense(int units, | |||
| string activation = "linear", | |||
| TensorShape input_shape = null) | |||
| => new Dense(new DenseArgs | |||
| { | |||
| Units = units, | |||
| Activation = GetActivationByName(activation), | |||
| InputShape = input_shape | |||
| }); | |||
| /// <summary> | |||
| /// Turns positive integers (indexes) into dense vectors of fixed size. | |||
| /// </summary> | |||
| /// <param name="input_dim"></param> | |||
| /// <param name="output_dim"></param> | |||
| /// <param name="embeddings_initializer"></param> | |||
| /// <param name="mask_zero"></param> | |||
| /// <returns></returns> | |||
| public Embedding Embedding(int input_dim, | |||
| int output_dim, | |||
| IInitializer embeddings_initializer = null, | |||
| bool mask_zero = false, | |||
| TensorShape input_shape = null, | |||
| int input_length = -1) | |||
| => new Embedding(new EmbeddingArgs | |||
| { | |||
| InputDim = input_dim, | |||
| OutputDim = output_dim, | |||
| MaskZero = mask_zero, | |||
| InputShape = input_shape ?? input_length, | |||
| InputLength = input_length, | |||
| EmbeddingsInitializer = embeddings_initializer | |||
| }); | |||
| public Flatten Flatten(string data_format = null) | |||
| => new Flatten(new FlattenArgs | |||
| { | |||
| DataFormat = data_format | |||
| }); | |||
| public MaxPooling2D MaxPooling2D(TensorShape pool_size = null, | |||
| TensorShape strides = null, | |||
| string padding = "valid") | |||
| => new MaxPooling2D(new MaxPooling2DArgs | |||
| { | |||
| PoolSize = pool_size ?? (2, 2), | |||
| Strides = strides, | |||
| Padding = padding | |||
| }); | |||
| public Rescaling Rescaling(float scale, | |||
| float offset = 0, | |||
| TensorShape input_shape = null) | |||
| => new Rescaling(new RescalingArgs | |||
| { | |||
| Scale = scale, | |||
| Offset = offset, | |||
| InputShape = input_shape | |||
| }); | |||
| Activation GetActivationByName(string name) | |||
| => name switch | |||
| { | |||
| "linear" => tf.keras.activations.Linear, | |||
| "relu" => tf.keras.activations.Relu, | |||
| "sigmoid" => tf.keras.activations.Sigmoid, | |||
| "tanh" => tf.keras.activations.Tanh, | |||
| _ => tf.keras.activations.Linear | |||
| }; | |||
| } | |||
| } | |||
| @@ -30,7 +30,7 @@ namespace Tensorflow.Keras.Layers | |||
| { | |||
| this.args = args; | |||
| args.PoolSize = conv_utils.normalize_tuple(args.PoolSize, 2, "pool_size"); | |||
| args.Strides = conv_utils.normalize_tuple(args.Strides, 2, "strides"); | |||
| args.Strides = conv_utils.normalize_tuple(args.Strides ?? args.PoolSize, 2, "strides"); | |||
| args.Padding = conv_utils.normalize_padding(args.Padding); | |||
| args.DataFormat = conv_utils.normalize_data_format(args.DataFormat); | |||
| input_spec = new InputSpec(ndim: 4); | |||
| @@ -23,7 +23,8 @@ namespace Tensorflow.Keras.Layers | |||
| protected override Tensor call(Tensor inputs, bool is_training = false, Tensor state = null) | |||
| { | |||
| scale = math_ops.cast(args.Scale, args.DType); | |||
| throw new NotImplementedException(""); | |||
| offset = math_ops.cast(args.Offset, args.DType); | |||
| return math_ops.cast(inputs, args.DType) * scale + offset; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,10 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| namespace Tensorflow.Keras.Losses | |||
| { | |||
| public interface ILossFunc | |||
| { | |||
| } | |||
| } | |||
| @@ -0,0 +1,29 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| namespace Tensorflow.Keras.Losses | |||
| { | |||
| /// <summary> | |||
| /// Loss base class. | |||
| /// </summary> | |||
| public abstract class Loss | |||
| { | |||
| protected string reduction; | |||
| protected string name; | |||
| bool _allow_sum_over_batch_size; | |||
| string _name_scope; | |||
| public Loss(string reduction = ReductionV2.AUTO, string name = null) | |||
| { | |||
| this.reduction = reduction; | |||
| this.name = name; | |||
| _allow_sum_over_batch_size = false; | |||
| } | |||
| void _set_name_scope() | |||
| { | |||
| _name_scope = name; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,20 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| namespace Tensorflow.Keras.Losses | |||
| { | |||
| public class LossFunctionWrapper : Loss | |||
| { | |||
| Action fn; | |||
| public LossFunctionWrapper(Action fn, | |||
| string reduction = ReductionV2.AUTO, | |||
| string name = null) | |||
| : base(reduction: reduction, | |||
| name: name) | |||
| { | |||
| this.fn = fn; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,12 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| namespace Tensorflow.Keras.Losses | |||
| { | |||
| public class LossesApi | |||
| { | |||
| public ILossFunc SparseCategoricalCrossentropy(bool from_logits = false) | |||
| => new SparseCategoricalCrossentropy(from_logits: from_logits); | |||
| } | |||
| } | |||
| @@ -0,0 +1,11 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| namespace Tensorflow.Keras.Losses | |||
| { | |||
| public class ReductionV2 | |||
| { | |||
| public const string AUTO = "auto"; | |||
| } | |||
| } | |||
| @@ -0,0 +1,24 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| namespace Tensorflow.Keras.Losses | |||
| { | |||
| public class SparseCategoricalCrossentropy : LossFunctionWrapper, ILossFunc | |||
| { | |||
| public SparseCategoricalCrossentropy(bool from_logits = false, | |||
| string reduction = ReductionV2.AUTO, | |||
| string name = "sparse_categorical_crossentropy") : | |||
| base(sparse_categorical_crossentropy, | |||
| reduction: reduction, | |||
| name: name) | |||
| { | |||
| } | |||
| static void sparse_categorical_crossentropy() | |||
| { | |||
| } | |||
| } | |||
| } | |||
| @@ -25,7 +25,7 @@ namespace Tensorflow.Keras | |||
| var image = path_to_image(image_paths[i], image_size, num_channels, interpolation); | |||
| data[i] = image.numpy(); | |||
| if (i % 100 == 0) | |||
| Console.WriteLine($"Filled {i}/{image_paths.Length} data into memory."); | |||
| Console.WriteLine($"Filled {i}/{image_paths.Length} data into ndarray."); | |||
| } | |||
| var img_ds = tf.data.Dataset.from_tensor_slices(data); | |||