您當前的位置:首頁 > 詩詞

Keras使用過程中的tricks和errors(持續更新)

作者:由 Derek 發表于 詩詞時間:2018-03-21

總而言之,就是在看完阿ga的知乎文章之後決定也開始做一個懶惰的知乎博主……使用Keras有一段時間了,作為高層的API使用起來很方便,並且如果能仔細研究研究原始碼其實靈活性也並不低。把使用過程中碰到的一些tricks和一些小errors放上來當個筆記,會持續更新,也歡迎大家來留言貢獻自己的小技巧。

注:文章例子和解釋一些是我自己寫的,一些來源於網上找的,具體網址不記得了,如果有人發現是我用了你們的答案請告知,我會註明。

順便推薦一下阿ga的知乎博文:知乎使用者

開始正文:

一個剛開始會常遇到的錯誤:

expected activation_1 to have shape (None,2) but got array with shape (21043,1)

一般遇到這種情況都是某一層輸入和資料輸入shape不符造成的。比較常見的多出現在最後一層,可能是y(label)的shape問題,舉個例子:

Keras使用過程中的tricks和errors(持續更新)

網路最後是用了softmax,所以y應該是shape(none,2),假設有兩類的情況下;

但是如果y向量是[1,0,0,0,1, 。。。]的list,shape是(none,1),所以會有如此的報錯,一種解決辦法是:

Keras使用過程中的tricks和errors(持續更新)

將Y轉化為categorical的型別就可以了。

2. 簡單列印模型的結構:model.summary()

這個本來是一個比較簡單的部分,但是初學者可能一般不會想到。給個例子:

Keras使用過程中的tricks和errors(持續更新)

使用model。summary()之後的輸出:

Keras使用過程中的tricks和errors(持續更新)

3. 使用word2vec的embedding層模型載入:

對於nlp問題,載入模型時embedding layer會被載入進來,但是要保證weights = [embedding_matrix], 也就是pre-trained 詞向量的map和tokenizer的index一樣。我的做法是需要同時儲存tokenizer,之後在下一次載入模型是呼叫tokenizer,具體:

Keras使用過程中的tricks和errors(持續更新)

4. 載入模型有自己定義的層(load model with custome layer)

很多時候我們需要自己編寫層的結構,對於這樣的模型,載入時需要註明了自己編寫的層。舉個例子:

Keras使用過程中的tricks和errors(持續更新)

模型中使用了AttentionwithContext層,所以在載入時需要註明,就不會報錯了。

5. keras中的masking層到底是幹什麼的

官方文件裡面是這麼說的:

Keras使用過程中的tricks和errors(持續更新)

很難理解吧,從網上找了一個簡潔的例子,原網址找不到了,直接上截圖吧:

Keras使用過程中的tricks和errors(持續更新)

6. keras讀取模型某一層的輸出

這個需求往往是在特徵提取的時候。比如訓練好一個模型,想要提取某一層的輸出作為輸入資料的特徵。具體方法:

Keras使用過程中的tricks和errors(持續更新)

這個例子同樣也是網上找的,注意了,其中

output = model。layer[3]。output

重點是怎麼知道你想呼叫的層在layer中的index和名字呢,可以輸出一下:

layers = model。layers

for i , layer in enumerate(layers):

print i, layer

當然,也可以透過layer的name特徵來找到某一層,具體情況讀讀原始碼吧!

7. Keras把幾個層封裝成一層,像函式一樣

keras是支援這樣的做法的,程式碼會比較簡潔明瞭。而且如果有寫層需要共享,比如在siamese network中的情況,這樣也會比較方便。具體方法:

a。 首先定義層

Keras使用過程中的tricks和errors(持續更新)

b。 在呼叫時建立該層:(注意,這裡只是建立圖,沒有tensor輸入)

Keras使用過程中的tricks和errors(持續更新)

c。 搭建完整結構:

Keras使用過程中的tricks和errors(持續更新)

8. 關於Keras模型訓練過程中的metric=“accuracy”的問題

今天訓練模型的時候遇到的一個大坑。沒看錯,如果沒有留意過這裡的話真的是大坑。。。

具體情況就是做分類任務時,

output layer的activation=“sigmoid”,對應的loss=“binary_crossentropy”

2。 output layer的activation=“softmax”,對應的loss=“categorical_crossentropy”

對於2來說,得到的是

join distribution and a multinomial likelihood

,相當於一個機率分佈,和為1;

對於1來說,得到的是

marginal distribution and a Bernoulli likelihood

, p(y0/x) , p(y1/x) etc。

具體的話,如果是multi-label classification,就是一個樣本屬於多類的情況下,需要用1。否則,如果各個類別之間有相互關係(比如簡單的情感分類,如果是正向情感就一定意味著負向情感的機率低),可以使用softmax;如果各個類別之間偏向於獨立,可以使用sigmoid。(注:這裡是我查了一些回答+個人的理解,如果有不同意見麻煩指出,靴靴)。

然後大坑來了:

再模型訓練中,往往在model。compile()我們設定metric=[“accuracy”]。但是,對於1來說,相當於是“binary_accuracy”,具體實現如下圖:

Keras使用過程中的tricks和errors(持續更新)

舉個例子,對於一個樣本來說,假設:

y_t = tf。constant([[1。, 0。, 1。, 1]]) # true label

y_p = tf。constant([[0。5, 0。2, 0。9, 0。8]]) # predict label

binary_accuracy的結果是0。75,因為這裡認為除了dim=0的class分錯了,別的還是對的;

然而對於2來說,此時的“accuracy”是“categorical_accuracy”,具體實現如下:

Keras使用過程中的tricks和errors(持續更新)

同樣對於上面的例子,此時categorical_acc的結果為0,因為預測錯了!

所以對於自己的分類任務,一定要把評估結果考慮清楚。就好像同樣的分類任務,我試了1和2兩種方法,結果輸出的acc一個達到93%+,一個才是84%,因為這裡metric=[‘acc’]的‘acc’並不是完全同一個評價方法。。。心累。。。

或者也可以直接指定metric=[‘binary_accuracy’, ‘categorical_accuracy’],在訓練過程中會兩個結果都輸出,這樣方便自己的判斷。

Anyway,因為Keras的整合封裝帶來了一定的便利性,同時的弊端就是如果不是非常瞭解或者如果沒有仔細看過原始碼,很容易帶來一些判斷誤區。

先寫這些。。。接下來找時間持續更新吧,各位有啥自己的keras小竅門求分享。。。

標簽: layer  accuracy  模型  shape  Model