默默地學 Deep Learning (7)-透過Keras進行非監督式分群

Mortis Huang
Jul 24 · 7 min read
引用自: https://stke.sciencemag.org/content/9/432/re6

此篇文章,主要是解釋、翻譯下面這篇文章中的實作程式碼以及裡面所想要呈現給大家的想法,初學者不適用,若是想接觸Deep Learning的朋友,建議可以先去讀讀前面幾篇文章,想要閱讀原文的朋友們,可以直接前往:

在正文開始前,建議讀者先看一下底下列這篇簡述性文章,稍微了解一下等等遇到的K-means。扣除掉一些錯字之外,此篇文章還真的挺易懂。

目前深度學習、機器學習中最火熱的題目不外乎就是分類、迴歸這兩個方向,但這兩者皆屬於監督式學習,換句話說我們必須要有「標準答案」才能夠進行訓練。而當我們的資料越龐大時,我們所耗費在「給標準答案」的心力、時間就會越多、越麻煩。(「給標準答案」的行話,慣用語是「Label」)

然而,Clustering (以下用「分群」稱之。)則是讓我們的演算法、神經網路單純透過資料之間的相似度來進行計算,也就是我們不必給予標準答案。不必給予標準答案,有許多好處,好比說在訓練當中我們的模型學到了一個我們所忽略或是從沒注意到過的方法以及避免掉「標準答案」不是真正答案的問題,其實算是避免了某些盲點以及先入為主之觀念所造成的問題。

「標準答案」這件事情一直都很弔詭,我們被教育成只習慣於二分法的思維模式,不是對就是錯,但這世間的事情不可能只存在對錯。扯遠了,下一回再來談談有關對錯這件事。

「分群」在現實生活中的應用

●商品推薦系統,分群透過你的購買、瀏覽資料,來將你分類到特定購買族群中,從而進行針對該族群的商品廣告推播,常見的功能像是「別人也買了...」、「別人也在關注...」等。

●生物學分類,序列分群演算法一直都是顯學,好比說蛋白質就透過其內部胺基酸組成來被分群。

●影像資訊也被透過其內容之相似度來進行分群。

●在病歷資料中,有許多實際的生理參數,像是血糖、血壓、血脂等資訊,我們可以先透過分群來提高癌症病徵診斷、存活率的評估準確性。

該怎麼進行好的「分群」

一個好的分群方法應該要具有以下特點:

  1. 高群內相似性:單一群內的內聚性很明顯。
  2. 低群間相似性:群與群之間有很高的區別性。

怎麼好像在講廢話,呵呵。

好啦,底下開始進行程式碼範例的說明、演示。

完整程式碼都放在原作者的Github上:

接下來會直接從Github上所附的程式碼「Keras-DEC.ipynb」來進行解說。

我很討厭import自己另外寫的程式碼,我習慣都放在同一個檔案裡面,因此我有改寫一些地方,跟原作者的不會完全一模一樣。想下載我改過的版本,請往這邊走:戳我

先從K-means開始吧!

傳統的K-means演算法具有快速以及對於不同問題的高適應性,然而,當輸入資料的維度很高時 (影像時),它就爛掉了。

我們先用K-means 模型來把著名的MNIST手寫數字資料庫來分成十個群:

這個程式碼我有修改過,跟原作者的不太一樣,但是結果是一樣的,就是我們都得到了一個準確率只有53%的結果,先記住這個數字,之後我們來看看用神經網路搭建的模型效果是不是真的比他好很多。

當然,如果你的需求只是用K-means的話,上述程式碼就夠你用了。

自己搭建 Deep Learning Model 吧!

簡單介紹一下我們即將搭建的模型,它主要是由三個部分組合而成的:

●Autoencoder,我實在不是很想把它翻成中文,它是用來學習如何正確地生成出手寫數字的樣子。

●一個用來將Autoencoder中的部分結果擷取出來,之後轉化為分群的神經層。

●重新針對這個Model 進行優化訓練。

好,我知道到這邊根本看不懂在講什麼,沒關係,我們繼續往下。

我們先來介紹,Autoencoder:

Autoencoder會由兩個部分組成,一個是Encoder,另一個是Decoder。前面的中文名字叫做編碼器,後面的就是解碼器。換個比喻好了,前面的Encoder負責把原本的圖片壓縮成只有少少的幾個數字,而後面的Decoder,則是要把那少少的數字還原成原本的圖片。實現上述這樣一個過程的Model,就被叫做Autoencoder。

MNIST手寫數字資料集中,每一張圖片是28x28 Pixel 的黑白照片,也就是說一開始我們一個資料有784個數值,那在上述模型當中,我們把它壓縮到10個點,再由這10個點還原成784個數值。

總之,我們就來試試看吧!

由於有使用到MNIST資料集,所以請接續著一開始的程式碼跑,不要把變數們都清掉。

這個程式碼跑完之後,你會得到幾張圖還有一個autoencoder的權重檔案(.h5 檔案)。那現在我們就有一個,你給他一張「7」數字的照片,他也會吐一張「7」給你的神經網路了。(看似無用,但其實用處很多,可以用在降躁、換風格等等)

其實重點在於「透過十個特徵,可以還原成原本的數字」,換言之,這十個特徵,一定是很關鍵、重要的特徵,才能夠還原成原本的數字。也因此,用這十個特徵來去做接下來的分群,會有比較好的效果 (準確率約0.96,遠大於使用K-means的0.53)。

上面的程式碼,把我們剛剛訓練好的Autoencoder腰斬,把下面Decoder的部分拔掉,換成一個分群到十個族群的結構,長這樣:

腰斬並重新組合的Autocluster Model

上面就是訓練我們的Model啦,中間客製化了很多訓練時要輸出的資訊,方便我們監控模型訓練的狀態。

訓練完之後,我們就得到了一個完整的Autocluster Model啦,是不是好棒棒。

訓練完了,我們要怎麼知道到底結果怎麼樣、準不準確?透過上述程式碼,我們用七萬張手寫數字來進行驗證,會生成Confusion Matrix還有最後計算一個正確率「sum([w[i, j] for i, j in ind]) * 1.0 / y_pred.size」,得到約0.96的結果。

使用Autoencoder做的非監督式分群效果,可以看到很好地分成了十個群。

Mortis Land

我在這裡,看著、想著還有努力活著。

Mortis Huang

Written by

搬家到個人網站囉!

Mortis Land

我在這裡,看著、想著還有努力活著。

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade