手把手教你 TensorFlow 初級入門

在開始使用機器學習算法之前,我們應該首先熟悉如何使用它們。而本文就是通過對 TensorFlow 的一些基本特點的介紹,讓你瞭解它是機器學習類庫中的一個不錯的選擇。

讓我們設想一下,當我們用 Python 寫代碼時,沒有那些方便的類庫會是怎樣一種窘境。 這就好比你有一個新的智能手機,而不安裝任何應用程序。 雖然它仍然可以打電話,發短信,但如果有了那些更方便的應用程序,這部智能手機才更有價值。

設想一下這個場景_..._ _你作爲一名業務負責人,需要負責跟蹤銷售流程。__你希望計算銷售產品的收入。__現在有_ _100_ _個不同的產品在你的倉庫中,你需要用一個向量表示每個產品的價格。__另一個大小爲_ _100_ _的向量表示每個產品的庫存量。__以下的_ _Python_ _代碼是用來計算銷售所有產品的收入。注意了,__這裏沒有調用任何類庫。_

revenue = 0 for price, amount in zip(prices, amounts):     revenue += price * amount

代碼列表 1. 不使用任何 Python 類庫計算兩個向量的內積

這段代碼只是計算兩個向量(也稱爲點積)的內積。 想象一下,對於更復雜的問題,需要多少代碼。例如求解線性方程或計算兩個向量之間的距離。

當你安裝 TensorFlow 類庫的同時,其中還包括了非常知名的 NumPy 類庫,對 Python 編程中的數學操作非常有用。用 Python 編程時,不使用類庫(例如 NumPy 和 TensorFlow)就像使用沒有自動對焦的相機:你雖然獲得了更多的靈活性,但你可能很容易犯錯。在機器學習的過程中已經很容易犯錯誤了,所以就讓我們使用 TensorFlow 來提高化軟件開發的效率吧。

代碼列表 2 展示瞭如何使用 NumPy 簡潔地編寫相同的內積運算。

import numpy as np revenue = np.dot(prices, amounts)

代碼列表 2. 用 NumPy 類庫計算內積

Python 是一種簡潔的語言,這意味着你不會看到冗長的代碼。另一方面,Python 語言的簡潔意味着許多處理都在後臺進行,因此我們應該熟悉它背後的原理。

關於 TensorFlow Python C ++ API 的各種函數的詳細文檔,請參見 https://www.tensorflow.org/api_docs/index.html

機器學習主要依賴於很多數學公式,本文將對使用 TensorFlow 進行這類數學運算做一個初步的介紹。通過示例和代碼,大家可以對 TensorFlow 有一個初步瞭解。例如如何運用 TensorFlow 計算大數據的統計信息。 因此本文的重點將完全是關於如何使用 TensorFlow,而不是一般的機器學習算法運用。

機器學習算法需要大量的數學運算。 通常,某個算法可以歸結爲簡單函數組合的迭代,直到它收斂爲止。 當然,也可以使用任何標準編程語言來執行這些計算。但是使用像 TensorFlow 這樣已經非常完善了的類庫是提高代碼可控性和性能的關鍵。

確保 TensorFlow 工作

首先,爲我們的第一段代碼創建一個名爲 test.py 的新文件。 通過運行以下代碼導入 TensorFlow:

import tensorflow as tf

在導入 TensorFlow 後,如果 Python 解釋器沒有報錯,那麼我們就可以開始使用 TensorFlow 了。

遇到了錯誤? 在這裏,常見錯誤的原因是你可能安裝了 GPU 版本,並且類庫無法搜索 CUDA 驅動程序。 請記住,如果使用 CUDA 編譯庫,則需要使用 CUDA 的路徑更新環境變量。你需要檢 TensorFlow 上的 CUDA 指令。    (有關詳情,請參閱 https://www.tensorflow.org/versions/master/get_started/os_setup.html#optional-linux-enable-gpu-support)。

使用 TensorFlow 中的規則

TensorFlow 庫通常使用 tf 限定名稱來進行導入。 一般來說,使用 tf 限定名稱是一個不錯的方法,以便與其他開發人員和開源 TensorFlow 項目保持一致。 你也可以選擇不使用這個限定名稱,但這會影響你在自己的項目中重用別人的 TensorFlow 代碼。

表示張量

在現實世界中描述對象的一個簡便方法就是通過羅列出它的屬性或特徵。例如,我們可以通過顏色,型號,發動機類型和里程數描述一輛汽車。這些特徵的有序列表被稱爲特徵向量,這正是我們要在 TensorFlow 代碼中所表示的。

特徵向量是機器學習中最有用的方法之一,(它們就是一個數字列表)。每個數據項通常有一個特徵向量,而一個好的數據集則具有數千個特徵向量。 毫無疑問,你會經常一次處理多個向量。 矩陣簡明地表示了向量列表,其中矩陣的每列表示一個特徵向量。

在 TensorFlow 中用向量的向量表示矩陣,每個向量具有相同的長度。 圖 1 是一個兩行三列的矩陣的示例,例如 [[1,2,3],[4,5,6]]。 注意,這是一個包含兩個元素的向量,每個元素對應一個矩陣行。

圖 1. 圖上半部分是計算機對矩陣的表示,下半部分是我們日常生活中對矩陣的表示。 這種形式的符號是大多數科學計算類庫中的常見範例。

我們通過指定其行和列索引來定位矩陣中的元素。 例如,第一行和第一列來表示左上角第一個元素。 有時,我們需要使用兩個以上的索引,這樣來表示一個元素會很方便。例如,在表示一個圖片中的像素時,我們不僅通過其行和列值來描述它,而且還使用紅,綠,藍通道來對其進行描述。 張量是通過任意數量的索引指定矩陣中元素的一般化。

一個張量的例子_..._ _假設一所小學爲每個學生分配座位。__而__你是這個學校的校長,並且你記不住這些學生的名字。__幸運的是,每個教室都有一個座位網格,可以通過學生的行和列來指定某個學生。_

因爲有多個教室,所以你不能簡單的說 _“_早上好,4 10 !” 你還需要指定教室,比如說 _“你好,教室 2 4 排 10 列。不像矩陣只需要兩個索引就能指定一個元素,這所學校的學生需要三個數字。_這三個數字都是三階張量的一部分!

張量是更多的嵌套向量。例如,一個 2×3×2 的張量爲 [[[1,2],[3,4],[5,6]],[[7,8],[9,10] 11,12]]],它可以被認爲是兩個矩陣,每個大小爲 3×2。 因此,我們說這個張量的秩是 3. 一般來說,張量的秩是指定一個元素所需的索引的數量。TensorFlow 中的機器學習算法是作用於張量上的,理解如何使用它們是關鍵。

圖 2. 該張量可以被認爲是堆疊在彼此之上的多個矩陣。 要指定其中的某個元素,必須指明行和列,以及要訪問的矩陣。 因此,該張量的秩爲三。

你可能會對如何表示張量產生疑惑。下面三行代碼試圖表示相同的 2×2 矩陣。 該矩陣表示兩個維度的兩個特徵向量。 例如,它可以表示兩個人對兩部電影的評價。 每個人,由矩陣的行索引表示,分配一個數字來描述每個人的電影評價值,由列索引表示。 運行代碼以瞭解如何在 TensorFlow 中生成矩陣。

import tensorflow as tf # We’ll use NumPy matrices in TensorFlow import numpy as np    # Define a 2x2 matrix in 3 different ways m1 = [[1.0, 2.0],        [3.0, 4.0]] m2 = np.array([[1.0, 2.0],                 [3.0, 4.0]], dtype=np.float32) m3 = tf.constant([[1.0, 2.0],                    [3.0, 4.0]]) # Print the type for each matrix print(type(m1)) print(type(m2)) print(type(m3)) # Create tensor objects out of the different types t1 = tf.convert_to_tensor(m1, dtype=tf.float32) t2 = tf.convert_to_tensor(m2, dtype=tf.float32) t3 = tf.convert_to_tensor(m3, dtype=tf.float32) # Notice that the types will be the same now print(type(t1)) print(type(t2)) print(type(t3))

 代碼列表 3. 表示張量的不同方式

第一個變量 m1 是一個列表,第二個變量 m2 是 NumPy 類庫中的一個 ndarray,最後一個變量 m3 是 TensorFlow 的 Tensor 對象。TensorFlow 中所有運算符(如 neg)都設計爲對張量對象進行操作。tf.convert_to_tensor(...)這個方法,我們可以用在任何地方,以確保我們處理張量而不是其他類型。TensorFlow 類庫中的大多數方法都已經調用了它。使用 tf.convert_to_tensor(...)並不是必須的,在這裏使用它,是因爲它有助於我們理解隱式類型的跨類庫處理。

