search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

機器學習怎麼快速入門?學習神經網路和TensorFlow(實例教程)

此文編譯自FCC(FreeCodeCamp),作者為Déborah Mesquita,該作者利用神經網路和TensorFlow進行了機器文本分類,並提出了一種新穎的學習方法——宏觀分析。機器人圈希望通過此文對圈友開始機器學習的探索之路有所幫助,文章略長,請耐心閱讀並收藏。我們附上了此實例最終代碼的GitHub鏈接,供圈友學習使用。

開發人員經常說,如果你想要著手機器學習,你就應該首先學習演算法是如何運行的。但是我的經驗告訴我並不需要如此。

我認為,你應該首先能夠宏觀了解:這個應用程序是如何運行的。一旦你弄明白這一點,深入挖掘和探索這個演算法的內部工作原理將變得相當簡單。

那麼,你該如何培養對機器學習的直覺並實現宏觀了解呢?創建機器學習模型就是一個很好的方法。

假設你依舊不知道該如何從頭開始創建這些演算法,那麼你將希望使用一個幫你實現所有這些演算法的庫,而這個庫就是TensorFlow。

在本文中,我們將要創建一個機器學習模型來進行文本分類。我們先討論一下主題:

1.TensorFlow是如何運行的?

2.什麼是機器學習模型?

3.什麼是神經網路?

4.神經網路是如何進行學習的?

5.如何操作數據並將其傳遞給神經網路輸入?

6.如何運行模型並獲得預測結果?

你將要學習到大量的新知識,那麼我們開始吧。

TensorFlow

TensorFlow是一種機器學習的開源庫,最初是由谷歌創立的。這個庫的名字幫助我們理解我們是如何用它工作的:張量(Tensor)是通過圖的節點流動的多維數組。

★tf.Graph

TensorFlow中的每一個計算都代表著一個數據流圖。這個圖有兩個元素:

為了看清這一切是如何運行的,你需要創建一下這張數據流圖:

計算X+Y的圖形

定義x= [1,3,6],y =[1,1,1],這個圖和tf.Tensor一起工作來代表數據的單位,你需要創建恆定的張量:

現在你需要定義操作單元:

你已經有足夠的圖元素了,現在你需要創建圖:

這就是TensorFlow工作流是如何運行的:首先,你需要創建一張圖,只有這樣你才能進行計算(真正地運行圖節點的操作)。為了運行這圖你將需要創建一個tf.Session。

★tf.Session

一個tf.Session對象封裝了操作對象執行的環境,並且對Tensor對象進行評估(tf.Session介紹)。為了做到這一點,我們需要定義在會話中將要用到哪一張圖:

想要執行這個操作,你會用到tf.Session.run這個方法。這個方法執行TensorFlow計算中的一步,而這個是通過運行必要的圖表片段來執行每個Operation和評估在參數提取中傳遞的每一個Tensor來實現的。在你的案例中,你需要運行一系列操作中的一步:

既然你已經知道TensorFlow是如何工作的,你就必須學習如何創建一個可預測模型。總的說來,就是:

機器學習演算法+數據=預測模型

構建模型的過程如下:

構建模型的過程

正如你所見,這個模型包含一種用數據「訓練」的機器學習演算法。一旦你有了這個模型,你將獲得以下的結果:

預測工作流

你創建的這個模型的目標是為了將文本類別進行分類,我們定義它為:

input: text, result: category

我們有一個包含所有文本的訓練數據集(每一個文本都有一個標籤,說明它屬於哪個類別)。在機器學習中這類任務是以「監督」學習的方式進行的。

你需要將數據進行類別分類,所以它也是一個分類任務。為了創建模型,我們將使用神經網路。

神經網路

一個神經網路就是一個計算模型(使用數學語言和數學概念來描述一個系統的一種方式)。這些系統進行自學習和訓練,而不是顯式地編程。

神經網路受到我們中樞神經系統的啟發,連接著和我們的神經元相似的節點。

一個神經網路

為了理解神經網路是如何工作的,我們需要通過TensorFlow建立一個神經網路結構。

神經網路結構

這個神經網路將有兩個隱藏層(你必須選擇網路中有多少個隱藏層,這是架構設計的一部分)。每個隱藏層的工作是將輸入轉換為輸出層可以使用的內容。

★隱藏層1

輸入層和第一層隱藏層

你還需要定義第一個隱藏層將有多少個節點。這些節點也被稱為特徵或神經元,在上面的圖像中,它們由每個圓圈表示。

在輸入層,每個節點都對應於數據集的一個詞(稍後我們將看到它是如何工作的)。

正像這裡解釋的,每個節點(神經元)乘以一個權重,每個節點都有一個權重,並在神經網路訓練階段調整這些值以產生正確的輸出(等等,我們一會兒說著重說一下這個)。

輸入乘以權重后,經過加法之後輸入給偏差,數據還要經過一個激活函數。這個激活函數定義了每個節點的最終輸出。舉個例子來說明,假設每個節點是一盞燈,激活函數將要斷定這盞燈是開還是關。

激活函數的類型有很多種,你將使用修正線性單元(ReLu),這個函數是這樣定義的:

f(x) = max(0,x)

[輸出X或0(zero),較大的那一個]

例如:如果x= -1,那麼f(x)=0(zero); 如果x=0.7,那麼f(x)=0.7

★隱藏層2

第二隱藏層的操作和第一隱藏層的操作是一樣的,但是現在第二隱藏層的輸入是第一隱藏層的輸出。

第一和第二隱藏層

★輸出層

