TensorFlow.NET機器學習


TensorFlow.NET機器學習入門【1】開發環境與類型簡介

 

TensorFlow.NET機器學習入門【0】前言與目錄

 

     曾經學習過一段時間ML.NET的知識,ML.NET是微軟提供的一套機器學習框架,相對於其他的一些機器學習框架,ML.NET側重於消費現有的網絡模型,不太好自定義自己的網絡模型,底層實現也做了高度封裝。

    最近想從底層學習一下機器學習的相關知識,經過初步篩選,計划定位於python + pytorch這個方向入手,經過一段時間的學習,我發現由於對python語言不太熟悉,導致實踐起來比較困難,先不說機器學習相關的代碼,光周邊代碼就搞得焦頭爛額了。想要下決心好好修煉一下python必然不是一朝一夕的事情,所以考慮是否學一個采用C#的機器學習框架,這樣就可以專心研究目標代碼,配套服務就可以輕松搞定了。

    經搜索發現了SciSharp-Stack這個項目,一開始我定位於Torch.Net,最終選擇了TensorFlow.NET這個框架。選擇TensorFlow.NET主要是因為如下幾個原因:

  •   示例比較豐富,第一次下載、編譯、運行都很順利。(如果開源項目提供的HelloWorld項目跑不起來的話,就沒有信心使用了)
  •   代碼一直在更新,社區比較活躍,Issue上問問題會有人回答;
  •   架構比較合理,通過.NET對google提供的原生動態鏈接庫進行封裝,和我們使用MySQL.Data的架構類似,C#開發人員很熟悉這種架構;
  •   代碼風格接近python+tensorflow的實現方式,便於參考網絡上大量python的例程。

這個系列的文章就是我這段時間學習TensorFlow.Net的心得體會,整個系列的文章目錄如下: 

  1. TensorFlow.NET機器學習入門【1】開發環境與類型簡介
  2. TensorFlow.NET機器學習入門【2】線性回歸
  3. TensorFlow.NET機器學習入門【3】采用神經網絡實現非線性回歸
  4. TensorFlow.NET機器學習入門【4】采用神經網絡處理分類問題
  5. TensorFlow.NET機器學習入門【5】采用神經網絡實現手寫數字識別(MNIST)
  6. TensorFlow.NET機器學習入門【6】采用神經網絡處理Fashion-MNIST
  7. TensorFlow.NET機器學習入門【7】采用卷積神經網絡(CNN)處理Fashion-MNIST
  8. TensorFlow.NET機器學習入門【8】采用GPU進行學習
  9. TensorFlow.NET機器學習入門【9】后記

由於作者本人對於機器學習的認識還處於入門階段,寫作過程中難免存在紕漏,如果您發現有什么錯誤的地方,請及時指出來。

 

【參考資料】

TensorFlow.NET

SciSharp-Stack-Examples

《深度學習入門:基於Python的理論與實踐(齋藤康毅)》

項目開發環境為Visual Studio 2019 + .Net 5

創建新項目后首先通過Nuget引入相關包:

 

 SciSharp.TensorFlow.Redist是Google提供的TensorFlow開發庫,是采用C語言開發的動態鏈接庫(DLL);

TensorFlow.NET采用C#語言對C語言的庫進行封裝,提供.NET調用接口;

TensorFlow.Keras是一個高級工具類,對建模和訓練過程進行封裝,提供簡便接口。

 通過下列語句對庫進行引用:

using Tensorflow;

using Tensorflow.NumPy;

using static Tensorflow.Binding;

using static Tensorflow.KerasApi;

下面展示一些TensorFlow.NET的基本類型操作:

復制代碼
       /// <summary>
        /// 構建張量
        /// </summary>
        private void Base_Constant()
        {
            //通過基本類型構建張量
            var c1 = tf.constant(3); // int
            var c2 = tf.constant(1.0f); // float
            var c3 = tf.constant(2.0); // double
            var c4 = tf.constant("Hello Tensorflow.Net!"); // string

            Console.WriteLine(c1);
            Console.WriteLine(c2);
            Console.WriteLine(c3);
            Console.WriteLine(c4);

            //通過多維數值構建張量
            int[,] arr = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } };
            var nd = np.array(arr);
            var tensor = tf.constant(nd);
            Console.WriteLine(tensor);

            //構建全0或全1張量
            var tensor0 = tf.constant(np.zeros(new Shape(2, 3)));
            var tensor1 = tf.constant(np.ones(new Shape(2, 3)));
            Console.WriteLine(tensor0);
            Console.WriteLine(tensor1);

            var tensor_0 = tf.zeros(new Shape(2, 3));
            var tensor_1 = tf.ones(new Shape(2, 3));
            Console.WriteLine(tensor_0);
            Console.WriteLine(tensor_1);
        }

        /// <summary>
        /// 張量運算
        /// </summary>
        private void Base_Operator()
        {
            var a = tf.constant(2.0f);
            var b = tf.constant(3.0f);
            var c = tf.constant(5.0f);

            // 基本運算,可以采+ - * / 等運算符
            var add = tf.add(a, b);
            var sub = tf.subtract(a, b);
            var mul = tf.multiply(a, b);
            var div = tf.divide(a, b);

            print($"{(float)a} + {(float)b} = {(float)add}");
            print($"{(float)a} - {(float)b} = {(float)sub}");
            print($"{(float)a} * {(float)b} = {(float)mul}");
            print($"{(float)a} / {(float)b} = {(float)div}");

            // 求平均、求和
            var mean = tf.reduce_mean(tf.constant(new[] { a, b, c }));
            var sum = tf.reduce_sum(tf.constant(new[] { a, b, c }));
            print("mean =", mean.numpy());
            print("sum =", sum.numpy());

            // 矩陣相乘
            var matrix1 = tf.constant(new float[,] { { 1, 2, 3 }, { 3, 4, 5 } });
            var matrix2 = tf.constant(new float[,] { { 3, 4 }, { 5, 6 }, { 7, 8 } });
            var product1 = tf.matmul(matrix1, matrix2);
            print("product1 =", product1.numpy());
        }

        /// <summary>
        /// 生成隨機數張量
        /// </summary>
        private void Base_Random()
        {
            var t1 = tf.random.normal(new Shape(10));
            var t2 = tf.random.uniform(new Shape(2, 5));
            var t3 = tf.random.uniform(new Shape(2, 5), 1, 100);

            Console.WriteLine($"t1={t1.numpy()}");
            Console.WriteLine($"t2={t2.numpy()}");
            Console.WriteLine($"t3={t3.numpy()}");

            t1 = tf.random.normal(new Shape(100), mean: 0.5f, stddev: 2);
            var mean = tf.reduce_mean(t1);
            var max = tf.reduce_max(t1);
            var min = tf.reduce_min(t1);
            Console.WriteLine($"mean={mean.numpy()},max={max.numpy()},min={min.numpy()}");
        }
復制代碼

上述代碼基本都比較簡單,基本一看就能懂,有幾處需要解釋一下:

1、平常我們在生成隨機數時,一般都是平均分布,但機器學習的數據更多趨向正態分布,所以采用normal生成隨機數,mean表示中心點,stddev表示分布范圍;

2、從表面看tf的框架似乎提供了一套可以進行矩陣運算的Math庫,但實際並非如此,tf框架的核心是可以計算運算的梯度,這個問題我們后面再講;

3、tf有兩個版本,V1版和V2版本,如果要使用V1版本語法,需要在代碼之前加一句:tf.compat.v1.disable_eager_execution();

     相對的,V2版本為:tf.enable_eager_execution();由於默認為V2版本,所以這行代碼可以省略不寫。

    本系列的所有代碼均采用V2版本。官方提供的樣例里有大量V1版本代碼,有一些V2版沒有提供的功能,可能不得不采用V1版代碼實現。

 

【參考資料】

TensorFlow教程:TensorFlow快速入門教程

 

【項目源碼】

 Git: https://gitee.com/seabluescn/tf_not.git

項目名稱:SayHello

目錄:TensorFlow.NET機器學習入門系列目錄

 


簽名區:
如果您覺得這篇博客對您有幫助或啟發,請點擊右側【推薦】支持,謝謝!
 
分類:  TensorFlow.Net


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM