keras實踐(一): multi-label神經網路
前沿
本篇記錄一下自己專案中用到的keras相關的部分。由於本專案既有涉及multi-class(多類分類),也有涉及multi-label(多標記分類)的部分,multi-class分類網上已經很多相關的文章了。這裡就說一說multi-label的搭建網路的部分。之後如果有時間的時候,再說一說cross validation(交叉驗證)和在epoch的callback函式中處理一些多標籤度量metric的問題。
multi-label多標記監督學習
其實我個人比較喜歡把label翻譯為標籤。那可能學術上翻譯multi-label多翻譯為多標記。其實和多標籤一個意思。
multi-class 和 multi-label的區別
multi-class是相對於binary二分類來說的,意思是需要分類的東西不止有兩個類別,可能是3個類別取一個(如iris分類),或者是10個類別取一個(如手寫數字識別mnist)。
而multi-label是更加general的一種情況了,它說為什麼一個sample的標籤只能有1個呢。為什麼一張圖片不是貓就是狗呢?難道我不能訓練一個人工智慧,它能告訴我這張圖片既有貓又有狗呢?
其實關於多標籤學習的研究,已經有很多成果了。
主要解法是
* 不擴充套件基礎分類器的本來演算法,只通過轉換原始問題來解決多標籤問題。如BR, LP等。
* 擴充套件基礎分類器的本來演算法來適配多標籤問題。如ML-kNN, BP-MLL等。
這裡不展開了。有興趣的同學可以自己去研究一下。
keras的multi-label
廢話不多說,直接上程式碼。這裡假設大家是有keras的基礎知識的,所以關鍵程式碼之外的程式碼請大家自行腦補。
def __create_model(self):
from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
print("create model. feature_dim = %s, label_dim = %s" % (self.feature_dim, self.label_dim))
model.add(Dense(500 , activation='relu', input_dim=self.feature_dim))
model.add(Dense(100, activation='relu'))
model.add(Dense(self.label_dim, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
return model
稍微解說一下:
* 整個網路是fully connected全連線網路。
* 網路結構是輸入層=你的特徵的維度
* 隱藏層是500*100,激勵函式都是relu。隱藏層的節點數量和深度請根據自己的數量來自行調整,這裡只是舉例。
* 輸出層是你的label的維度。使用sigmoid作為激勵,使輸出值介於0-1之間。
* 訓練資料的label請用0和1的向量來表示。0代表這條資料沒有這個位的label,1代表這條資料有這個位的label。假設3個label的向量[天空,人,大海]的向量值是[1,1,0]的編碼的意思是這張圖片有天空,有人,但是沒有大海。
* 使用binary_crossentropy來進行損失函式的評價,從而在訓練過程中不斷降低交叉商。實際變相的使1的label的節點的輸出值更靠近1,0的label的節點的輸出值更靠近0。
結語
有了這個結構,就可以run起來一個multi label的神經網路了。這個只是基礎中的基礎,關於multi-label的度量程式碼才是我們研究一個機器學習問題的核心。