:::

不深度學習也不用寫程式的圖片辨識:用Weka實作MNIST手寫數字辨識 / MNIST digits Classification with Weka

image

深度學習CNN的熱門讓人再度對「圖片辨識」這塊領域投入許多注意。不過先不論你是很懂數學公式喜歡計算卷積的朋友,還是不求甚解只會call套件來用的朋友,大部分的朋友都必須經過安裝Python環境、tensorflow或keras等套件、一步一步遵照範例程式碼來執行CNN的這段辛苦過程。不過,在這之中應該也有不少朋友,一旦遇到輸入程式碼就十分痛苦到無法繼續作下去,對吧?別擔心,如果只是要作預測圖片、辨識圖片的話,其實來自紐西蘭的Weka也可以做到,還不用寫任何程式喔!

那麼本篇繼利用Image Filter抽取圖片特徵分類初音彩色圖片之後,接下來這篇就要來挑戰現在CNN主要使用的資料集:MNIST手寫數字辨識問題囉。


MNIST手寫數字資料集 / MNIST digits

mnist_0_6mnist_1_998mnist_2_426mnist_3_249mnist_4_638mnist_5_562mnist_6_877mnist_7_633mnist_8_238mnist_9_197

mnist_0_9mnist_1_1003mnist_2_423mnist_3_247mnist_4_641mnist_5_565mnist_6_878mnist_7_630mnist_8_242mnist_9_202

MNIST是一個1988年LeCun等人在美國郵務局為了自動辨識郵遞區號手寫號碼而發展出來的資料集,現今作為許多圖片辨識系統的標準測試集。這個資料集中包含了從0到9的手寫數字圖片,總共有60000張訓練圖片及10000張測試圖片。我們的目標是從這60000張訓練圖片建立分類模型,然後能夠正確地分類這10000張測試圖片。

維基百科的資料來看,目前分類器正確率最高的是卷積式神經網路 (Convolutional Neural Network),也就是現今最熱門的CNN,正確率高達99.79%。而我們在前一篇分類彩色圖片使用的SMO支持向量機 (Support vector machine)的正確率則是99.44%。其實也是挺不錯的。

這個知名MNIST手寫數字辨識問題,就讓我們也用Weka來處理看看吧!

MNIST手寫數字資料下載 / MNIST Data Set Download

這份MNIST手寫資料集的圖片檔案是我從MARE's Computer Vision Study的「mnist image dataset (jpg files)」中下載而來。為了方便在Weka中處理,我將之整理後打包成「mnist_set」提供大家下載:

但是因為原始的7萬份資料集實在是太大了,不太適合練習使用。我從中挑選1/100的樣本,重新組成7百份的資料集「mnist_set_mini」,這樣練習時比較簡單:

這兩份檔案除了案例的數量上不一樣之外,其他都是一樣的。

image

在解壓縮下載下來的MNIST資料集,我們可以看到兩個資料夾:「train-set」跟「test-set」,前者是建模用的訓練集,後者是驗證用的測試集。

image

在兩個資料夾裡面,除了0到9的手寫數字之外,還有額外兩個檔案:

接下來的分類處理流程中,我們主要是以「train-set-phogfilter.arff」這個檔案來進行建模與預測。在「train-set」中的「train-set-phogfilter.arff」用於建模,而在「test-set」中的「train-set-phogfilter.arff」則是用於預測。


Weka分類手寫數字圖片 / MNIST Digists Classification with Weak

有了圖片檔案跟圖片分類檔之後,我們就可以到Weka裡面進行分類了。不過因為這次我事先作好了已經從圖片抽取特徵了的「train-set-phogfilter.arff」,而且也有足夠數量的測試檔,這次我們的流程就直接簡化,變成1. 建立模型、2. 以測試集評估模型正確率,這樣子就好。

這裡我用的是700個案例的「mnist_set_mini」,而非完整的「mnist_set」,但兩者的操作方式是一樣的喔。

建立模型、並評估正確率 / Model Building and Evaluation from Test-set

image

1. 開啟Weka,從GUI Chooser中開啟Explorer,然後用Open file開啟「train-set」資料夾底下的「train-set-phogfilter.arff」。

image

2. 點選「Classify」分頁進入分類功能。

image

3. 在Classifier的「Choose」選擇「weka.classifieres.functions.SMO」。

image

4. 在Test options (評估選項)選擇「Supplied test set」,並按下「Set」按鈕。

image

5. 按下「Open file」中選擇「test-set」資料夾底下的「train-set-phogfilter.arff」,然後按下「Close」退出回到Classifier主畫面。

image

6. 按下「More options」。

image

