簡(jiǎn)易的深度學(xué)習(xí)框架Keras代碼解析與應(yīng)用

Author: Zongwei Zhou | 周縱葦
Weibo: @MrGiovanni
Email: zongweiz@asu.edu


Please cite this paper if you found it useful. Thanks!
Wang H, Zhou Z, Li Y, et al. Comparison of machine learning methods for classifying mediastinal lymph node metastasis of non-small cell lung cancer from 18F-FDG PET/CT images[J]. 2017, 7.

再來一波論文周邊吧——是關(guān)于代碼

總體來講keras這個(gè)深度學(xué)習(xí)框架真的很“簡(jiǎn)易”,它體現(xiàn)在可參考的文檔寫的比較詳細(xì),不像caffe,裝完以后都得靠技術(shù)博客,keras有它自己的官方文檔(不過是英文的),這給初學(xué)者提供了很大的學(xué)習(xí)空間。
這個(gè)文檔必須要強(qiáng)推!英文nice的可以直接看文檔,我這篇文章就是用中文來講這個(gè)事兒。

http://keras.io/

Keras官方文檔

首先要明確一點(diǎn):我沒學(xué)過Python,寫代碼都是需要什么百度什么的,所以有時(shí)候代碼會(huì)比較冗余,可能一句話就能搞定的能寫很多~


論文引用——3.2 測(cè)試平臺(tái)

項(xiàng)目代碼是在Windows 7上運(yùn)行的,主要用到的Matlab R2013a和Python,其中Matlab用于patch的分割和預(yù)處理,卷積神經(jīng)網(wǎng)絡(luò)搭建用到了根植于Python和Theano的深度學(xué)習(xí)框架Keras。Keras是基于Theano的一個(gè)深度學(xué)習(xí)框架,它的設(shè)計(jì)參考了Torch,用Python語(yǔ)言編寫,是一個(gè)高度模塊化的神經(jīng)網(wǎng)絡(luò)庫(kù),支持GPU和CPU,用起來特別簡(jiǎn)單,適合快速開發(fā)。


程序代碼下載:[ Github ]

等發(fā)表了就立刻放到Github :-)


參考資料


1. 直接上卷積神經(jīng)網(wǎng)絡(luò)構(gòu)建的主函數(shù)

def create_model(data):

    model = Sequential()
    
    model.add(Convolution2D(64, 5, 5, border_mode='valid', input_shape=data.shape[-3:])) 
    model.add(Activation('relu'))
    model.add(Dropout(0.5))
    
    model.add(Convolution2D(64, 5, 5, border_mode='valid'))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.5))
    
    model.add(Convolution2D(32, 3, 3, border_mode='valid')) 
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    
    model.add(Convolution2D(32, 3, 3, border_mode='valid')) 
    model.add(Activation('relu'))
    model.add(Dropout(0.5))
    
    model.add(Flatten())
    model.add(Dense(512, init='normal'))
    model.add(Activation('relu'))
    model.add(Dropout(0.5))
    
    model.add(Dense(LABELTYPE, init='normal'))
    model.add(Activation('softmax'))
    
    sgd = SGD(l2=0.0, lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
    model.compile(loss='categorical_crossentropy', optimizer=sgd, class_mode="categorical")
        
    return model

這個(gè)函數(shù)相當(dāng)?shù)暮?jiǎn)潔清楚了,輸入訓(xùn)練集,輸出一個(gè)空的神經(jīng)網(wǎng)絡(luò),其實(shí)就是卷積神經(jīng)網(wǎng)絡(luò)的初始化。model = Sequential()是給神經(jīng)網(wǎng)絡(luò)起了頭,后面的model.add()是一直加層,像搭積木一樣,要什么加什么,卷積神經(jīng)網(wǎng)絡(luò)有兩種類型的層:1)卷積,2)降采樣,對(duì)應(yīng)到代碼上是:

model.add(Convolution2D(64, 5, 5, border_mode='valid'))
# 加一個(gè)卷積層,卷積個(gè)數(shù)64,卷積尺寸5*5

model.add(MaxPooling2D(pool_size=(2, 2)))
# 加一個(gè)降采樣層,采樣窗口尺寸2*2

