Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / artificial-intelligence / Keras

Starting with Keras.NET in C# - Train Your First Model

5.00/5 (1 vote)
20 Nov 2020MIT4 min read 28.5K  
In this article, I want to show an example to make a simple .NET-Core App using Keras.NET and Zalandos Fashion-mnist.
The article is about a short introduction on how to train a first Model with Keras.NET.

Introduction

Since machine learning has become very popular, using open source SDKs like Keras and/or as backend Tensorflow, the language Python has become popular too again (as opposed to the forecast, that Python will be dead in the next five years). As a Research Engineer in the .NET environment, it creates a lot of problems for me, using Python there and my main focus is on C#. Of course, you can somehow embed Python code to your application (i.e., run a Python script within your .NET application), but this doesn't make it much more better.

Another solution, I thought, would be using IronPython, an SDK to run directly Python code, but

  1. it is still using Python 2.7 (with end of support in 2020), and support for Python 3 is pronounced like "DO NOT USE!", ok...
  2. it doesn't support a lot of additional packages like numpy which is essential to do machine learning things
  3. it's very hard to fix all this issues... just don't use it for purposes like this.

So I started to figure new solutions out and how to avoid using additional Python environments, that had to be called extra while the application is started, in a .NET Core application and get to know about Keras.NET (https://github.com/SciSharp/Keras.NET) from SciSharp STACK. To be clear, I don't care if a SDK is using Python embedded, but I don't want to code my machine learning prototypes in Python, so this is the game changer here.

Background

The documentation of Keras.NET is very short, and if you need further knowledge, they linked to the original Keras documentation. This is very useful for the understanding of how this Framework is working. But it is big pain to figure out how the SDK works in C#.

Here is the documentation link: https://scisharp.github.io/Keras.NET/
Please have a look at the prerequisites (where you get to know, that you have to install Python as well).

And here, you will find the API Documentation: https://scisharp.github.io/Keras.NET/api/index.html

To understand what is happening here, you need to understand the way in which Keras is working, what's the purposes of a Dense Layer, Epochs and so on.

Using the Code

The article from inspires me to show a second example using existing datasets and how to train them using Keras.NET. So this is something about using Keras.NET to see some difference than using Keras (in Python) and maybe someone can find this very useful.

First, you will need the Nuget Keras.NET. Using the package Manager in Visual Studio, it goes like:

PM> Install-Package Keras.NET -Version 3.8.4.4

Besides this, you will need to install Keras and Tensorflow for Python using the pip installer in the windows CLI or Powershell:

pip install keras

pip install tensorflow

It has to look like within the Windows-CLI:

PowerShell
C:\Users\YOURNAME>pip install keras

If you have trouble with the pip installer, please check if you have set up Python to the System environment. There is a checkbox, called 'Add Python to PATH' on the bottom of the install screen, which is very important.

If this doesn't help, you probably have to set the path by yourself (there are tones of How-To in the internet, how to fix pip, and once you fixed this issue, you are sure that Python is set up correctly).

And finally, you will need the training and test sets: https://github.com/zalandoresearch/fashion-mnist#get-the-data.

First, I stored the data locally and unzipped them, because I didn't want to make an other function for unzipping purposes (which is actually not hard to implement, but I want to stay on focus here). It is just one data. Using the code below (and call the openDatas function, you will need to unzip this, otherwise the function can't read the data. Put the four datas (2x images, 2x lables...train and test).

Second, I figure in the API-Doc out, that there is already implement a function to load the datas directly, see: https://scisharp.github.io/Keras.NET/api/Keras.Datasets.FashionMNIST.html

So here we go: running the first training of the model for further purposes.

The entry point of my .NET-Core is very simple. I made a class (KerasClass) for my training and just call them from the Main function:

C#
using System;

namespace Keras.net_and_fashion_mnist
{
    class Program
    {
        static void Main(string[] args)
        {
            KerasClass keras = new KerasClass();
            keras.TrainModel();
        }        
    }
}

The KerasClass is much more interesting:

C#
using Keras.Datasets;
using Keras.Layers;
using Keras.Models;
using Keras.Utils;
using Numpy;
using System;
using System.IO;
using System.Linq;

namespace Keras.net_and_fashion_mnist
{
    class KerasClass
    {
        public void TrainModel()
        {

            int batch_size = 1000;   //Size of the batches per epoch
            int num_classes = 10;    //We got 10 outputs since 
                                     //we can predict 10 different labels seen on the 
                    //dataset: https://github.com/zalandoresearch/fashion-mnist#labels
            int epochs = 30;         //Amount on trainingperiods, 
                                     //I figure it out that the maximum is something about 
                                     //700 epochs, after this it won't increase the 
                                     //accuracy siginificantly

            // input image dimensions
            int img_rows = 28, img_cols = 28;

            // the data, split between train and test sets
            var ((x_train, y_train), (x_test, y_test)) = 
                                      FashionMNIST.LoadData(); // Load the datasets from 
                                      // fashion MNIST, Keras.Net implement this directly

            x_train.reshape(-1, img_rows, img_cols).astype(np.float32); //ByteArray needs 
                                      //to be reshaped to fit the dimmensions of the y arrays

            y_train = Util.ToCategorical(y_train, num_classes); //here, you modify the 
                                                                //forecast data to 10 outputs
                                                                //as we have 10 different 
                                                                //labels to predict (see the 
                                                                //Labels on the Dataset)
            y_test = Util.ToCategorical(y_test, num_classes);   //same for the test data 
                                                                //[hint: you can change this 
                                                                //in example you want to 
                                                                //make just a binary 
                                                                //crossentropy as you just 
                                                                //want to figure, i.e., if 
                                                                //this is a angleboot or not

            var model = new Sequential();

            model.Add(new Dense(100, 784, "sigmoid")); //hidden dense layer, with 100 neurons, 
                                                       //you have 28*28 pixel which make 
                                                       //784 'inputs', and sigmoid function 
                                                       //as activationfunction
            model.Add(new Dense(10, null, "sigmoid")); //Ouputlayer with 10 outputs,...
            model.Compile(optimizer: "sgd", loss: "categorical_crossentropy", 
                metrics: new string[] { "accuracy" }); //we have a crossentropy as prediction 
                                                       //and want to see as well the 
                                                       //accuracy metric.

            var X_train = x_train.reshape(60000, 784); //this is actually very important. 
                                                       //C# works with pointers, 
                                                       //so if you have to reshape (again) 
                                                       //the function for the correct 
                                                       //processing, you need to write this 
                                                       //to a different var
            var X_test = x_test.reshape(10000, 784);

            model.Fit(X_train, y_train, batch_size, epochs, 1); //now, we set the data to 
                                                                //the model with all the 
                                                                //arguments (x and y data, 
                                                                //batch size...the '1' is 
                                                                //just verbose=1

            Console.WriteLine("---------------------");
            Console.WriteLine(X_train.shape);
            Console.WriteLine(X_test.shape);
            Console.WriteLine(y_train[0]);
            Console.WriteLine(y_train[1]);       //some outputs...you can play with them
            
            var y_train_pred = model.Predict(X_train);       //prediction on the train data
            Console.WriteLine(y_train_pred);

            model.Evaluate(X_test.reshape(-1, 784), y_test); //-1 tells the code that 
                                                             //it can figure out the size of 
                                                             //the array by itself
        }

        private byte[] openDatas(string path, int skip)      //just the open Data function. 
                                                             //As I mentioned, I did not work 
                                                             //with unzip stuff, you have 
                                                             //to unzip the data before 
                                                             //by yourself
        {
            var file = File.ReadAllBytes(path).Skip(skip).ToArray();
            return file;
        }

        //Hint: First, I was working by opening the data locally and 
        //I wanted to figure it out how to present data to the arrays. 
        //So you can use something like this and call this within the TrainModel() function:
        //x_train = openDatas(@"PATH\OF\YOUR\DATAS\train-images-idx3-ubyte", 16);
        //y_train = openDatas(@"PATH\OF\YOUR\DATAS\train-labels-idx1-ubyte", 8);
        //x_test = openDatas(@"PATH\OF\YOUR\DATAS\t10k-images-idx3-ubyte", 16);
        //y_test = openDatas(@"PATH\OF\YOUR\DATAS\t10k-labels-idx1-ubyte", 8);
    }
}

Points of Interest

Using this code will provide your first training of your own model. For me, this was my first step to Keras.NET and I want to share this, because there are not that many examples of Keras.NET. Maybe you can use this for your purposes.

History

  • 19th November, 2020: Initial release
  • 20th November, 2020: Removed two images

License

This article, along with any associated source code and files, is licensed under The MIT License