7. Output predictions (輸出預測結果)的「Choose」選擇「weka.classifiers.evaluation.output.prediction.CSV」。

image

8. 點下「CSV」粗體字,進入設定。

image

9. outputDistribution (輸出預測機率分佈)設定為「True」,然後一直按「OK」退出到Classifier主畫面。

image

10. 分類目標選擇「(Nom) class」。這是預設值,一般來說不用修改。

image

11. 按下「Start」。

image

12. 等待Weka跑完之後,右邊的Classifier output (分類輸出)可以找到「Correctly Classified Instances          90               90    %」。90表示分類正確的數量,後面的「90%」就是分類的正確率。表示100張手寫數字圖片中只有10張分類錯誤。

image

13. 繼續找到「Confusion Martix」(混淆矩陣),直欄表示Weka認為的分類,橫列表示實際的分類。如果數字出現在對角線上,例如「a-a=mnist_0=10」,表示mninst=0分類完全正確。

從混淆矩陣中可以看到,數字1、數字2、數字5跟數字7各分錯1個,數字3、數字8跟數字9各分錯2個,合集總共分錯10個。由此可以知道此模型在分辨各個數字的準確程度。

image

14. 最後是找到「Predictions on test set」,裡面寫著對未知案例的預測結果。每一種結果以逗號「,」分隔不同欄位,欄位的意義如下:

  1. inst# (案例編號):跟「test-set」資料夾中的「train-set-phogfilter.arff」對應,從上而下為每一個案例編號。因為「train-set-phogfilter.arff」是來自於「train-set.arff」,而我們可以從「train-set.arff」找到檔案名稱,因此1就是對應到檔案「mnist_0_1.jpg」。
  2. actual (實際分類):實際上這些數字的分類目標,從mninst_0到mnist_9。
  3. predicted (預測分類):這裡Weka會預測該圖片的分類,從mninst_0到mnist_9。如果predicted跟actual不一樣,表示Weka分類錯誤。
  4. error (發生錯誤):如果如果predicted跟actual不一樣,表示Weka分類錯誤,這個欄位會顯示「+」。
  5. distribution (分類機率分佈):表示該案例分類到每一種類別的機率。
錯誤案例說明 / Error Cases

以下我們就10個錯誤分類的案例中挑3個來說明吧。

mnist_1_999

20,2:mnist_1,8:mnist_7,+,0.022,0.178,0.089,0,0.133,0.044,0.067,*0.2,0.133,0.133

這張手寫圖片1被分類到數字7去了,其次最高分類機率就是數字1。

mnist_3_251

35,4:mnist_3,9:mnist_8,+,0.111,0,0.156,0.178,0.044,0.133,0.089,0.022,*0.2,0.067

這張手寫圖片3被分類到數字8去了,其次分類機率最高的就是數字3。

mnist_7_626

71,8:mnist_7,5:mnist_4,+,0.044,0.133,0.022,0,*0.178,0.089,0.067,0.178,0.111,0.178

這張手寫圖片7被分類到數字4去了,不過從機率分佈來看,Weka認為它可能是數字4、7跟9。

雖然準確率並沒有CNN的99.97%這麼高,不過Weka也能夠順利識別圖片,功能非常強大喔。如果最後的結果搭配「不寫程式也能預測未知!用Weka分類模型來預測未知案例」中的「預測未知案例」輸出成CSV檔案,後續分析就更容易處理了喔。

全資料的正確率 / Correctly Classified Rate of Full MNIST Data Set

image

附帶一提,如果拿完整的資料集「mnist_set」來跑的話,雖然計算時間需要3分鐘,還會佔用大量記憶器、導致電腦一副快當快當的樣子,但結果正確率可以達到99.05%

雖然跟面前說的99.44%有一點差距,不過也是很厲害的喔。


小結 / In Closing

這一整個「Weka Image Classification」系列的文章,其實只是我想要介紹「Image Filter」這個套件而已。有Image Filter可以簡單地從圖片中抽取特徵,這樣就能讓我們能夠順利處理非結構化的圖片資料,這樣的概念是從結構化資料分類跨越到非結構化資料分類的重要關鍵。

此外,我也想要讓大家看看,除了用Python寫CNN之外,還有其他方法可以簡單地辨識圖片。正確率雖然沒有CNN這麼高,但安裝與設置非常簡單、計算速度比起CNN快很多,而正確率也在一個可以接受的程度。不論是在教課或實務應用上,用Weka來分類圖片都能派上用場。

