你可以把 Keras想像為以 Tensorflow及 Theano做為運算後臺的前臺使用者介面,讓你能夠在略懂皮毛的知識濃度下就輕鬆地建立起自己需要的類神經網絡。
關於安裝及設定、測試顯示卡(gpu)的訊息,我最推薦這份 Keras的中文文檔,其中展示了不同作業系統下如 Windows及 Linux的範例。此外,建議在安裝以上任何套件前先下載並安裝 Anaconda,它是一套 python科學計算的整合系統,可以省下很多自行摸索的麻煩。
而關於Keras的入門以及詳細參數設定則建議從 Keras官網的「新手入門:30秒學會建立類神經網絡」開始。
接著回到這篇文章的主題,如何建立多個 convolutional neural network(CNN)的結構。我預想會找到這篇文章的朋友應該是對CNN有一定的認識才會產生技術上的需求,但"誤入歧途"的觀眾我非常建議閱讀WILDML部落格的這篇文章對CNN的基本介紹,以及其中所有連結出去的網頁。
=====以下就開始 CNN的程式碼實作=====
假如你看完 Keras官網的教學後,你會發現其中的例子都是 Sequential model,線性式的將層與層之間推疊起來。但若想要建立如下圖中這樣「網狀」的結構時,我們就必須利用 Keras當中 Graph的物件(object)。
from keras.preprocessing import sequence from keras.models import Sequential from keras.layers.core import Dense, Dropout, Activation, Flatten from keras.layers.embeddings import Embedding from keras.layers.convolutional import Convolution1D, MaxPooling1D # 建立 Graph物件 graph = Graph() # 定義輸入層參數及進行 embedding graph.add_input(name='input', input_shape=(maxlen,), dtype='int') graph.add_node(Embedding(maxfeatures, word_dim, input_length=maxlen), name='embedding', input='input') # 第一個CNN、Maxpool、flatetn graph.add_node(Convolution1D(nb_filter=nb_filter,filter_length=fw[0],activation="relu"), name='conv1', input='embedding') graph.add_node(MaxPooling1D(pool_length =pool_length[0], border_mode='valid'), name='pool1', input = 'conv1') graph.add_node(Flatten(), name='flat1', input='conv1') # 第二個CNN、Maxpool、flatetn graph.add_node(Convolution1D(nb_filter=nb_filter,filter_length=fw[1],activation="relu"), name='conv2', input='embedding') graph.add_node(MaxPooling1D(pool_length =pool_length[1], border_mode='valid'), name='pool2', input = 'conv2') graph.add_node(Flatten(), name='flat2', input='conv2') # 第三個CNN、Maxpool、flatetn graph.add_node(Convolution1D(nb_filter=nb_filter,filter_length=fw[2],activation="relu"), name='conv3', input='embedding') graph.add_node(MaxPooling1D(pool_length =pool_length[2], border_mode='valid'), name='pool3', input = 'conv3') graph.add_node(Flatten(), name='flat3', input='conv3') # 將上面三個flat的結果整合 graph.add_node(Dense(hidden_dims,activation='relu'), name='dense1', inputs=['flat1', 'flat2', 'flat3'], merge_mode='concat') graph.add_node(Dropout(0.5), name='drop1', input='dense1') graph.add_node(Dense(nb_classes, activation='softmax'), name='softmax', input='drop1') graph.add_output(name='output', input='softmax') graph.compile('Adam', loss = {'output': 'categorical_crossentropy'}, metrics=['accuracy']) history = graph.fit({'input':X_train, 'output':Y_train}, nb_epoch=nb_epoch,batch_size=batch_size,validation_split=0.2)
在 Graph物件中,原先在 Sequential中的 add方法改名為 add_node。而且特別要注意的是,由於 Graph可以建立非線性疊加的網絡結構,如同我們這個的例子一樣,因此各個連結之間的輸入(input)都必需要標示清楚。
圖片特徵的截取是 CNN最常見的應用。但拜 word2vec方法的建立,一個單詞可以被投影至一個虛構的潛在語意空間而成為一個多維向量,而含有許多單詞文本的資料也就可以被轉換為由多個單詞向量堆積而成類似圖片的 2D結構,也就是矩陣,而這樣的動作就稱之為 embedding。
大家可能會注意到這個例子中使用的是 Convolutional1D,可以想像 filter是在一個單詞的向量空間滑動的特徵截取器。但由於向量空間的基底(basis)並沒有具體意義,因此想法上比較隱誨,而經過測試後也證實是有用的。
在WILDML這篇以Tensorflow實作CNN的文章以及其他許多的文獻中,實際上採用的是 Convolutional2D,可以想像成類似n-gram的特徵取法,也就是 filter會在詞彙空間中滑動,一次框起 n個詞。
基本上,Convolutional2D的實作只需要將上面程式碼的1D換做2D即可,但需要重新設定filter size、pool size等等參數。其中要特別注意的是,Convolutional2D的 input是吃一個四維的 tensor,而四個維度分別的參數為 (samples, channels, rows, cols)。
由於本身對於CNN的認識還是非常的有限,若有任何錯誤的話也歡迎大家提出來討論!
圖片特徵的截取是 CNN最常見的應用。但拜 word2vec方法的建立,一個單詞可以被投影至一個虛構的潛在語意空間而成為一個多維向量,而含有許多單詞文本的資料也就可以被轉換為由多個單詞向量堆積而成類似圖片的 2D結構,也就是矩陣,而這樣的動作就稱之為 embedding。
大家可能會注意到這個例子中使用的是 Convolutional1D,可以想像 filter是在一個單詞的向量空間滑動的特徵截取器。但由於向量空間的基底(basis)並沒有具體意義,因此想法上比較隱誨,而經過測試後也證實是有用的。
在WILDML這篇以Tensorflow實作CNN的文章以及其他許多的文獻中,實際上採用的是 Convolutional2D,可以想像成類似n-gram的特徵取法,也就是 filter會在詞彙空間中滑動,一次框起 n個詞。
基本上,Convolutional2D的實作只需要將上面程式碼的1D換做2D即可,但需要重新設定filter size、pool size等等參數。其中要特別注意的是,Convolutional2D的 input是吃一個四維的 tensor,而四個維度分別的參數為 (samples, channels, rows, cols)。
由於本身對於CNN的認識還是非常的有限,若有任何錯誤的話也歡迎大家提出來討論!
喜歡這篇文章的話請不要忘了點個讚哦!
關鍵字:python深度學習, deep learning, Keras CNN example, Keras graph example
keras graph model 已經停止更新了
回覆刪除如果改用新的model functional API 會更好用
https://keras.io/getting-started/functional-api-guide/
感謝你提供重要資訊!!
刪除