終於,我們來到了最後一層,輸出層。你需要使用獨熱編碼(One-Hot Encoding)來獲得這一層的結果。在這個編碼中值為以1的比特只有一個,其他的值都是0。

例如,如果我們想編碼三個類別(運動、空間和計算機圖形學):

所以輸出節點的數量就是輸入數據集的類的數量。

輸出層的值也乘以權重,並且我們還添加了偏差,但現在激活函數是不同的。

你想用一個類別來標明每一個文本,這些類別是互斥的(一個文本不能同時屬於兩類)。考慮這一點,我們將使用Softmax函數,而不是使用ReLu激活函數Softmax函數簡介)。這個函數將每個統一的輸出轉換為一個範圍在0和1之間的值,也確保單位的總和等於1。這種方式的輸出會告訴我們每個文本為每個類別的概率。

現在你已經有了神經網路的數據流圖。將我們到目前為止看到的翻譯成代碼,結果是:

神經網路是如何學習的

正如我們前面看到的那樣,權重值在網路訓練的時候是不斷更新的。現在我們將看到在TensorFlow環境中這些是如何發生的。

★tf.Variable

權重和偏差都存儲在變數(tf.Variable)中。這些變數通過調用run來維護圖的狀態。在機器學習中,我們通常通過正態分佈值來啟動權重和偏差值。

當我們第一次運行網路(即由正態分佈的定義的權重值):

想知道網路是不是在學習,你需要比較輸出值(z)與預期值(expected)。我們如何計算這種差異(loss)?有許多方法可以實現這一點,因為我們正在與一個分類任務協同工作,最好的衡量損失最好的方法就是「交叉熵代價函數(cross-entropy error)」。

在TensorFlow中你會使用tf.nn.softmax_cross_entropy_with_logits來計算交叉熵誤差(這是softmax激活函數)並計算平均誤差(tf.reduced_mean)。

你當然想找到最好的權重值和偏差,以最小化輸出誤差(我們得到的值和正確的值之間的區別)。為了做到這一點,你需要使用梯度下降法,更具體地說,你將使用隨機梯度下降法。

梯度下降法

也有很多演算法來計算梯度下降,你需要使用自適應估計方法(Adam),在TensorFlow中使用這個演算法需要通過learning_rate值,它決定增量步的值來找到最好的權重值。

tf.train.AdamOptimizer(learning_rate).minimize(loss)是一種語法糖(syntactic sugar),它做兩件事:

1.計算梯度(loss, )

2.運用梯度()

這種方法用新值來更新所有的tf.Variables,所以我們不需要傳遞變數的列表。現在你有訓練網路的代碼(點圖放大):

你將使用的數據集會有許多英文文字,那麼我們需要操縱這些數據使它們通過神經網路。這樣做的話你需要做兩件事:

為每個單詞創建索引

為每個文本創建一個矩陣,如果字在文本中值為1,否則的話為0

讓我們看看代碼理解這個過程(點圖放大):

在上面的示例中,文本內容是『Hi from Brazil』,矩陣是[1,1,1],那麼如果文本內容是『Hi』呢?

現在你將要使用到獨熱編碼:

運行圖表並得到結果

這是最有意思的部分:從模型中得到結果,首先讓我們仔細看看輸入數據集。

★數據集

你需要使用20新聞組、約20主題的18000帖子的數據集,為了載入這個數據集,你將使用scikit-learn圖書館(scikit-learn圖書館),我們只使用到其中3類:comp.graphics、sci.space和rec.sport.baseball。

scikit-learn有兩個子集:一個用於訓練,另一個用於測試。我的建議就是,你不應該看測試數據,因為這會在創建模型的時候會幹涉你的選擇。你當然不想創建一個模型來預測這個特定的測試數據,而是需要創建一個具有良好的泛化性能的模型。

載入數據集:

訓練模型

在神經網路術語中, 一次epoch=一個向前傳遞(得到輸出值)和一個向後傳遞(更新權重)。

需要記住tf.Session.run方法么?我們來仔細地瞧一瞧吧。

在本文開始的數據流圖操作中,你使用的是和操作,但是我們也可以通過一系列的事情來運行。在整個神經網路運行,你要傳遞兩件事:損失計算和優化步驟。

這個feed_dict參數是我們每一次運行步驟中用來傳遞數據的,為了傳遞這些數據我們需要定義tf.placeholders(為feed_dict提供供給)。

正如TensorFlow文件中說的那樣:

「一個佔位符存在的唯一理由就是作為供給的目標,這不是初始化也不包含數據。」

所以,你可以這樣定義定位符:

你需要分批次地訓練數據:

「如果使用佔位符進行輸入,則可以通過使用tf.placeholder(...,shape = [None,...])創建佔位符來指定變數批量維度。該形狀的「None」元素對應於可變大小的維度」 

在測試模型的時候,我們用一個更大的批次來供給,這就是為什麼你需要定義一個變數批維度。

這個get_batches函數可以為我們提供文本的數量與批量的大小,現在我們可以運行這個模式(點圖放大):

現在你有了這個訓練好的模型。要測試它,你還需要創建圖形元素,我們將測量模型的準確性,所以你需要預報值的索引和正確值的索引(因為我們使用的是一個獨熱編碼),檢查他們是否相等,並計算所有的測試數據集的平均值(點圖放大):

就是它!你使用神經網路創建了一個模型來對文本進行類別分類。恭喜你!

你可以在這裡看到最終代碼提示:修改我們定義的值,以查看不同更改對訓練時間和模型精度的影響。

原文鏈接:

歡迎加入數據君數據分析秘密組織(收費)

這是一份事業!

數據挖掘與大數據分析

(datakong)



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