對了,這種做法還有一個額外的好處:不受限圖片的尺寸CNN的原理上限制每一張圖片必須維持同樣的長寬,否則必須以填白的方式補齊差異的部分。相對的,因為Weka的Image Filter大多是針對顏色、紋理來抽取特徵,所以並沒有這樣的限制,不論什麼大小的圖片都可以拿來分類。「從圖片抽取量化特徵:Weka的ImageFilter」中貓頭鷹與蝴蝶的資料集就是最好的例子。

看到這裡,是不是覺得Weka非常厲害呢?除了這些做法外,Weka還能作財經分析常用上的時間序列預測、以及社會科學統計上常用的PLS-SEM喔。簡單又好操作,快來學習Weka吧。

Weka的問答集 / Q&A of Weka

這篇寫完之後,馬上就有研究Python的朋友過來問我一些關於Weka的問題,那我就一併在這裡回答吧。

Q: Weka可以跑大量資料嗎?

A: 可以,不過要調整RunWeka.ini中的maxstack記憶體設定。但嚴格來說,我不太建議用Weka來跑超大量資料,Java太容易當掉了。

Q: Weka可以連結資料庫嗎?

A: 可以,但做法很複雜,做法請見「How do I connect to a database?」,不然「王者歸來: WEKA機器學習與大數據聖經」這本書的內容也有介紹如何存取資料庫。

Q: Weka可以用GPU來跑嗎?

A: 可以,做法是安裝套件「wekaDeeplearning4jGPU」。但似乎有點複雜,我並沒有試過怎麼用。

Q: Weka可以用Python或R的套件嗎?

A: 可以,要跑Python請用套件「python-weka-wrapper」,做法請見「Can I use WEKA from Python?」。要跑R請看這份線上課程:「3.4: Using R to run a classifier」。不過要跑Python或跑R的話,為何不要到它們各自的環境下跑就好了呢?

Q: Weka可以用指令控制嗎?

A: 可以。Weka本身就只是一個Java Library,可以直接以參數呼叫就能運作。Weka也有提供Simple CLI的指令列介面,但我覺得不是很好用啦。

Q: 跟Python比起來,你覺得Weka有什麼缺點?

A: 雖然大家可能覺得Python跟Weka主要差異是在於要寫程式跟有圖形化介面,但其實這倒不是這兩者優劣的關鍵。要我說的話,Weka比起Python明顯不足的地方有兩個:

一、Weka在前處理跟結果輸出較為困難:雖然對初學者來說,點點filter就能處理資料是很方便,但要處理大量資料的時候,還像Python這樣寫程式比較容易。同樣地,雖然分類中按下「Start」就能跑出結果,但要讓這個結果導向自己想要的格式或下一個應用,Weka也比較麻煩。

儘管如此,如果用程式語言來呼叫Weka的話,這個問題並不算是什麼大問題。關鍵還是下一個:

二、Python套件較為蓬勃發展:Weka雖然也有很多套件,但仔細一看會發現大多都已經有一定年紀,也沒有更新。以Java撰寫而成的Weka套件,也讓人難以重新改寫、編譯。相較之下,Python的發展欣欣向榮、前途一片光明,許多最新研究也會重新包裝成Python的套件供人下載使用,研究Python的開發者更是多不勝數。就這點來看,Weka可真的是完全比不上Python。

以我的角度來看,若要在實務應用的話,我也會用Python來建模、預測;但是對連觀念都沒有的初學者來說,我認為在課堂教授Weka,讓大家先建立起基本的資料探勘概念,這樣子切入到寫程式為主的Python時就會容易許多了。

Weka雖然有其極限,但在教學上還是一項很不錯的工具。學習資料探勘、機器學習,就從Weka開始吧。

總共2 則留言 ( 我要發問 , 隱藏留言 顯示留言 )

  1. 布丁老師您好,身為一個WEKA初學者感謝你的文章分享,真的覺得受益良多。
    有一個問題想請問一下,為何這一篇沒有像之前「分類初音圖片」那篇一樣,先做10 fold Cross-validation去驗證模型的準確性呢?

    回覆刪除
    回覆
    1. To Chao196,

      這是因為這篇的資料有測試集(test-set),而測試集裡面有正確答案,所以驗證模型成效的時候使用測試集驗證。
      如果你沒有測試集,或是測試集裡面沒有正確答案(需要等待被預測),才會退一步,只使用訓練集(train-set)來做交互驗證(cross-validation)

      https://blog.pulipuli.info/2017/06/weka-colorful-images-classification.html
      在分類初音的例子中,我們的測試集並沒有正確答案、分類目標未知,需要建立模型後來預測

      關於分類模型驗證中正確率與交互驗證的概念,我在「分類與預測:貝氏網路」中有介紹,可以跳過去看看教學內容。
      https://blog.pulipuli.info/2017/10/classification-and-prediction-bayesnet.html

      刪除