?
機器學習是一個令人激動人心的領域,一直有新的技術突破。研究人員不斷推動機器智能的提升,教機器如何聽說讀寫——這些曾經是我們人類專屬的技能。機器學習的首選語言是Python,最受歡迎的庫是Google的TensorFlow。幾乎所有的代碼示例都是用Python編寫的,并且依賴于TensorFlow和NumPy庫。對于C#和.NET的開發人員來說,我們在面臨著一個嚴峻的選擇:要么學習Python,要么使用NET機器學習庫,并從頭開始精心編寫我們自己的C#代碼 。
?
事實上,這就是我在機器學習課程中常用的策略。我研究了許多使用Keras和TensorFlow的Python代碼,然后我從頭開始編寫自己的C#代碼,使用原生的CNTK和ML.NET庫代替。這種方法很有效,但它也有一些缺點:
?
- 我的學生習慣于.NET,這些編碼技巧不容易轉移到Python。
- CNTK和ML.NET不支持某些TensorFlow功能,因此我必須使用Python代碼向C#開發人員演示它們。
?
我一直在努力在.NET中編寫機器學習庫,模仿Python的API和編碼風格,如NativeKeras和KerasSharp,但這些項目不再處于積極開發的階段。我一直在尋找一個全面的.NET庫,它完全模仿了如何用Python編寫機器學習代碼,終于我發現了她——SciSharp。SciSharp正在為數據科學,機器學習和人工智能構建一個.NET開源生態系統,其理念是C#機器學習代碼應該像對應的Python代碼一樣盡可能地語法,與編程的感覺。
?
看看下面的例子 - 這是TensorFlow中的簡單線性回歸演示。 Python代碼在左側,相應的C#代碼在右側:
右邊的代碼看起來像Python,但它是實際的C#代碼。 它使用一個名為TesorFlow.NET的包裝器在幕后調用真正的TensorFlow庫。請注意,我們已經有了TensorFlow包裝器; 幾年前,Xamarin創始人米格爾大神建造了優秀的TensorFlowSharp。 但是,他的庫只暴露了低級別的TensorFlow API。 相比之下,SciSharp庫神奇地暴露了所有TensorFlow,包括高級圖形構建功能。
?
TensorFlow在很大程度上依賴于NumPy,這是一個高性能的Python數學庫,可以在內存中處理非常大的數據數組。 因此,SciSharp團隊開發了自己的版本NumSharp,這是NumPy到C#的端口。
NumSharp遵循與原始NumPy完全相同的編碼風格。 使用左側的Python代碼和右側的相應C#代碼查看此示例:同樣,右邊的代碼遵循與Python相同的語法約定和API樣式,但它實際上是C#代碼。
?
SciSharp團隊在這里取得了一項重大成就。 使用TensorFlow.NET和NumSharp,我們實際上可以使用Python代碼示例,將它們復制并粘貼到C#文件中,然后只需稍作修改即可運行它們——這為.NET開發人員打開了完整的機器學習生態系統。
?
我決定采用SciSharp。查看以下說明,以便在C#中啟動并運行您自己的TensorFlow代碼。我將構建一個簡單的線性回歸演示,它適合一些樣本數據的回歸線。
?
讓我們開始吧。以下是在.NET Core中設置新控制臺項目的方法:
?
$ dotnet new console -o LinearRegression
$ cd LinearRegression
?
?
接下來,我需要安裝我需要的軟件包:
?
$ dotnet add package TensorFlow.NET
?
?
就這樣簡單!這將安裝TensorFlow.NET包,它也將自動拉入NumSharp。該軟件包還安裝了Microsoft.ML.TensorFlow.Redist
,它是本機TensorFlow庫的跨平臺安裝程序。這將在Windows,Linux和OS / X上為您設置一切。
?
現在我準備開始編碼了。這是Program.cs的上半部分應該是這樣的:
?
using System;
using NumSharp;
using Tensorflow;
using static Tensorflow.Python;namespace LinearRegression
{/// <summary>/// The main program class/// </summary>public class Program{/// <summary>/// The main program entry point/// </summary>/// <param name="args">The command line arguments</param>public static void Main(string[] args){// load the datavar dataX = np.array(3.3f, 4.4f, 5.5f, 6.71f, 6.93f, 4.168f, 9.779f, 6.182f, 7.59f, 2.167f,7.042f, 10.791f, 5.313f, 7.997f, 5.654f, 9.27f, 3.1f);var dataY = np.array(1.7f, 2.76f, 2.09f, 3.19f, 1.694f, 1.573f, 3.366f, 2.596f, 2.53f, 1.221f,2.827f, 3.465f, 1.65f, 2.904f, 2.42f, 2.94f, 1.3f);var samples = dataX.shape[0];// the rest of the code goes here...}}
}
?
?
這是一個簡單的.NET Core控制臺應用程序。 請注意使用訓練數據設置NumPy數組的np.array
方法。 shape [0]調用檢索數組的長度,就像在Python中一樣。現在我將在TensorFlow中設置一個簡單的線性回歸模型:
?
此代碼調用tf.placeholder
來設置模型輸入和輸出:X表示輸入數據,Y表示輸出數據。
以下兩個調用tf.Variable
設置權重和偏差模型變量。 這些變量組合成一個模型如下:
?
讀者會發現這只是線性回歸的等式。 TensorFlow將在訓練期間調整W和b變量以找到完美的回歸線。
最后,代碼在損失變量中設置了一個損失函數。 損失函數是一種表達式,其值在訓練期間需要最小化。 我將使用均方誤差或MSE:
這只是模型預測與實際值之差的平方和。接下來,我將訓練這個模型1000次:
?
// use these training parameters
var epochs = 1000;
var learningRate = 0.01f;
var displayEvery = 50;// use a gradient descent optimizer
var optimizer = tf.train.GradientDescentOptimizer(learningRate).minimize(loss);// train the model
var init = tf.global_variables_initializer();
with(tf.Session(), sess =>
{sess.run(init);// run training epochsConsole.WriteLine("Training model...");for (int epoch = 0; epoch < epochs; epoch++){foreach (var (x, y) in zip<float>(dataX, dataY)){sess.run(optimizer, new FeedItem(X, x),new FeedItem(Y, y));}// display intermittent resultsif ((epoch + 1) % displayEvery == 0){var lossValue = sess.run(loss, new FeedItem(X, dataX), new FeedItem(Y, dataY));Console.WriteLine($" epoch: {epoch + 1}\tMSE = {lossValue}\tW = {sess.run(W)}\tb = {sess.run(b)}");}}// show final training lossvar trainingLoss = sess.run(loss,new FeedItem(X, dataX),new FeedItem(Y, dataY));Console.WriteLine($" Final MSE = {trainingLoss}");// the rest of the code goes here...
});
?
?
代碼設置GradientDescentOptimizer
以最小化損失函數,并使用tf.Session()
啟動TensorFlow會話。TensorFlow中的所有內容都需要調用tf.run()
來執行。所以我首先設置了一個global_variables_initializer
來初始化模型,然后運行它。然后我運行優化器1000個時期來訓練模型,每50個時期我運行損失函數并顯示中間訓練損失。循環完成后,我再次運行損失功能并顯示最終的訓練損失。
?
我現在有一個訓練有素的好模型,是時候在一些新數據上測試這個模型:
?
// load validation data
var testDataX = np.array(6.83f, 4.668f, 8.9f, 7.91f, 5.7f, 8.7f, 3.1f, 2.1f);
var testDataY = np.array(1.84f, 2.273f, 3.2f, 2.831f, 2.92f, 3.24f, 1.35f, 1.03f);
var validationSamples = testDataX.shape[0];// validate the model
Console.WriteLine("Validating model...");
var validationLoss = tf.reduce_sum(tf.pow(model - Y, 2.0f)) / validationSamples;
var lossValue2 = sess.run(validationLoss, new FeedItem(X, testDataX), new FeedItem(Y, testDataY));
Console.WriteLine($" Validation loss = {lossValue2}");
?
?
代碼調用np.array
來設置新的驗證數據,并設置一個新的validationLoss
函數來在驗證期間計算MSE。然后它在驗證數據上運行此損失函數,并在控制臺上顯示驗證丟失。就是這樣。這是TensorFlow中的完整線性回歸演示。
此代碼將在所有主要操作系統上運行 - Windows,Linux和OS / X.您可以在控制臺上運行代碼,如下所示:
?
$ dotnet run
?
?
或者通過點擊F5在Visual Studio Code中。這是在最新版本的VS Code中在我的Mac上運行的應用程序:
這是在終端的命令行上運行的相同應用程序:
?
經過1000個訓練時期后,我最終損失了0.1548。完全訓練的模型在驗證數據上的損失為0.1572。
?
這是一個最初用Python編寫的TensorFlow線性回歸演示,現在移植到C#,只有很少的語法更改。
有數千個類似的代碼示例,現在它們都可供C#開發人員訪問。
?
你意如何?準備好開始用TensorFlow.NET和NumSharp編寫C#機器學習應用了嗎?
?
作者:Mark Farragher
英文版地址:https://medium.com/machinelearningadvantage/run-tensorflow-machine-learning-code-in-c-with-almost-no-changes-77f7b629389
---------------------
作者:SciSharp Stack
來源:CSDN
原文:https://blog.csdn.net/SciSharp/article/details/100223186
版權聲明:本文為作者原創文章,轉載請附上博文鏈接!