1.1 激活函數(shù)

注意:每個(gè)卷積層后面要加一個(gè)激活函數(shù),就是在教科書上說的這個(gè)部分

它可以將卷積后的結(jié)果控制在某一個(gè)數(shù)值范圍內(nèi),如0~1,-1~1等等,不會(huì)讓每次卷積完的數(shù)值相差懸殊

對(duì)應(yīng)到代碼上是這句:

model.add(Activation('relu'))

這個(gè)激活函數(shù)(Activation)keras提供了很多備選的,我這兒用的是ReLU這個(gè),其他還有

  • tanh
  • sigmoid
  • hard_sigmoid
  • linear
    等等,keras庫(kù)是不斷更新的,新出來的論文里面用到的更優(yōu)化的激活函數(shù)里面也會(huì)有收錄,比如:
  • LeakyReLU
  • PReLU
  • ELU
    等等,都是可以替換的,美其名曰“優(yōu)化網(wǎng)絡(luò)”,其實(shí)就只不過是改一下名字罷了哈哈,內(nèi)部函數(shù)已經(jīng)都幫你寫好了呢。注意一下:卷積神經(jīng)網(wǎng)絡(luò)的最后一層的激活函數(shù)一般就是選擇“softmax”。我這兒多說一嘴這些激活函數(shù)應(yīng)該怎么去選擇吧,一句話
參考的是[這篇文章]( ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/1689929-cfa5df3e478f594d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240))

原因分別是

導(dǎo)致梯度消失,不是零中心
導(dǎo)致梯度消失
x<0時(shí)梯度沒了
啊喲,不錯(cuò)哦

我知道Leaky ReLU已經(jīng)有現(xiàn)成的了,但是暫時(shí)還沒有用,現(xiàn)在還用的是ReLU這個(gè),別問我為什么:)

1.2 Dropout層

棄權(quán)(Dropout):針對(duì)“過度擬合”問題


不讓某些神經(jīng)元興奮

人腦在處理信號(hào)的時(shí)候并不是所有的神經(jīng)元都處于興奮狀態(tài)的,原因是1) 大腦的能量供給跟不上,2)神經(jīng)元的特異性,特定的神經(jīng)元處理特定信號(hào),3) 全部的神經(jīng)元都激活的話增加了反應(yīng)時(shí)間。所以我們用神經(jīng)網(wǎng)絡(luò)模擬的也要有所取舍,比如把信號(hào)強(qiáng)度低于某個(gè)值的神經(jīng)元都抑制下來,這樣能提高了網(wǎng)絡(luò)的速度和魯棒性,降低“過擬合”的可能性。額,廢話不說了,反正就是好!體現(xiàn)在代碼上是這個(gè):

model.add(Dropout(0.5))

這個(gè)0.5可以改,意思是信號(hào)強(qiáng)度排在后50%的神經(jīng)元都被抑制,就是把他們都扔掉~

1.3 還有點(diǎn)細(xì)節(jié)

到現(xiàn)在為止對(duì)這個(gè)網(wǎng)絡(luò)初始化的函數(shù)應(yīng)該只有一些小東西不清楚了吧:

model.add(Convolution2D(64, 5, 5, border_mode='valid', input_shape=data.shape[-3:])) 

你會(huì)發(fā)現(xiàn)第一個(gè)卷積層代碼比其他的長(zhǎng),原因是它還需要加上訓(xùn)練集的一些參數(shù),也就是input_shape = data.shape[-3:]這個(gè),它的意思是說明一下訓(xùn)練集的樣本有幾個(gè)通道和每個(gè)輸入圖像的尺寸,我這兒是

data.shape[-3:],表示我用了六通道,每個(gè)patch的尺寸是24*24像素。

通道的概念就是比如一幅黑白圖,就是一通道,即灰度值;一幅彩色圖就是三通道,即RGB;當(dāng)然也可以不用顏色作為通道,比如我用的六通道。但是通道內(nèi)部的機(jī)制我并不是很清楚,可能它就是為RGB設(shè)置的也說不定。這兒打一個(gè)問號(hào)?

model.add(Flatten())
model.add(Dense(512, init='normal'))

