總體來(lái)講keras這個(gè)深度學(xué)習(xí)框架真的很“簡(jiǎn)易”,它體現(xiàn)在可參考的文檔寫(xiě)的比較詳細(xì),不像caffe,裝完以后都得靠技術(shù)博客,keras有它自己的官方文檔(不過(guò)是英文的),這給初學(xué)者提供了很大的學(xué)習(xí)空間。
這個(gè)文檔必須要強(qiáng)推!英文nice的可以直接看文檔,我這篇文章就是用中文來(lái)講這個(gè)事兒。
Keras官方文檔
首先要明確一點(diǎn):我沒(méi)學(xué)過(guò)Python,寫(xiě)代碼都是需要什么百度什么的,所以有時(shí)候代碼會(huì)比較冗余,可能一句話就能搞定的能寫(xiě)很多~
論文引用——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ǔ)言編寫(xiě),是一個(gè)高度模塊化的神經(jīng)網(wǎng)絡(luò)庫(kù),支持GPU和CPU,用起來(lái)特別簡(jiǎn)單,適合快速開(kāi)發(fā)。
基于Theano的深度學(xué)習(xí)(Deep Learning)框架Keras學(xué)習(xí)隨筆-12-核心層
基于Theano的深度學(xué)習(xí)(Deep Learning)框架Keras學(xué)習(xí)隨筆-13-卷積層
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ù),就是在教科書(shū)上說(shuō)的這個(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
等等,keras庫(kù)是不斷更新的,新出來(lái)的論文里面用到的更優(yōu)化的激活函數(shù)里面也會(huì)有收錄,比如:
LeakyReLU
PReLU
ELU
等等,都是可以替換的,美其名曰“優(yōu)化網(wǎng)絡(luò)”,其實(shí)就只不過(guò)是改一下名字罷了哈哈,內(nèi)部函數(shù)已經(jīng)都幫你寫(xiě)好了呢。注意一下:卷積神經(jīng)網(wǎng)絡(luò)的最后一層的激活函數(shù)一般就是選擇“softmax”。我這兒多說(shuō)一嘴這些激活函數(shù)應(yīng)該怎么去選擇吧,一句話

參考的是這篇文章
原因分別是

導(dǎo)致梯度消失,不是零中心

導(dǎo)致梯度消失

x《0時(shí)梯度沒(méi)了

我知道Leaky ReLU已經(jīng)有現(xiàn)成的了,但是暫時(shí)還沒(méi)有用,現(xiàn)在還用的是ReLU這個(gè),別問(wèn)我為什么:)
1.2 Dropout層
棄權(quán)(Dropout):針對(duì)“過(guò)度擬合”問(wèn)題

不讓某些神經(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)元都抑制下來(lái),這樣能提高了網(wǎng)絡(luò)的速度和魯棒性,降低“過(guò)擬合”的可能性。額,廢話不說(shuō)了,反正就是好!體現(xiàn)在代碼上是這個(gè):
model.add(Dropout(0.5))
這個(gè)0.5可以改,意思是信號(hào)強(qiáng)度排在后50%的神經(jīng)元都被抑制,就是把他們都扔掉~(yú)
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è),它的意思是說(shuō)明一下訓(xùn)練集的樣本有幾個(gè)通道和每個(gè)輸入圖像的尺寸,我這兒是

data.shape[-3:],表示我用了六通道,每個(gè)patch的尺寸是24*24像素。
通道的概念就是比如一幅黑白圖,就是一通道,即灰度值;一幅彩色圖就是三通道,即RGB;當(dāng)然也可以不用顏色作為通道,比如我用的六通道。但是通道內(nèi)部的機(jī)制我并不是很清楚,可能它就是為RGB設(shè)置的也說(shuō)不定。這兒打一個(gè)問(wèn)號(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)元
沒(méi)什么可說(shuō)的,就是模型里的一部分,可以有好幾層,但一般放在網(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”)
這部分就是傳說(shuō)中的“梯度下降法”,它用在神經(jīng)網(wǎng)絡(luò)的反饋階段,不斷地學(xué)習(xí),調(diào)整每一層卷積的參數(shù),即所謂“學(xué)習(xí)”的過(guò)程。我這兒用的是最常見(jiàn)的sgd,參數(shù)包括學(xué)習(xí)速度(lr),,雖然吧其他的參數(shù)理論上也能改,但是我沒(méi)有去改它們,呵呵。
小建議:學(xué)習(xí)參數(shù)一般比較小,我用的是0.01,這個(gè)是根據(jù)不同的訓(xùn)練集數(shù)據(jù)決定的,太小的話訓(xùn)練的速度很慢,太大的話容易訓(xùn)練自爆掉,像這樣

