Browse Source

Implement serializing attributes other keras arg definitions.

pull/976/head
AsakusaRinne 2 years ago
parent
commit
ad541a7971
57 changed files with 702 additions and 524 deletions
  1. +7
    -4
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Activation/ELUArgs.cs
  2. +4
    -2
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Activation/LeakyReLuArgs.cs
  3. +1
    -7
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Activation/SoftmaxArgs.cs
  4. +4
    -0
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Attention/AttentionArgs.cs
  5. +4
    -1
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Attention/BaseDenseAttentionArgs.cs
  6. +19
    -1
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Attention/MultiHeadAttentionArgs.cs
  7. +6
    -0
      src/TensorFlowNET.Core/Keras/ArgsDefinition/AutoSerializeLayerArgs.cs
  8. +37
    -3
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Convolution/ConvolutionalArgs.cs
  9. +34
    -2
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Core/EinsumDenseArgs.cs
  10. +13
    -2
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Core/EmbeddingArgs.cs
  11. +0
    -16
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Cropping/Cropping2DArgs.cs
  12. +0
    -16
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Cropping/Cropping3DArgs.cs
  13. +0
    -10
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Cropping/CroppingArgs.cs
  14. +0
    -6
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Lstm/LSTMCellArgs.cs
  15. +1
    -0
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Merging/MergeArgs.cs
  16. +18
    -2
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Normalization/BatchNormalizationArgs.cs
  17. +13
    -2
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Normalization/LayerNormalizationArgs.cs
  18. +8
    -2
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Pooling/Pooling1DArgs.cs
  19. +8
    -2
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Pooling/Pooling2DArgs.cs
  20. +1
    -1
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Preprocessing/PreprocessingLayerArgs.cs
  21. +12
    -0
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Preprocessing/RescalingArgs.cs
  22. +1
    -0
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Preprocessing/ResizingArgs.cs
  23. +10
    -1
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Preprocessing/TextVectorizationArgs.cs
  24. +7
    -2
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Regularization/DropoutArgs.cs
  25. +0
    -8
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Rescaling/RescalingArgs.cs
  26. +18
    -0
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Reshaping/Cropping2DArgs.cs
  27. +18
    -0
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Reshaping/Cropping3DArgs.cs
  28. +12
    -0
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Reshaping/CroppingArgs.cs
  29. +8
    -4
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Reshaping/PermuteArgs.cs
  30. +5
    -2
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Reshaping/ReshapeArgs.cs
  31. +7
    -2
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Reshaping/UpSampling2DArgs.cs
  32. +1
    -0
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Reshaping/ZeroPadding2DArgs.cs
  33. +2
    -3
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Rnn/LSTMArgs.cs
  34. +7
    -0
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Rnn/LSTMCellArgs.cs
  35. +12
    -3
      src/TensorFlowNET.Core/Keras/ArgsDefinition/Rnn/RNNArgs.cs
  36. +1
    -1
      src/TensorFlowNET.Core/Keras/Layers/ILayersApi.Cropping.cs
  37. +82
    -0
      src/TensorFlowNET.Keras/Activations.cs
  38. +0
    -10
      src/TensorFlowNET.Keras/Activations/Activations.Linear.cs
  39. +0
    -10
      src/TensorFlowNET.Keras/Activations/Activations.Relu.cs
  40. +0
    -11
      src/TensorFlowNET.Keras/Activations/Activations.Sigmoid.cs
  41. +0
    -11
      src/TensorFlowNET.Keras/Activations/Activations.Softmax.cs
  42. +0
    -11
      src/TensorFlowNET.Keras/Activations/Activations.Tanh.cs
  43. +1
    -0
      src/TensorFlowNET.Keras/Layers/Attention/MultiHeadAttention.cs
  44. +1
    -1
      src/TensorFlowNET.Keras/Layers/Core/EinsumDense.cs
  45. +0
    -114
      src/TensorFlowNET.Keras/Layers/Cropping/Cropping2D.cs
  46. +0
    -124
      src/TensorFlowNET.Keras/Layers/Cropping/Cropping3D.cs
  47. +6
    -4
      src/TensorFlowNET.Keras/Layers/LayersApi.Cropping.cs
  48. +10
    -27
      src/TensorFlowNET.Keras/Layers/LayersApi.cs
  49. +1
    -1
      src/TensorFlowNET.Keras/Layers/Normalization/BatchNormalization.cs
  50. +0
    -0
      src/TensorFlowNET.Keras/Layers/Preprocessing/Rescaling.cs
  51. +8
    -7
      src/TensorFlowNET.Keras/Layers/Reshaping/Cropping1D.cs
  52. +140
    -0
      src/TensorFlowNET.Keras/Layers/Reshaping/Cropping2D.cs
  53. +150
    -0
      src/TensorFlowNET.Keras/Layers/Reshaping/Cropping3D.cs
  54. +2
    -3
      src/TensorFlowNET.Keras/Layers/Rnn/LSTM.cs
  55. +2
    -2
      src/TensorFlowNET.Keras/Layers/Rnn/LSTMCell.cs
  56. +0
    -1
      src/TensorFlowNET.Keras/Layers/Rnn/RNN.cs
  57. +0
    -82
      test/TensorFlowNET.Keras.UnitTest/SaveModel/SequentialModelTest.cs

+ 7
- 4
src/TensorFlowNET.Core/Keras/ArgsDefinition/Activation/ELUArgs.cs View File

@@ -1,9 +1,12 @@
using System;
using Newtonsoft.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;


namespace Tensorflow.Keras.ArgsDefinition { namespace Tensorflow.Keras.ArgsDefinition {
public class ELUArgs : LayerArgs {
public float Alpha { get; set; } = 0.1f;
}
public class ELUArgs : AutoSerializeLayerArgs
{
[JsonProperty("alpha")]
public float Alpha { get; set; } = 0.1f;
}
} }

+ 4
- 2
src/TensorFlowNET.Core/Keras/ArgsDefinition/Activation/LeakyReLuArgs.cs View File

@@ -1,14 +1,16 @@
using System;
using Newtonsoft.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;


namespace Tensorflow.Keras.ArgsDefinition namespace Tensorflow.Keras.ArgsDefinition
{ {
public class LeakyReLuArgs : LayerArgs
public class LeakyReLuArgs : AutoSerializeLayerArgs
{ {
/// <summary> /// <summary>
/// Negative slope coefficient. /// Negative slope coefficient.
/// </summary> /// </summary>
[JsonProperty("alpha")]
public float Alpha { get; set; } = 0.3f; public float Alpha { get; set; } = 0.3f;
} }
} }

+ 1
- 7
src/TensorFlowNET.Core/Keras/ArgsDefinition/Activation/SoftmaxArgs.cs View File

@@ -4,15 +4,9 @@ using System.Collections.Generic;
using System.Text; using System.Text;


namespace Tensorflow.Keras.ArgsDefinition { namespace Tensorflow.Keras.ArgsDefinition {
public class SoftmaxArgs : LayerArgs
public class SoftmaxArgs : AutoSerializeLayerArgs
{ {
[JsonProperty("axis")] [JsonProperty("axis")]
public Axis axis { get; set; } = -1; public Axis axis { get; set; } = -1;
[JsonProperty("name")]
public override string Name { get => base.Name; set => base.Name = value; }
[JsonProperty("trainable")]
public override bool Trainable { get => base.Trainable; set => base.Trainable = value; }
[JsonProperty("dtype")]
public override TF_DataType DType { get => base.DType; set => base.DType = value; }
} }
} }

+ 4
- 0
src/TensorFlowNET.Core/Keras/ArgsDefinition/Attention/AttentionArgs.cs View File

@@ -1,3 +1,5 @@
using Newtonsoft.Json;

namespace Tensorflow.Keras.ArgsDefinition namespace Tensorflow.Keras.ArgsDefinition
{ {
public class AttentionArgs : BaseDenseAttentionArgs public class AttentionArgs : BaseDenseAttentionArgs
@@ -6,6 +8,7 @@ namespace Tensorflow.Keras.ArgsDefinition
/// <summary> /// <summary>
/// If `true`, will create a scalar variable to scale the attention scores. /// If `true`, will create a scalar variable to scale the attention scores.
/// </summary> /// </summary>
[JsonProperty("use_scale")]
public bool use_scale { get; set; } = false; public bool use_scale { get; set; } = false;


/// <summary> /// <summary>
@@ -14,6 +17,7 @@ namespace Tensorflow.Keras.ArgsDefinition
/// and key vectors. `"concat"` refers to the hyperbolic tangent of the /// and key vectors. `"concat"` refers to the hyperbolic tangent of the
/// concatenation of the query and key vectors. /// concatenation of the query and key vectors.
/// </summary> /// </summary>
[JsonProperty("score_mode")]
public string score_mode { get; set; } = "dot"; public string score_mode { get; set; } = "dot";


} }

+ 4
- 1
src/TensorFlowNET.Core/Keras/ArgsDefinition/Attention/BaseDenseAttentionArgs.cs View File

@@ -1,6 +1,8 @@
using Newtonsoft.Json;

