[转]在C#中像Python一样编写TensorFlow机器学习代码
?
機器學(xué)習(xí)是一個令人激動人心的領(lǐng)域,一直有新的技術(shù)突破。研究人員不斷推動機器智能的提升,教機器如何聽說讀寫——這些曾經(jīng)是我們?nèi)祟悓俚募寄堋C器學(xué)習(xí)的首選語言是Python,最受歡迎的庫是Google的TensorFlow。幾乎所有的代碼示例都是用Python編寫的,并且依賴于TensorFlow和NumPy庫。對于C#和.NET的開發(fā)人員來說,我們在面臨著一個嚴(yán)峻的選擇:要么學(xué)習(xí)Python,要么使用NET機器學(xué)習(xí)庫,并從頭開始精心編寫我們自己的C#代碼 。
?
事實上,這就是我在機器學(xué)習(xí)課程中常用的策略。我研究了許多使用Keras和TensorFlow的Python代碼,然后我從頭開始編寫自己的C#代碼,使用原生的CNTK和ML.NET庫代替。這種方法很有效,但它也有一些缺點:
?
- 我的學(xué)生習(xí)慣于.NET,這些編碼技巧不容易轉(zhuǎn)移到Python。
- CNTK和ML.NET不支持某些TensorFlow功能,因此我必須使用Python代碼向C#開發(fā)人員演示它們。
?
我一直在努力在.NET中編寫機器學(xué)習(xí)庫,模仿Python的API和編碼風(fēng)格,如NativeKeras和KerasSharp,但這些項目不再處于積極開發(fā)的階段。我一直在尋找一個全面的.NET庫,它完全模仿了如何用Python編寫機器學(xué)習(xí)代碼,終于我發(fā)現(xiàn)了她——SciSharp。SciSharp正在為數(shù)據(jù)科學(xué),機器學(xué)習(xí)和人工智能構(gòu)建一個.NET開源生態(tài)系統(tǒng),其理念是C#機器學(xué)習(xí)代碼應(yīng)該像對應(yīng)的Python代碼一樣盡可能地語法,與編程的感覺。
?
看看下面的例子 - 這是TensorFlow中的簡單線性回歸演示。 Python代碼在左側(cè),相應(yīng)的C#代碼在右側(cè):
右邊的代碼看起來像Python,但它是實際的C#代碼。 它使用一個名為TesorFlow.NET的包裝器在幕后調(diào)用真正的TensorFlow庫。請注意,我們已經(jīng)有了TensorFlow包裝器; 幾年前,Xamarin創(chuàng)始人米格爾大神建造了優(yōu)秀的TensorFlowSharp。 但是,他的庫只暴露了低級別的TensorFlow API。 相比之下,SciSharp庫神奇地暴露了所有TensorFlow,包括高級圖形構(gòu)建功能。
?
TensorFlow在很大程度上依賴于NumPy,這是一個高性能的Python數(shù)學(xué)庫,可以在內(nèi)存中處理非常大的數(shù)據(jù)數(shù)組。 因此,SciSharp團隊開發(fā)了自己的版本NumSharp,這是NumPy到C#的端口。
NumSharp遵循與原始NumPy完全相同的編碼風(fēng)格。 使用左側(cè)的Python代碼和右側(cè)的相應(yīng)C#代碼查看此示例:同樣,右邊的代碼遵循與Python相同的語法約定和API樣式,但它實際上是C#代碼。
?
SciSharp團隊在這里取得了一項重大成就。 使用TensorFlow.NET和NumSharp,我們實際上可以使用Python代碼示例,將它們復(fù)制并粘貼到C#文件中,然后只需稍作修改即可運行它們——這為.NET開發(fā)人員打開了完整的機器學(xué)習(xí)生態(tài)系統(tǒng)。
?
我決定采用SciSharp。查看以下說明,以便在C#中啟動并運行您自己的TensorFlow代碼。我將構(gòu)建一個簡單的線性回歸演示,它適合一些樣本數(shù)據(jù)的回歸線。
?
讓我們開始吧。以下是在.NET Core中設(shè)置新控制臺項目的方法:
?
$ dotnet new console -o LinearRegression $ cd LinearRegression?
?
接下來,我需要安裝我需要的軟件包:
?
$ dotnet add package TensorFlow.NET?
?
就這樣簡單!這將安裝TensorFlow.NET包,它也將自動拉入NumSharp。該軟件包還安裝了Microsoft.ML.TensorFlow.Redist,它是本機TensorFlow庫的跨平臺安裝程序。這將在Windows,Linux和OS / X上為您設(shè)置一切。
?
現(xiàn)在我準(zhǔn)備開始編碼了。這是Program.cs的上半部分應(yīng)該是這樣的:
?
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控制臺應(yīng)用程序。 請注意使用訓(xùn)練數(shù)據(jù)設(shè)置NumPy數(shù)組的np.array方法。 shape [0]調(diào)用檢索數(shù)組的長度,就像在Python中一樣。現(xiàn)在我將在TensorFlow中設(shè)置一個簡單的線性回歸模型:
?
此代碼調(diào)用tf.placeholder來設(shè)置模型輸入和輸出:X表示輸入數(shù)據(jù),Y表示輸出數(shù)據(jù)。
以下兩個調(diào)用tf.Variable設(shè)置權(quán)重和偏差模型變量。 這些變量組合成一個模型如下:
?
讀者會發(fā)現(xiàn)這只是線性回歸的等式。 TensorFlow將在訓(xùn)練期間調(diào)整W和b變量以找到完美的回歸線。
最后,代碼在損失變量中設(shè)置了一個損失函數(shù)。 損失函數(shù)是一種表達式,其值在訓(xùn)練期間需要最小化。 我將使用均方誤差或MSE:
這只是模型預(yù)測與實際值之差的平方和。接下來,我將訓(xùn)練這個模型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... });?
?
代碼設(shè)置GradientDescentOptimizer以最小化損失函數(shù),并使用tf.Session()啟動TensorFlow會話。TensorFlow中的所有內(nèi)容都需要調(diào)用tf.run()來執(zhí)行。所以我首先設(shè)置了一個global_variables_initializer來初始化模型,然后運行它。然后我運行優(yōu)化器1000個時期來訓(xùn)練模型,每50個時期我運行損失函數(shù)并顯示中間訓(xùn)練損失。循環(huán)完成后,我再次運行損失功能并顯示最終的訓(xùn)練損失。
?
我現(xiàn)在有一個訓(xùn)練有素的好模型,是時候在一些新數(shù)據(jù)上測試這個模型:
?
// 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}");?
?
代碼調(diào)用np.array來設(shè)置新的驗證數(shù)據(jù),并設(shè)置一個新的validationLoss函數(shù)來在驗證期間計算MSE。然后它在驗證數(shù)據(jù)上運行此損失函數(shù),并在控制臺上顯示驗證丟失。就是這樣。這是TensorFlow中的完整線性回歸演示。
此代碼將在所有主要操作系統(tǒng)上運行 - Windows,Linux和OS / X.您可以在控制臺上運行代碼,如下所示:
?
$ dotnet run?
?
或者通過點擊F5在Visual Studio Code中。這是在最新版本的VS Code中在我的Mac上運行的應(yīng)用程序:
這是在終端的命令行上運行的相同應(yīng)用程序:
?
經(jīng)過1000個訓(xùn)練時期后,我最終損失了0.1548。完全訓(xùn)練的模型在驗證數(shù)據(jù)上的損失為0.1572。
?
這是一個最初用Python編寫的TensorFlow線性回歸演示,現(xiàn)在移植到C#,只有很少的語法更改。
有數(shù)千個類似的代碼示例,現(xiàn)在它們都可供C#開發(fā)人員訪問。
?
你意如何?準(zhǔn)備好開始用TensorFlow.NET和NumSharp編寫C#機器學(xué)習(xí)應(yīng)用了嗎?
?
作者: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
版權(quán)聲明:本文為作者原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!
總結(jié)
以上是生活随笔為你收集整理的[转]在C#中像Python一样编写TensorFlow机器学习代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转]redis 5.0.5 5分钟搭建
- 下一篇: [转]Python 列表(List) 的