diff --git a/src/TensorFlowNET.Core/Framework/common_shapes.py.cs b/src/TensorFlowNET.Core/Framework/common_shapes.py.cs new file mode 100644 index 00000000..3fa9f6bf --- /dev/null +++ b/src/TensorFlowNET.Core/Framework/common_shapes.py.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tensorflow.Framework +{ + public static class common_shapes + { + /// + /// Returns the broadcasted shape between `shape_x` and `shape_y + /// + /// + /// + public static Tensor broadcast_shape(Tensor shape_x, Tensor shape_y) + { + var return_dims = _broadcast_shape_helper(shape_x, shape_y); + // return tensor_shape(return_dims); + throw new NotFiniteNumberException(); + } + /// + /// Helper functions for is_broadcast_compatible and broadcast_shape. + /// + /// A `TensorShape` + /// A `TensorShape` + /// Returns None if the shapes are not broadcast compatible, + /// a list of the broadcast dimensions otherwise. + /// + public static Tensor _broadcast_shape_helper(Tensor shape_x, Tensor shape_y) + { + throw new NotFiniteNumberException(); + } + } +} diff --git a/src/TensorFlowNET.Core/Operations/Distributions/DistributionEnum.cs b/src/TensorFlowNET.Core/Operations/Distributions/DistributionEnum.cs new file mode 100644 index 00000000..69a62d27 --- /dev/null +++ b/src/TensorFlowNET.Core/Operations/Distributions/DistributionEnum.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Tensorflow; + +namespace Tensorflow.Operations.Distributions +{ + public enum DistributionEnum + { + + + + } +} diff --git a/src/TensorFlowNET.Core/Operations/Distributions/distribution.py.cs b/src/TensorFlowNET.Core/Operations/Distributions/distribution.py.cs index 984dc2a9..7d9aef11 100644 --- a/src/TensorFlowNET.Core/Operations/Distributions/distribution.py.cs +++ b/src/TensorFlowNET.Core/Operations/Distributions/distribution.py.cs @@ -6,7 +6,7 @@ using System.Text; namespace Tensorflow { - abstract class _BaseDistribution : Object + abstract class _BaseDistribution : Python { // Abstract base class needed for resolving subclass hierarchy. } @@ -22,8 +22,8 @@ namespace Tensorflow public ReparameterizationType _reparameterization_type {get;set;} public bool _validate_args {get;set;} public bool _allow_nan_stats {get;set;} - public Dictionary _parameters {get;set;} - public List _graph_parents {get;set;} + public Dictionary _parameters {get;set;} + public List _graph_parents {get;set;} public string _name {get;set;} /// @@ -82,7 +82,21 @@ namespace Tensorflow /// class ReparameterizationType { + public string _rep_type { get; set; } + public ReparameterizationType(string rep_type) + { + this._rep_type = rep_type; + } + public void repr() + { + Console.WriteLine($"" ); + } + + public bool eq (ReparameterizationType other) + { + return this.Equals(other); + } } diff --git a/src/TensorFlowNET.Core/Operations/Distributions/normal.py.cs b/src/TensorFlowNET.Core/Operations/Distributions/normal.py.cs index 67bc2ea8..d588fab7 100644 --- a/src/TensorFlowNET.Core/Operations/Distributions/normal.py.cs +++ b/src/TensorFlowNET.Core/Operations/Distributions/normal.py.cs @@ -1,10 +1,80 @@ +using System.Collections.Generic; + namespace Tensorflow { class Normal : Distribution { - public Normal (Tensor loc, Tensor scale, bool validate_args=false, bool allow_nan_stats=true, string name="Normal") + public Tensor _loc { get; set; } + public Tensor _scale { get; set; } + + Dictionary parameters = new Dictionary(); + /// + /// The Normal distribution with location `loc` and `scale` parameters. + /// Mathematical details + /// The probability density function(pdf) is, + /// ''' + /// pdf(x; mu, sigma) = exp(-0.5 (x - mu)**2 / sigma**2) / Z + /// Z = (2 pi sigma**2)**0.5 + /// ''' + /// where `loc = mu` is the mean, `scale = sigma` is the std.deviation, and, `Z` + /// is the normalization constant. + /// + /// + /// + /// + /// + /// + public Normal (Tensor loc, Tensor scale, bool validate_args=false, bool allow_nan_stats=true, string name="Normal") + { + parameters.Add("name", name); + parameters.Add("loc", loc); + parameters.Add("scale", scale); + parameters.Add("validate_args", validate_args); + parameters.Add("allow_nan_stats", allow_nan_stats); + + with(new ops.name_scope(name, "", new { loc, scale }), scope => + { + with(ops.control_dependencies(validate_args ? new Operation[] { scale.op} : new Operation[] { }), cd => + { + this._loc = array_ops.identity(loc, name); + this._scale = array_ops.identity(scale, name); + base._dtype = this._scale.dtype; + base._reparameterization_type = new ReparameterizationType("FULLY_REPARAMETERIZED"); + base._validate_args = validate_args; + base._allow_nan_stats = allow_nan_stats; + base._parameters = parameters; + base._graph_parents = new List(new Tensor[] { this._loc, this._scale }); + base._name = name; + }); + + }); + + } + /// + /// Distribution parameter for the mean. + /// + /// + public Tensor loc() + { + return this._loc; + } + /// + /// Distribution parameter for standard deviation." + /// + /// + public Tensor scale() + { + return this._scale; + } + + public Tensor _batch_shape_tensor() + { + return array_ops.broadcast_dynamic_shape(array_ops.shape(this._loc), array_ops.shape(this._scale)); + } + + public Tensor _batch_shape() { - + return array_ops.broadcast_static_shape(new Tensor(this._loc.shape), new Tensor(this._scale.shape)); } } diff --git a/src/TensorFlowNET.Core/Operations/array_ops.py.cs b/src/TensorFlowNET.Core/Operations/array_ops.py.cs index 6f8f2f05..66574dae 100644 --- a/src/TensorFlowNET.Core/Operations/array_ops.py.cs +++ b/src/TensorFlowNET.Core/Operations/array_ops.py.cs @@ -239,5 +239,34 @@ namespace Tensorflow { return gen_array_ops.squeeze(input, axis, name); } + + public static Tensor identity(Tensor input, string name = null) + { + return gen_array_ops.identity(input, name); + } + /// + /// Computes the shape of a broadcast given symbolic shapes. + /// When shape_x and shape_y are Tensors representing shapes(i.e.the result of + /// calling tf.shape on another Tensor) this computes a Tensor which is the shape + /// of the result of a broadcasting op applied in tensors of shapes shape_x and + /// shape_y. + /// For example, if shape_x is [1, 2, 3] and shape_y is [5, 1, 3], the result is a + /// Tensor whose value is [5, 2, 3]. + /// This is useful when validating the result of a broadcasting operation when the + /// tensors do not have statically known shapes. + /// + /// A rank 1 integer `Tensor`, representing the shape of x. + /// A rank 1 integer `Tensor`, representing the shape of y. + /// A rank 1 integer `Tensor` representing the broadcasted shape. + public static Tensor broadcast_dynamic_shape(Tensor shape_x, Tensor shape_y) + { + return gen_array_ops.broadcast_args(shape_x, shape_y); + } + + public static Tensor broadcast_static_shape(Tensor shape_x, Tensor shape_y) + { + return Framework.common_shapes.broadcast_shape(shape_x, shape_y); + } + } } diff --git a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs index 2a4617e4..80884393 100644 --- a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs +++ b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs @@ -178,5 +178,21 @@ namespace Tensorflow return _op.outputs[0]; } + + /// + /// Return the shape of s0 op s1 with broadcast. + /// Given `s0` and `s1`, tensors that represent shapes, compute `r0`, the + /// broadcasted shape. `s0`, `s1` and `r0` are all integer vectors. + /// + /// A `Tensor`. Must be one of the following types: `int32`, `int64`. + /// A `Tensor`. Must have the same type as `s0`. + /// A name for the operation (optional). + /// `Tensor`. Has the same type as `s0`. + public static Tensor broadcast_args(Tensor s0, Tensor s1, string name = null) + { + var _op = _op_def_lib._apply_op_helper("BroadcastArgs", name, args: new { s0, s1, name }); + + return _op.outputs[0]; + } } }