From 7d0f38a9e46f8e786bd05f97c2392b49fcb85de6 Mon Sep 17 00:00:00 2001 From: Oceania2018 Date: Tue, 19 Feb 2019 22:54:36 -0600 Subject: [PATCH] Update document --- README.md | 2 +- docs/TIM.jpg | Bin 0 -> 66505 bytes docs/TIM.png | Bin 15162 -> 0 bytes docs/source/ImageRecognition.md | 136 ++++++++++++++++++ docs/source/Table of Contents.md | 24 ++++ docs/source/index.rst | 3 +- src/TensorFlowNET.Core/Graphs/Graph.Import.cs | 8 ++ .../Sessions/BaseSession.cs | 4 + .../TensorFlowNET.Core.csproj | 5 +- ...abelImage.cs => InceptionArchGoogLeNet.cs} | 21 +-- 10 files changed, 181 insertions(+), 22 deletions(-) create mode 100644 docs/TIM.jpg delete mode 100644 docs/TIM.png create mode 100644 docs/source/ImageRecognition.md rename test/TensorFlowNET.Examples/{LabelImage.cs => InceptionArchGoogLeNet.cs} (86%) diff --git a/README.md b/README.md index 0e0327ae..48469df0 100644 --- a/README.md +++ b/README.md @@ -61,4 +61,4 @@ Star me or raise issue on [Github](https://github.com/SciSharp/TensorFlow.NET) f Scan QR code to join TIM group: -![SciSharp STACK](docs/TIM.png) +![SciSharp STACK](docs/TIM.jpg) diff --git a/docs/TIM.jpg b/docs/TIM.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a557a7be34237fe6184ae778e1f351d9f0c589df GIT binary patch literal 66505 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 literal 0 HcmV?d00001 diff --git a/docs/TIM.png b/docs/TIM.png deleted file mode 100644 index 55e2ebbe9f6f0e7920d0282c3ca42c2361ff51b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15162 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 diff --git a/docs/source/ImageRecognition.md b/docs/source/ImageRecognition.md new file mode 100644 index 00000000..312d006e --- /dev/null +++ b/docs/source/ImageRecognition.md @@ -0,0 +1,136 @@ +# Chapter. Image Recognition + +An example for using the [TensorFlow.NET](https://github.com/SciSharp/TensorFlow.NET) and [NumSharp](https://github.com/SciSharp/NumSharp) for image recognition, it will use a pre-trained inception model to predict a image which outputs the categories sorted by probability. The original paper is [here](https://arxiv.org/pdf/1512.00567.pdf). The Inception architecture of GoogLeNet was designed to perform well even under strict constraints on memory and computational budget. The computational cost of Inception is also much lower than other performing successors. This has made it feasible to utilize Inception networks in big-data scenarios, where huge amount of data needed to be processed at reasonable cost or scenarios where memory or computational capacity is inherently limited, for example in mobile vision settings. + +The GoogLeNet architecture conforms to below design principles: + +* Avoid representational bottlenecks, especially early in the network. +* Higher dimensional representations are easier to process locally within a network. +* Spatial aggregation can be done over lower dimensional embeddings without much or any loss in representational power. +* Balance the width and depth of the network. + +#### Let's get started with real code. + +##### 1. Prepare data + +This example will download the dataset and uncompress it automatically. Some external paths are omitted, please refer to the source code for the real path. + +```csharp +private void PrepareData() +{ + Directory.CreateDirectory(dir); + + // get model file + string url = "models/inception_v3_2016_08_28_frozen.pb.tar.gz"; + + string zipFile = Path.Join(dir, $"{pbFile}.tar.gz"); + Utility.Web.Download(url, zipFile); + + Utility.Compress.ExtractTGZ(zipFile, dir); + + // download sample picture + string pic = "grace_hopper.jpg"; + Utility.Web.Download($"data/{pic}", Path.Join(dir, pic)); +} +``` + +##### 2. Load image file and normalize + +We need to load a sample image to test our pre-trained inception model. Convert it into tensor and normalized the input image. The pre-trained model takes input in the form of a 4-dimensional tensor with shape [BATCH_SIZE, INPUT_HEIGHT, INPUT_WEIGHT, 3] where: + +- BATCH_SIZE allows for inference of multiple images in one pass through the graph +- INPUT_HEIGHT is the height of the images on which the model was trained +- INPUT_WEIGHT is the width of the images on which the model was trained +- 3 is the (R, G, B) values of the pixel colors represented as a float. + +```csharp +private NDArray ReadTensorFromImageFile(string file_name, + int input_height = 299, + int input_width = 299, + int input_mean = 0, + int input_std = 255) +{ + return with(tf.Graph().as_default(), graph => + { + var file_reader = tf.read_file(file_name, "file_reader"); + var image_reader = tf.image.decode_jpeg(file_reader, channels: 3, name: "jpeg_reader"); + var caster = tf.cast(image_reader, tf.float32); + var dims_expander = tf.expand_dims(caster, 0); + var resize = tf.constant(new int[] { input_height, input_width }); + var bilinear = tf.image.resize_bilinear(dims_expander, resize); + var sub = tf.subtract(bilinear, new float[] { input_mean }); + var normalized = tf.divide(sub, new float[] { input_std }); + + return with(tf.Session(graph), sess => sess.run(normalized)); + }); +} +``` + +##### 3. Load pre-trained model and predict + +Load the pre-trained inception model which is saved as Google's protobuf file format. Construct a new graph then set input and output operations in a new session. After run the session, you will get a numpy-like ndarray which is provided by NumSharp. With NumSharp, you can easily perform various operations on multiple dimensional arrays in the .NET environment. + +```csharp +public void Run() +{ + PrepareData(); + + var labels = File.ReadAllLines(Path.Join(dir, labelFile)); + + var nd = ReadTensorFromImageFile(Path.Join(dir, picFile), + input_height: input_height, + input_width: input_width, + input_mean: input_mean, + input_std: input_std); + + var graph = Graph.ImportFromPB(Path.Join(dir, pbFile)); + var input_operation = graph.get_operation_by_name(input_name); + var output_operation = graph.get_operation_by_name(output_name); + + var results = with(tf.Session(graph), + sess => sess.run(output_operation.outputs[0], + new FeedItem(input_operation.outputs[0], nd))); + + results = np.squeeze(results); + + var argsort = results.argsort(); + var top_k = argsort.Data() + .Skip(results.size - 5) + .Reverse() + .ToArray(); + + foreach (float idx in top_k) + Console.WriteLine($"{picFile}: {idx} {labels[(int)idx]}, {results[(int)idx]}"); +} +``` + +##### 4. Print the result + +The best probability is `military uniform` which is 0.8343058. It's the correct classification. + +```powershell +2/18/2019 3:56:18 AM Starting InceptionArchGoogLeNet +label_image_data\inception_v3_2016_08_28_frozen.pb.tar.gz already exists. +label_image_data\grace_hopper.jpg already exists. +2019-02-19 21:56:18.684463: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 +create_op: Const 'file_reader/filename', inputs: empty, control_inputs: empty, outputs: file_reader/filename:0 +create_op: ReadFile 'file_reader', inputs: file_reader/filename:0, control_inputs: empty, outputs: file_reader:0 +create_op: DecodeJpeg 'jpeg_reader', inputs: file_reader:0, control_inputs: empty, outputs: jpeg_reader:0 +create_op: Cast 'Cast/Cast', inputs: jpeg_reader:0, control_inputs: empty, outputs: Cast/Cast:0 +create_op: Const 'ExpandDims/dim', inputs: empty, control_inputs: empty, outputs: ExpandDims/dim:0 +create_op: ExpandDims 'ExpandDims', inputs: Cast/Cast:0, ExpandDims/dim:0, control_inputs: empty, outputs: ExpandDims:0 +create_op: Const 'Const', inputs: empty, control_inputs: empty, outputs: Const:0 +create_op: ResizeBilinear 'ResizeBilinear', inputs: ExpandDims:0, Const:0, control_inputs: empty, outputs: ResizeBilinear:0 +create_op: Const 'y', inputs: empty, control_inputs: empty, outputs: y:0 +create_op: Sub 'Sub', inputs: ResizeBilinear:0, y:0, control_inputs: empty, outputs: Sub:0 +create_op: Const 'y_1', inputs: empty, control_inputs: empty, outputs: y_1:0 +create_op: RealDiv 'truediv', inputs: Sub:0, y_1:0, control_inputs: empty, outputs: truediv:0 +grace_hopper.jpg: 653 military uniform, 0.8343058 +grace_hopper.jpg: 668 mortarboard, 0.02186947 +grace_hopper.jpg: 401 academic gown, 0.01035806 +grace_hopper.jpg: 716 pickelhaube, 0.008008132 +grace_hopper.jpg: 466 bulletproof vest, 0.005350832 +2/18/2019 3:56:25 AM Completed InceptionArchGoogLeNet +``` + +You can find the full source code from [github](https://github.com/SciSharp/TensorFlow.NET/tree/master/test/TensorFlowNET.Examples). \ No newline at end of file diff --git a/docs/source/Table of Contents.md b/docs/source/Table of Contents.md index 0783195d..b28505cc 100644 --- a/docs/source/Table of Contents.md +++ b/docs/source/Table of Contents.md @@ -14,7 +14,31 @@ ##### 2. Hello World + + ## Part II. Tensorflow.NET in Depth +##### 1. Control Dependency ...................................................................................................... + +##### 2. Graph .................................... + +##### 3. Session ............................ + + + ## Part III. Dealing with Human Language +##### 1. Text Classification ............................................................................................ + +##### 2. Named Entity Recognition .............................................................................. + +##### 3. Sentiment Analyze ........................................................................................... + +##### 4. Sentence Dependency ........................................................................ + + + +## Part IV. Image Recognition + +##### 1. Inception Model ................................................................................................................. 100 + diff --git a/docs/source/index.rst b/docs/source/index.rst index 362240de..8ad5a091 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -27,4 +27,5 @@ Welcome to TensorFlow.NET's documentation! ControlDependency Gradient Train - EagerMode \ No newline at end of file + EagerMode + ImageRecognition \ No newline at end of file diff --git a/src/TensorFlowNET.Core/Graphs/Graph.Import.cs b/src/TensorFlowNET.Core/Graphs/Graph.Import.cs index 8511cc01..1576c650 100644 --- a/src/TensorFlowNET.Core/Graphs/Graph.Import.cs +++ b/src/TensorFlowNET.Core/Graphs/Graph.Import.cs @@ -34,5 +34,13 @@ namespace Tensorflow c_api.TF_GraphImportGraphDef(_handle, graph_def, opts, Status); return Status; } + + public static Graph ImportFromPB(string file_path) + { + var graph = tf.Graph().as_default(); + var graph_def = GraphDef.Parser.ParseFrom(File.ReadAllBytes(file_path)); + importer.import_graph_def(graph_def); + return graph; + } } } diff --git a/src/TensorFlowNET.Core/Sessions/BaseSession.cs b/src/TensorFlowNET.Core/Sessions/BaseSession.cs index f8e7f36b..9c058413 100644 --- a/src/TensorFlowNET.Core/Sessions/BaseSession.cs +++ b/src/TensorFlowNET.Core/Sessions/BaseSession.cs @@ -70,6 +70,9 @@ namespace Tensorflow case float floatVal: feed_dict_tensor[subfeed_t] = (NDArray)floatVal; break; + case double doubleVal: + feed_dict_tensor[subfeed_t] = (NDArray)doubleVal; + break; case int intVal: feed_dict_tensor[subfeed_t] = (NDArray)intVal; break; @@ -80,6 +83,7 @@ namespace Tensorflow feed_dict_tensor[subfeed_t] = (NDArray)bytes; break; default: + Console.WriteLine($"can't handle data type of subfeed_val"); throw new NotImplementedException("_run subfeed"); } feed_map[subfeed_t.name] = (subfeed_t, subfeed_val); diff --git a/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj b/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj index 68842cba..eda472c1 100644 --- a/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj +++ b/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj @@ -17,9 +17,8 @@ Google's TensorFlow binding in .NET Standard. Docs: https://tensorflownet.readthedocs.io 0.3.0.0 - Added a bunch of APIs. -Fixed String tensor creation bug. -Upgraded to TensorFlow 1.13 RC-1. + Added image prediction example. +Upgraded to TensorFlow 1.13 RC2. 7.2 0.3.0.0 diff --git a/test/TensorFlowNET.Examples/LabelImage.cs b/test/TensorFlowNET.Examples/InceptionArchGoogLeNet.cs similarity index 86% rename from test/TensorFlowNET.Examples/LabelImage.cs rename to test/TensorFlowNET.Examples/InceptionArchGoogLeNet.cs index afe86aec..3cd0dbda 100644 --- a/test/TensorFlowNET.Examples/LabelImage.cs +++ b/test/TensorFlowNET.Examples/InceptionArchGoogLeNet.cs @@ -14,9 +14,10 @@ using Tensorflow; namespace TensorFlowNET.Examples { /// + /// Inception Architecture for Computer Vision /// Port from tensorflow\examples\label_image\label_image.py /// - public class LabelImage : Python, IExample + public class InceptionArchGoogLeNet : Python, IExample { string dir = "label_image_data"; string pbFile = "inception_v3_2016_08_28_frozen.pb"; @@ -33,7 +34,7 @@ namespace TensorFlowNET.Examples { PrepareData(); - var labels = LoadLabels(Path.Join(dir, labelFile)); + var labels = File.ReadAllLines(Path.Join(dir, labelFile)); var nd = ReadTensorFromImageFile(Path.Join(dir, picFile), input_height: input_height, @@ -41,7 +42,7 @@ namespace TensorFlowNET.Examples input_mean: input_mean, input_std: input_std); - var graph = LoadGraph(Path.Join(dir, pbFile)); + var graph = Graph.ImportFromPB(Path.Join(dir, pbFile)); var input_operation = graph.get_operation_by_name(input_name); var output_operation = graph.get_operation_by_name(output_name); @@ -61,19 +62,6 @@ namespace TensorFlowNET.Examples Console.WriteLine($"{picFile}: {idx} {labels[(int)idx]}, {results[(int)idx]}"); } - private string[] LoadLabels(string file) - { - return File.ReadAllLines(file); - } - - private Graph LoadGraph(string modelFile) - { - var graph = tf.Graph().as_default(); - var graph_def = GraphDef.Parser.ParseFrom(File.ReadAllBytes(modelFile)); - tf.import_graph_def(graph_def); - return graph; - } - private NDArray ReadTensorFromImageFile(string file_name, int input_height = 299, int input_width = 299, @@ -97,7 +85,6 @@ namespace TensorFlowNET.Examples private void PrepareData() { - Directory.CreateDirectory(dir); // get model file