這兒加個(gè)一個(gè)全連接層,就是這兩句代碼,相當(dāng)于卷積神經(jīng)網(wǎng)絡(luò)中的這個(gè)

512意思就是這個(gè)層有512個(gè)神經(jīng)元

沒什么可說的,就是模型里的一部分,可以有好幾層,但一般放在網(wǎng)絡(luò)靠后的地方。

sgd = SGD(l2=0.0, lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd, class_mode="categorical")

這部分就是傳說中的“梯度下降法”,它用在神經(jīng)網(wǎng)絡(luò)的反饋階段,不斷地學(xué)習(xí),調(diào)整每一層卷積的參數(shù),即所謂“學(xué)習(xí)”的過程。我這兒用的是最常見的sgd,參數(shù)包括學(xué)習(xí)速度(lr),,雖然吧其他的參數(shù)理論上也能改,但是我沒有去改它們,呵呵。
小建議:學(xué)習(xí)參數(shù)一般比較小,我用的是0.01,這個(gè)是根據(jù)不同的訓(xùn)練集數(shù)據(jù)決定的,太小的話訓(xùn)練的速度很慢,太大的話容易訓(xùn)練自爆掉,像這樣

圓圈是當(dāng)前位置,五角星是目標(biāo)位置,若學(xué)習(xí)速度過快容易直接跳過目標(biāo)位置,導(dǎo)致訓(xùn)練失敗

對(duì)于keras提供的其他反饋的方法(Optimizer),我并沒有試過,也不清楚它們各自的優(yōu)缺點(diǎn),這兒列舉幾個(gè)其他的可選方法:

  • RMSprop
  • Adagrad
  • Adadelta
  • Adam
  • Adamax
    等等,我猜每一個(gè)方法都能對(duì)應(yīng)一篇深度學(xué)習(xí)的論文吧,代碼keras已經(jīng)都提供了,想了解詳情就去追溯論文吧。這兒我提一嘴代價(jià)函數(shù)的事兒,針對(duì)“學(xué)習(xí)緩慢”和“過渡擬合”問題,有提出對(duì)代價(jià)函數(shù)進(jìn)行修改的方法。道理都懂,具體在keras的哪兒做修改我還在摸索中,先來講一波道理:
講道理

由此可見,比較好的代價(jià)函數(shù)是

找機(jī)會(huì)把keras內(nèi)部這一部分的代碼改了

主代碼部分,The End


2. 訓(xùn)練前期代碼

在開始訓(xùn)練以前需要做幾個(gè)步驟

  • 導(dǎo)入需要的python包
  • 導(dǎo)入數(shù)據(jù)
  • 瓜分訓(xùn)練集和測(cè)試集

2.1 相關(guān)的python包導(dǎo)入

#coding:utf-8

'''
    GPU run command:
        THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python cnn.py
    CPU run command:
        python cnn.py
'''

######################################
#   導(dǎo)入各種用到的模塊組件
######################################

#   ConvNets的模塊
from __future__ import absolute_import
from __future__ import print_function
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.advanced_activations import PReLU, LeakyReLU
import keras.layers.advanced_activations as adact
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.optimizers import SGD, Adadelta, Adagrad, Adam, Adamax
from keras.utils import np_utils, generic_utils
from six.moves import range
from keras.callbacks import EarlyStopping

#   統(tǒng)計(jì)的模塊
from collections import Counter
import random, cPickle
from cutslice3d import load_data
from cutslice3d import ROW, COL, LABELTYPE, CHANNEL

#   內(nèi)存調(diào)整的模塊
import sys   

這兒就沒的說了,相當(dāng)于C語(yǔ)言里面的#include,后面要用到什么就導(dǎo)入什么。對(duì)了具體導(dǎo)入哪些包就是去keras安裝的位置看看,我的安裝路徑是

C:\Users\Administrator\Anaconda2\Lib\site-packages\keras

你會(huì)看到一個(gè)個(gè)的.py文件

keras目錄下就這樣子的

比如你需要導(dǎo)入Sequential()這個(gè)函數(shù)的話首先得知道它在keras的models.py中定義的,然后就很自然的出來這個(gè)代碼

from keras.models import Sequential
# 從keras的models.py中導(dǎo)入Sequential。