圓圈是當(dāng)前位置,五角星是目標(biāo)位置,若學(xué)習(xí)速度過(guò)快容易直接跳過(guò)目標(biāo)位置,導(dǎo)致訓(xùn)練失敗
對(duì)于keras提供的其他反饋的方法(Optimizer),我并沒(méi)有試過(guò),也不清楚它們各自的優(yōu)缺點(diǎn),這兒列舉幾個(gè)其他的可選方法:
RMSprop
Adagrad
Adadelta
Adam
Adamax
等等,我猜每一個(gè)方法都能對(duì)應(yīng)一篇深度學(xué)習(xí)的論文吧,代碼keras已經(jīng)都提供了,想了解詳情就去追溯論文吧。這兒我提一嘴代價(jià)函數(shù)的事兒,針對(duì)“學(xué)習(xí)緩慢”和“過(guò)渡擬合”問(wèn)題,有提出對(duì)代價(jià)函數(shù)進(jìn)行修改的方法。道理都懂,具體在keras的哪兒做修改我還在摸索中,先來(lái)講一波道理:

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

找機(jī)會(huì)把keras內(nèi)部這一部分的代碼改了
主代碼部分,The End
2. 訓(xùn)練前期代碼
在開(kāi)始訓(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
這兒就沒(méi)的說(shuō)了,相當(dāng)于C語(yǔ)言里面的#include,后面要用到什么就導(dǎo)入什么。對(duì)了具體導(dǎo)入哪些包就是去keras安裝的位置看看,我的安裝路徑是
C:UsersAdministratorAnaconda2Libsite-packageskeras
你會(huì)看到一個(gè)個(gè)的.py文件

keras目錄下就這樣子的
比如你需要導(dǎo)入Sequential()這個(gè)函數(shù)的話首先得知道它在keras的models.py中定義的,然后就很自然的出來(lái)這個(gè)代碼
from keras.models import Sequential
# 從keras的models.py中導(dǎo)入Sequential。
你看,代碼簡(jiǎn)單的都能直譯了。難點(diǎn)是你根本不知道Sequential()函數(shù)在哪兒定義的,這個(gè)就需要好好地去系統(tǒng)得看一下keras的文檔了,這么多函數(shù)我這兒也不可能逐一舉例。
這部分我個(gè)人感覺(jué)挺需要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ù),是自己寫(xiě)的,就是一個(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)單,不展開(kāi)說(shuō)了。關(guān)于MATLAB端的數(shù)據(jù)拓展(Data Augmentation),我將在后續(xù)再介紹。說(shuō)明一下數(shù)據(jù)拓展的作用也是針對(duì)“過(guò)度擬合”問(wèn)題的。
注意一點(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)練中后期代碼
前面的硬骨頭啃完了,這兒就是向開(kāi)玩笑一樣,短短幾句代碼解決問(wè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])
:)沒(méi)錯(cuò),就一句話,不過(guò)這句話里面的事兒稍微比較多一點(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)的來(lái)就可以了:)
提一嘴,如果你想要看每一次的訓(xùn)練的結(jié)果是可以做到的!hist = model.fit()的hist中存放的是每一次訓(xùn)練完的結(jié)果和測(cè)試精確度等信息。
再來(lái)一嘴,如果你想要看每一層的輸出的啥,也是可以做到的!
這個(gè)可以用到卷積神經(jīng)網(wǎng)絡(luò)和其他傳統(tǒng)分類器結(jié)合來(lái)優(yōu)化softmax方法的實(shí)驗(yàn),涉及到比較高級(jí)的算法了,我以后再說(shuō)。這兒先只放上看每一層輸出的代碼:
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)
好吧,再提供一下SVM和Random Forests的Python函數(shù)代碼吧,如果大家想做這個(gè)實(shí)驗(yàn)可以用哈:
######################################
# SVM
######################################
def svc(traindata,trainlabel,testdata,testlabel):
print(“Start training SVM.。?!保?/p>
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.。?!保?/p>
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ǔ)的模型啦。
電子發(fā)燒友App























評(píng)論