add Convolution class add convert_data_format add as_numpy_dtypetags/v0.8.0
| @@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Core", "src\T | |||||
| EndProject | EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Visualization", "src\TensorFlowNET.Visualization\TensorFlowNET.Visualization.csproj", "{0254BFF9-453C-4FE0-9609-3644559A79CE}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Visualization", "src\TensorFlowNET.Visualization\TensorFlowNET.Visualization.csproj", "{0254BFF9-453C-4FE0-9609-3644559A79CE}" | ||||
| EndProject | EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NumSharp.Core", "..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj", "{3EEAFB06-BEF0-4261-BAAB-630EABD25290}" | |||||
| EndProject | |||||
| Global | Global | ||||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| Debug|Any CPU = Debug|Any CPU | Debug|Any CPU = Debug|Any CPU | ||||
| @@ -33,6 +35,10 @@ Global | |||||
| {0254BFF9-453C-4FE0-9609-3644559A79CE}.Debug|Any CPU.Build.0 = Debug|Any CPU | {0254BFF9-453C-4FE0-9609-3644559A79CE}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| {0254BFF9-453C-4FE0-9609-3644559A79CE}.Release|Any CPU.ActiveCfg = Release|Any CPU | {0254BFF9-453C-4FE0-9609-3644559A79CE}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| {0254BFF9-453C-4FE0-9609-3644559A79CE}.Release|Any CPU.Build.0 = Release|Any CPU | {0254BFF9-453C-4FE0-9609-3644559A79CE}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| {3EEAFB06-BEF0-4261-BAAB-630EABD25290}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
| {3EEAFB06-BEF0-4261-BAAB-630EABD25290}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
| {3EEAFB06-BEF0-4261-BAAB-630EABD25290}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
| {3EEAFB06-BEF0-4261-BAAB-630EABD25290}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
| EndGlobalSection | EndGlobalSection | ||||
| GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
| HideSolutionNode = FALSE | HideSolutionNode = FALSE | ||||
| @@ -21,6 +21,7 @@ namespace Tensorflow | |||||
| public int _version; | public int _version; | ||||
| private int _next_id_counter; | private int _next_id_counter; | ||||
| private List<String> _unfetchable_ops = new List<string>(); | private List<String> _unfetchable_ops = new List<string>(); | ||||
| private List<Tensor> _unfeedable_tensors = new List<Tensor>(); | |||||
| public string _name_stack = ""; | public string _name_stack = ""; | ||||
| public string _graph_key; | public string _graph_key; | ||||
| @@ -366,6 +367,11 @@ namespace Tensorflow | |||||
| return _collections[name]; | return _collections[name]; | ||||
| } | } | ||||
| public void prevent_feeding(Tensor tensor) | |||||
| { | |||||
| _unfeedable_tensors.Add(tensor); | |||||
| } | |||||
| public void Dispose() | public void Dispose() | ||||
| { | { | ||||
| c_api.TF_DeleteGraph(_handle); | c_api.TF_DeleteGraph(_handle); | ||||
| @@ -10,11 +10,16 @@ namespace Tensorflow.Keras.Engine | |||||
| public class InputSpec | public class InputSpec | ||||
| { | { | ||||
| public int ndim; | public int ndim; | ||||
| Dictionary<int, int> axes; | |||||
| public InputSpec(TF_DataType dtype = TF_DataType.DtInvalid, | public InputSpec(TF_DataType dtype = TF_DataType.DtInvalid, | ||||
| int? ndim = null) | |||||
| int? ndim = null, | |||||
| Dictionary<int, int> axes = null) | |||||
| { | { | ||||
| this.ndim = ndim.Value; | this.ndim = ndim.Value; | ||||
| if (axes == null) | |||||
| axes = new Dictionary<int, int>(); | |||||
| this.axes = axes; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -66,7 +66,7 @@ namespace Tensorflow.Keras.Engine | |||||
| } | } | ||||
| protected virtual void add_weight(string name, | |||||
| protected virtual RefVariable add_weight(string name, | |||||
| int[] shape, | int[] shape, | ||||
| TF_DataType dtype = TF_DataType.DtInvalid, | TF_DataType dtype = TF_DataType.DtInvalid, | ||||
| IInitializer initializer = null, | IInitializer initializer = null, | ||||
| @@ -82,6 +82,8 @@ namespace Tensorflow.Keras.Engine | |||||
| trainable: trainable.Value); | trainable: trainable.Value); | ||||
| backend.track_variable(variable); | backend.track_variable(variable); | ||||
| _trainable_weights.Add(variable); | _trainable_weights.Add(variable); | ||||
| return variable; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -2,6 +2,8 @@ | |||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Text; | using System.Text; | ||||
| using Tensorflow.Keras.Engine; | using Tensorflow.Keras.Engine; | ||||
| using Tensorflow.Keras.Utils; | |||||
| using Tensorflow.Operations; | |||||
| using Tensorflow.Operations.Activation; | using Tensorflow.Operations.Activation; | ||||
| namespace Tensorflow.Keras.Layers | namespace Tensorflow.Keras.Layers | ||||
| @@ -19,6 +21,9 @@ namespace Tensorflow.Keras.Layers | |||||
| protected bool use_bias; | protected bool use_bias; | ||||
| protected IInitializer kernel_initializer; | protected IInitializer kernel_initializer; | ||||
| protected IInitializer bias_initializer; | protected IInitializer bias_initializer; | ||||
| protected RefVariable kernel; | |||||
| protected RefVariable bias; | |||||
| protected Convolution _convolution_op; | |||||
| public Conv(int rank, | public Conv(int rank, | ||||
| int filters, | int filters, | ||||
| @@ -53,11 +58,37 @@ namespace Tensorflow.Keras.Layers | |||||
| int channel_axis = data_format == "channels_first" ? 1 : -1; | int channel_axis = data_format == "channels_first" ? 1 : -1; | ||||
| int input_dim = input_shape.Dimensions[input_shape.NDim - 1]; | int input_dim = input_shape.Dimensions[input_shape.NDim - 1]; | ||||
| var kernel_shape = new int[] { kernel_size[0], kernel_size[1], input_dim, filters }; | var kernel_shape = new int[] { kernel_size[0], kernel_size[1], input_dim, filters }; | ||||
| add_weight(name: "kernel", | |||||
| kernel = add_weight(name: "kernel", | |||||
| shape: kernel_shape, | shape: kernel_shape, | ||||
| initializer: kernel_initializer, | initializer: kernel_initializer, | ||||
| trainable: true, | trainable: true, | ||||
| dtype: _dtype); | dtype: _dtype); | ||||
| if (use_bias) | |||||
| bias = add_weight(name: "bias", | |||||
| shape: new int[] { filters }, | |||||
| initializer: bias_initializer, | |||||
| trainable: true, | |||||
| dtype: _dtype); | |||||
| var axes = new Dictionary<int, int>(); | |||||
| axes.Add(-1, input_dim); | |||||
| input_spec = new InputSpec(ndim: rank + 2, axes: axes); | |||||
| string op_padding; | |||||
| if (padding == "causal") | |||||
| op_padding = "valid"; | |||||
| else | |||||
| op_padding = padding; | |||||
| var df = conv_utils.convert_data_format(data_format, rank + 2); | |||||
| _convolution_op = nn_ops.Convolution(input_shape, | |||||
| kernel.shape, | |||||
| op_padding.ToUpper(), | |||||
| strides, | |||||
| dilation_rate, | |||||
| data_format: df); | |||||
| built = true; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,33 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Text; | |||||
| namespace Tensorflow.Keras.Utils | |||||
| { | |||||
| public class conv_utils | |||||
| { | |||||
| public static string convert_data_format(string data_format, int ndim) | |||||
| { | |||||
| if (data_format == "channels_last") | |||||
| if (ndim == 3) | |||||
| return "NWC"; | |||||
| else if (ndim == 4) | |||||
| return "NHWC"; | |||||
| else if (ndim == 5) | |||||
| return "NDHWC"; | |||||
| else | |||||
| throw new ValueError($"Input rank not supported: {ndim}"); | |||||
| else if (data_format == "channels_first") | |||||
| if (ndim == 3) | |||||
| return "NCW"; | |||||
| else if (ndim == 4) | |||||
| return "NCHW"; | |||||
| else if (ndim == 5) | |||||
| return "NCDHW"; | |||||
| else | |||||
| throw new ValueError($"Input rank not supported: {ndim}"); | |||||
| else | |||||
| throw new ValueError($"Invalid data_format: {data_format}"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -68,7 +68,7 @@ namespace Tensorflow.Layers | |||||
| throw new NotImplementedException(""); | throw new NotImplementedException(""); | ||||
| } | } | ||||
| protected virtual void add_weight(string name, | |||||
| protected virtual RefVariable add_weight(string name, | |||||
| int[] shape, | int[] shape, | ||||
| TF_DataType dtype = TF_DataType.DtInvalid, | TF_DataType dtype = TF_DataType.DtInvalid, | ||||
| IInitializer initializer = null, | IInitializer initializer = null, | ||||
| @@ -93,14 +93,14 @@ namespace Tensorflow.Layers | |||||
| _set_scope(); | _set_scope(); | ||||
| var reuse = built || (_reuse != null && _reuse.Value); | var reuse = built || (_reuse != null && _reuse.Value); | ||||
| Python.with(tf.variable_scope(_scope, | |||||
| return Python.with(tf.variable_scope(_scope, | |||||
| reuse: reuse, | reuse: reuse, | ||||
| auxiliary_name_scope: false), scope => | auxiliary_name_scope: false), scope => | ||||
| { | { | ||||
| _current_scope = scope; | _current_scope = scope; | ||||
| Python.with(ops.name_scope(_name_scope()), delegate | |||||
| return Python.with(ops.name_scope(_name_scope()), delegate | |||||
| { | { | ||||
| base.add_weight(name, | |||||
| var variable = base.add_weight(name, | |||||
| shape, | shape, | ||||
| dtype: dtype, | dtype: dtype, | ||||
| initializer: initializer, | initializer: initializer, | ||||
| @@ -113,6 +113,12 @@ namespace Tensorflow.Layers | |||||
| initializer: initializer1, | initializer: initializer1, | ||||
| trainable: trainable1); | trainable: trainable1); | ||||
| }); | }); | ||||
| if(init_graph != null) | |||||
| { | |||||
| var trainable_variables = variables.trainable_variables(); | |||||
| } | |||||
| return variable; | |||||
| }); | }); | ||||
| }); | }); | ||||
| } | } | ||||
| @@ -0,0 +1,66 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| namespace Tensorflow.Operations | |||||
| { | |||||
| public class Convolution | |||||
| { | |||||
| public TensorShape input_shape; | |||||
| public TensorShape filter_shape; | |||||
| public string data_format; | |||||
| public int[] strides; | |||||
| public string name; | |||||
| public _WithSpaceToBatch conv_op; | |||||
| public Convolution(TensorShape input_shape, | |||||
| TensorShape filter_shape, | |||||
| string padding, | |||||
| int[] strides, | |||||
| int[] dilation_rate, | |||||
| string name = null, | |||||
| string data_format = null) | |||||
| { | |||||
| var num_total_dims = filter_shape.NDim; | |||||
| var num_spatial_dims = num_total_dims - 2; | |||||
| int input_channels_dim; | |||||
| int[] spatial_dims; | |||||
| if (string.IsNullOrEmpty(data_format) || !data_format.StartsWith("NC")) | |||||
| { | |||||
| input_channels_dim = input_shape.Dimensions[num_spatial_dims + 1]; | |||||
| spatial_dims = Enumerable.Range(1, num_spatial_dims).ToArray(); | |||||
| } | |||||
| else | |||||
| { | |||||
| input_channels_dim = input_shape.Dimensions[1]; | |||||
| spatial_dims = Enumerable.Range(2, num_spatial_dims).ToArray(); | |||||
| } | |||||
| this.input_shape = input_shape; | |||||
| this.filter_shape = filter_shape; | |||||
| this.data_format = data_format; | |||||
| this.strides = strides; | |||||
| this.name = name; | |||||
| conv_op = new _WithSpaceToBatch( | |||||
| input_shape, | |||||
| dilation_rate: dilation_rate, | |||||
| padding: padding, | |||||
| build_op: _build_op, | |||||
| filter_shape: filter_shape, | |||||
| spatial_dims: spatial_dims, | |||||
| data_format: data_format); | |||||
| } | |||||
| public _NonAtrousConvolution _build_op(int _, string padding) | |||||
| { | |||||
| return new _NonAtrousConvolution(input_shape, | |||||
| filter_shape: filter_shape, | |||||
| padding: padding, | |||||
| data_format: data_format, | |||||
| strides: strides, | |||||
| name: name); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,56 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| namespace Tensorflow.Operations | |||||
| { | |||||
| public class _NonAtrousConvolution | |||||
| { | |||||
| public string padding; | |||||
| public string name; | |||||
| public int[] strides; | |||||
| public string data_format; | |||||
| private Func<object, Tensor> conv_op; | |||||
| public _NonAtrousConvolution(TensorShape input_shape, | |||||
| TensorShape filter_shape, | |||||
| string padding, | |||||
| string data_format, | |||||
| int[] strides, | |||||
| string name) | |||||
| { | |||||
| this.padding = padding; | |||||
| this.name = name; | |||||
| var conv_dims = input_shape.NDim - 2; | |||||
| if (conv_dims == 1) | |||||
| { | |||||
| throw new NotImplementedException("_NonAtrousConvolution conv_dims 1"); | |||||
| } | |||||
| else if (conv_dims == 2) | |||||
| { | |||||
| var list = strides.ToList(); | |||||
| if (string.IsNullOrEmpty(data_format) || data_format == "NHWC") | |||||
| { | |||||
| data_format = "NHWC"; | |||||
| list.Insert(0, 1); | |||||
| list.Add(1); | |||||
| } | |||||
| else if (data_format == "NCHW") | |||||
| list.InsertRange(0, new int[] { 1, 1 }); | |||||
| else | |||||
| throw new ValueError("data_format must be \"NHWC\" or \"NCHW\"."); | |||||
| strides = list.ToArray(); | |||||
| this.strides = strides; | |||||
| this.data_format = data_format; | |||||
| conv_op = gen_nn_ops.conv2d; | |||||
| } | |||||
| else if (conv_dims == 3) | |||||
| { | |||||
| throw new NotImplementedException("_NonAtrousConvolution conv_dims 3"); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,55 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| namespace Tensorflow.Operations | |||||
| { | |||||
| public class _WithSpaceToBatch | |||||
| { | |||||
| private _NonAtrousConvolution call; | |||||
| public _WithSpaceToBatch(TensorShape input_shape, | |||||
| int[] dilation_rate, | |||||
| string padding, | |||||
| Func<int, string, _NonAtrousConvolution> build_op, | |||||
| TensorShape filter_shape = null, | |||||
| int[] spatial_dims = null, | |||||
| string data_format = null) | |||||
| { | |||||
| var dilation_rate_tensor = ops.convert_to_tensor(dilation_rate, TF_DataType.TF_INT32, name: "dilation_rate"); | |||||
| var rate_shape = dilation_rate_tensor.getShape(); | |||||
| var num_spatial_dims = rate_shape.Dimensions[0]; | |||||
| int starting_spatial_dim = -1; | |||||
| if (!string.IsNullOrEmpty(data_format) && data_format.StartsWith("NC")) | |||||
| starting_spatial_dim = 2; | |||||
| else | |||||
| starting_spatial_dim = 1; | |||||
| if (spatial_dims == null) | |||||
| throw new NotImplementedException("_WithSpaceToBatch spatial_dims"); | |||||
| var orig_spatial_dims = spatial_dims; | |||||
| spatial_dims = spatial_dims.OrderBy(x => x).ToArray(); | |||||
| if (!Enumerable.SequenceEqual(spatial_dims, orig_spatial_dims) || spatial_dims.Any(x => x < 1)) | |||||
| throw new ValueError("spatial_dims must be a montonically increasing sequence of positive integers"); | |||||
| int expected_input_rank = -1; | |||||
| if (!string.IsNullOrEmpty(data_format) && data_format.StartsWith("NC")) | |||||
| expected_input_rank = spatial_dims.Last(); | |||||
| else | |||||
| expected_input_rank = spatial_dims.Last() + 1; | |||||
| var const_rate = tensor_util.constant_value(dilation_rate_tensor); | |||||
| var rate_or_const_rate = dilation_rate; | |||||
| if(!(const_rate is null)) | |||||
| { | |||||
| if (const_rate.Data<int>().Count(x => x == 1) == const_rate.size) | |||||
| { | |||||
| call = build_op(num_spatial_dims, padding); | |||||
| return; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,14 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Text; | |||||
| namespace Tensorflow.Operations | |||||
| { | |||||
| public class gen_nn_ops | |||||
| { | |||||
| public static Tensor conv2d(object parameters) | |||||
| { | |||||
| throw new NotImplementedException("gen_nn_op.conv2d"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -12,7 +12,7 @@ namespace Tensorflow | |||||
| { | { | ||||
| public class OpDefLibrary : Python | public class OpDefLibrary : Python | ||||
| { | { | ||||
| public Operation _apply_op_helper(string op_type_name, string name = null, dynamic args = null) | |||||
| public Operation _apply_op_helper(string op_type_name, string name = null, object args = null) | |||||
| { | { | ||||
| Dictionary<string, object> keywords = ConvertToDict(args); | Dictionary<string, object> keywords = ConvertToDict(args); | ||||
| var g = ops.get_default_graph(); | var g = ops.get_default_graph(); | ||||
| @@ -358,25 +358,5 @@ namespace Tensorflow | |||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| private Dictionary<string, object> ConvertToDict(dynamic dyn) | |||||
| { | |||||
| var dictionary = new Dictionary<string, object>(); | |||||
| foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(dyn)) | |||||
| { | |||||
| object obj = propertyDescriptor.GetValue(dyn); | |||||
| string name = propertyDescriptor.Name; | |||||
| // avoid .net keyword | |||||
| switch (name) | |||||
| { | |||||
| case "_ref_": | |||||
| name = "ref"; | |||||
| break; | |||||
| } | |||||
| dictionary.Add(name, obj); | |||||
| } | |||||
| return dictionary; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -164,7 +164,7 @@ namespace Tensorflow | |||||
| return grouped_inputs.ToArray(); | return grouped_inputs.ToArray(); | ||||
| } | } | ||||
| public object get_attr<T>(string name) | |||||
| public object get_attr(string name) | |||||
| { | { | ||||
| AttrValue x = null; | AttrValue x = null; | ||||
| @@ -175,24 +175,17 @@ namespace Tensorflow | |||||
| x = AttrValue.Parser.ParseFrom(buf); | x = AttrValue.Parser.ParseFrom(buf); | ||||
| } | } | ||||
| switch (name) | |||||
| { | |||||
| case "T": | |||||
| case "dtype": | |||||
| return x.Type; | |||||
| case "shape": | |||||
| return x.Shape; | |||||
| default: | |||||
| switch (typeof(T).Name) | |||||
| { | |||||
| case "Boolean": | |||||
| return x.B; | |||||
| case "String": | |||||
| return x.S; | |||||
| default: | |||||
| throw new NotImplementedException($"Unsupported field type in {x.ToString()}"); | |||||
| } | |||||
| } | |||||
| string oneof_value = x.ValueCase.ToString(); | |||||
| if (string.IsNullOrEmpty(oneof_value)) | |||||
| return null; | |||||
| if(oneof_value == "list") | |||||
| throw new NotImplementedException($"Unsupported field type in {x.ToString()}"); | |||||
| if (oneof_value == "type") | |||||
| return x.Type; | |||||
| return x.GetType().GetProperty(oneof_value).GetValue(x); | |||||
| } | } | ||||
| public TF_AttrMetadata GetAttributeMetadata(string attr_name, Status s) | public TF_AttrMetadata GetAttributeMetadata(string attr_name, Status s) | ||||
| @@ -47,8 +47,8 @@ namespace Tensorflow | |||||
| var _inputs_flat = _op.inputs; | var _inputs_flat = _op.inputs; | ||||
| var _attrs = new Dictionary<string, object>(); | var _attrs = new Dictionary<string, object>(); | ||||
| _attrs["dtype"] = _op.get_attr<DataType>("dtype"); | |||||
| _attrs["shape"] = _op.get_attr<int[]>("shape"); | |||||
| _attrs["dtype"] = _op.get_attr("dtype"); | |||||
| _attrs["shape"] = _op.get_attr("shape"); | |||||
| _execute.record_gradient("Placeholder", _inputs_flat, _attrs, _result, name); | _execute.record_gradient("Placeholder", _inputs_flat, _attrs, _result, name); | ||||
| @@ -0,0 +1,24 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Text; | |||||
| using Tensorflow.Operations; | |||||
| namespace Tensorflow | |||||
| { | |||||
| public class nn_ops | |||||
| { | |||||
| public static Convolution Convolution(TensorShape input_shape, | |||||
| TensorShape filter_shape, | |||||
| string padding, | |||||
| int[] strides, | |||||
| int[] dilation_rate, | |||||
| string name = null, | |||||
| string data_format = null) => new Convolution(input_shape, | |||||
| filter_shape, | |||||
| padding, | |||||
| strides, | |||||
| dilation_rate, | |||||
| name: name, | |||||
| data_format: data_format); | |||||
| } | |||||
| } | |||||
| @@ -1,6 +1,7 @@ | |||||
| using NumSharp.Core; | using NumSharp.Core; | ||||
| using System; | using System; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.ComponentModel; | |||||
| using System.Text; | using System.Text; | ||||
| namespace Tensorflow | namespace Tensorflow | ||||
| @@ -109,6 +110,26 @@ namespace Tensorflow | |||||
| for (int i = 0; i < values.Count; i++) | for (int i = 0; i < values.Count; i++) | ||||
| yield return (i, values[i]); | yield return (i, values[i]); | ||||
| } | } | ||||
| public static Dictionary<string, object> ConvertToDict(object dyn) | |||||
| { | |||||
| var dictionary = new Dictionary<string, object>(); | |||||
| foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(dyn)) | |||||
| { | |||||
| object obj = propertyDescriptor.GetValue(dyn); | |||||
| string name = propertyDescriptor.Name; | |||||
| // avoid .net keyword | |||||
| switch (name) | |||||
| { | |||||
| case "_ref_": | |||||
| name = "ref"; | |||||
| break; | |||||
| } | |||||
| dictionary.Add(name, obj); | |||||
| } | |||||
| return dictionary; | |||||
| } | |||||
| } | } | ||||
| public interface IPython : IDisposable | public interface IPython : IDisposable | ||||
| @@ -51,4 +51,8 @@ Fixed import name scope issue.</PackageReleaseNotes> | |||||
| <Content CopyToOutputDirectory="PreserveNewest" Include="./runtimes/win-x64/native/tensorflow.dll" Link="tensorflow.dll" Pack="true" PackagePath="runtimes/win-x64/native/tensorflow.dll" /> | <Content CopyToOutputDirectory="PreserveNewest" Include="./runtimes/win-x64/native/tensorflow.dll" Link="tensorflow.dll" Pack="true" PackagePath="runtimes/win-x64/native/tensorflow.dll" /> | ||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | |||||
| <ProjectReference Include="..\..\..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj" /> | |||||
| </ItemGroup> | |||||
| </Project> | </Project> | ||||
| @@ -79,6 +79,11 @@ namespace Tensorflow | |||||
| return (int)type; | return (int)type; | ||||
| } | } | ||||
| public static Type as_numpy_dtype(this DataType type) | |||||
| { | |||||
| return type.as_tf_dtype().as_numpy_datatype(); | |||||
| } | |||||
| public static DataType as_base_dtype(this DataType type) | public static DataType as_base_dtype(this DataType type) | ||||
| { | { | ||||
| return (int)type > 100 ? | return (int)type > 100 ? | ||||
| @@ -17,6 +17,42 @@ namespace Tensorflow | |||||
| TF_DataType.TF_QUINT16, TF_DataType.TF_QINT32, TF_DataType.TF_UINT32, TF_DataType.TF_UINT64 | TF_DataType.TF_QUINT16, TF_DataType.TF_QINT32, TF_DataType.TF_UINT32, TF_DataType.TF_UINT64 | ||||
| }; | }; | ||||
| /// <summary> | |||||
| /// Returns the constant value of the given tensor, if efficiently calculable. | |||||
| /// </summary> | |||||
| /// <param name="tensor"></param> | |||||
| /// <param name="partial"></param> | |||||
| /// <returns></returns> | |||||
| public static NDArray constant_value(Tensor tensor, bool partial = false) | |||||
| { | |||||
| NDArray ret = _ConstantValue(tensor, partial); | |||||
| if (!(ret is null)) | |||||
| tensor.graph.prevent_feeding(tensor); | |||||
| return ret; | |||||
| } | |||||
| private static NDArray _ConstantValue(Tensor tensor, bool partial) | |||||
| { | |||||
| if (tensor.op.type == "Const") | |||||
| { | |||||
| return MakeNdarray(tensor.op.get_attr("value") as TensorProto); | |||||
| } | |||||
| throw new NotImplementedException("_ConstantValue"); | |||||
| } | |||||
| public static NDArray MakeNdarray(TensorProto tensor) | |||||
| { | |||||
| var shape = tensor.TensorShape.Dim.Select(x => (int)x.Size).ToArray(); | |||||
| long num_elements = np.prod(shape); | |||||
| var tensor_dtype = tensor.Dtype.as_numpy_dtype(); | |||||
| if (tensor.TensorContent.Length > 0) | |||||
| return np.frombuffer(tensor.TensorContent.ToByteArray(), tensor_dtype) | |||||
| .reshape(shape); | |||||
| throw new NotImplementedException("MakeNdarray"); | |||||
| } | |||||
| /// <summary> | /// <summary> | ||||
| /// Create a TensorProto. | /// Create a TensorProto. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -113,7 +113,7 @@ namespace Tensorflow | |||||
| _graph_key = ops.get_default_graph()._graph_key; | _graph_key = ops.get_default_graph()._graph_key; | ||||
| _trainable = trainable; | _trainable = trainable; | ||||
| if (!collections.Contains(ops.GraphKeys.TRAINABLE_VARIABLES)) | |||||
| if (trainable && !collections.Contains(ops.GraphKeys.TRAINABLE_VARIABLES)) | |||||
| collections.Add(ops.GraphKeys.TRAINABLE_VARIABLES); | collections.Add(ops.GraphKeys.TRAINABLE_VARIABLES); | ||||
| ops.init_scope(); | ops.init_scope(); | ||||
| @@ -29,10 +29,10 @@ namespace Tensorflow | |||||
| var _inputs_flat = _op.inputs; | var _inputs_flat = _op.inputs; | ||||
| var _attrs = new Dictionary<string, object>(); | var _attrs = new Dictionary<string, object>(); | ||||
| _attrs["dtype"] = _op.get_attr<DataType>("dtype"); | |||||
| _attrs["shape"] = _op.get_attr<int[]>("shape"); | |||||
| _attrs["container"] = _op.get_attr<string>("container"); | |||||
| _attrs["shared_name"] = _op.get_attr<string>("shared_name"); | |||||
| _attrs["dtype"] = _op.get_attr("dtype"); | |||||
| _attrs["shape"] = _op.get_attr("shape"); | |||||
| _attrs["container"] = _op.get_attr("container"); | |||||
| _attrs["shared_name"] = _op.get_attr("shared_name"); | |||||
| _execute.record_gradient("VariableV2", _inputs_flat, _attrs, _result, name); | _execute.record_gradient("VariableV2", _inputs_flat, _attrs, _result, name); | ||||
| @@ -58,9 +58,9 @@ namespace Tensorflow | |||||
| var _inputs_flat = _op.inputs; | var _inputs_flat = _op.inputs; | ||||
| var _attrs = new Dictionary<string, object>(); | var _attrs = new Dictionary<string, object>(); | ||||
| _attrs["T"] = _op.get_attr<DataType>("T"); | |||||
| _attrs["validate_shape"] = _op.get_attr<bool>("validate_shape"); | |||||
| _attrs["use_locking"] = _op.get_attr<bool>("use_locking"); | |||||
| _attrs["T"] = _op.get_attr("T"); | |||||
| _attrs["validate_shape"] = _op.get_attr("validate_shape"); | |||||
| _attrs["use_locking"] = _op.get_attr("use_locking"); | |||||
| _execute.record_gradient("Assign", _inputs_flat, _attrs, _result, name); | _execute.record_gradient("Assign", _inputs_flat, _attrs, _result, name); | ||||
| @@ -155,6 +155,7 @@ namespace Tensorflow | |||||
| else | else | ||||
| { | { | ||||
| return new RefVariable(initial_value, | return new RefVariable(initial_value, | ||||
| trainable: trainable.Value, | |||||
| name: name, | name: name, | ||||
| dtype: dtype); | dtype: dtype); | ||||
| } | } | ||||
| @@ -12,6 +12,7 @@ | |||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <ProjectReference Include="..\..\..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj" /> | |||||
| <ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | <ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | ||||
| </ItemGroup> | </ItemGroup> | ||||
| @@ -24,6 +24,7 @@ | |||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <ProjectReference Include="..\..\..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj" /> | |||||
| <ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | <ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | ||||
| </ItemGroup> | </ItemGroup> | ||||