你看,代碼簡(jiǎn)單的都能直譯了。難點(diǎn)是你根本不知道Sequential()函數(shù)在哪兒定義的,這個(gè)就需要好好地去系統(tǒng)得看一下keras的文檔了,這么多函數(shù)我這兒也不可能逐一舉例。
這部分我個(gè)人感覺挺需要python的知識(shí),因?yàn)槌eras,很多包都蠻有用的,有了這些函數(shù)能省不少事兒。舉例:

from collections import Counter

作用是統(tǒng)計(jì)一個(gè)矩陣?yán)锩娴牟煌胤謩e出現(xiàn)的次數(shù),落實(shí)到后面的代碼就是

cnt = Counter(A)
for k,v in cnt.iteritems():
    print ('\\t', k, '-->', v)
# 實(shí)現(xiàn)了統(tǒng)計(jì)A矩陣的元素各自出現(xiàn)的次數(shù)

2.2 數(shù)據(jù)的簡(jiǎn)單處理模塊


######################################
#   對(duì)于本次試驗(yàn)的描述
######################################
print("\\n\\n\\nHey you, this is a trial on malignance and benign tumors detection via ConvNets. I'm Zongwei Zhou. :)")
print("Each input patch is 51*51, cutted from 1383 3d CT & PT images. The MINIMUM is above 30 segment pixels.")

######################################
#   加載數(shù)據(jù)
######################################
print(">> Loading Data ...")
TrData, TrLabel, VaData, VaLabel = load_data()
        
######################################
#   打亂數(shù)據(jù)
######################################
index = [i for i in range(len(TrLabel))]
random.shuffle(index)
TrData = TrData[index]
TrLabel = TrLabel[index]

print('\\tTherefore, read in', TrData.shape[0], 'samples from the dataset totally.')

#   label為0~1共2個(gè)類別,keras要求格式為binary class matrices,轉(zhuǎn)化一下,直接調(diào)用keras提供的這個(gè)函數(shù)
TrLabel = np_utils.to_categorical(TrLabel, LABELTYPE)

這兒我用到了一個(gè)load_data()函數(shù),是自己寫的,就是一個(gè)數(shù)據(jù)導(dǎo)入,從.mat文件中分別讀入訓(xùn)練集和測(cè)試集。也就是對(duì)于輸入patch的平移,旋轉(zhuǎn)變換以及訓(xùn)練集測(cè)試集劃分都是在MATLAB中完成的,得到的數(shù)據(jù)量爆大,截止到4月7日,我的訓(xùn)練集以及達(dá)到了31.4GB的規(guī)模,而python端的函數(shù)就比較直觀了,是這樣的

