diff --git a/README.md b/README.md index a2a205fd..196a8f76 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Import TF.NET. using Tensorflow; ``` -Add two constants. +Add two constants: ```cs // Create a Constant op var a = tf.constant(4.0f); @@ -50,7 +50,7 @@ using (var sess = tf.Session()) } ``` -Feed placeholder. +Feed placeholder: ```cs // Create a placeholder op var a = tf.placeholder(tf.float32); @@ -59,27 +59,86 @@ var c = tf.add(a, b); using(var sess = tf.Session()) { - var feed_dict = new Dictionary(); - feed_dict.Add(a, 3.0f); - feed_dict.Add(b, 2.0f); - - var o = sess.run(c, feed_dict); + var o = sess.run(c, new FeedItem(a, 3.0f), new FeedItem(b, 2.0f)); } ``` +Linear Regression: + +```c# +// We can set a fixed init value in order to debug +var W = tf.Variable(-0.06f, name: "weight"); +var b = tf.Variable(-0.73f, name: "bias"); + +// Construct a linear model +var pred = tf.add(tf.multiply(X, W), b); + +// Mean squared error +var cost = tf.reduce_sum(tf.pow(pred - Y, 2.0f)) / (2.0f * n_samples); + +// Gradient descent +// Note, minimize() knows to modify W and b because Variable objects are trainable=True by default +var optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost); + +// Initialize the variables (i.e. assign their default value) +var init = tf.global_variables_initializer(); + +// Start training +with(tf.Session(), sess => +{ + // Run the initializer + sess.run(init); + + // Fit all training data + for (int epoch = 0; epoch < training_epochs; epoch++) + { + foreach (var (x, y) in zip(train_X, train_Y)) + sess.run(optimizer, new FeedItem(X, x), new FeedItem(Y, y)); + + // Display logs per epoch step + if ((epoch + 1) % display_step == 0) + { + var c = sess.run(cost, new FeedItem(X, train_X), new FeedItem(Y, train_Y)); + Console.WriteLine($"Epoch: {epoch + 1} cost={c} " + $"W={sess.run(W)} b={sess.run(b)}"); + } + + Console.WriteLine("Optimization Finished!"); + var training_cost = sess.run(cost, new FeedItem(X, train_X), new FeedItem(Y, train_Y)); + Console.WriteLine($"Training cost={training_cost} W={sess.run(W)} b={sess.run(b)}"); + + // Testing example + var test_X = np.array(6.83f, 4.668f, 8.9f, 7.91f, 5.7f, 8.7f, 3.1f, 2.1f); + var test_Y = np.array(1.84f, 2.273f, 3.2f, 2.831f, 2.92f, 3.24f, 1.35f, 1.03f); + Console.WriteLine("Testing... (Mean square loss Comparison)"); + + var testing_cost = sess.run(tf.reduce_sum(tf.pow(pred - Y, 2.0f)) / (2.0f * test_X.shape[0]), new FeedItem(X, test_X), new FeedItem(Y, test_Y)); + Console.WriteLine($"Testing cost={testing_cost}"); + + var diff = Math.Abs((float)training_cost - (float)testing_cost); + Console.WriteLine($"Absolute mean square loss difference: {diff}"); + } +}); +``` + + + Read the docs & book [The Definitive Guide to Tensorflow.NET](https://tensorflownet.readthedocs.io/en/latest/FrontCover.html). ### More examples: * [Hello World](test/TensorFlowNET.Examples/HelloWorld.cs) * [Basic Operations](test/TensorFlowNET.Examples/BasicOperations.cs) -* [Image Recognition](test/TensorFlowNET.Examples/ImageRecognition.cs) * [Linear Regression](test/TensorFlowNET.Examples/LinearRegression.cs) * [Logistic Regression](test/TensorFlowNET.Examples/LogisticRegression.cs) * [Nearest Neighbor](test/TensorFlowNET.Examples/NearestNeighbor.cs) +* [Naive Bayes Classification](test/TensorFlowNET.Examples/NaiveBayesClassifier.cs) +* [Image Recognition](test/TensorFlowNET.Examples/ImageRecognition.cs) +* [K-means Clustering](test/TensorFlowNET.Examples/KMeansClustering.cs) +* [NN XOR](test/TensorFlowNET.Examples/NeuralNetXor.cs) +* [Object Detection](test/TensorFlowNET.Examples/ObjectDetection.cs) * [Text Classification](test/TensorFlowNET.Examples/TextClassificationWithMovieReviews.cs) * [CNN Text Classification](test/TensorFlowNET.Examples/CnnTextClassification.cs) -* [Naive Bayes Classification](test/TensorFlowNET.Examples/NaiveBayesClassifier.cs) + * [Named Entity Recognition](test/TensorFlowNET.Examples/NamedEntityRecognition.cs) ### Contribute: @@ -94,7 +153,7 @@ You can: * Debug one of the unit tests that is marked as Ignored to get it to work (can be challenging) * Debug one of the not yet working examples and get it to work (hard) -How to debug unit tests: +### How to debug unit tests: The best way to find out why a unit test is failing is to single step it in C# and its pendant Python at the same time to see where the flow of execution digresses or where variables exhibit different values. Good Python IDEs like PyCharm let you single step into the tensorflow library code. diff --git a/docs/TIM.jpg b/docs/TIM.jpg index 448e3b6e..a436aa30 100644 Binary files a/docs/TIM.jpg and b/docs/TIM.jpg differ diff --git a/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj b/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj index 16ffa373..6368f9b7 100644 --- a/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj +++ b/src/TensorFlowNET.Core/TensorFlowNET.Core.csproj @@ -44,7 +44,7 @@ More math/ linalg APIs. - + diff --git a/test/TensorFlowNET.Examples/NeuralNetXor.cs b/test/TensorFlowNET.Examples/NeuralNetXor.cs index 56dbcd14..dca0aa54 100644 --- a/test/TensorFlowNET.Examples/NeuralNetXor.cs +++ b/test/TensorFlowNET.Examples/NeuralNetXor.cs @@ -76,7 +76,7 @@ namespace TensorFlowNET.Examples var init = tf.global_variables_initializer(); float loss_value = 0; // Start tf session - with(tf.Session(graph), sess => + with(tf.Session(graph), sess => { sess.run(init); var step = 0; diff --git a/test/TensorFlowNET.Examples/Text/TextClassificationWithMovieReviews.cs b/test/TensorFlowNET.Examples/Text/BinaryTextClassification.cs similarity index 82% rename from test/TensorFlowNET.Examples/Text/TextClassificationWithMovieReviews.cs rename to test/TensorFlowNET.Examples/Text/BinaryTextClassification.cs index 2df012ac..c9a1c95a 100644 --- a/test/TensorFlowNET.Examples/Text/TextClassificationWithMovieReviews.cs +++ b/test/TensorFlowNET.Examples/Text/BinaryTextClassification.cs @@ -9,14 +9,19 @@ using NumSharp; namespace TensorFlowNET.Examples { - public class TextClassificationWithMovieReviews : Python, IExample + /// + /// This example classifies movie reviews as positive or negative using the text of the review. + /// This is a binary—or two-class—classification, an important and widely applicable kind of machine learning problem. + /// https://github.com/tensorflow/docs/blob/master/site/en/tutorials/keras/basic_text_classification.ipynb + /// + public class BinaryTextClassification : Python, IExample { public int Priority => 9; - public bool Enabled { get; set; } = false; - public string Name => "Movie Reviews"; - public bool ImportGraph { get; set; } = true; + public bool Enabled { get; set; } = true; + public string Name => "Binary Text Classification"; + public bool ImportGraph { get; set; } = true; - string dir = "text_classification_with_movie_reviews"; + string dir = "binary_text_classification"; string dataFile = "imdb.zip"; NDArray train_data, train_labels, test_data, test_labels; @@ -89,17 +94,18 @@ namespace TensorFlowNET.Examples private NDArray ReadData(string file) { var lines = File.ReadAllLines(file); - var nd = new NDArray(lines[0].StartsWith("[") ? typeof(object) : np.int32, new Shape(lines.Length)); + var nd = new NDArray(lines[0].StartsWith("[") ? typeof(string) : np.int32, new Shape(lines.Length)); if (lines[0].StartsWith("[")) { for (int i = 0; i < lines.Length; i++) { - var matches = Regex.Matches(lines[i], @"\d+\s*"); + /*var matches = Regex.Matches(lines[i], @"\d+\s*"); var data = new int[matches.Count]; for (int j = 0; j < data.Length; j++) data[j] = Convert.ToInt32(matches[j].Value); - nd[i] = data.ToArray(); + nd[i] = data.ToArray();*/ + nd[i] = lines[i].Substring(1, lines[i].Length - 2).Replace(" ", string.Empty); } } else diff --git a/test/TensorFlowNET.Examples/python/text_classification_with_movie_reviews.py b/test/TensorFlowNET.Examples/python/binary_text_classification.py similarity index 85% rename from test/TensorFlowNET.Examples/python/text_classification_with_movie_reviews.py rename to test/TensorFlowNET.Examples/python/binary_text_classification.py index 42824e35..f783327c 100644 --- a/test/TensorFlowNET.Examples/python/text_classification_with_movie_reviews.py +++ b/test/TensorFlowNET.Examples/python/binary_text_classification.py @@ -71,30 +71,12 @@ partial_y_train = train_labels[10000:] history = model.fit(partial_x_train, partial_y_train, - epochs=40, + epochs=20, batch_size=512, validation_data=(x_val, y_val), verbose=1) results = model.evaluate(test_data, test_labels) - -# serialize model to JSON -model_json = model.to_json() -with open("model.json", "w") as json_file: - json_file.write(model_json) -# serialize weights to HDF5 -model.save_weights("model.h5") -print("Saved model to disk") - -# load json and create model -json_file = open('model.json', 'r') -loaded_model_json = json_file.read() -json_file.close() -loaded_model = model_from_json(loaded_model_json) -# load weights into new model -loaded_model.load_weights("model.h5") -print("Loaded model from disk") - print(results) history_dict = history.history diff --git a/test/TensorFlowNET.UnitTest/ExamplesTests/ExamplesTest.cs b/test/TensorFlowNET.UnitTest/ExamplesTests/ExamplesTest.cs index 92177dc2..b93f678b 100644 --- a/test/TensorFlowNET.UnitTest/ExamplesTests/ExamplesTest.cs +++ b/test/TensorFlowNET.UnitTest/ExamplesTests/ExamplesTest.cs @@ -105,7 +105,7 @@ namespace TensorFlowNET.ExamplesTests public void TextClassificationWithMovieReviews() { tf.Graph().as_default(); - new TextClassificationWithMovieReviews() { Enabled = true }.Run(); + new BinaryTextClassification() { Enabled = true }.Run(); } [TestMethod]