namespace Tensorflow.Keras.ArgsDefinition namespace Tensorflow.Keras.ArgsDefinition
{ {
public class BaseDenseAttentionArgs : LayerArgs
public class BaseDenseAttentionArgs : AutoSerializeLayerArgs
{ {


/// <summary> /// <summary>
@@ -14,6 +16,7 @@ namespace Tensorflow.Keras.ArgsDefinition
/// Float between 0 and 1. Fraction of the units to drop for the /// Float between 0 and 1. Fraction of the units to drop for the
/// attention scores. /// attention scores.
/// </summary> /// </summary>
[JsonProperty("dropout")]
public float dropout { get; set; } = 0f; public float dropout { get; set; } = 0f;


} }

+ 19
- 1
src/TensorFlowNET.Core/Keras/ArgsDefinition/Attention/MultiHeadAttentionArgs.cs View File

@@ -1,22 +1,40 @@
using Newtonsoft.Json;
using System; using System;
using static Tensorflow.Binding; using static Tensorflow.Binding;


namespace Tensorflow.Keras.ArgsDefinition namespace Tensorflow.Keras.ArgsDefinition
{ {
public class MultiHeadAttentionArgs : LayerArgs
public class MultiHeadAttentionArgs : AutoSerializeLayerArgs
{ {
[JsonProperty("num_heads")]
public int NumHeads { get; set; } public int NumHeads { get; set; }
[JsonProperty("key_dim")]
public int KeyDim { get; set; } public int KeyDim { get; set; }
[JsonProperty("value_dim")]
public int? ValueDim { get; set; } = null; public int? ValueDim { get; set; } = null;
[JsonProperty("dropout")]
public float Dropout { get; set; } = 0f; public float Dropout { get; set; } = 0f;
[JsonProperty("use_bias")]
public bool UseBias { get; set; } = true; public bool UseBias { get; set; } = true;
[JsonProperty("output_shape")]
public Shape OutputShape { get; set; } = null; public Shape OutputShape { get; set; } = null;
[JsonProperty("attention_axes")]
public Shape AttentionAxis { get; set; } = null; public Shape AttentionAxis { get; set; } = null;
[JsonProperty("kernel_initializer")]
public IInitializer KernelInitializer { get; set; } = tf.glorot_uniform_initializer; public IInitializer KernelInitializer { get; set; } = tf.glorot_uniform_initializer;
[JsonProperty("bias_initializer")]
public IInitializer BiasInitializer { get; set; } = tf.zeros_initializer; public IInitializer BiasInitializer { get; set; } = tf.zeros_initializer;
[JsonProperty("kernel_regularizer")]
public IRegularizer KernelRegularizer { get; set; } = null; public IRegularizer KernelRegularizer { get; set; } = null;
[JsonProperty("bias_regularizer")]
public IRegularizer BiasRegularizer { get; set; } = null; public IRegularizer BiasRegularizer { get; set; } = null;
[JsonProperty("kernel_constraint")]
public Action KernelConstraint { get; set; } = null; public Action KernelConstraint { get; set; } = null;
[JsonProperty("bias_constraint")]
public Action BiasConstraint { get; set; } = null; public Action BiasConstraint { get; set; } = null;
[JsonProperty("activity_regularizer")]
public override IRegularizer ActivityRegularizer { get => base.ActivityRegularizer; set => base.ActivityRegularizer = value; }

// TODO: Add `key_shape`, `value_shape`, `query_shape`.
} }
} }

+ 6
- 0
src/TensorFlowNET.Core/Keras/ArgsDefinition/AutoSerializeLayerArgs.cs View File

@@ -5,6 +5,12 @@ using System.Text;


namespace Tensorflow.Keras.ArgsDefinition namespace Tensorflow.Keras.ArgsDefinition
{ {
/// <summary>
/// This class has nothing but the attributes different from `LayerArgs`.
/// It's used to serialize the model to `tf` format.
/// If the `get_config` of a `Layer` in python code of tensorflow contains `super().get_config`,
/// then the Arg definition should inherit `utoSerializeLayerArgs` instead of `LayerArgs`.
/// </summary>
public class AutoSerializeLayerArgs: LayerArgs public class AutoSerializeLayerArgs: LayerArgs
{ {
[JsonProperty("name")] [JsonProperty("name")]


+ 37
- 3
src/TensorFlowNET.Core/Keras/ArgsDefinition/Convolution/ConvolutionalArgs.cs View File

@@ -1,31 +1,65 @@
using System;
using Newtonsoft.Json;
using System;
using static Tensorflow.Binding; using static Tensorflow.Binding;


namespace Tensorflow.Keras.ArgsDefinition namespace Tensorflow.Keras.ArgsDefinition
{ {
public class ConvolutionalArgs : LayerArgs
public class ConvolutionalArgs : AutoSerializeLayerArgs
{ {
public int Rank { get; set; } = 2; public int Rank { get; set; } = 2;
[JsonProperty("filters")]
public int Filters { get; set; } public int Filters { get; set; }
public int NumSpatialDims { get; set; } = Unknown; public int NumSpatialDims { get; set; } = Unknown;
[JsonProperty("kernel_size")]
public Shape KernelSize { get; set; } = 5; public Shape KernelSize { get; set; } = 5;


/// <summary> /// <summary>
/// specifying the stride length of the convolution. /// specifying the stride length of the convolution.
/// </summary> /// </summary>
[JsonProperty("strides")]
public Shape Strides { get; set; } = (1, 1); public Shape Strides { get; set; } = (1, 1);
[JsonProperty("padding")]
public string Padding { get; set; } = "valid"; public string Padding { get; set; } = "valid";
[JsonProperty("data_format")]
public string DataFormat { get; set; } public string DataFormat { get; set; }
[JsonProperty("dilation_rate")]
public Shape DilationRate { get; set; } = (1, 1); public Shape DilationRate { get; set; } = (1, 1);
[JsonProperty("groups")]
public int Groups { get; set; } = 1; public int Groups { get; set; } = 1;
public Activation Activation { get; set; } public Activation Activation { get; set; }
private string _activationName;
[JsonProperty("activation")]
public string ActivationName
{
get
{
if (string.IsNullOrEmpty(_activationName))
{
return Activation.Method.Name;
}
else
{
return _activationName;
}
}
set
{
_activationName = value;
}
}
[JsonProperty("use_bias")]
public bool UseBias { get; set; } public bool UseBias { get; set; }
[JsonProperty("kernel_initializer")]
public IInitializer KernelInitializer { get; set; } = tf.glorot_uniform_initializer; public IInitializer KernelInitializer { get; set; } = tf.glorot_uniform_initializer;
[JsonProperty("bias_initializer")]
public IInitializer BiasInitializer { get; set; } = tf.zeros_initializer; public IInitializer BiasInitializer { get; set; } = tf.zeros_initializer;
[JsonProperty("kernel_regularizer")]
public IRegularizer KernelRegularizer { get; set; } public IRegularizer KernelRegularizer { get; set; }
[JsonProperty("bias_regularizer")]
public IRegularizer BiasRegularizer { get; set; } public IRegularizer BiasRegularizer { get; set; }
[JsonProperty("kernel_constraint")]
public Action KernelConstraint { get; set; } public Action KernelConstraint { get; set; }
[JsonProperty("bias_constraint")]
public Action BiasConstraint { get; set; } public Action BiasConstraint { get; set; }
} }
} }

src/TensorFlowNET.Core/Keras/ArgsDefinition/Attention/EinsumDenseArgs.cs → src/TensorFlowNET.Core/Keras/ArgsDefinition/Core/EinsumDenseArgs.cs View File

@@ -1,9 +1,10 @@
using Newtonsoft.Json;
using System; using System;
using static Tensorflow.Binding; using static Tensorflow.Binding;


namespace Tensorflow.Keras.ArgsDefinition
namespace Tensorflow.Keras.ArgsDefinition.Core
{ {
public class EinsumDenseArgs : LayerArgs
public class EinsumDenseArgs : AutoSerializeLayerArgs
{ {
/// <summary> /// <summary>
/// An equation describing the einsum to perform. This equation must /// An equation describing the einsum to perform. This equation must
@@ -11,6 +12,7 @@ namespace Tensorflow.Keras.ArgsDefinition
/// `ab...,bc->ac...` where 'ab', 'bc', and 'ac' can be any valid einsum axis /// `ab...,bc->ac...` where 'ab', 'bc', and 'ac' can be any valid einsum axis
/// expression sequence. /// expression sequence.
/// </summary> /// </summary>
[JsonProperty("equation")]
public string Equation { get; set; } public string Equation { get; set; }


/// <summary> /// <summary>
@@ -19,6 +21,7 @@ namespace Tensorflow.Keras.ArgsDefinition
/// None for any dimension that is unknown or can be inferred from the input /// None for any dimension that is unknown or can be inferred from the input
/// shape. /// shape.
/// </summary> /// </summary>
[JsonProperty("output_shape")]
public Shape OutputShape { get; set; } public Shape OutputShape { get; set; }


/// <summary> /// <summary>
@@ -26,41 +29,70 @@ namespace Tensorflow.Keras.ArgsDefinition
/// Each character in the `bias_axes` string should correspond to a character /// Each character in the `bias_axes` string should correspond to a character
/// in the output portion of the `equation` string. /// in the output portion of the `equation` string.
/// </summary> /// </summary>
[JsonProperty("bias_axes")]
public string BiasAxes { get; set; } = null; public string BiasAxes { get; set; } = null;


/// <summary> /// <summary>
/// Activation function to use. /// Activation function to use.
/// </summary> /// </summary>
public Activation Activation { get; set; } public Activation Activation { get; set; }
private string _activationName;
[JsonProperty("activation")]
public string ActivationName
{
get
{
if (string.IsNullOrEmpty(_activationName))
{
return Activation.Method.Name;
}
else
{
return _activationName;
}
}
set
{
_activationName = value;
}
}


/// <summary> /// <summary>
/// Initializer for the `kernel` weights matrix. /// Initializer for the `kernel` weights matrix.
/// </summary> /// </summary>
[JsonProperty("kernel_initializer")]
public IInitializer KernelInitializer { get; set; } = tf.glorot_uniform_initializer; public IInitializer KernelInitializer { get; set; } = tf.glorot_uniform_initializer;


/// <summary> /// <summary>
/// Initializer for the bias vector. /// Initializer for the bias vector.
/// </summary> /// </summary>
[JsonProperty("bias_initializer")]
public IInitializer BiasInitializer { get; set; } = tf.zeros_initializer; public IInitializer BiasInitializer { get; set; } = tf.zeros_initializer;


/// <summary> /// <summary>
/// Regularizer function applied to the `kernel` weights matrix. /// Regularizer function applied to the `kernel` weights matrix.
/// </summary> /// </summary>
[JsonProperty("kernel_regularizer")]
public IRegularizer KernelRegularizer { get; set; } public IRegularizer KernelRegularizer { get; set; }


/// <summary> /// <summary>
/// Regularizer function applied to the bias vector. /// Regularizer function applied to the bias vector.
/// </summary> /// </summary>
[JsonProperty("bias_regularizer")]
public IRegularizer BiasRegularizer { get; set; } public IRegularizer BiasRegularizer { get; set; }


/// <summary> /// <summary>
/// Constraint function applied to the `kernel` weights matrix. /// Constraint function applied to the `kernel` weights matrix.
/// </summary> /// </summary>
[JsonProperty("kernel_constraint")]
public Action KernelConstraint { get; set; } public Action KernelConstraint { get; set; }


/// <summary> /// <summary>
/// Constraint function applied to the bias vector. /// Constraint function applied to the bias vector.
/// </summary> /// </summary>
[JsonProperty("bias_constraint")]
public Action BiasConstraint { get; set; } public Action BiasConstraint { get; set; }
[JsonProperty("activity_regularizer")]
public override IRegularizer ActivityRegularizer { get => base.ActivityRegularizer; set => base.ActivityRegularizer = value; }
} }
} }

+ 13
- 2
src/TensorFlowNET.Core/Keras/ArgsDefinition/Core/EmbeddingArgs.cs View File

@@ -1,11 +1,22 @@
namespace Tensorflow.Keras.ArgsDefinition
using Newtonsoft.Json;

namespace Tensorflow.Keras.ArgsDefinition
{ {
public class EmbeddingArgs : LayerArgs
public class EmbeddingArgs : AutoSerializeLayerArgs
{ {
[JsonProperty("input_dim")]
public int InputDim { get; set; } public int InputDim { get; set; }
[JsonProperty("output_dim")]
public int OutputDim { get; set; } public int OutputDim { get; set; }
[JsonProperty("mask_zero")]
public bool MaskZero { get; set; } public bool MaskZero { get; set; }
[JsonProperty("input_length")]
public int InputLength { get; set; } = -1; public int InputLength { get; set; } = -1;
[JsonProperty("embeddings_initializer")]
public IInitializer EmbeddingsInitializer { get; set; } public IInitializer EmbeddingsInitializer { get; set; }
[JsonProperty("activity_regularizer")]
public override IRegularizer ActivityRegularizer { get => base.ActivityRegularizer; set => base.ActivityRegularizer = value; }

// TODO: `embeddings_regularizer`, `embeddings_constraint`.
} }
} }

+ 0
- 16
src/TensorFlowNET.Core/Keras/ArgsDefinition/Cropping/Cropping2DArgs.cs View File

@@ -1,16 +0,0 @@
using Tensorflow.NumPy;

namespace Tensorflow.Keras.ArgsDefinition {
public class Cropping2DArgs : LayerArgs {
/// <summary>
/// channel last: (b, h, w, c)
/// channels_first: (b, c, h, w)
/// </summary>
public enum DataFormat { channels_first = 0, channels_last = 1 }
/// <summary>
/// Accept: int[1][2], int[1][1], int[2][2]
/// </summary>
public NDArray cropping { get; set; }
public DataFormat data_format { get; set; } = DataFormat.channels_last;
}
}

+ 0
- 16
src/TensorFlowNET.Core/Keras/ArgsDefinition/Cropping/Cropping3DArgs.cs View File

@@ -1,16 +0,0 @@
using Tensorflow.NumPy;

namespace Tensorflow.Keras.ArgsDefinition {
public class Cropping3DArgs : LayerArgs {
/// <summary>
/// channel last: (b, h, w, c)
/// channels_first: (b, c, h, w)
/// </summary>
public enum DataFormat { channels_first = 0, channels_last = 1 }
/// <summary>
/// Accept: int[1][3], int[1][1], int[3][2]
/// </summary>
public NDArray cropping { get; set; }
public DataFormat data_format { get; set; } = DataFormat.channels_last;
}
}

+ 0
- 10
src/TensorFlowNET.Core/Keras/ArgsDefinition/Cropping/CroppingArgs.cs View File

@@ -1,10 +0,0 @@
using Tensorflow.NumPy;

namespace Tensorflow.Keras.ArgsDefinition {
public class CroppingArgs : LayerArgs {
/// <summary>
/// Accept length 1 or 2
/// </summary>
public NDArray cropping { get; set; }
}
}

+ 0
- 6
src/TensorFlowNET.Core/Keras/ArgsDefinition/Lstm/LSTMCellArgs.cs View File

@@ -1,6 +0,0 @@
namespace Tensorflow.Keras.ArgsDefinition.Lstm
{
public class LSTMCellArgs : LayerArgs
{
}
}

+ 1
- 0
src/TensorFlowNET.Core/Keras/ArgsDefinition/Merging/MergeArgs.cs View File

@@ -4,6 +4,7 @@ using System.Text;


namespace Tensorflow.Keras.ArgsDefinition namespace Tensorflow.Keras.ArgsDefinition
{ {
// TODO: complete the implementation
public class MergeArgs : LayerArgs public class MergeArgs : LayerArgs
{ {
public Tensors Inputs { get; set; } public Tensors Inputs { get; set; }


+ 18
- 2
src/TensorFlowNET.Core/Keras/ArgsDefinition/Normalization/BatchNormalizationArgs.cs View File

@@ -1,21 +1,37 @@
using static Tensorflow.Binding;
using Newtonsoft.Json;
using static Tensorflow.Binding;


namespace Tensorflow.Keras.ArgsDefinition namespace Tensorflow.Keras.ArgsDefinition
{ {
public class BatchNormalizationArgs : LayerArgs
public class BatchNormalizationArgs : AutoSerializeLayerArgs
{ {
[JsonProperty("axis")]
public Shape Axis { get; set; } = -1; public Shape Axis { get; set; } = -1;
[JsonProperty("momentum")]
public float Momentum { get; set; } = 0.99f; public float Momentum { get; set; } = 0.99f;
[JsonProperty("epsilon")]
public float Epsilon { get; set; } = 1e-3f; public float Epsilon { get; set; } = 1e-3f;
[JsonProperty("center")]
public bool Center { get; set; } = true; public bool Center { get; set; } = true;
[JsonProperty("scale")]
public bool Scale { get; set; } = true; public bool Scale { get; set; } = true;
[JsonProperty("beta_initializer")]
public IInitializer BetaInitializer { get; set; } = tf.zeros_initializer; public IInitializer BetaInitializer { get; set; } = tf.zeros_initializer;
[JsonProperty("gamma_initializer")]
public IInitializer GammaInitializer { get; set; } = tf.ones_initializer; public IInitializer GammaInitializer { get; set; } = tf.ones_initializer;
[JsonProperty("moving_mean_initializer")]
public IInitializer MovingMeanInitializer { get; set; } = tf.zeros_initializer; public IInitializer MovingMeanInitializer { get; set; } = tf.zeros_initializer;
[JsonProperty("moving_variance_initializer")]
public IInitializer MovingVarianceInitializer { get; set; } = tf.ones_initializer; public IInitializer MovingVarianceInitializer { get; set; } = tf.ones_initializer;
[JsonProperty("beta_regularizer")]
public IRegularizer BetaRegularizer { get; set; } public IRegularizer BetaRegularizer { get; set; }
[JsonProperty("gamma_regularizer")]
public IRegularizer GammaRegularizer { get; set; } public IRegularizer GammaRegularizer { get; set; }
// TODO: `beta_constraint` and `gamma_constraint`.
[JsonProperty("renorm")]
public bool Renorm { get; set; } public bool Renorm { get; set; }
// TODO: `renorm_clipping` and `virtual_batch_size`.
[JsonProperty("renorm_momentum")]
public float RenormMomentum { get; set; } = 0.99f; public float RenormMomentum { get; set; } = 0.99f;
} }
} }

+ 13
- 2
src/TensorFlowNET.Core/Keras/ArgsDefinition/Normalization/LayerNormalizationArgs.cs View File

@@ -1,16 +1,27 @@
using static Tensorflow.Binding;
using Newtonsoft.Json;
using static Tensorflow.Binding;


namespace Tensorflow.Keras.ArgsDefinition namespace Tensorflow.Keras.ArgsDefinition
{ {
public class LayerNormalizationArgs : LayerArgs
public class LayerNormalizationArgs : AutoSerializeLayerArgs
{ {
[JsonProperty("axis")]
public Axis Axis { get; set; } = -1; public Axis Axis { get; set; } = -1;
[JsonProperty("epsilon")]
public float Epsilon { get; set; } = 1e-3f; public float Epsilon { get; set; } = 1e-3f;
[JsonProperty("center")]
public bool Center { get; set; } = true; public bool Center { get; set; } = true;
[JsonProperty("scale")]
public bool Scale { get; set; } = true; public bool Scale { get; set; } = true;
[JsonProperty("beta_initializer")]
public IInitializer BetaInitializer { get; set; } = tf.zeros_initializer; public IInitializer BetaInitializer { get; set; } = tf.zeros_initializer;
[JsonProperty("gamma_initializer")]
public IInitializer GammaInitializer { get; set; } = tf.ones_initializer; public IInitializer GammaInitializer { get; set; } = tf.ones_initializer;
[JsonProperty("beta_regularizer")]
public IRegularizer BetaRegularizer { get; set; } public IRegularizer BetaRegularizer { get; set; }
[JsonProperty("gamma_regularizer")]
public IRegularizer GammaRegularizer { get; set; } public IRegularizer GammaRegularizer { get; set; }

// TODO: `beta_constraint` and `gamma_constraint`.
} }
} }

+ 8
- 2
src/TensorFlowNET.Core/Keras/ArgsDefinition/Pooling/Pooling1DArgs.cs View File

@@ -1,6 +1,8 @@
namespace Tensorflow.Keras.ArgsDefinition
using Newtonsoft.Json;

namespace Tensorflow.Keras.ArgsDefinition
{ {
public class Pooling1DArgs : LayerArgs
public class Pooling1DArgs : AutoSerializeLayerArgs
{ {
/// <summary> /// <summary>
/// The pooling function to apply, e.g. `tf.nn.max_pool2d`. /// The pooling function to apply, e.g. `tf.nn.max_pool2d`.
@@ -10,11 +12,13 @@
/// <summary> /// <summary>
/// specifying the size of the pooling window. /// specifying the size of the pooling window.
/// </summary> /// </summary>
[JsonProperty("pool_size")]
public int PoolSize { get; set; } public int PoolSize { get; set; }


/// <summary> /// <summary>
/// specifying the strides of the pooling operation. /// specifying the strides of the pooling operation.
/// </summary> /// </summary>
[JsonProperty("strides")]
public int Strides { public int Strides {
get { return _strides.HasValue ? _strides.Value : PoolSize; } get { return _strides.HasValue ? _strides.Value : PoolSize; }
set { _strides = value; } set { _strides = value; }
@@ -24,11 +28,13 @@
/// <summary> /// <summary>
/// The padding method, either 'valid' or 'same'. /// The padding method, either 'valid' or 'same'.
/// </summary> /// </summary>
[JsonProperty("padding")]
public string Padding { get; set; } = "valid"; public string Padding { get; set; } = "valid";


/// <summary> /// <summary>
/// one of `channels_last` (default) or `channels_first`. /// one of `channels_last` (default) or `channels_first`.
/// </summary> /// </summary>
[JsonProperty("data_format")]
public string DataFormat { get; set; } public string DataFormat { get; set; }
} }
} }

+ 8
- 2
src/TensorFlowNET.Core/Keras/ArgsDefinition/Pooling/Pooling2DArgs.cs View File

@@ -1,6 +1,8 @@
namespace Tensorflow.Keras.ArgsDefinition
using Newtonsoft.Json;

namespace Tensorflow.Keras.ArgsDefinition
{ {
public class Pooling2DArgs : LayerArgs
public class Pooling2DArgs : AutoSerializeLayerArgs
{ {
/// <summary> /// <summary>
/// The pooling function to apply, e.g. `tf.nn.max_pool2d`. /// The pooling function to apply, e.g. `tf.nn.max_pool2d`.
@@ -10,21 +12,25 @@
/// <summary> /// <summary>
/// specifying the size of the pooling window. /// specifying the size of the pooling window.
/// </summary> /// </summary>
[JsonProperty("pool_size")]
public Shape PoolSize { get; set; } public Shape PoolSize { get; set; }


/// <summary> /// <summary>
/// specifying the strides of the pooling operation. /// specifying the strides of the pooling operation.
/// </summary> /// </summary>
[JsonProperty("strides")]
public Shape Strides { get; set; } public Shape Strides { get; set; }


/// <summary> /// <summary>
/// The padding method, either 'valid' or 'same'. /// The padding method, either 'valid' or 'same'.
/// </summary> /// </summary>
[JsonProperty("padding")]
public string Padding { get; set; } = "valid"; public string Padding { get; set; } = "valid";


/// <summary> /// <summary>
/// one of `channels_last` (default) or `channels_first`. /// one of `channels_last` (default) or `channels_first`.
/// </summary> /// </summary>
[JsonProperty("data_format")]
public string DataFormat { get; set; } public string DataFormat { get; set; }
} }
} }

+ 1
- 1
src/TensorFlowNET.Core/Keras/ArgsDefinition/Preprocessing/PreprocessingLayerArgs.cs View File

@@ -4,7 +4,7 @@ using System.Text;


namespace Tensorflow.Keras.ArgsDefinition namespace Tensorflow.Keras.ArgsDefinition
{ {
public class PreprocessingLayerArgs : LayerArgs
public class PreprocessingLayerArgs : AutoSerializeLayerArgs
{ {
} }
} }

+ 12
- 0
src/TensorFlowNET.Core/Keras/ArgsDefinition/Preprocessing/RescalingArgs.cs View File

@@ -0,0 +1,12 @@
using Newtonsoft.Json;

namespace Tensorflow.Keras.ArgsDefinition
{
public class RescalingArgs : AutoSerializeLayerArgs
{
[JsonProperty("scale")]
public float Scale { get; set; }
[JsonProperty("offset")]
public float Offset { get; set; }
}
}

+ 1
- 0
src/TensorFlowNET.Core/Keras/ArgsDefinition/Preprocessing/ResizingArgs.cs View File

@@ -1,5 +1,6 @@
namespace Tensorflow.Keras.ArgsDefinition namespace Tensorflow.Keras.ArgsDefinition
{ {
// TODO: no corresponding class found in keras python, maybe obselete?
public class ResizingArgs : PreprocessingLayerArgs public class ResizingArgs : PreprocessingLayerArgs
{ {
public int Height { get; set; } public int Height { get; set; }


+ 10
- 1
src/TensorFlowNET.Core/Keras/ArgsDefinition/Preprocessing/TextVectorizationArgs.cs View File

@@ -1,4 +1,5 @@
using System;
using Newtonsoft.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;


@@ -6,11 +7,19 @@ namespace Tensorflow.Keras.ArgsDefinition
{ {
public class TextVectorizationArgs : PreprocessingLayerArgs public class TextVectorizationArgs : PreprocessingLayerArgs
{ {
[JsonProperty("standardize")]
public Func<Tensor, Tensor> Standardize { get; set; } public Func<Tensor, Tensor> Standardize { get; set; }
[JsonProperty("split")]
public string Split { get; set; } = "standardize"; public string Split { get; set; } = "standardize";
[JsonProperty("max_tokens")]
public int MaxTokens { get; set; } = -1; public int MaxTokens { get; set; } = -1;
[JsonProperty("output_mode")]
public string OutputMode { get; set; } = "int"; public string OutputMode { get; set; } = "int";
[JsonProperty("output_sequence_length")]
public int OutputSequenceLength { get; set; } = -1; public int OutputSequenceLength { get; set; } = -1;
[JsonProperty("vocabulary")]
public string[] Vocabulary { get; set; } public string[] Vocabulary { get; set; }

// TODO: Add `ngrams`, `sparse`, `ragged`, `idf_weights`, `encoding`
} }
} }

+ 7
- 2
src/TensorFlowNET.Core/Keras/ArgsDefinition/Regularization/DropoutArgs.cs View File

@@ -1,21 +1,26 @@
namespace Tensorflow.Keras.ArgsDefinition
using Newtonsoft.Json;

namespace Tensorflow.Keras.ArgsDefinition
{ {
public class DropoutArgs : LayerArgs
public class DropoutArgs : AutoSerializeLayerArgs
{ {
/// <summary> /// <summary>
/// Float between 0 and 1. Fraction of the input units to drop. /// Float between 0 and 1. Fraction of the input units to drop.
/// </summary> /// </summary>
[JsonProperty("rate")]
public float Rate { get; set; } public float Rate { get; set; }


/// <summary> /// <summary>
/// 1D integer tensor representing the shape of the /// 1D integer tensor representing the shape of the
/// binary dropout mask that will be multiplied with the input. /// binary dropout mask that will be multiplied with the input.
/// </summary> /// </summary>
[JsonProperty("noise_shape")]
public Shape NoiseShape { get; set; } public Shape NoiseShape { get; set; }


/// <summary> /// <summary>
/// random seed. /// random seed.
/// </summary> /// </summary>
[JsonProperty("seed")]
public int? Seed { get; set; } public int? Seed { get; set; }


public bool SupportsMasking { get; set; } public bool SupportsMasking { get; set; }


+ 0
- 8
src/TensorFlowNET.Core/Keras/ArgsDefinition/Rescaling/RescalingArgs.cs View File

@@ -1,8 +0,0 @@
namespace Tensorflow.Keras.ArgsDefinition
{
public class RescalingArgs : LayerArgs
{
public float Scale { get; set; }
public float Offset { get; set; }
}
}

+ 18
- 0
src/TensorFlowNET.Core/Keras/ArgsDefinition/Reshaping/Cropping2DArgs.cs View File

@@ -0,0 +1,18 @@
using Tensorflow.NumPy;

namespace Tensorflow.Keras.ArgsDefinition.Reshaping
{
public class Cropping2DArgs : LayerArgs
{
/// <summary>
/// channel last: (b, h, w, c)
/// channels_first: (b, c, h, w)
/// </summary>
public enum DataFormat { channels_first = 0, channels_last = 1 }
/// <summary>
/// Accept: int[1][2], int[1][1], int[2][2]
/// </summary>
public NDArray cropping { get; set; }
public DataFormat data_format { get; set; } = DataFormat.channels_last;
}
}

+ 18
- 0
src/TensorFlowNET.Core/Keras/ArgsDefinition/Reshaping/Cropping3DArgs.cs View File

@@ -0,0 +1,18 @@
using Tensorflow.NumPy;

namespace Tensorflow.Keras.ArgsDefinition.Reshaping
{
public class Cropping3DArgs : LayerArgs
{
/// <summary>
/// channel last: (b, h, w, c)
/// channels_first: (b, c, h, w)
/// </summary>
public enum DataFormat { channels_first = 0, channels_last = 1 }
/// <summary>
/// Accept: int[1][3], int[1][1], int[3][2]
/// </summary>
public NDArray cropping { get; set; }
public DataFormat data_format { get; set; } = DataFormat.channels_last;
}
}

+ 12
- 0
src/TensorFlowNET.Core/Keras/ArgsDefinition/Reshaping/CroppingArgs.cs View File

@@ -0,0 +1,12 @@
using Tensorflow.NumPy;

namespace Tensorflow.Keras.ArgsDefinition.Reshaping
{
public class Cropping1DArgs : LayerArgs
{
/// <summary>
/// Accept length 1 or 2
/// </summary>
public NDArray cropping { get; set; }
}
}

+ 8
- 4
src/TensorFlowNET.Core/Keras/ArgsDefinition/Reshaping/PermuteArgs.cs View File

@@ -1,5 +1,9 @@
namespace Tensorflow.Keras.ArgsDefinition {
public class PermuteArgs : LayerArgs {
public int[] dims { get; set; }
}
using Newtonsoft.Json;

namespace Tensorflow.Keras.ArgsDefinition {
public class PermuteArgs : AutoSerializeLayerArgs
{
[JsonProperty("dims")]
public int[] dims { get; set; }
}
} }

+ 5
- 2
src/TensorFlowNET.Core/Keras/ArgsDefinition/Reshaping/ReshapeArgs.cs View File

@@ -1,7 +1,10 @@
namespace Tensorflow.Keras.ArgsDefinition
using Newtonsoft.Json;

namespace Tensorflow.Keras.ArgsDefinition
{ {
public class ReshapeArgs : LayerArgs
public class ReshapeArgs : AutoSerializeLayerArgs
{ {
[JsonProperty("target_shape")]
public Shape TargetShape { get; set; } public Shape TargetShape { get; set; }
public object[] TargetShapeObjects { get; set; } public object[] TargetShapeObjects { get; set; }
} }


+ 7
- 2
src/TensorFlowNET.Core/Keras/ArgsDefinition/Reshaping/UpSampling2DArgs.cs View File

@@ -1,12 +1,17 @@
namespace Tensorflow.Keras.ArgsDefinition
using Newtonsoft.Json;

namespace Tensorflow.Keras.ArgsDefinition
{ {
public class UpSampling2DArgs : LayerArgs
public class UpSampling2DArgs : AutoSerializeLayerArgs
{ {
[JsonProperty("size")]
public Shape Size { get; set; } public Shape Size { get; set; }
[JsonProperty("data_format")]
public string DataFormat { get; set; } public string DataFormat { get; set; }
/// <summary> /// <summary>
/// 'nearest', 'bilinear' /// 'nearest', 'bilinear'
/// </summary> /// </summary>
[JsonProperty("interpolation")]
public string Interpolation { get; set; } = "nearest"; public string Interpolation { get; set; } = "nearest";
} }
} }

+ 1
- 0
src/TensorFlowNET.Core/Keras/ArgsDefinition/Reshaping/ZeroPadding2DArgs.cs View File

@@ -2,6 +2,7 @@


namespace Tensorflow.Keras.ArgsDefinition namespace Tensorflow.Keras.ArgsDefinition
{ {
// TODO: complete the implementation
public class ZeroPadding2DArgs : LayerArgs public class ZeroPadding2DArgs : LayerArgs
{ {
public NDArray Padding { get; set; } public NDArray Padding { get; set; }


src/TensorFlowNET.Core/Keras/ArgsDefinition/Lstm/LSTMArgs.cs → src/TensorFlowNET.Core/Keras/ArgsDefinition/Rnn/LSTMArgs.cs View File

@@ -1,9 +1,8 @@
using Tensorflow.Keras.ArgsDefinition.Rnn;

namespace Tensorflow.Keras.ArgsDefinition.Lstm
namespace Tensorflow.Keras.ArgsDefinition.Rnn
{ {
public class LSTMArgs : RNNArgs public class LSTMArgs : RNNArgs
{ {
// TODO: maybe change the `RNNArgs` and implement this class.
public bool UnitForgetBias { get; set; } public bool UnitForgetBias { get; set; }
public float Dropout { get; set; } public float Dropout { get; set; }
public float RecurrentDropout { get; set; } public float RecurrentDropout { get; set; }

+ 7
- 0
src/TensorFlowNET.Core/Keras/ArgsDefinition/Rnn/LSTMCellArgs.cs View File

@@ -0,0 +1,7 @@
namespace Tensorflow.Keras.ArgsDefinition.Rnn
{
// TODO: complete the implementation
public class LSTMCellArgs : LayerArgs
{
}
}

+ 12
- 3
src/TensorFlowNET.Core/Keras/ArgsDefinition/Rnn/RNNArgs.cs View File

@@ -1,21 +1,30 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Collections.Generic;


namespace Tensorflow.Keras.ArgsDefinition.Rnn namespace Tensorflow.Keras.ArgsDefinition.Rnn
{ {
public class RNNArgs : LayerArgs
public class RNNArgs : AutoSerializeLayerArgs
{ {
public interface IRnnArgCell : ILayer public interface IRnnArgCell : ILayer
{ {
object state_size { get; } object state_size { get; }
} }

[JsonProperty("cell")]
// TODO: the cell should be serialized with `serialize_keras_object`.
public IRnnArgCell Cell { get; set; } = null; public IRnnArgCell Cell { get; set; } = null;
[JsonProperty("return_sequences")]
public bool ReturnSequences { get; set; } = false; public bool ReturnSequences { get; set; } = false;
[JsonProperty("return_state")]
public bool ReturnState { get; set; } = false; public bool ReturnState { get; set; } = false;
[JsonProperty("go_backwards")]
public bool GoBackwards { get; set; } = false; public bool GoBackwards { get; set; } = false;
[JsonProperty("stateful")]
public bool Stateful { get; set; } = false; public bool Stateful { get; set; } = false;
[JsonProperty("unroll")]
public bool Unroll { get; set; } = false; public bool Unroll { get; set; } = false;
[JsonProperty("time_major")]
public bool TimeMajor { get; set; } = false; public bool TimeMajor { get; set; } = false;
// TODO: Add `num_constants` and `zero_output_for_mask`.
public Dictionary<string, object> Kwargs { get; set; } = null; public Dictionary<string, object> Kwargs { get; set; } = null;


public int Units { get; set; } public int Units { get; set; }


+ 1
- 1
src/TensorFlowNET.Core/Keras/Layers/ILayersApi.Cropping.cs View File

@@ -1,5 +1,5 @@
using System; using System;
using Tensorflow.Keras.ArgsDefinition;
using Tensorflow.Keras.ArgsDefinition.Reshaping;
using Tensorflow.NumPy; using Tensorflow.NumPy;


namespace Tensorflow.Keras.Layers namespace Tensorflow.Keras.Layers


+ 82
- 0
src/TensorFlowNET.Keras/Activations.cs View File

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Operations.Activation;
using static Tensorflow.Binding;

namespace Tensorflow.Keras
{
public class Activations
{
private static Dictionary<string, Activation> _nameActivationMap;
private static Dictionary<Activation, string> _activationNameMap;

private static Activation _linear = (features, name) => features;
private static Activation _relu = (features, name)
=> tf.Context.ExecuteOp("Relu", name, new ExecuteOpArgs(features));
private static Activation _sigmoid = (features, name)
=> tf.Context.ExecuteOp("Sigmoid", name, new ExecuteOpArgs(features));
private static Activation _softmax = (features, name)
=> tf.Context.ExecuteOp("Softmax", name, new ExecuteOpArgs(features));
private static Activation _tanh = (features, name)
=> tf.Context.ExecuteOp("Tanh", name, new ExecuteOpArgs(features));

/// <summary>
/// Register the name-activation mapping in this static class.
/// </summary>
/// <param name="name"></param>
/// <param name="Activation"></param>
private static void RegisterActivation(string name, Activation activation)
{
_nameActivationMap[name] = activation;
_activationNameMap[activation] = name;
}

static Activations()
{
_nameActivationMap = new Dictionary<string, Activation>();
_activationNameMap= new Dictionary<Activation, string>();

RegisterActivation("relu", _relu);
RegisterActivation("linear", _linear);
RegisterActivation("sigmoid", _sigmoid);
RegisterActivation("softmax", _softmax);
RegisterActivation("tanh", _tanh);
}

public Activation Linear => _linear;

public Activation Relu => _relu;

public Activation Sigmoid => _sigmoid;

public Activation Softmax => _softmax;

public Activation Tanh => _tanh;


public static Activation GetActivationByName(string name)
{
if (!_nameActivationMap.TryGetValue(name, out var res))
{
throw new Exception($"Activation {name} not found");
}
else
{
return res;
}
}

public static string GetNameByActivation(Activation activation)
{
if(!_activationNameMap.TryGetValue(activation, out var name))
{
throw new Exception($"Activation {activation} not found");
}
else
{
return name;
}
}
}
}

+ 0
- 10
src/TensorFlowNET.Keras/Activations/Activations.Linear.cs View File

@@ -1,10 +0,0 @@
namespace Tensorflow.Keras
{
public partial class Activations
{
/// <summary>
/// Linear activation function (pass-through).
/// </summary>
public Activation Linear = (features, name) => features;
}
}

+ 0
- 10
src/TensorFlowNET.Keras/Activations/Activations.Relu.cs View File

@@ -1,10 +0,0 @@
using static Tensorflow.Binding;

namespace Tensorflow.Keras
{
public partial class Activations
{
public Activation Relu = (features, name)
=> tf.Context.ExecuteOp("Relu", name, new ExecuteOpArgs(features));
}
}

+ 0
- 11
src/TensorFlowNET.Keras/Activations/Activations.Sigmoid.cs View File

@@ -1,11 +0,0 @@
using System;
using static Tensorflow.Binding;

namespace Tensorflow.Keras
{
public partial class Activations
{
public Activation Sigmoid = (features, name)
=> tf.Context.ExecuteOp("Sigmoid", name, new ExecuteOpArgs(features));
}
}

+ 0
- 11
src/TensorFlowNET.Keras/Activations/Activations.Softmax.cs View File

@@ -1,11 +0,0 @@
using System;
using static Tensorflow.Binding;

namespace Tensorflow.Keras
{
public partial class Activations
{
public Activation Softmax = (features, name)
=> tf.Context.ExecuteOp("Softmax", name, new ExecuteOpArgs(features));
}
}

+ 0
- 11
src/TensorFlowNET.Keras/Activations/Activations.Tanh.cs View File

@@ -1,11 +0,0 @@
using System;
using static Tensorflow.Binding;

namespace Tensorflow.Keras
{
public partial class Activations
{
public Activation Tanh = (features, name)
=> tf.Context.ExecuteOp("Tanh", name, new ExecuteOpArgs(features));
}
}

+ 1
- 0
src/TensorFlowNET.Keras/Layers/Attention/MultiHeadAttention.cs View File

@@ -1,4 +1,5 @@
using Tensorflow.Keras.ArgsDefinition; using Tensorflow.Keras.ArgsDefinition;
using Tensorflow.Keras.ArgsDefinition.Core;
using Tensorflow.Keras.Engine; using Tensorflow.Keras.Engine;
using Tensorflow.NumPy; using Tensorflow.NumPy;
using static Tensorflow.Binding; using static Tensorflow.Binding;


+ 1
- 1
src/TensorFlowNET.Keras/Layers/Core/EinsumDense.cs View File

@@ -4,8 +4,8 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Tensorflow.Keras.ArgsDefinition;
using Tensorflow.Keras.Engine; using Tensorflow.Keras.Engine;
using Tensorflow.Keras.ArgsDefinition.Core;


namespace Tensorflow.Keras.Layers namespace Tensorflow.Keras.Layers
{ {


+ 0
- 114
src/TensorFlowNET.Keras/Layers/Cropping/Cropping2D.cs View File

@@ -1,114 +0,0 @@
using Tensorflow.Keras.ArgsDefinition;
using Tensorflow.Keras.Engine;

namespace Tensorflow.Keras.Layers {
/// <summary>
/// Crop the input along axis 1 and 2.
/// <para> For example: </para>
/// <para> shape (1, 5, 5, 5) -- crop2D ((1, 2), (1, 3)) --> shape (1, 2, 1, 5) </para>
/// </summary>
public class Cropping2D : Layer {
Cropping2DArgs args;
public Cropping2D ( Cropping2DArgs args ) : base(args) {
this.args = args;
}
public override void build(Shape input_shape) {
built = true;
_buildInputShape = input_shape;
}
protected override Tensors Call ( Tensors inputs, Tensor state = null, bool? training = null ) {
Tensor output = inputs;
if ( output.rank != 4 ) {
// throw an ValueError exception
throw new ValueError("Expected dim=4, found dim=" + output.rank);
}
if ( args.cropping.shape == new Shape(1) ) {
int crop = args.cropping[0];
if ( args.data_format == Cropping2DArgs.DataFormat.channels_last ) {
output = output[new Slice(),
new Slice(crop, ( int ) output.shape[1] - crop),
new Slice(crop, ( int ) output.shape[2] - crop),
new Slice()];
}
else {
output = output[new Slice(),
new Slice(),
new Slice(crop, ( int ) output.shape[2] - crop),
new Slice(crop, ( int ) output.shape[3] - crop)];
}
}
// a tuple of 2 integers
else if ( args.cropping.shape == new Shape(2) ) {
int crop_1 = args.cropping[0];
int crop_2 = args.cropping[1];
if ( args.data_format == Cropping2DArgs.DataFormat.channels_last ) {
output = output[new Slice(),
new Slice(crop_1, ( int ) output.shape[1] - crop_1),
new Slice(crop_2, ( int ) output.shape[2] - crop_2),
new Slice()];
}
else {
output = output[new Slice(),
new Slice(),
new Slice(crop_1, ( int ) output.shape[2] - crop_1),
new Slice(crop_2, ( int ) output.shape[3] - crop_2)];
}
}
else if ( args.cropping.shape[0] == 2 && args.cropping.shape[1] == 2 ) {
int x_start = args.cropping[0, 0], x_end = args.cropping[0, 1];
int y_start = args.cropping[1, 0], y_end = args.cropping[1, 1];
if ( args.data_format == Cropping2DArgs.DataFormat.channels_last ) {
output = output[new Slice(),
new Slice(x_start, ( int ) output.shape[1] - x_end),
new Slice(y_start, ( int ) output.shape[2] - y_end),
new Slice()];
}
else {
output = output[new Slice(),
new Slice(),
new Slice(x_start, ( int ) output.shape[2] - x_end),
new Slice(y_start, ( int ) output.shape[3] - y_end)
];
}
}
return output;
}

public override Shape ComputeOutputShape ( Shape input_shape ) {
if ( args.cropping.shape == new Shape(1) ) {
int crop = args.cropping[0];
if ( args.data_format == Cropping2DArgs.DataFormat.channels_last ) {
return new Shape(( int ) input_shape[0], ( int ) input_shape[1] - crop * 2, ( int ) input_shape[2] - crop * 2, ( int ) input_shape[3]);
}
else {
return new Shape(( int ) input_shape[0], ( int ) input_shape[1], ( int ) input_shape[2] - crop * 2, ( int ) input_shape[3] - crop * 2);
}
}
// a tuple of 2 integers
else if ( args.cropping.shape == new Shape(2) ) {
int crop_1 = args.cropping[0], crop_2 = args.cropping[1];
if ( args.data_format == Cropping2DArgs.DataFormat.channels_last ) {
return new Shape(( int ) input_shape[0], ( int ) input_shape[1] - crop_1 * 2, ( int ) input_shape[2] - crop_2 * 2, ( int ) input_shape[3]);
}
else {
return new Shape(( int ) input_shape[0], ( int ) input_shape[1], ( int ) input_shape[2] - crop_1 * 2, ( int ) input_shape[3] - crop_2 * 2);
}
}
else if ( args.cropping.shape == new Shape(2, 2) ) {
int crop_1_start = args.cropping[0, 0], crop_1_end = args.cropping[0, 1];
int crop_2_start = args.cropping[1, 0], crop_2_end = args.cropping[1, 1];
if ( args.data_format == Cropping2DArgs.DataFormat.channels_last ) {
return new Shape(( int ) input_shape[0], ( int ) input_shape[1] - crop_1_start - crop_1_end,
( int ) input_shape[2] - crop_2_start - crop_2_end, ( int ) input_shape[3]);
}
else {
return new Shape(( int ) input_shape[0], ( int ) input_shape[1],
( int ) input_shape[2] - crop_1_start - crop_1_end, ( int ) input_shape[3] - crop_2_start - crop_2_end);
}
}
else {
throw new ValueError();
}
}
}
}

+ 0
- 124
src/TensorFlowNET.Keras/Layers/Cropping/Cropping3D.cs View File

@@ -1,124 +0,0 @@
using Tensorflow.Keras.ArgsDefinition;
using Tensorflow.Keras.Engine;

namespace Tensorflow.Keras.Layers {
/// <summary>
/// Similar to copping 2D
/// </summary>
public class Cropping3D : Layer {
Cropping3DArgs args;
public Cropping3D ( Cropping3DArgs args ) : base(args) {
this.args = args;
}

public override void build(Shape input_shape) {
built = true;
_buildInputShape = input_shape;
}

protected override Tensors Call ( Tensors inputs, Tensor state = null, bool? training = null ) {
Tensor output = inputs;
if ( output.rank != 5 ) {
// throw an ValueError exception
throw new ValueError("Expected dim=5, found dim=" + output.rank);
}

if ( args.cropping.shape == new Shape(1) ) {
int crop = args.cropping[0];
if ( args.data_format == Cropping3DArgs.DataFormat.channels_last ) {
output = output[new Slice(),
new Slice(crop, ( int ) output.shape[1] - crop),
new Slice(crop, ( int ) output.shape[2] - crop),
new Slice(crop, ( int ) output.shape[3] - crop),
new Slice()];
}
else {
output = output[new Slice(),
new Slice(),
new Slice(crop, ( int ) output.shape[2] - crop),
new Slice(crop, ( int ) output.shape[3] - crop),
new Slice(crop, ( int ) output.shape[4] - crop)];
}

}
// int[1][3] equivalent to a tuple of 3 integers
else if ( args.cropping.shape == new Shape(3) ) {
var crop_1 = args.cropping[0];
var crop_2 = args.cropping[1];
var crop_3 = args.cropping[2];
if ( args.data_format == Cropping3DArgs.DataFormat.channels_last ) {
output = output[new Slice(),
new Slice(crop_1, ( int ) output.shape[1] - crop_1),
new Slice(crop_2, ( int ) output.shape[2] - crop_2),
new Slice(crop_3, ( int ) output.shape[3] - crop_3),
new Slice()];
}
else {
output = output[new Slice(),
new Slice(),
new Slice(crop_1, ( int ) output.shape[2] - crop_1),
new Slice(crop_2, ( int ) output.shape[3] - crop_2),
new Slice(crop_3, ( int ) output.shape[4] - crop_3)];
}
}
else if ( args.cropping.shape[0] == 3 && args.cropping.shape[1] == 2 ) {
int x = args.cropping[0, 0], x_end = args.cropping[0, 1];
int y = args.cropping[1, 0], y_end = args.cropping[1, 1];
int z = args.cropping[2, 0], z_end = args.cropping[2, 1];
if ( args.data_format == Cropping3DArgs.DataFormat.channels_last ) {
output = output[new Slice(),
new Slice(x, ( int ) output.shape[1] - x_end),
new Slice(y, ( int ) output.shape[2] - y_end),
new Slice(z, ( int ) output.shape[3] - z_end),
new Slice()];
}
else {
output = output[new Slice(),
new Slice(),
new Slice(x, ( int ) output.shape[2] - x_end),
new Slice(y, ( int ) output.shape[3] - y_end),
new Slice(z, ( int ) output.shape[4] - z_end)
];
}
}
return output;
}
public override Shape ComputeOutputShape ( Shape input_shape ) {
if ( args.cropping.shape == new Shape(1) ) {
int crop = args.cropping[0];
if ( args.data_format == Cropping3DArgs.DataFormat.channels_last ) {
return new Shape(( int ) input_shape[0], ( int ) input_shape[1] - crop * 2, ( int ) input_shape[2] - crop * 2, ( int ) input_shape[3] - crop * 2, ( int ) input_shape[4]);
}
else {
return new Shape(( int ) input_shape[0], ( int ) input_shape[1], ( int ) input_shape[2] - crop * 2, ( int ) input_shape[3] - crop * 2, ( int ) input_shape[4] - crop * 2);
}
}
// int[1][3] equivalent to a tuple of 3 integers
else if ( args.cropping.shape == new Shape(3) ) {
var crop_start_1 = args.cropping[0];
var crop_start_2 = args.cropping[1];
var crop_start_3 = args.cropping[2];
if ( args.data_format == Cropping3DArgs.DataFormat.channels_last ) {
return new Shape(( int ) input_shape[0], ( int ) input_shape[1] - crop_start_1 * 2, ( int ) input_shape[2] - crop_start_2 * 2, ( int ) input_shape[3] - crop_start_3 * 2, ( int ) input_shape[4]);
}
else {
return new Shape(( int ) input_shape[0], ( int ) input_shape[1], ( int ) input_shape[2] - crop_start_1 * 2, ( int ) input_shape[3] - crop_start_2 * 2, ( int ) input_shape[4] - crop_start_3 * 2);
}
}
else if ( args.cropping.shape == new Shape(3, 2) ) {
int x = args.cropping[0, 0], x_end = args.cropping[0, 1];
int y = args.cropping[1, 0], y_end = args.cropping[1, 1];
int z = args.cropping[2, 0], z_end = args.cropping[2, 1];
if ( args.data_format == Cropping3DArgs.DataFormat.channels_last ) {
return new Shape(( int ) input_shape[0], ( int ) input_shape[1] - x - x_end, ( int ) input_shape[2] - y - y_end, ( int ) input_shape[3] - z - z_end, ( int ) input_shape[4]);
}
else {
return new Shape(( int ) input_shape[0], ( int ) input_shape[1], ( int ) input_shape[2] - x - x_end, ( int ) input_shape[3] - y - y_end, ( int ) input_shape[4] - z - z_end);
}
}
else {
throw new ValueError();
}
}
}
}

+ 6
- 4
src/TensorFlowNET.Keras/Layers/LayersApi.Cropping.cs View File

@@ -2,16 +2,18 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using Tensorflow.Keras.ArgsDefinition;
using Tensorflow.Keras.Layers.Reshaping;
using Tensorflow.Keras.ArgsDefinition.Reshaping;


namespace Tensorflow.Keras.Layers {
public partial class LayersApi {
namespace Tensorflow.Keras.Layers
{
public partial class LayersApi {
/// <summary> /// <summary>
/// Cropping layer for 1D input /// Cropping layer for 1D input
/// </summary> /// </summary>
/// <param name="cropping">cropping size</param> /// <param name="cropping">cropping size</param>
public ILayer Cropping1D ( NDArray cropping ) public ILayer Cropping1D ( NDArray cropping )
=> new Cropping1D(new CroppingArgs {
=> new Cropping1D(new Cropping1DArgs {
cropping = cropping cropping = cropping
}); });




+ 10
- 27
src/TensorFlowNET.Keras/Layers/LayersApi.cs View File

@@ -1,9 +1,8 @@
using System; using System;
using Tensorflow.Keras.ArgsDefinition; using Tensorflow.Keras.ArgsDefinition;
using Tensorflow.Keras.ArgsDefinition.Lstm;
using Tensorflow.Keras.ArgsDefinition.Core;
using Tensorflow.Keras.ArgsDefinition.Rnn; using Tensorflow.Keras.ArgsDefinition.Rnn;
using Tensorflow.Keras.Engine; using Tensorflow.Keras.Engine;
using Tensorflow.Keras.Layers.Lstm;
using Tensorflow.Keras.Layers.Rnn; using Tensorflow.Keras.Layers.Rnn;
using static Tensorflow.Binding; using static Tensorflow.Binding;
using static Tensorflow.KerasApi; using static Tensorflow.KerasApi;
@@ -108,7 +107,7 @@ namespace Tensorflow.Keras.Layers
DilationRate = dilation_rate, DilationRate = dilation_rate,
Groups = groups, Groups = groups,
UseBias = use_bias, UseBias = use_bias,
Activation = GetActivationByName(activation),
Activation = Activations.GetActivationByName(activation),
KernelInitializer = GetInitializerByName(kernel_initializer), KernelInitializer = GetInitializerByName(kernel_initializer),
BiasInitializer = GetInitializerByName(bias_initializer) BiasInitializer = GetInitializerByName(bias_initializer)
}); });
@@ -163,7 +162,7 @@ namespace Tensorflow.Keras.Layers
BiasInitializer = bias_initializer == null ? tf.zeros_initializer : bias_initializer, BiasInitializer = bias_initializer == null ? tf.zeros_initializer : bias_initializer,
BiasRegularizer = bias_regularizer, BiasRegularizer = bias_regularizer,
ActivityRegularizer = activity_regularizer, ActivityRegularizer = activity_regularizer,
Activation = activation ?? keras.activations.Linear
Activation = activation ?? keras.activations.Linear,
}); });


/// <summary> /// <summary>
@@ -210,7 +209,8 @@ namespace Tensorflow.Keras.Layers
UseBias = use_bias, UseBias = use_bias,
KernelInitializer = GetInitializerByName(kernel_initializer), KernelInitializer = GetInitializerByName(kernel_initializer),
BiasInitializer = GetInitializerByName(bias_initializer), BiasInitializer = GetInitializerByName(bias_initializer),
Activation = GetActivationByName(activation)
Activation = Activations.GetActivationByName(activation),
ActivationName = activation
}); });


/// <summary> /// <summary>
@@ -255,7 +255,7 @@ namespace Tensorflow.Keras.Layers
UseBias = use_bias, UseBias = use_bias,
KernelInitializer = GetInitializerByName(kernel_initializer), KernelInitializer = GetInitializerByName(kernel_initializer),
BiasInitializer = GetInitializerByName(bias_initializer), BiasInitializer = GetInitializerByName(bias_initializer),
Activation = GetActivationByName(activation)
Activation = Activations.GetActivationByName(activation)
}); });


/// <summary> /// <summary>
@@ -300,7 +300,7 @@ namespace Tensorflow.Keras.Layers
=> new Dense(new DenseArgs => new Dense(new DenseArgs
{ {
Units = units, Units = units,
Activation = GetActivationByName("linear"),
Activation = Activations.GetActivationByName("linear"),
ActivationName = "linear" ActivationName = "linear"
}); });


@@ -321,7 +321,7 @@ namespace Tensorflow.Keras.Layers
=> new Dense(new DenseArgs => new Dense(new DenseArgs
{ {
Units = units, Units = units,
Activation = GetActivationByName(activation),
Activation = Activations.GetActivationByName(activation),
ActivationName = activation, ActivationName = activation,
InputShape = input_shape InputShape = input_shape
}); });
@@ -666,7 +666,7 @@ namespace Tensorflow.Keras.Layers
=> new SimpleRNN(new SimpleRNNArgs => new SimpleRNN(new SimpleRNNArgs
{ {
Units = units, Units = units,
Activation = GetActivationByName(activation),
Activation = Activations.GetActivationByName(activation),
KernelInitializer = GetInitializerByName(kernel_initializer), KernelInitializer = GetInitializerByName(kernel_initializer),
RecurrentInitializer = GetInitializerByName(recurrent_initializer), RecurrentInitializer = GetInitializerByName(recurrent_initializer),
BiasInitializer = GetInitializerByName(bias_initializer), BiasInitializer = GetInitializerByName(bias_initializer),
@@ -814,24 +814,7 @@ namespace Tensorflow.Keras.Layers
public ILayer GlobalMaxPooling2D(string data_format = "channels_last") public ILayer GlobalMaxPooling2D(string data_format = "channels_last")
=> new GlobalMaxPooling2D(new Pooling2DArgs { DataFormat = data_format }); => new GlobalMaxPooling2D(new Pooling2DArgs { DataFormat = data_format });



/// <summary>
/// Get an activation function layer from its name.
/// </summary>
/// <param name="name">The name of the activation function. One of linear, relu, sigmoid, and tanh.</param>
/// <returns></returns>

Activation GetActivationByName(string name)
=> name switch
{
"linear" => keras.activations.Linear,
"relu" => keras.activations.Relu,
"sigmoid" => keras.activations.Sigmoid,
"tanh" => keras.activations.Tanh,
"softmax" => keras.activations.Softmax,
_ => throw new Exception($"Activation {name} not found")
};

Activation GetActivationByName(string name) => Activations.GetActivationByName(name);
/// <summary> /// <summary>
/// Get an weights initializer from its name. /// Get an weights initializer from its name.
/// </summary> /// </summary>


+ 1
- 1
src/TensorFlowNET.Keras/Layers/Normalization/BatchNormalization.cs View File

@@ -58,7 +58,7 @@ namespace Tensorflow.Keras.Layers
var ndims = input_shape.ndim; var ndims = input_shape.ndim;
foreach (var (idx, x) in enumerate(axis)) foreach (var (idx, x) in enumerate(axis))
if (x < 0) if (x < 0)
axis[idx] = ndims + x;
args.Axis.dims[idx] = axis[idx] = ndims + x;


fused = ndims == 4; fused = ndims == 4;




src/TensorFlowNET.Keras/Layers/Rescaling/Rescaling.cs → src/TensorFlowNET.Keras/Layers/Preprocessing/Rescaling.cs View File


src/TensorFlowNET.Keras/Layers/Cropping/Cropping1D.cs → src/TensorFlowNET.Keras/Layers/Reshaping/Cropping1D.cs View File

@@ -1,11 +1,12 @@
using Tensorflow.Keras.ArgsDefinition;
using Tensorflow.Keras.ArgsDefinition.Reshaping;
using Tensorflow.Keras.Engine; using Tensorflow.Keras.Engine;


namespace Tensorflow.Keras.Layers {
namespace Tensorflow.Keras.Layers.Reshaping
{
public class Cropping1D : Layer public class Cropping1D : Layer
{ {
CroppingArgs args;
public Cropping1D(CroppingArgs args) : base(args)
Cropping1DArgs args;
public Cropping1D(Cropping1DArgs args) : base(args)
{ {
this.args = args; this.args = args;
} }
@@ -41,7 +42,7 @@ namespace Tensorflow.Keras.Layers {
else else
{ {
int crop_start = args.cropping[0], crop_end = args.cropping[1]; int crop_start = args.cropping[0], crop_end = args.cropping[1];
output = output[new Slice(), new Slice(crop_start, (int)(output.shape[1]) - crop_end), new Slice()];
output = output[new Slice(), new Slice(crop_start, (int)output.shape[1] - crop_end), new Slice()];
} }
return output; return output;
} }
@@ -51,12 +52,12 @@ namespace Tensorflow.Keras.Layers {
if (args.cropping.shape[0] == 1) if (args.cropping.shape[0] == 1)
{ {
int crop = args.cropping[0]; int crop = args.cropping[0];
return new Shape((int)(input_shape[0]), (int)(input_shape[1] - crop * 2), (int)(input_shape[2]));
return new Shape((int)input_shape[0], (int)(input_shape[1] - crop * 2), (int)input_shape[2]);
} }
else else
{ {
int crop_start = args.cropping[0], crop_end = args.cropping[1]; int crop_start = args.cropping[0], crop_end = args.cropping[1];
return new Shape((int)(input_shape[0]), (int)(input_shape[1] - crop_start - crop_end), (int)(input_shape[2]));
return new Shape((int)input_shape[0], (int)(input_shape[1] - crop_start - crop_end), (int)input_shape[2]);
} }
} }
} }

+ 140
- 0
src/TensorFlowNET.Keras/Layers/Reshaping/Cropping2D.cs View File

@@ -0,0 +1,140 @@
using Tensorflow.Keras.ArgsDefinition.Reshaping;
using Tensorflow.Keras.Engine;

namespace Tensorflow.Keras.Layers.Reshaping
{
/// <summary>
/// Crop the input along axis 1 and 2.
/// <para> For example: </para>
/// <para> shape (1, 5, 5, 5) -- crop2D ((1, 2), (1, 3)) --> shape (1, 2, 1, 5) </para>
/// </summary>
public class Cropping2D : Layer
{
Cropping2DArgs args;
public Cropping2D(Cropping2DArgs args) : base(args)
{
this.args = args;
}
public override void build(Shape input_shape)
{
built = true;
_buildInputShape = input_shape;
}
protected override Tensors Call(Tensors inputs, Tensor state = null, bool? training = null)
{
Tensor output = inputs;
if (output.rank != 4)
{
// throw an ValueError exception
throw new ValueError("Expected dim=4, found dim=" + output.rank);
}
if (args.cropping.shape == new Shape(1))
{
int crop = args.cropping[0];
if (args.data_format == Cropping2DArgs.DataFormat.channels_last)
{
output = output[new Slice(),
new Slice(crop, (int)output.shape[1] - crop),
new Slice(crop, (int)output.shape[2] - crop),
new Slice()];
}
else
{
output = output[new Slice(),
new Slice(),
new Slice(crop, (int)output.shape[2] - crop),
new Slice(crop, (int)output.shape[3] - crop)];
}
}
// a tuple of 2 integers
else if (args.cropping.shape == new Shape(2))
{
int crop_1 = args.cropping[0];
int crop_2 = args.cropping[1];
if (args.data_format == Cropping2DArgs.DataFormat.channels_last)
{
output = output[new Slice(),
new Slice(crop_1, (int)output.shape[1] - crop_1),
new Slice(crop_2, (int)output.shape[2] - crop_2),
new Slice()];
}
else
{
output = output[new Slice(),
new Slice(),
new Slice(crop_1, (int)output.shape[2] - crop_1),
new Slice(crop_2, (int)output.shape[3] - crop_2)];
}
}
else if (args.cropping.shape[0] == 2 && args.cropping.shape[1] == 2)
{
int x_start = args.cropping[0, 0], x_end = args.cropping[0, 1];
int y_start = args.cropping[1, 0], y_end = args.cropping[1, 1];
if (args.data_format == Cropping2DArgs.DataFormat.channels_last)
{
output = output[new Slice(),
new Slice(x_start, (int)output.shape[1] - x_end),
new Slice(y_start, (int)output.shape[2] - y_end),
new Slice()];
}
else
{
output = output[new Slice(),
new Slice(),
new Slice(x_start, (int)output.shape[2] - x_end),
new Slice(y_start, (int)output.shape[3] - y_end)
];
}
}
return output;
}

public override Shape ComputeOutputShape(Shape input_shape)
{
if (args.cropping.shape == new Shape(1))
{
int crop = args.cropping[0];
if (args.data_format == Cropping2DArgs.DataFormat.channels_last)
{
return new Shape((int)input_shape[0], (int)input_shape[1] - crop * 2, (int)input_shape[2] - crop * 2, (int)input_shape[3]);
}
else
{
return new Shape((int)input_shape[0], (int)input_shape[1], (int)input_shape[2] - crop * 2, (int)input_shape[3] - crop * 2);
}
}
// a tuple of 2 integers
else if (args.cropping.shape == new Shape(2))
{
int crop_1 = args.cropping[0], crop_2 = args.cropping[1];
if (args.data_format == Cropping2DArgs.DataFormat.channels_last)
{
return new Shape((int)input_shape[0], (int)input_shape[1] - crop_1 * 2, (int)input_shape[2] - crop_2 * 2, (int)input_shape[3]);
}
else
{
return new Shape((int)input_shape[0], (int)input_shape[1], (int)input_shape[2] - crop_1 * 2, (int)input_shape[3] - crop_2 * 2);
}
}
else if (args.cropping.shape == new Shape(2, 2))
{
int crop_1_start = args.cropping[0, 0], crop_1_end = args.cropping[0, 1];
int crop_2_start = args.cropping[1, 0], crop_2_end = args.cropping[1, 1];
if (args.data_format == Cropping2DArgs.DataFormat.channels_last)
{
return new Shape((int)input_shape[0], (int)input_shape[1] - crop_1_start - crop_1_end,
(int)input_shape[2] - crop_2_start - crop_2_end, (int)input_shape[3]);
}
else
{
return new Shape((int)input_shape[0], (int)input_shape[1],
(int)input_shape[2] - crop_1_start - crop_1_end, (int)input_shape[3] - crop_2_start - crop_2_end);
}
}
else
{
throw new ValueError();
}
}
}
}

+ 150
- 0
src/TensorFlowNET.Keras/Layers/Reshaping/Cropping3D.cs View File

@@ -0,0 +1,150 @@
using Tensorflow.Keras.ArgsDefinition.Reshaping;
using Tensorflow.Keras.Engine;

namespace Tensorflow.Keras.Layers.Reshaping
{
/// <summary>
/// Similar to copping 2D
/// </summary>
public class Cropping3D : Layer
{
Cropping3DArgs args;
public Cropping3D(Cropping3DArgs args) : base(args)
{
this.args = args;
}

public override void build(Shape input_shape)
{
built = true;
_buildInputShape = input_shape;
}

protected override Tensors Call(Tensors inputs, Tensor state = null, bool? training = null)
{
Tensor output = inputs;
if (output.rank != 5)
{
// throw an ValueError exception
throw new ValueError("Expected dim=5, found dim=" + output.rank);
}

if (args.cropping.shape == new Shape(1))
{
int crop = args.cropping[0];
if (args.data_format == Cropping3DArgs.DataFormat.channels_last)
{
output = output[new Slice(),
new Slice(crop, (int)output.shape[1] - crop),
new Slice(crop, (int)output.shape[2] - crop),
new Slice(crop, (int)output.shape[3] - crop),
new Slice()];
}
else
{
output = output[new Slice(),
new Slice(),
new Slice(crop, (int)output.shape[2] - crop),
new Slice(crop, (int)output.shape[3] - crop),
new Slice(crop, (int)output.shape[4] - crop)];
}

}
// int[1][3] equivalent to a tuple of 3 integers
else if (args.cropping.shape == new Shape(3))
{
var crop_1 = args.cropping[0];
var crop_2 = args.cropping[1];
var crop_3 = args.cropping[2];
if (args.data_format == Cropping3DArgs.DataFormat.channels_last)
{
output = output[new Slice(),
new Slice(crop_1, (int)output.shape[1] - crop_1),
new Slice(crop_2, (int)output.shape[2] - crop_2),
new Slice(crop_3, (int)output.shape[3] - crop_3),
new Slice()];
}
else
{
output = output[new Slice(),
new Slice(),
new Slice(crop_1, (int)output.shape[2] - crop_1),
new Slice(crop_2, (int)output.shape[3] - crop_2),
new Slice(crop_3, (int)output.shape[4] - crop_3)];
}
}
else if (args.cropping.shape[0] == 3 && args.cropping.shape[1] == 2)
{
int x = args.cropping[0, 0], x_end = args.cropping[0, 1];
int y = args.cropping[1, 0], y_end = args.cropping[1, 1];
int z = args.cropping[2, 0], z_end = args.cropping[2, 1];
if (args.data_format == Cropping3DArgs.DataFormat.channels_last)
{
output = output[new Slice(),
new Slice(x, (int)output.shape[1] - x_end),
new Slice(y, (int)output.shape[2] - y_end),
new Slice(z, (int)output.shape[3] - z_end),
new Slice()];
}
else
{
output = output[new Slice(),
new Slice(),
new Slice(x, (int)output.shape[2] - x_end),
new Slice(y, (int)output.shape[3] - y_end),
new Slice(z, (int)output.shape[4] - z_end)
];
}
}
return output;
}
public override Shape ComputeOutputShape(Shape input_shape)
{
if (args.cropping.shape == new Shape(1))
{
int crop = args.cropping[0];
if (args.data_format == Cropping3DArgs.DataFormat.channels_last)
{
return new Shape((int)input_shape[0], (int)input_shape[1] - crop * 2, (int)input_shape[2] - crop * 2, (int)input_shape[3] - crop * 2, (int)input_shape[4]);
}
else
{
return new Shape((int)input_shape[0], (int)input_shape[1], (int)input_shape[2] - crop * 2, (int)input_shape[3] - crop * 2, (int)input_shape[4] - crop * 2);
}
}
// int[1][3] equivalent to a tuple of 3 integers
else if (args.cropping.shape == new Shape(3))
{
var crop_start_1 = args.cropping[0];
var crop_start_2 = args.cropping[1];
var crop_start_3 = args.cropping[2];
if (args.data_format == Cropping3DArgs.DataFormat.channels_last)
{
return new Shape((int)input_shape[0], (int)input_shape[1] - crop_start_1 * 2, (int)input_shape[2] - crop_start_2 * 2, (int)input_shape[3] - crop_start_3 * 2, (int)input_shape[4]);
}
else
{
return new Shape((int)input_shape[0], (int)input_shape[1], (int)input_shape[2] - crop_start_1 * 2, (int)input_shape[3] - crop_start_2 * 2, (int)input_shape[4] - crop_start_3 * 2);
}
}
else if (args.cropping.shape == new Shape(3, 2))
{
int x = args.cropping[0, 0], x_end = args.cropping[0, 1];
int y = args.cropping[1, 0], y_end = args.cropping[1, 1];
int z = args.cropping[2, 0], z_end = args.cropping[2, 1];
if (args.data_format == Cropping3DArgs.DataFormat.channels_last)
{
return new Shape((int)input_shape[0], (int)input_shape[1] - x - x_end, (int)input_shape[2] - y - y_end, (int)input_shape[3] - z - z_end, (int)input_shape[4]);
}
else
{
return new Shape((int)input_shape[0], (int)input_shape[1], (int)input_shape[2] - x - x_end, (int)input_shape[3] - y - y_end, (int)input_shape[4] - z - z_end);
}
}
else
{
throw new ValueError();
}
}
}
}

src/TensorFlowNET.Keras/Layers/Lstm/LSTM.cs → src/TensorFlowNET.Keras/Layers/Rnn/LSTM.cs View File

@@ -1,9 +1,8 @@
using System.Linq; using System.Linq;
using Tensorflow.Keras.ArgsDefinition.Lstm;
using Tensorflow.Keras.ArgsDefinition.Rnn;
using Tensorflow.Keras.Engine; using Tensorflow.Keras.Engine;
using Tensorflow.Keras.Layers.Rnn;


namespace Tensorflow.Keras.Layers.Lstm
namespace Tensorflow.Keras.Layers.Rnn
{ {
/// <summary> /// <summary>
/// Long Short-Term Memory layer - Hochreiter 1997. /// Long Short-Term Memory layer - Hochreiter 1997.

src/TensorFlowNET.Keras/Layers/Lstm/LSTMCell.cs → src/TensorFlowNET.Keras/Layers/Rnn/LSTMCell.cs View File

@@ -1,7 +1,7 @@
using Tensorflow.Keras.ArgsDefinition.Lstm;
using Tensorflow.Keras.ArgsDefinition.Rnn;
using Tensorflow.Keras.Engine; using Tensorflow.Keras.Engine;


namespace Tensorflow.Keras.Layers.Lstm
namespace Tensorflow.Keras.Layers.Rnn
{ {
public class LSTMCell : Layer public class LSTMCell : Layer
{ {

+ 0
- 1
src/TensorFlowNET.Keras/Layers/Rnn/RNN.cs View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using Tensorflow.Keras.ArgsDefinition; using Tensorflow.Keras.ArgsDefinition;
using Tensorflow.Keras.ArgsDefinition.Rnn; using Tensorflow.Keras.ArgsDefinition.Rnn;
using Tensorflow.Keras.Engine; using Tensorflow.Keras.Engine;
using Tensorflow.Keras.Layers.Lstm;
// from tensorflow.python.distribute import distribution_strategy_context as ds_context; // from tensorflow.python.distribute import distribution_strategy_context as ds_context;


namespace Tensorflow.Keras.Layers.Rnn namespace Tensorflow.Keras.Layers.Rnn


+ 0
- 82
test/TensorFlowNET.Keras.UnitTest/SaveModel/SequentialModelTest.cs View File

@@ -1,82 +0,0 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Tensorflow.NumPy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tensorflow;
using static Tensorflow.Binding;
using static Tensorflow.KerasApi;
using Tensorflow.Keras;
using Tensorflow.Keras.ArgsDefinition;
using Tensorflow.Keras.Engine;
using Tensorflow.Keras.Layers;
using Tensorflow.Keras.Losses;
using Tensorflow.Keras.Metrics;
using Tensorflow.Keras.Optimizers;
using Tensorflow.Operations;

namespace TensorFlowNET.Keras.UnitTest.SaveModel;

[TestClass]
public class SequentialModelTest
{
[TestMethod]
public void SimpleModelFromAutoCompile()
{
var inputs = new KerasInterface().Input((28, 28, 1));
var x = new Flatten(new FlattenArgs()).Apply(inputs);
x = new Dense(new DenseArgs() { Units = 100, Activation = tf.nn.relu }).Apply(x);
x = new LayersApi().Dense(units: 10).Apply(x);
var outputs = new LayersApi().Softmax(axis: 1).Apply(x);
var model = new KerasInterface().Model(inputs, outputs);

model.compile(new Adam(0.001f), new LossesApi().SparseCategoricalCrossentropy(), new string[] { "accuracy" });

var data_loader = new MnistModelLoader();
var num_epochs = 1;
var batch_size = 50;

var dataset = data_loader.LoadAsync(new ModelLoadSetting
{
TrainDir = "mnist",
OneHot = false,
ValidationSize = 10000,
}).Result;

model.fit(dataset.Train.Data, dataset.Train.Labels, batch_size, num_epochs);

model.save("C:\\Work\\tf.net\\tf_test\\tf.net.simple.compile", save_format: "tf");
}

[TestMethod]
public void SimpleModelFromSequential()
{
Model model = KerasApi.keras.Sequential(new List<ILayer>()
{
keras.layers.InputLayer((28, 28, 1)),
keras.layers.Flatten(),
keras.layers.Dense(100, "relu"),
keras.layers.Dense(10),
keras.layers.Softmax(1)
});

model.compile(new Adam(0.001f), new LossesApi().SparseCategoricalCrossentropy(), new string[] { "accuracy" });

var data_loader = new MnistModelLoader();
var num_epochs = 1;
var batch_size = 50;

var dataset = data_loader.LoadAsync(new ModelLoadSetting
{
TrainDir = "mnist",
OneHot = false,
ValidationSize = 10000,
}).Result;

model.fit(dataset.Train.Data, dataset.Train.Labels, batch_size, num_epochs);

model.save("C:\\Work\\tf.net\\tf_test\\tf.net.simple.sequential", save_format: "tf");
}
}

Loading…
Cancel
Save