def load_data():    
    
    ######################################
    #   從.mat文件中讀入數(shù)據(jù)
    ######################################
    
    mat_training = h5py.File(DATAPATH_Training);
    mat_training.keys()
    Training_CT_x = mat_training[Training_CT_1];
    Training_CT_y = mat_training[Training_CT_2];
    Training_CT_z = mat_training[Training_CT_3];
    Training_PT_x = mat_training[Training_PT_1];
    Training_PT_y = mat_training[Training_PT_2];
    Training_PT_z = mat_training[Training_PT_3];
    TrLabel = mat_training[Training_label];
    TrLabel = np.transpose(TrLabel);
    Training_Dataset = len(TrLabel);
    
    mat_validation = h5py.File(DATAPATH_Validation);
    mat_validation.keys()
    Validation_CT_x = mat_validation[Validation_CT_1];
    Validation_CT_y = mat_validation[Validation_CT_2];
    Validation_CT_z = mat_validation[Validation_CT_3];
    Validation_PT_x = mat_validation[Validation_PT_1];
    Validation_PT_y = mat_validation[Validation_PT_2];
    Validation_PT_z = mat_validation[Validation_PT_3];
    VaLabel = mat_validation[Validation_label];
    VaLabel = np.transpose(VaLabel);
    Validation_Dataset = len(VaLabel);
        
    ######################################
    #   初始化
    ######################################
    TrData = np.empty((Training_Dataset, CHANNEL, ROW, COL), dtype = "float32");
    VaData = np.empty((Validation_Dataset, CHANNEL, ROW, COL), dtype = "float32");

    ######################################
    #   裁剪圖片,通道輸入
    ######################################
    for i in range(Training_Dataset):
        TrData[i,0,:,:]=Training_CT_x[:,:,i];
        TrData[i,1,:,:]=Training_CT_y[:,:,i];
        TrData[i,2,:,:]=Training_CT_z[:,:,i];
        TrData[i,3,:,:]=Training_PT_x[:,:,i];   
        TrData[i,4,:,:]=Training_PT_y[:,:,i]; 
        TrData[i,5,:,:]=Training_PT_z[:,:,i];
    
    for i in range(Validation_Dataset):
        VaData[i,0,:,:]=Validation_CT_x[:,:,i];
        VaData[i,1,:,:]=Validation_CT_y[:,:,i];
        VaData[i,2,:,:]=Validation_CT_z[:,:,i];
        VaData[i,3,:,:]=Validation_PT_x[:,:,i]; 
        VaData[i,4,:,:]=Validation_PT_y[:,:,i]; 
        VaData[i,5,:,:]=Validation_PT_z[:,:,i];
    
    print '\\tThe dimension of each data and label, listed as folllowing:'
    print '\\tTrData  : ', TrData.shape
    print '\\tTrLabel : ', TrLabel.shape
    print '\\tRange : ', np.amin(TrData[:,0,:,:]), '~', np.amax(TrData[:,0,:,:])
    print '\\t\\t', np.amin(TrData[:,1,:,:]), '~', np.amax(TrData[:,1,:,:])
    print '\\t\\t', np.amin(TrData[:,2,:,:]), '~', np.amax(TrData[:,2,:,:])
    print '\\t\\t', np.amin(TrData[:,3,:,:]), '~', np.amax(TrData[:,3,:,:])
    print '\\t\\t', np.amin(TrData[:,4,:,:]), '~', np.amax(TrData[:,4,:,:])
    print '\\t\\t', np.amin(TrData[:,5,:,:]), '~', np.amax(TrData[:,5,:,:])
    print '\\tVaData  : ', VaData.shape
    print '\\tVaLabel : ', VaLabel.shape
    print '\\tRange : ', np.amin(VaData[:,0,:,:]), '~', np.amax(VaData[:,0,:,:])
    print '\\t\\t', np.amin(VaData[:,1,:,:]), '~', np.amax(VaData[:,1,:,:])
    print '\\t\\t', np.amin(VaData[:,2,:,:]), '~', np.amax(VaData[:,2,:,:])
    print '\\t\\t', np.amin(VaData[:,3,:,:]), '~', np.amax(VaData[:,3,:,:])
    print '\\t\\t', np.amin(VaData[:,4,:,:]), '~', np.amax(VaData[:,4,:,:])
    print '\\t\\t', np.amin(VaData[:,5,:,:]), '~', np.amax(VaData[:,5,:,:])

    return TrData, TrLabel, VaData, VaLabel

讀入.mat中儲(chǔ)存的數(shù)據(jù),輸出的就直接是劃分好的訓(xùn)練集(TrData, TrLabel)和測(cè)試集(VaData, VaLabel)啦,比較簡(jiǎn)單,不展開說了。關(guān)于MATLAB端的數(shù)據(jù)拓展(Data Augmentation),我將在后續(xù)再介紹。說明一下數(shù)據(jù)拓展的作用也是針對(duì)“過度擬合”問題的。

注意一點(diǎn):我的label為0~1共2個(gè)類別,keras要求格式為binary class matrices,所以要轉(zhuǎn)化一下,直接調(diào)用keras提供的這個(gè)函數(shù)np_utils.to_categorical()即可。


3. 訓(xùn)練中后期代碼

前面的硬骨頭啃完了,這兒就是向開玩笑一樣,短短幾句代碼解決問題。

print(">> Build Model ...")
model = create_model(TrData)