<class ‘tensorflow.python.framework.ops.Tensor’>

讓我們再來看看如何中定義張量。 導入 TensorFlow 類庫之後,我們可以使用常量運算符,如代碼列表 4 所示。

import tensorflow as tf # Define a 2x1 matrix matrix1 = tf.constant([[1., 2.]]) # Define a 1x2 matrix matrix2 = tf.constant([[1],                         [2]]) # Define a rank 3 tensor myTensor = tf.constant([ [[1,2],                            [3,4],                            [5,6]],                           [[7,8],                            [9,10],                            [11,12]] ]) # Try printing the tensors  print(matrix1) print(matrix2) print(myTensor)

 代碼列表 4。創建張量

代碼 4 的運行結果:

Tensor( “Const:0”,         shape=TensorShape([Dimension(1),                             Dimension(2)]),         dtype=float32 ) Tensor( “Const_1:0”,         shape=TensorShape([Dimension(2),                             Dimension(1)]),         dtype=int32 ) Tensor( “Const_2:0”,          shape=TensorShape([Dimension(2),                              Dimension(3),                              Dimension(2)]),          dtype=int32 )

從運行結果中可以看出,每個張量都由已命名的 Tensor 對象表示。每個 Tensor 對象都有一個唯一的標籤(名稱),一個用於定義其結構的維度(shape),以及用於指定我們要操作的數據類型(dtype)。因爲我們並沒有顯示指定名稱,所以他們被自動命名爲:“Const:0”,“Const_1:0” 和 “Const_2:0”。

張量類型

需要注意的是 matrix1 的每個元素以小數點結束,這是爲了告訴 Python 該元素的數據類型不是整數,而是浮點數。 我們可以傳遞顯式 dtype 值。 和 NumPy 數組一樣,張量可以接受我們指定的類型。

TensorFlow 也提供了一些構造函數用於一些簡單的張量。例如,tf.zeros(shape)創建了一個包涵所有值都被初始化爲零的特定形態的張量。類似地,tf.ones(shape)創建了一個所有元素值爲 1 的張量。shape 參數是描述張量的維度的一維張量,它的類型是 int32。

創建運算符 

我們已經有了幾個初始的張量,現在我們可以用運算符對他們進行操作,比如加減乘除。 假設現在有一個矩陣,它的行表示貨幣交易,收款金額(正值)和收款金額(負值)。 矩陣取反是表示某個人的貨幣流歷史記錄的一種方式。 我們現在對代碼列表 4 中的 matrix1 進行取反操作 neg(negation 的縮寫)。矩陣取反將正數轉換爲絕對值相同的負數,反之亦然。

取反操作是最簡單的操作之一。 如代碼列表 5 所示,取反只需將一個張量作爲輸入,得出另一個張量,每個元素取反。現在,嘗試自己運行代碼。 如果你已經掌握瞭如何使用取反,那就可以推廣到所有其他 TensorFlow 的操作。

這裏需要指出,定義操作(如取反操作)和運行它是不一樣的。

import tensorflow as tf # Define an arbitrary tensor x = tf.constant([[1, 2]]) # Negate the tensor neg_x = tf.neg(x) # Print the object print(neg_x)

代碼列表 5. 取反運算符的使用

代碼列表 5 的輸出:

Tensor(“Neg:0”, shape=(1, 2), dtype=int32)

更多 TensorFlow 的運算符

官方文檔詳細地列出了所有可用的數學操作:

https://www.tensorflow.org/api_docs/Python/math_ops.html。

常用操作符的示例包括:

tf.add(x, y)  Add two tensors of the same type, x + y tf.sub(x, y)  Subtract tensors of the same type, x — y tf.mul(x, y)  Multiply two tensors element-wise tf.pow(x, y)  Take the element-wise power of x to y tf.exp(x)  Equivalent to pow(e, x), where e is Euler’s number (2.718…) tf.sqrt(x)  Equivalent to pow(x, 0.5) tf.div(x, y)  Take the element-wise division of x and y tf.truediv(x, y)  Same as tf.div, except casts the arguments as a float tf.floordiv(x, y)  Same as truediv, except rounds down the final answer into an integer tf.mod(x, y)  Takes the element-wise remainder from division

