diff --git a/.gitignore b/.gitignore index eee1dc7b..e4aba715 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,7 @@ StyleCopReport.xml *_p.c *_i.h *.ilk +*.meta *.obj *.iobj *.pch diff --git a/README.md b/README.md index a2a205fd..3ac68eed 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # TensorFlow.NET +TensorFlow.NET provides a .NET Standard binding for [TensorFlow](https://www.tensorflow.org/). It aims to implement the complete Tensorflow API in CSharp which allows .NET developers to develop, train and deploy Machine Learning models with the cross-platform .NET Standard framework. TensorFlow.NET (TF.NET) provides a .NET Standard binding for [TensorFlow](https://www.tensorflow.org/). It aims to implement the complete Tensorflow API in CSharp which allows .NET developers to develop, train and deploy Machine Learning models with the cross-platform .NET Standard framework. [![Join the chat at https://gitter.im/publiclab/publiclab](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/sci-sharp/community) diff --git a/TensorFlow.NET.sln b/TensorFlow.NET.sln index bef96f5e..b96f8203 100644 --- a/TensorFlow.NET.sln +++ b/TensorFlow.NET.sln @@ -9,8 +9,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Examples", "t EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Core", "src\TensorFlowNET.Core\TensorFlowNET.Core.csproj", "{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NumSharp.Core", "..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj", "{DE97EAD7-B92C-4112-9690-91C40A97179E}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -29,10 +27,6 @@ Global {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug|Any CPU.Build.0 = Debug|Any CPU {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|Any CPU.ActiveCfg = Release|Any CPU {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|Any CPU.Build.0 = Release|Any CPU - {DE97EAD7-B92C-4112-9690-91C40A97179E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DE97EAD7-B92C-4112-9690-91C40A97179E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DE97EAD7-B92C-4112-9690-91C40A97179E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DE97EAD7-B92C-4112-9690-91C40A97179E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/docs/source/LogisticRegression.md b/docs/source/LogisticRegression.md index 415233b3..8c524ea9 100644 --- a/docs/source/LogisticRegression.md +++ b/docs/source/LogisticRegression.md @@ -23,8 +23,9 @@ logistic回归通过函数S将ax+b对应到一个隐状态p,p = S(ax+b),然 将t换成ax+b,可以得到逻辑回归模型的参数形式: P(x;a,b) = 1 / (1 + e^(-ax+b)) -![image](https://github.com/SciEvan/TensorFlow.NET/blob/master/docs/source/sigmoid.png) - sigmoid函数的图像 +![image](https://github.com/SciEvan/TensorFlow.NET/tree/master/docs/source/sigmoid.png) + +sigmoid函数的图像 By the function of the function S, we can limit the output value to the interval [0, 1], p(x) can then be used to represent the probability p(y=1|x), the probability that y is divided into 1 group when an x occurs. diff --git a/graph/README.md b/graph/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/graph/cond_test.meta b/graph/cond_test.meta deleted file mode 100644 index 2110d577..00000000 Binary files a/graph/cond_test.meta and /dev/null differ diff --git a/graph/kmeans.meta b/graph/kmeans.meta deleted file mode 100644 index 0ad4f03f..00000000 Binary files a/graph/kmeans.meta and /dev/null differ diff --git a/src/TensorFlowNET.Core/Framework/op_def_registry.py.cs b/src/TensorFlowNET.Core/Framework/op_def_registry.py.cs index 270b9056..11a89af1 100644 --- a/src/TensorFlowNET.Core/Framework/op_def_registry.py.cs +++ b/src/TensorFlowNET.Core/Framework/op_def_registry.py.cs @@ -20,9 +20,32 @@ namespace Tensorflow foreach (var op_def in op_list.Op) _registered_ops[op_def.Name] = op_def; + + if (!_registered_ops.ContainsKey("NearestNeighbors")) + _registered_ops["NearestNeighbors"] = op_NearestNeighbors(); } return _registered_ops; } + + /// + /// Doesn't work because the op can't be found on binary + /// + /// + private static OpDef op_NearestNeighbors() + { + var def = new OpDef + { + Name = "NearestNeighbors" + }; + + def.InputArg.Add(new ArgDef { Name = "points", Type = DataType.DtFloat }); + def.InputArg.Add(new ArgDef { Name = "centers", Type = DataType.DtFloat }); + def.InputArg.Add(new ArgDef { Name = "k", Type = DataType.DtInt64 }); + def.OutputArg.Add(new ArgDef { Name = "nearest_center_indices", Type = DataType.DtInt64 }); + def.OutputArg.Add(new ArgDef { Name = "nearest_center_distances", Type = DataType.DtFloat }); + + return def; + } } } diff --git a/src/TensorFlowNET.Core/Operations/ControlFlows/CondContext.cs b/src/TensorFlowNET.Core/Operations/ControlFlows/CondContext.cs index 40238dce..254df0cf 100644 --- a/src/TensorFlowNET.Core/Operations/ControlFlows/CondContext.cs +++ b/src/TensorFlowNET.Core/Operations/ControlFlows/CondContext.cs @@ -335,7 +335,7 @@ namespace Tensorflow.Operations ret.Enter(); foreach (var nested_def in proto.NestedContexts) - from_control_flow_context_def(nested_def, import_scope: import_scope); + throw new NotImplementedException(""); ret.Exit(); return ret; } diff --git a/src/TensorFlowNET.Core/Operations/ControlFlows/ControlFlowContext.cs b/src/TensorFlowNET.Core/Operations/ControlFlows/ControlFlowContext.cs index a36602f7..48a519db 100644 --- a/src/TensorFlowNET.Core/Operations/ControlFlows/ControlFlowContext.cs +++ b/src/TensorFlowNET.Core/Operations/ControlFlows/ControlFlowContext.cs @@ -3,8 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Tensorflow.Operations.ControlFlows; -using static Tensorflow.ControlFlowContextDef; - + namespace Tensorflow.Operations { /// @@ -185,23 +184,6 @@ namespace Tensorflow.Operations return null; } - /// - /// Deserializes `context_def` into the appropriate ControlFlowContext. - /// - /// ControlFlowContextDef proto - /// Name scope to add - /// A ControlFlowContext subclass - protected ControlFlowContext from_control_flow_context_def(ControlFlowContextDef context_def, string import_scope = "") - { - switch (context_def.CtxtCase) - { - case CtxtOneofCase.CondCtxt: - return new CondContext().from_proto(context_def.CondCtxt, import_scope: import_scope); - } - - throw new NotImplementedException($"Unknown ControlFlowContextDef field: {context_def.CtxtCase}"); - } - public object to_proto() { throw new NotImplementedException(); diff --git a/src/TensorFlowNET.Core/Operations/Operation.Implicit.cs b/src/TensorFlowNET.Core/Operations/Operation.Implicit.cs deleted file mode 100644 index 013c193c..00000000 --- a/src/TensorFlowNET.Core/Operations/Operation.Implicit.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Tensorflow -{ - /// - /// Convert to other datatype implicitly - /// - public partial class Operation - { - public static implicit operator Operation(IntPtr handle) => new Operation(handle); - public static implicit operator IntPtr(Operation op) => op._handle; - public static implicit operator Tensor(Operation op) => op.output; - - public override string ToString() - { - return _handle == IntPtr.Zero ? "tf.Operation Undefined" : $"tf.Operation '{name}' type={OpType}"; - } - - public override bool Equals(object obj) - { - switch (obj) - { - case IntPtr val: - return val == _handle; - case Operation val: - return val._handle == _handle; - } - - return base.Equals(obj); - } - } -} diff --git a/src/TensorFlowNET.Core/Operations/Operation.cs b/src/TensorFlowNET.Core/Operations/Operation.cs index bbb62be2..5915c216 100644 --- a/src/TensorFlowNET.Core/Operations/Operation.cs +++ b/src/TensorFlowNET.Core/Operations/Operation.cs @@ -248,6 +248,27 @@ namespace Tensorflow s.Check(); return NodeDef.Parser.ParseFrom(buffer); } + } + + public override string ToString() + { + return _handle == IntPtr.Zero ? "tf.Operation Undefined" : $"tf.Operation '{name}' type={OpType}"; + } + + public static implicit operator Operation(IntPtr handle) => new Operation(handle); + public static implicit operator IntPtr(Operation op) => op._handle; + + public override bool Equals(object obj) + { + switch (obj) + { + case IntPtr val: + return val == _handle; + case Operation val: + return val._handle == _handle; + } + + return base.Equals(obj); } /// diff --git a/src/TensorFlowNET.Core/Python.cs b/src/TensorFlowNET.Core/Python.cs index e183ef43..d216dae3 100644 --- a/src/TensorFlowNET.Core/Python.cs +++ b/src/TensorFlowNET.Core/Python.cs @@ -27,11 +27,6 @@ namespace Tensorflow return Enumerable.Range(0, end); } - protected IEnumerable range(int start, int end) - { - return Enumerable.Range(start, end); - } - public static T New(object args) where T : IPyClass { var instance = Activator.CreateInstance(); diff --git a/src/TensorFlowNET.Core/Sessions/BaseSession.cs b/src/TensorFlowNET.Core/Sessions/BaseSession.cs index 3c0c7486..06862cdb 100644 --- a/src/TensorFlowNET.Core/Sessions/BaseSession.cs +++ b/src/TensorFlowNET.Core/Sessions/BaseSession.cs @@ -204,12 +204,6 @@ namespace Tensorflow switch (tensor.dtype) { - case TF_DataType.TF_BOOL: - var bools = new bool[tensor.size]; - for (ulong i = 0; i < tensor.size; i++) - bools[i] = *(bool*)(offset + (int)(tensor.itemsize * i)); - nd = np.array(bools).reshape(ndims); - break; case TF_DataType.TF_STRING: var bytes = tensor.Data(); // wired, don't know why we have to start from offset 9. @@ -217,6 +211,12 @@ namespace Tensorflow var str = UTF8Encoding.Default.GetString(bytes, 9, bytes[8]); nd = np.array(str).reshape(); break; + case TF_DataType.TF_UINT8: + var _bytes = new byte[tensor.size]; + for (ulong i = 0; i < tensor.size; i++) + _bytes[i] = *(byte*)(offset + (int)(tensor.itemsize * i)); + nd = np.array(_bytes).reshape(ndims); + break; case TF_DataType.TF_INT16: var shorts = new short[tensor.size]; for (ulong i = 0; i < tensor.size; i++) diff --git a/src/TensorFlowNET.Core/Sessions/_ElementFetchMapper.cs b/src/TensorFlowNET.Core/Sessions/_ElementFetchMapper.cs index e18eebc0..e06f9f2e 100644 --- a/src/TensorFlowNET.Core/Sessions/_ElementFetchMapper.cs +++ b/src/TensorFlowNET.Core/Sessions/_ElementFetchMapper.cs @@ -10,9 +10,9 @@ namespace Tensorflow /// public class _ElementFetchMapper : _FetchMapper { - private Func, object> _contraction_fn; + private Func, object> _contraction_fn; - public _ElementFetchMapper(object[] fetches, Func, object> contraction_fn) + public _ElementFetchMapper(object[] fetches, Func, object> contraction_fn) { var g = ops.get_default_graph(); ITensorOrOperation el = null; @@ -31,7 +31,7 @@ namespace Tensorflow /// /// /// - public override NDArray build_results(List values) + public override NDArray build_results(List values) { NDArray result = null; diff --git a/src/TensorFlowNET.Core/Sessions/_FetchHandler.cs b/src/TensorFlowNET.Core/Sessions/_FetchHandler.cs index 2c5b55f6..9a6a738a 100644 --- a/src/TensorFlowNET.Core/Sessions/_FetchHandler.cs +++ b/src/TensorFlowNET.Core/Sessions/_FetchHandler.cs @@ -42,7 +42,7 @@ namespace Tensorflow public NDArray build_results(BaseSession session, NDArray[] tensor_values) { - var full_values = new List(); + var full_values = new List(); if (_final_fetches.Count != tensor_values.Length) throw new InvalidOperationException("_final_fetches mismatch tensor_values"); diff --git a/src/TensorFlowNET.Core/Sessions/_FetchMapper.cs b/src/TensorFlowNET.Core/Sessions/_FetchMapper.cs index 4b2691a8..ef066abe 100644 --- a/src/TensorFlowNET.Core/Sessions/_FetchMapper.cs +++ b/src/TensorFlowNET.Core/Sessions/_FetchMapper.cs @@ -24,7 +24,19 @@ namespace Tensorflow { var type = values[0].GetType(); var nd = new NDArray(type, values.Count); - nd.SetData(values.ToArray()); + + switch (type.Name) + { + case "Single": + nd.SetData(values.Select(x => (float)x).ToArray()); + break; + case "NDArray": + NDArray[] arr = values.Select(x => (NDArray)x).ToArray(); + nd = new NDArray(arr); + break; + default: + break; + } return nd; } diff --git a/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj b/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj index cae47f15..ee59b28d 100644 --- a/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj +++ b/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj @@ -57,8 +57,4 @@ More math/ linalg APIs. - - - - diff --git a/src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs b/src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs index 5f26becd..3b8b65dd 100644 --- a/src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs +++ b/src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs @@ -67,7 +67,8 @@ namespace Tensorflow case "Double": Marshal.Copy(nd1.Data(), 0, dotHandle, nd.size); break; - //case "Byte": + case "Byte": + Marshal.Copy(nd1.Data(), 0, dotHandle, nd.size); /*var bb = nd.Data(); var bytes = Marshal.AllocHGlobal(bb.Length); Marshal.Copy(bb, 0, bytes, bb.Length); diff --git a/src/TensorFlowNET.Core/Tensors/Tensor.cs b/src/TensorFlowNET.Core/Tensors/Tensor.cs index 0c2e84d5..46a0e264 100644 --- a/src/TensorFlowNET.Core/Tensors/Tensor.cs +++ b/src/TensorFlowNET.Core/Tensors/Tensor.cs @@ -195,6 +195,7 @@ namespace Tensorflow case "Double": return TF_DataType.TF_DOUBLE; case "Byte": + return TF_DataType.TF_UINT8; case "String": return TF_DataType.TF_STRING; default: diff --git a/src/TensorFlowNET.Core/Train/Saving/BaseSaverBuilder.cs b/src/TensorFlowNET.Core/Train/Saving/BaseSaverBuilder.cs index 6b58c184..0cc3c981 100644 --- a/src/TensorFlowNET.Core/Train/Saving/BaseSaverBuilder.cs +++ b/src/TensorFlowNET.Core/Train/Saving/BaseSaverBuilder.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using Tensorflow.Operations; namespace Tensorflow { @@ -116,9 +115,6 @@ namespace Tensorflow case List values: foreach (var element in values) ; break; - case List values: - foreach (var element in values) ; - break; default: throw new NotImplementedException("_build_internal.check_collection_list"); } diff --git a/tensorflowlib/runtimes/win-x64/native/tensorflow.dll b/tensorflowlib/runtimes/win-x64/native/tensorflow.dll index 0be52700..f98eb380 100644 Binary files a/tensorflowlib/runtimes/win-x64/native/tensorflow.dll and b/tensorflowlib/runtimes/win-x64/native/tensorflow.dll differ diff --git a/test/TensorFlowNET.Examples/ObjectDetection.cs b/test/TensorFlowNET.Examples/ObjectDetection.cs new file mode 100644 index 00000000..5e76d4b7 --- /dev/null +++ b/test/TensorFlowNET.Examples/ObjectDetection.cs @@ -0,0 +1,169 @@ +using Newtonsoft.Json; +using NumSharp; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Tensorflow; +using TensorFlowNET.Examples.Utility; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Linq; + +namespace TensorFlowNET.Examples +{ + + public class ObjectDetection : Python, IExample + { + public int Priority => 7; + public bool Enabled { get; set; } = true; + public string Name => "Image Recognition"; + public float MIN_SCORE = 0.5f; + + string modelDir = "ssd_mobilenet_v1_coco_2018_01_28"; + string imageDir = "images"; + string pbFile = "frozen_inference_graph.pb"; + string labelFile = "mscoco_label_map.pbtxt"; + string picFile = "input.jpg"; + + public bool Run() + { + //buildOutputImage(null); + + // read in the input image + var imgArr = ReadTensorFromImageFile(Path.Join(imageDir, "input.jpg")); + + var graph = new Graph().as_default(); + graph.Import(Path.Join(modelDir, pbFile)); + + var tensorNum = graph.OperationByName("num_detections").outputs[0]; + var tensorBoxes = graph.OperationByName("detection_boxes").outputs[0]; + var tensorScores = graph.OperationByName("detection_scores").outputs[0]; + var tensorClasses = graph.OperationByName("detection_classes").outputs[0]; + + var imgTensor = graph.OperationByName("image_tensor").outputs[0]; + + + + Tensor[] outTensorArr = new Tensor[] { tensorNum, tensorBoxes, tensorScores, tensorClasses }; + + with(tf.Session(graph), sess => + { + var results = sess.run(outTensorArr, new FeedItem(imgTensor, imgArr)); + + NDArray[] resultArr = results.Data(); + + buildOutputImage(resultArr); + }); + + return true; + } + + public void PrepareData() + { + if (!Directory.Exists(modelDir)) + Directory.CreateDirectory(modelDir); + + if (!File.Exists(Path.Join(modelDir, "ssd_mobilenet_v1_coco.tar.gz"))) + { + // get model file + string url = "http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2018_01_28.tar.gz"; + + Utility.Web.Download(url, modelDir, "ssd_mobilenet_v1_coco.tar.gz"); + } + + if (!File.Exists(Path.Join(modelDir, "frozen_inference_graph.pb"))) + { + Utility.Compress.ExtractTGZ(Path.Join(modelDir, "ssd_mobilenet_v1_coco.tar.gz"), "./"); + } + + + // download sample picture + if (!Directory.Exists(imageDir)) + Directory.CreateDirectory(imageDir); + + if (!File.Exists(Path.Join(imageDir, "input.jpg"))) + { + string url = $"https://github.com/tensorflow/models/raw/master/research/object_detection/test_images/image2.jpg"; + Utility.Web.Download(url, imageDir, "input.jpg"); + } + + // download the pbtxt file + if (!File.Exists(Path.Join(modelDir, "mscoco_label_map.pbtxt"))) + { + string url = $"https://github.com/tensorflow/models/blob/master/research/object_detection/data/mscoco_label_map.pbtxt"; + Utility.Web.Download(url, modelDir, "mscoco_label_map.pbtxt"); + } + } + + private NDArray ReadTensorFromImageFile(string file_name) + { + return with(tf.Graph().as_default(), graph => + { + var file_reader = tf.read_file(file_name, "file_reader"); + var decodeJpeg = tf.image.decode_jpeg(file_reader, channels: 3, name: "DecodeJpeg"); + var casted = tf.cast(decodeJpeg, TF_DataType.TF_UINT8); + var dims_expander = tf.expand_dims(casted, 0); + return with(tf.Session(graph), sess => sess.run(dims_expander)); + }); + } + + private void buildOutputImage(NDArray[] resultArr) + { + // get pbtxt items + PbtxtItems pbTxtItems = PbtxtParser.ParsePbtxtFile(Path.Join(modelDir, "mscoco_label_map.pbtxt")); + + // get bitmap + Bitmap bitmap = new Bitmap(Path.Join(imageDir, "input.jpg")); + + float[] scores = resultArr[2].Data(); + + for (int i=0; i MIN_SCORE) + { + //var boxes = resultArr[1].Data(); + float[] boxes = resultArr[1].Data(); + float top = boxes[i * 4] * bitmap.Height; + float left = boxes[i * 4 + 1] * bitmap.Width; + float bottom = boxes[i * 4 + 2] * bitmap.Height; + float right = boxes[i * 4 + 3] * bitmap.Width; + + Rectangle rect = new Rectangle() + { + X = (int)left, + Y = (int)top, + Width = (int)(right - left), + Height = (int)(bottom - top) + }; + + float[] ids = resultArr[3].Data(); + + string name = pbTxtItems.items.Where(w => w.id == (int)ids[i]).Select(s=>s.display_name).FirstOrDefault(); + + drawObjectOnBitmap(bitmap, rect, score, name); + } + } + + bitmap.Save(Path.Join(imageDir, "output.jpg")); + } + + private void drawObjectOnBitmap(Bitmap bmp, Rectangle rect, float score, string name) + { + using (Graphics graphic = Graphics.FromImage(bmp)) + { + graphic.SmoothingMode = SmoothingMode.AntiAlias; + + using (Pen pen = new Pen(Color.Red, 2)) + { + graphic.DrawRectangle(pen, rect); + + Point p = new Point(rect.Right + 5, rect.Top + 5); + string text = string.Format("{0}:{1}%", name, (int)(score * 100)); + graphic.DrawString(text, new Font("Verdana", 8), Brushes.Red, p); + } + } + } + } +} diff --git a/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj b/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj index ba342e5f..2920a534 100644 --- a/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj +++ b/test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj @@ -10,10 +10,10 @@ + - diff --git a/test/TensorFlowNET.Examples/Utility/PbtxtParser.cs b/test/TensorFlowNET.Examples/Utility/PbtxtParser.cs new file mode 100644 index 00000000..45d6ebb8 --- /dev/null +++ b/test/TensorFlowNET.Examples/Utility/PbtxtParser.cs @@ -0,0 +1,74 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; + +namespace TensorFlowNET.Examples.Utility +{ + public class PbtxtItem + { + public string name { get; set; } + public int id { get; set; } + public string display_name { get; set; } + } + public class PbtxtItems + { + public List items { get; set; } + } + + public class PbtxtParser + { + public static PbtxtItems ParsePbtxtFile(string filePath) + { + string line; + string newText = "{\"items\":["; + + try + { + using (System.IO.StreamReader reader = new System.IO.StreamReader(filePath)) + { + + while ((line = reader.ReadLine()) != null) + { + string newline = string.Empty; + + if (line.Contains("{")) + { + newline = line.Replace("item", "").Trim(); + //newText += line.Insert(line.IndexOf("=") + 1, "\"") + "\","; + newText += newline; + } + else if (line.Contains("}")) + { + newText = newText.Remove(newText.Length - 1); + newText += line; + newText += ","; + } + else + { + newline = line.Replace(":", "\":").Trim(); + newline = "\"" + newline;// newline.Insert(0, "\""); + newline += ","; + + newText += newline; + } + + } + + newText = newText.Remove(newText.Length - 1); + newText += "]}"; + + reader.Close(); + } + + PbtxtItems items = JsonConvert.DeserializeObject(newText); + + return items; + } + catch (Exception ex) + { + return null; + } + } + } +} diff --git a/test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj b/test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj index dd6e6ff6..05530031 100644 --- a/test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj +++ b/test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj @@ -22,7 +22,6 @@ -