######################################
#   訓(xùn)練ConvNets模型
######################################
print(">> Training ConvNets Model ...")
print("\\tHere, batch_size =", BATCH_SIZE, ", epoch =", EPOCH, ", lr =", LR, ", momentum =", MOMENTUM)
early_stopping = EarlyStopping(monitor='val_loss', patience=2)
hist = model.fit(TrData, TrLabel,               \\
                batch_size=BATCH_SIZE,      \\
                nb_epoch=EPOCH,             \\
                shuffle=True,               \\
                verbose=1,                  \\
                show_accuracy=True,         \\
                validation_split=VALIDATION_SPLIT,      \\
                callbacks=[early_stopping])

######################################
#   測(cè)試ConvNets模型
######################################
print(">> Test the model ...")
pre_temp=model.predict_classes(VaData)

3.1 訓(xùn)練模型

先調(diào)用1. 直接上卷積神經(jīng)網(wǎng)絡(luò)構(gòu)建的主函數(shù)中的函數(shù)create_model()建立一個(gè)初始化的模型。然后的訓(xùn)練主代碼就是一句話

hist = model.fit(TrData, TrLabel,               \\
                batch_size=100,         \\
                nb_epoch=10,            \\
                shuffle=True,               \\
                verbose=1,                  \\
                show_accuracy=True,         \\
                validation_split=0.2,       \\
                callbacks=[early_stopping])

:)沒錯(cuò),就一句話,不過這句話里面的事兒稍微比較多一點(diǎn)。。。我這兒就簡(jiǎn)單列舉一下我關(guān)注的項(xiàng):

  • TrData:訓(xùn)練數(shù)據(jù)
  • TrLabel:訓(xùn)練數(shù)據(jù)標(biāo)簽
  • batch_size:每次梯度下降調(diào)整參數(shù)是用的訓(xùn)練樣本
  • nb_epoch:訓(xùn)練迭代的次數(shù)
  • shuffle:當(dāng)suffle=True時(shí),會(huì)隨機(jī)打算每一次epoch的數(shù)據(jù)(默認(rèn)打亂),但是驗(yàn)證數(shù)據(jù)默認(rèn)不會(huì)打亂。
  • validation_split:測(cè)試集的比例,我這兒選了0.2。注意,這和2.2 數(shù)據(jù)的簡(jiǎn)單處理模塊中的測(cè)試集不是一個(gè)東西,這個(gè)測(cè)試集是一次訓(xùn)練的測(cè)試集,也就是下次訓(xùn)練他有可能變成訓(xùn)練集了。而2.2 數(shù)據(jù)的簡(jiǎn)單處理模塊中的是全局的測(cè)試集,對(duì)于訓(xùn)練好的網(wǎng)絡(luò)做的最終測(cè)試。
  • early_stopping:是否提前結(jié)束訓(xùn)練,網(wǎng)絡(luò)自己判斷,當(dāng)本次訓(xùn)練和上次訓(xùn)練的結(jié)果差不多了自動(dòng)回停止訓(xùn)練迭代,也就是不一定訓(xùn)練完nb_epoch(10)次哦

early_stopping的調(diào)用在這兒

early_stopping = EarlyStopping(monitor='val_loss', patience=2)

其他的都是和訓(xùn)練的時(shí)候的界面有關(guān),按照我的或者默認(rèn)的來就可以了:)

提一嘴,如果你想要看每一次的訓(xùn)練的結(jié)果是可以做到的!hist = model.fit()的hist中存放的是每一次訓(xùn)練完的結(jié)果和測(cè)試精確度等信息。

再來一嘴,如果你想要看每一層的輸出的啥,也是可以做到的!
這個(gè)可以用到卷積神經(jīng)網(wǎng)絡(luò)和其他傳統(tǒng)分類器結(jié)合來優(yōu)化softmax方法的實(shí)驗(yàn),涉及到比較高級(jí)的算法了,我以后再說。這兒先只放上看每一層輸出的代碼:

get_feature = theano.function([origin_model.layers[0].input],origin_model.layers[12].get_output(train=False),allow_input_downcast=False)
feature = get_feature(data)

好吧,再提供一下SVMRandom Forests的Python函數(shù)代碼吧,如果大家想做這個(gè)實(shí)驗(yàn)可以用哈:

