Looking for a coding video?

If you are looking for videos related to software development, please search!

使用 TensorFlow 學習 kNN 分類演算法 – Airwaves – Medium

Source link

引入所需相依套件、資料集

首先,引入我們需要的幾個套件,在這個範例中,使用的 TensorFlow 版本為 1.9,因為有使用到 tf.contrib 的函式,該函式庫的函式未來有可能會修改,所以請注意電腦中的 TensorFlow 版本是否已經不包含在這個範例中使用的函式。

我們使用的 Dataset 是 TensorFlow 提供的 MNIST,如果要使用其他來源的 MNIST 也可以,例如 kaggle 提供的 MNIST

定義訓練資料集與測試資料集

TensorFlow 提供的 MNIST 分成訓練資料 (testing data) 與測試資料 (training data),我們將測試資料做為欲分類的影像,目標即是在訓練資料中找出相近的影像。

原始的訓練資料與測試資料分別有 55000 與 10000 筆,如果將訓練資料 55000 筆資料全部作為 kNN 分類的資料將會導致運算時間過長,因為 kNN 是一個時間複雜度為 O(ndk) 的演算法,n 為欲分類的影像數量,d 為需要計算距離的影像數量,k 為一張影像中的像素個數。

在這個範例中,如果 n=10000、d=55000、k=764,則 big-O 相當地可觀,所以我們將 d 縮小成 10000,藉此減少 kNN 的計算量。

定義運算過程(建立計算圖)

首先,我們定義 X 為輸入訓練資料的節點,y 為輸入預測的影像的節點。因為一張手寫辨識的影像大小為 28 ✕ 28 = 784,所以節點的大小為 784。

placeholder 是 TensorFlow 中一個很有趣的用法,可以預先在神經網路中 佔位,而不用事先定義好輸入的資料,這也是 TensorFlow 中計算圖(Computing Graph)的概念,之後再使用 Session 將資料傳入計算圖中。

placeholder 中定義節點的形狀 shape=(None, num_inputs)None 的意思是二維矩陣的 row 事先尚未定義,也就是「不定義輸入資料的筆數」,隨著透過 Session 將資料傳入計算圖時,動態符合輸入資料的筆數。

在手寫數字辨識這個範例中,將影像的像素作為特徵,使用歐幾里得距離計算兩張影像之間的距離。

在計算完距離後,我們想要知道最鄰近的 7 張影像,所以使用 tf.contrib 中的函式排序張量,將結果進行切片 (slice),取得距離最接近的 7 個距離。

執行 kNN 演算法(運行計算圖)

訓練時,透過 Session 傳遞資料至計算圖中,別忘了記得要初始化所有的變數。top_k 能夠取得 7 個最接近的距離,所以我們可以利用 top_k 反查詢 dist 的索引值,而 dist 的索引值可以對應至 test_label 該影像的原始分類。

接著,我們要對 7 張最鄰近的影像進行投票,使用的是 Counter 這個資料結構, Counter 可以幫助我們計算在串列中數值出現的次數,並取得出現次數最多的影像類別,則該類別為 kNN 所預測的影像類別。我們將預測分類與真實分類都存入 prediction,為了在 kNN 執行完後計算辨識的準確率。

辨識結果

我們將 prediction 放入 DataFrame 中,方便我們計算準確率。最後可以得到準確率大約為 0.9391,是一個不錯的準確率,但在手寫數字辨識中還不算是最好的。如果你有興趣在手寫數字辨識這個問題中得到更好的結果,可以嘗試使用深度學習的模型,在這個網站中有許多方法在手寫數字辨識這個問題上得到 99 % 以上的準確率。

結論

最近鄰居法 ( kNN) 是一個機器學習中最簡單的演算法之一,在這篇文章中提供使用 TensorFlow 實現 kNN 的方法,經由一個簡單的範例,讓你了解 kNN 的運作。

在你執行完這個範例後,應該會發現執行時間非常地長,因為 kNN 的時間複雜度為 O(ndk),在特徵為高維度或是訓練資料過多時容易造成運行時間過長的問題。

如果你想嘗試更快更好的模型,而且對於運用類神經網路分類手寫數字有興趣,可以參考延伸閱讀。

閱讀資料

延伸閱讀

Source link

 

Leave a Reply

You must be logged in to post a comment.