我們可以這些 TensorFlow 運算符來產生高斯分佈(也稱爲正態分佈)。參見圖 3 提示。你可以參考 wiki,找到正態分佈的概率密度:https://en.wikipedia.org/wiki/Normal_distribution。

爲了簡潔起見,諸如 “*”,“ - ”,“+” 等大多數數學表達式是其 TensorFlow 運算符的快捷方式。高斯函數包括許多運算,如下所示:

from math import pi mean = 1.0 sigma = 0.0 (tf.exp(tf.neg(tf.pow(x — mean, 2.0) /                (2.0 * tf.pow(sigma, 2.0) ))) * (1.0 / (sigma * tf.sqrt(2.0 * pi) )))

圖 3. 該圖表示產生高斯分佈所需的操作。 節點之間的鏈接表示數據如何從一個操作進入下一個操作。 操作本身很簡單,但是它們如何相互作用是相對複雜的。

TensorFlow 算法很容易可視化。 它們可以用流程圖來進行描述。 流程圖就是一種圖表。 流程圖中的每個箭頭都稱爲圖形的邊。 而它的每個狀態被稱爲節點。

在會話中執行運算符

會話 (session) 是描述代碼應該如何運行的軟件系統環境。在 TensorFlow 中,會話設置了硬件設備(如 CPU 和 GPU)如何相互通信。這樣,你只要關心如何設計機器學習算法,而不必擔心底層硬件設備的運行。當然,你也可以配置會話以更改其底層硬件設備交互行爲,而不更改上層代碼。

要在 TensorFlow 中運行程序計算數值是需要一個會話的。 只有在已創建的會話纔可以對 Tensor 對象進行賦值。 爲此,我們必須使用 tf.Session()創建一個會話類,並由它來運行一個運算符(代碼列表 6)。

import tensorflow as tf # Define an arbitrary matrix matrix = tf.constant([[1., 2.]]) # Run the negation operator on it neg_matrix = tf.neg(matrix) # Start a session to be able to run operations with tf.Session() as sess:     # Tell the session to evaluate negMatrix     result = sess.run(neg_matrix) # Print the resulting matrix print(result)

代碼列表 6. 使用會話

恭喜! 你剛剛寫了第一個完整的 TensorFlow 代碼。 儘管它所做的是隻是對一個矩陣進行取反,但它已經能充分體現 TensorFlow 中的核心概念與框架了。

會話配置

在創建 tf.Session 類時,我們可以向構造函數傳遞一些參數。例如,TensorFlow 會根據可用的內容自動確定爲指定 GPU 或 CPU 設備的最佳方式。在創建會話時,我們可以設置 log_device_placements = True,如代碼列表 7 所示。

import tensorflow as tf # Define a matrix and negate it matrix = tf.constant([[1., 2.]]) negMatrix = tf.neg(matrix) # Start the session with a special config passed into the constructor to enable logging with tf.Session(config=tf.ConfigProto(log_device_placement=True)) as sess:     # Evaluate negMatrix     result = sess.run(negMatrix) # Print the resulting value print(result)

代碼列表 7 登錄一個會話

這將輸出有關每個操作的會話中使用哪些 CPU / GPU 設備的信息。 例如,執行代碼列表 6 中的程序會有以下輸出,它顯示了用於運行取反操作的設備:

Neg: /job:localhost/replica:0/task:0/cpu:0

會話在 TensorFlow 中是必不可少的。 我們需要調用一個會話來執行數學操作。 圖 4 描述了 TensorFlow 上的不同組件如何與機器學習管道的交互。 會話不僅執行圖像操作,而且還可以使用佔位符,變量和常量作爲輸入。 到目前爲止,我們已經使用了常量,但在後面的部分,我們將開始使用變量和佔位符。 以下是這三種類型值的簡要概述。

• 佔位符:未分配的值,但將由運行的會話初始化。

• 變量:可以更改的值,例如機器學習模型的參數。

• 常數:不更改的值,例如超參數或設置。

圖 4. 會話指示如何使用硬件來最有效地處理圖形。 當會話開始時,它將 CPU 和 GPU 設備分配給每個節點。 在處理之後,會話用可用格式(例如 NumPy 數組)輸出數據。 會話可以接受佔位符,變量和常量。

我希望你通過本文已經熟悉了一些 TensorFlow 編程的基本方法。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/bMFCzNiMBfQhMxkHyZDFqg