######################################
#   SVM
######################################
def svc(traindata,trainlabel,testdata,testlabel):
    print("Start training SVM...")
    svcClf = SVC(C=1.0,kernel="rbf",cache_size=3000)
    svcClf.fit(traindata,trainlabel)
    
    pred_testlabel = svcClf.predict(testdata)
    num = len(pred_testlabel)
    accuracy = len([1 for i in range(num) if testlabel[i]==pred_testlabel[i]])/float(num)
    print("\\n>> cnn-svm Accuracy")
    prt(testlabel, pred_testlabel)

######################################
#   Random Forests
######################################
def rf(traindata,trainlabel,testdata,testlabel):
    print("Start training Random Forest...")
    rfClf = RandomForestClassifier(n_estimators=100,criterion='gini')
    rfClf.fit(traindata,trainlabel)    
    pred_testlabel = rfClf.predict(testdata)
    print("\\n>> cnn-rf Accuracy")
    prt(testlabel, pred_testlabel)

收~打住。

3.2 測(cè)試模型

呼呼,這個(gè)最水,也是一句話

pre_temp=model.predict_classes(VaData)

套用一個(gè)現(xiàn)有函數(shù)predict_classes()輸入測(cè)試集VaData,返回訓(xùn)練完的網(wǎng)絡(luò)的預(yù)測(cè)結(jié)果pre_temp。好了,最后把pre_temp和正確的測(cè)試集標(biāo)簽VaLabel對(duì)比一下,就知道這個(gè)網(wǎng)絡(luò)訓(xùn)練的咋樣了,實(shí)驗(yàn)階段性勝利!發(fā)個(gè)截圖:

Everybody Happy

3.3 保存模型

訓(xùn)練一個(gè)模型不容易,不但需要調(diào)整參數(shù),調(diào)整網(wǎng)絡(luò)結(jié)構(gòu),訓(xùn)練的時(shí)間還特別長(zhǎng),所以要學(xué)會(huì)保存訓(xùn)練完的網(wǎng)絡(luò),代碼是這樣的:

######################################
#   保存ConvNets模型
######################################

model.save_weights('MyConvNets.h5')
cPickle.dump(model, open('./MyConvNets.pkl',"wb"))
json_string = model.to_json()
open(W_MODEL, 'w').write(json_string)

就保存好啦,是這三個(gè)文件


保存的模型文件

當(dāng)你回頭要調(diào)用這個(gè)網(wǎng)絡(luò)時(shí),用這個(gè)代碼就可以了

model = cPickle.load(open(’MyConvNets.pkl',"rb"))

model中就讀入了pkl文件內(nèi)存儲(chǔ)的模型啦。


本文是keras的初階分享,如果其中涉及到有些知識(shí)點(diǎn)我略過了,可以參考
基于Theano的深度學(xué)習(xí)(Deep Learning)框架Keras學(xué)習(xí)隨筆-01-FAQ
回頭我會(huì)在整理一篇中階的分享,詳細(xì)地去講這些東西:)


4. 結(jié)語(yǔ)

又不是論文,要什么結(jié)語(yǔ)!

祝一切都好:)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 愿有人陪你顛沛流離 如果沒有 希望你成為自己的太陽(yáng) “現(xiàn)在是午夜十二點(diǎn)整,寂靜無(wú)聲,只有回憶與音...
    小阿歡閱讀 1,010評(píng)論 0 1
  • 看見磚縫上的青苔,就覺得很親切,西安的城墻反而因?yàn)橹匦蓿褂X得沒有歷史的味道。這里的一樹一木,一磚一瓦,雖破舊卻有...
    夢(mèng)海蓉閱讀 250評(píng)論 2 1
  • 兒子2周歲了,我也當(dāng)了2個(gè)月的奶爸。分享一下其中的體會(huì)和思考。 1、辭職在家當(dāng)奶爸需要勇氣,承認(rèn)當(dāng)全職奶爸更需要勇...
    龔少90990閱讀 1,952評(píng)論 4 3
  • 踏著時(shí)光的節(jié)拍,和著春天的韻律,看著有趣的動(dòng)漫片《鄭義門》,那生機(jī)靈動(dòng)的畫面,打開了傳統(tǒng)文化的內(nèi)涵,看“家風(fēng)”和“...
    佳佳最美閱讀 1,317評(píng)論 0 12