65.9K
CodeProject 正在变化。 阅读更多。
Home

在 C# 中使用 Keras.NET 入门 - 训练你的第一个模型

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2020 年 11 月 20 日

MIT

4分钟阅读

viewsIcon

29661

在本文中,我想展示一个使用 Keras.NET 和 Zalando Fashion-mnist 创建简单 .NET-Core 应用程序的例子。

引言

由于机器学习变得非常流行,使用像 Keras 和/或作为后端的 Tensorflow 这样的开源 SDK,Python 语言也再次流行起来(与预测 Python 将在未来五年内消亡相反)。作为 .NET 环境中的研究工程师,在其中使用 Python 给我带来了很多问题,而我的主要重点是 C#。 当然,你可以以某种方式将 Python 代码嵌入到你的应用程序中(例如,在你的 .NET 应用程序中运行 Python 脚本),但这并没有使它变得更好。

我想到另一种解决方案是使用 IronPython,这是一个直接运行 Python 代码的 SDK,但是

  1. 它仍然使用 Python 2.7(在 2020 年结束支持),并且对 Python 3 的支持听起来像“不要使用!”...好吧...
  2. 它不支持很多额外的包,比如 numpy,这对于进行机器学习事情至关重要
  3. 修复所有这些问题非常困难... 不要将其用于这样的目的。

因此,我开始寻找新的解决方案,以及如何避免在使用 .NET Core 应用程序时调用额外的 Python 环境,并了解了 SciSharp STACK 中的 Keras.NET (https://github.com/SciSharp/Keras.NET)。 需要明确的是,我不在乎 SDK 是否使用了嵌入式 Python,但我不想用 Python 编写我的机器学习原型,所以这是改变游戏规则的地方。

背景

Keras.NET 的文档非常简短,如果你需要更多知识,他们链接到原始的 Keras 文档。 这对于理解这个框架的工作原理非常有用。 但是弄清楚 SDK 在 C# 中如何工作是很痛苦的。

这是文档链接:https://scisharp.github.io/Keras.NET/
请查看先决条件(在那里你会知道,你必须安装 Python)。

在这里,你将找到 API 文档:https://scisharp.github.io/Keras.NET/api/index.html

要理解这里发生了什么,你需要理解 Keras 的工作方式,密集层、Epoch 等的用途。

Using the Code

来自的文章激励我展示第二个使用现有数据集的示例,以及如何使用 Keras.NET 训练它们。 因此,这是关于使用 Keras.NET 来查看与使用 Keras(在 Python 中)的一些差异,也许有人会发现这非常有用。

首先,你需要 Nuget Keras.NET。 使用 Visual Studio 中的包管理器,它看起来像

PM> Install-Package Keras.NET -Version 3.8.4.4

除此之外,你还需要使用 Windows CLI 或 Powershell 中的 pip 安装程序为 Python 安装 Keras 和 Tensorflow

pip install keras

pip install tensorflow

它在 Windows-CLI 中必须看起来像这样

C:\Users\YOURNAME>pip install keras

如果你在使用 pip 安装程序时遇到问题,请检查是否已将 Python 设置到系统环境变量。 在安装屏幕的底部有一个名为 '将 Python 添加到 PATH' 的复选框,这非常重要。

如果这没有帮助,你可能必须自己设置路径(互联网上有很多关于如何修复 pip 的方法,一旦你解决了这个问题,你就可以确定 Python 已正确设置)。

最后,你需要训练和测试集:https://github.com/zalandoresearch/fashion-mnist#get-the-data

首先,我将数据存储在本地并解压缩,因为我不想为解压缩目的创建一个其他函数(实际上这并不难实现,但我想专注于此)。 这只是一份数据。 使用下面的代码(并调用 openDatas 函数,你需要解压缩它,否则该函数无法读取数据。 将四个数据(2x 图像,2x 标签...训练和测试)放入其中。

其次,我在 API 文档中发现,已经实现了一个直接加载数据的函数,请参阅:https://scisharp.github.io/Keras.NET/api/Keras.Datasets.FashionMNIST.html

所以我们开始吧:运行模型的第一次训练以用于进一步的目的。

我的 .NET-Core 的入口点非常简单。 我为我的训练创建了一个类 (KerasClass),然后只是从 Main 函数调用它们

using System;

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

KerasClass 更有趣

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);
    }
}

关注点

使用此代码将提供您自己的模型的第一次训练。 对我来说,这是我迈向 Keras.NET 的第一步,我想分享它,因为 Keras.NET 的例子不多。 也许你可以将其用于你的目的。

历史

  • 2020 年 11 月 19 日:首次发布
  • 2020 年 11 月 20 日:删除了两张图片
© . All rights reserved.