Keras深度學習實戰(zhàn)_第1頁
Keras深度學習實戰(zhàn)_第2頁
Keras深度學習實戰(zhàn)_第3頁
Keras深度學習實戰(zhàn)_第4頁
Keras深度學習實戰(zhàn)_第5頁
已閱讀5頁,還剩259頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

Keras深度學習實戰(zhàn)基于TensorFlow和Theano創(chuàng)建神經(jīng)網(wǎng)絡目錄TOC\h\h第1章神經(jīng)網(wǎng)絡基礎\h1.1感知機\h1.2多層感知機——第一個神經(jīng)網(wǎng)絡的示例\h1.3實例——手寫數(shù)字識別\h1.4一種實用的反向傳播概述\h1.5走向深度學習之路\h1.6小結(jié)\h第2章Keras安裝和API\h2.1安裝Keras\h2.2配置Keras\h2.3在Docker上安裝Keras\h2.4在谷歌CloudML上安裝Keras\h2.5在亞馬遜AWS上安裝Keras\h2.6在微軟Azure上安裝Keras\h2.7KerasAPI\h2.8自定義訓練過程的回調(diào)函數(shù)\h2.9小結(jié)\h第3章深度學習之卷積網(wǎng)絡\h3.1深度卷積神經(jīng)網(wǎng)絡——DCNN\h3.2DCNN示例——LeNet\h3.3用深度學習網(wǎng)絡識別CIFAR-10圖像\h3.4用于大型圖片識別的極深度卷積網(wǎng)絡\h3.5小結(jié)\h第4章生成對抗網(wǎng)絡和WaveNet\h4.1什么是生成對抗網(wǎng)絡\h4.2深度卷積生成對抗網(wǎng)絡\h4.3用Kerasadversarial生成MNIST數(shù)據(jù)\h4.4用Kerasadversarial生成CIFAR數(shù)據(jù)\h4.5WaveNet——一個學習如何產(chǎn)生音頻的生成模型\h4.6小結(jié)\h第5章詞嵌入\h5.1分布式表示\h5.2word2vec\h5.3探索GloVe\h5.4使用預訓練好的詞向量\h5.5小結(jié)\h第6章循環(huán)神經(jīng)網(wǎng)絡——RNN\h6.1SimpleRNN單元\h6.2RNN拓撲結(jié)構(gòu)\h6.3梯度消失和梯度爆炸\h6.4長短期記憶網(wǎng)絡——LSTM\h6.5門控循環(huán)單元——GRU\h6.6雙向RNN\h6.7有狀態(tài)RNN\h6.8其他RNN變體\h6.9小結(jié)\h第7章其他深度學習模型\h7.1Keras函數(shù)API\h7.2回歸網(wǎng)絡\h7.3無監(jiān)督學習——自動編碼器\h7.4構(gòu)造深度網(wǎng)絡\h7.5自定義Keras\h7.6生成模型\h7.7小結(jié)\h第8章游戲中的AI\h8.1強化學習\h8.2示例——用Keras深度Q網(wǎng)絡實現(xiàn)捕捉游戲\h8.3未來之路\h8.4小結(jié)\h第9章結(jié)束語\h9.1Keras2.0——新特性第1章神經(jīng)網(wǎng)絡基礎人工神經(jīng)網(wǎng)絡表示一類機器學習的模型,最初是受到了哺乳動物中央神經(jīng)系統(tǒng)研究的啟發(fā)。網(wǎng)絡由相互連接的分層組織的神經(jīng)元組成,這些神經(jīng)元在達到一定條件時就會互相交換信息(專業(yè)術語是激發(fā)(fire))。最初的研究開始于20世紀50年代后期,當時引入了感知機(Perceptron)模型(更多信息請參考文章《ThePerceptron:AProbabilisticModelforInformationStorageandOrganizationintheBrain》,作者F.Rosenblatt,PsychologicalReview,vol.65,pp.386~408,1958)。感知機是一個可以實現(xiàn)簡單操作的兩層網(wǎng)絡,并在20世紀60年代后期引入反向傳播算法(backpropagationalgorithm)后得到進一步擴展,用于高效的多層網(wǎng)絡的訓練(據(jù)以下文章《BackpropagationthroughTime:WhatItDoesandHowtoDoIt》,作者P.J.Werbos,ProceedingsoftheIEEE,vol.78,pp.1550~1560,1990;《AFastLearningAlgorithmforDeepBeliefNets》,作者G.E.Hinton,S.Osindero,Y.W.Teh,NeuralComputing,vol.18,pp.1527~1554,2006)。有些研究認為這些技術起源可以追溯到比通常引述的更早的時候(更多信息,請參考文章《DeepLearninginNeuralNetworks:AnOverview》,作者J.Schmidhuber,NeuralNetworks,vol.61,pp.85~117,2015)。直到20世紀80年代,人們才對神經(jīng)網(wǎng)絡進行了大量的學術研究,那時其他更簡單的方法正變得更加有用。然后,由于G.Hinton提出的快速學習算法(更多信息,請參考文章《TheRootsofBackpropagation:FromOrderedDerivativestoNeuralNetworksandPoliticalForecasting》,作者S.Leven,NeuralNetworks,vol.9,1996;《LearningRepresentationsbyBackpropagatingErrors》,作者D.E.Rumelhart,G.E.Hinton,R.J.Williams,Nature,vol.323,1986),以及2011年前后引入GPU后使大量數(shù)值計算成為可能,開始再度出現(xiàn)了神經(jīng)網(wǎng)絡研究的熱潮。這些進展打開了現(xiàn)代深度學習的大門。深度學習是以一定數(shù)量網(wǎng)絡層的神經(jīng)元為標志的神經(jīng)網(wǎng)絡,它可以基于漸進的層級抽象學習相當復雜的模型。幾年前,3~5層的網(wǎng)絡就是深度的,而現(xiàn)在的深度網(wǎng)絡已經(jīng)是指100~200層。這種漸進式抽象的學習模型,模仿了歷經(jīng)幾百萬年演化的人類大腦的視覺模型。人類大腦視覺系統(tǒng)由不同的層組成。我們?nèi)搜坳P聯(lián)的大腦區(qū)域叫作初級視覺皮層V1,它位于大腦后下方。視覺皮層為多數(shù)哺乳動物所共有,它承擔著感知和區(qū)分視覺定位、空間頻率以及色彩等方面的基本屬性和微小變化的角色。據(jù)估計,初級視覺層包含了1億4000萬個神經(jīng)元,以及100億個神經(jīng)元之間的連接。V1層隨后和其他視覺皮層V2、V3、V4、V5和V6連接,以進一步處理更復雜的圖像信息,并識別更復雜的視覺元素,如形狀、面部、動物等。這種分層組織是1億年間無數(shù)次嘗試的結(jié)果。據(jù)估計,人類大腦包含大約160億個腦皮質(zhì)神經(jīng)細胞,其中10%~25%是負責視覺信息處理的(更多信息,請參考文章《TheHumanBraininNumbers:ALinearlyScaled-upPrimateBrain》,作者S.Herculano-Houzel,vol.3,2009)。深度學習就是從人類大腦視覺系統(tǒng)的層次結(jié)構(gòu)中獲得了啟發(fā),前面的人工神經(jīng)網(wǎng)絡層負責學習圖像基本信息,更深的網(wǎng)絡層負責學習更復雜的概念。本書涵蓋了神經(jīng)網(wǎng)絡的幾個主要方面,并提供了基于Keras和最小有效Python庫作為深度學習計算的可運行網(wǎng)絡實例編碼,后端基于谷歌的TensorFlow或者蒙特利爾大學的Theano框架。好的,讓我們切入正題。在本章,我們將介紹以下內(nèi)容:感知機多層感知機激活函數(shù)梯度下降隨機梯度下降反向傳播算法1.1感知機感知機是一個簡單的算法,給定n維向量x(x1,x2,…,xn)作為輸入,通常稱作輸入特征或者簡單特征,輸出為1(是)或0(否)。數(shù)學上,我們定義以下函數(shù):這里,w是權重向量,wx是點積(譯者注:也稱內(nèi)積、數(shù)量積或標量積),b是偏差。如果你還記得基礎的幾何知識,就應該知道wx+b定義了一個邊界超平面,我們可以通過設置w和b的值來改變它的位置。如果x位于直線之上,則結(jié)果為正,否則為負。非常簡單的算法!感知機不能表示非確定性答案。如果我們知道如何定義w和b,就能回答是(1)或否(0)。接下來我們將討論這個訓練過程。第一個Keras代碼示例Keras的原始構(gòu)造模塊是模型,最簡單的模型稱為序貫模型,Keras的序貫模型是神經(jīng)網(wǎng)絡層的線性管道(堆棧)。以下代碼段定義了一個包含12個人工神經(jīng)元的單層網(wǎng)絡,它預計有8個輸入變量(也稱為特征):fromkeras.modelsimportSequential

model=Sequential()

model.add(Dense(12,input_dim=8,kernel_initializer='random_uniform'))

每個神經(jīng)元可以用特定的權重進行初始化。Keras提供了幾個選擇,其中最常用的選擇如下所示。random_uniform:初始化權重為(–0.05,0.05)之間的均勻隨機的微小數(shù)值。換句話說,給定區(qū)間里的任何值都可能作為權重。random_normal:根據(jù)高斯分布初始化權重,平均值為0,標準差為0.05。如果你不熟悉高斯分布,可以回想一下對稱鐘形曲線。zero:所有權重初始化為0。完整選項列表請參考Keras官網(wǎng)。1.2多層感知機——第一個神經(jīng)網(wǎng)絡的示例在本章中,我們將定義一個多層線性網(wǎng)絡,并將其作為本書的第一個代碼示例。從歷史上來看,感知機這個名稱是指具有單一線性層的模型,因此,如果它有多層,我們就可以稱之為多層感知機(Multilayerperceptron,MLP)。圖1.1展示了一個一般的神經(jīng)網(wǎng)絡,它具有一個輸入層、一個中間層和一個輸出層。圖1.1在圖1.1中,第一層中的每個節(jié)點接收一個輸入,并根據(jù)預設的本地決策邊界值確定是否激發(fā)。然后,第一層的輸出傳遞給中間層,中間層再傳遞給由單一神經(jīng)元組成的最終的輸出層。有趣的是,這種分層組織似乎模仿了我們前面討論過的人類的視覺系統(tǒng)。全連接的網(wǎng)絡是指每層中的每個神經(jīng)元和上一層的所有神經(jīng)元有連接,和下一層的所有神經(jīng)元也都有連接。1.2.1感知機訓練方案中的問題讓我們來考慮一個單一的神經(jīng)元如何選擇最佳的權重w和偏差b?理想情況下,我們想提供一組訓練樣本,讓機器通過調(diào)整權重值和偏差值,使輸出誤差最小化。為了更加的具體,我們假設有一組包含貓的圖像,以及另外單獨的一組不包含貓的圖像。為了簡單起見,假設每個神經(jīng)元只考慮單個輸入像素值。當計算機處理這些圖像時,我們希望我們的神經(jīng)元調(diào)整其權重和偏差,使得越來越少的圖像被錯誤識別為非貓。這種方法似乎非常直觀,但是它要求權重(和/或偏差)的微小變化只會在輸出上產(chǎn)生微小變化。如果我們有一個較大的輸出增量,我們就不能進行漸進式學習(而非在所有的方向上進行嘗試——這樣的過程稱為窮舉搜索——我們不知道是否在改進)。畢竟,小孩子是一點一點學習的。不幸的是,感知機并不表現(xiàn)出這種一點一點學習的行為,感知機的結(jié)果是0或1,這是一個大的增量,它對學習沒有幫助,如圖1.2所示。我們需要一些更平滑的東西,一個從0到1逐漸變化不間斷的函數(shù)。在數(shù)學上,這意味著我們需要一個可以計算其導數(shù)的連續(xù)的函數(shù)。圖激活函數(shù)——sigmoidsigmoid函數(shù)的定義如下:如圖1.3所示,當輸入在(?∞,∞)的區(qū)間上變化時,位于(0,1)區(qū)間上的輸出值變化很小。從數(shù)學的角度講,該函數(shù)是連續(xù)的。典型的sigmoid函數(shù)如圖1.3所示。圖1.3神經(jīng)元可以使用sigmoid來計算非線性函數(shù)σ(z=wx+b)。注意,如果z=wx+b是非常大的正值,那么e?z→0,因而σ(z)→1;而如果z=wx+b是非常大的負值,e?z→∞,因而σ(z)→0。換句話說,以sigmoid為激活函數(shù)的神經(jīng)元具有和感知機類似的行為,但它的變化是漸進的,輸出值如0.5539或0.123191非常合理。在這個意義上,sigmoid神經(jīng)元可能正是我們所要的。1.2.3激活函數(shù)——ReLUsigmoid并非可用于神經(jīng)網(wǎng)絡的唯一的平滑激活函數(shù)。最近,一個被稱為修正線性單元(RectifiedLinearUnit,ReLU)的激活函數(shù)很受歡迎,因為它可以產(chǎn)生非常好的實驗結(jié)果。ReLU函數(shù)簡單定義為f(x)=max(0,x),這個非線性函數(shù)如圖1.4所示。對于負值,函數(shù)值為零;對于正值,函數(shù)呈線性增長。圖激活函數(shù)在神經(jīng)網(wǎng)絡領域,sigmoid和ReLU通常被稱為激活函數(shù)。在“Keras中的不同優(yōu)化器測試”一節(jié)中,我們將看到,那些通常由sigmoid和ReLU函數(shù)產(chǎn)生的漸進的變化,構(gòu)成了開發(fā)學習算法的基本構(gòu)件,這些構(gòu)件通過逐漸減少網(wǎng)絡中發(fā)生的錯誤,來一點一點進行調(diào)整。圖1.5給出了一個使用σ激活函數(shù)的例子,其中(x1,x2,…,xm)為輸入向量,(w1,w2,…,wm)為權重向量,b為偏差,表示總和。圖1.5Keras支持多種激活函數(shù),完整列表請參考Keras官網(wǎng)。1.3實例——手寫數(shù)字識別在本節(jié)中,我們將構(gòu)建一個可識別手寫數(shù)字的網(wǎng)絡。為此,我們使用MNIST數(shù)據(jù)集,這是一個由60000個訓練樣例和10000個測試樣例組成的手寫數(shù)字數(shù)據(jù)庫。訓練樣例由人標注出正確答案,例如,如果手寫數(shù)字是“3”,那么“3”就是該樣例關聯(lián)的標簽。在機器學習中,如果使用的是帶有正確答案的數(shù)據(jù)集,我們就說我們在進行監(jiān)督學習。在這種情況下,我們可以使用訓練樣例調(diào)整網(wǎng)絡。測試樣例也帶有與每個數(shù)字關聯(lián)的正確答案。然而,這種情況下,我們要假裝標簽未知,從而讓網(wǎng)絡進行預測,稍后再借助標簽來評估我們的神經(jīng)網(wǎng)絡對于識別數(shù)字的學習程度。因此,如你所料,測試樣例只用于測試我們的網(wǎng)絡。每個MNIST圖像都是灰度的,它由28×28像素組成。這些數(shù)字的一個子集如圖1.6所示。圖One-hot編碼——OHE在很多應用中,將類別(非數(shù)字)特征轉(zhuǎn)換為數(shù)值變量都很方便。例如,[0-9]中值為d的分類特征數(shù)字可以編碼為10位二進制向量,除了第d位為1,其他位始終為0。這類表示法稱為One-hot編碼(OHE),當數(shù)據(jù)挖掘中的學習算法專門用于處理數(shù)值函數(shù)時,這種編碼的使用非常普遍。1.3.2用Keras定義簡單神經(jīng)網(wǎng)絡這里,我們使用Keras定義一個識別MNIST手寫數(shù)字的網(wǎng)絡。我們從一個非常簡單的神經(jīng)網(wǎng)絡開始,然后逐步改進。Keras提供了必要的庫來加載數(shù)據(jù)集,并將其劃分成用于微調(diào)網(wǎng)絡的訓練集X_train,以及用于評估性能的測試集X_test。數(shù)據(jù)轉(zhuǎn)換為支持GPU計算的float32類型,并歸一化為[0,1]。另外,我們將真正的標簽各自加載到Y(jié)_train和Y_test中,并對其進行One-hot編碼。我們來看以下代碼:from__future__importprint_function

importnumpyasnp

fromkeras.datasetsimportmnist

fromkeras.modelsimportSequential

fromkeras.layers.coreimportDense,Activation

fromkeras.optimizersimportSGD

fromkeras.utilsimportnp_utils

np.random.seed(1671)#重復性設置

#網(wǎng)絡和訓練

NB_EPOCH=200

BATCH_SIZE=128

VERBOSE=1

NB_CLASSES=10#輸出個數(shù)等于數(shù)字個數(shù)

OPTIMIZER=SGD()#SGD優(yōu)化器,本章稍后介紹

N_HIDDEN=128

VALIDATION_SPLIT=0.2#訓練集中用作驗證集的數(shù)據(jù)比例

#數(shù)據(jù):混合并劃分訓練集和測試集數(shù)據(jù)

#

(X_train,y_train),(X_test,y_test)=mnist.load_data()

#X_train是60000行28×28的數(shù)據(jù),變形為60000×784

RESHAPED=784

#

X_train=X_train.reshape(60000,RESHAPED)

X_test=X_test.reshape(10000,RESHAPED)

X_train=X_train.astype('float32')

X_test=X_test.astype('float32')

#歸一化

#

X_train/=255

X_test/=255

print(X_train.shape[0],'trainsamples')

print(X_test.shape[0],'testsamples')

#將類向量轉(zhuǎn)換為二值類別矩陣

Y_train=np_utils.to_categorical(y_train,NB_CLASSES)

Y_test=np_utils.to_categorical(y_test,NB_CLASSES)

輸入層中,每個像素都有一個神經(jīng)元與其關聯(lián),因而共有28×28=784個神經(jīng)元,每個神經(jīng)元對應MNIST圖像中的一個像素。通常來說,與每個像素關聯(lián)的值被歸一化到[0,1]區(qū)間中(即每個像素的亮度除以255,255是最大亮度值)。輸出為10個類別,每個數(shù)字對應一個類。最后一層是使用激活函數(shù)softmax的單個神經(jīng)元,它是sigmoid函數(shù)的擴展。softmax將任意k維實向量壓縮到區(qū)間(0,1)上的k維實向量。在我們的例子中,它聚合了上一層中由10個神經(jīng)元給出的10個答案。#10個輸出

#最后是softmax激活函數(shù)

model=Sequential()

model.add(Dense(NB_CLASSES,input_shape=(RESHAPED,)))

model.add(Activation('softmax'))

model.summary()

一旦我們定義好模型,我們就要對它進行編譯,這樣它才能由Keras后端(Theano或TensorFlow)執(zhí)行。編譯期間有以下幾個選項。我們需要選擇優(yōu)化器,這是訓練模型時用于更新權重的特定算法。我們需要選擇優(yōu)化器使用的目標函數(shù),以確定權重空間(目標函數(shù)往往被稱為損失函數(shù),優(yōu)化過程也被定義為損失最小化的過程)。我們需要評估訓練好的模型。目標函數(shù)的一些常見選項(Keras目標函數(shù)的完整列表請參考官網(wǎng))如下所示。MSE:預測值和真實值之間的均方誤差。從數(shù)學上講,如果γ是n個預測值的向量,Y是n個觀測值的向量,則它們滿足以下等式:這些目標函數(shù)平均了所有預測錯誤,并且如果預測遠離真實值,平方運算將讓該差距更加明顯。Binarycross-entropy:這是二分對數(shù)損失。假設我們的模型在目標值為t時預測結(jié)果為p,則二分交叉熵定義如下:?tlog(p)?(1?t)log(1?p)該目標函數(shù)適用于二元標簽預測。Categoricalcross-entropy:這是多分類對數(shù)損失。如果目標值為ti,j時預測結(jié)果為pi,j,則分類交叉熵是:該目標函數(shù)適用于多分類標簽預測。它也是與激活函數(shù)softmax關聯(lián)的默認選擇。一些常見的性能評估指標(Keras性能評估指標的完整列表請參考官網(wǎng))如下所示。Accuracy:準確率,針對預測目標的預測正確的比例。Precision:查準率,衡量多分類問題中多少選擇項是關聯(lián)正確的。Recall:查全率,衡量多分類問題中多少關聯(lián)正確的數(shù)據(jù)被選出。性能評估與目標函數(shù)類似,唯一的區(qū)別是它們不用于訓練模型,而只用于評估模型。在Keras中編譯模型很容易:pile(loss='categorical_crossentropy',optimizer=OPTIMIZER,metrics=['accuracy'])

一旦模型編譯好,就可以用fit()函數(shù)進行訓練了,該函數(shù)指定了以下參數(shù)。epochs:訓練輪數(shù),是模型基于訓練集重復訓練的次數(shù)。在每次迭代中,優(yōu)化器嘗試調(diào)整權重,以使目標函數(shù)最小化。batch_size:這是優(yōu)化器進行權重更新前要觀察的訓練實例數(shù)。在Keras中訓練一個模型很簡單。假設我們要迭代NB_EPOCH步:history=model.fit(X_train,Y_train,

batch_size=BATCH_SIZE,epochs=NB_EPOCH,

verbose=VERBOSE,validation_split=VALIDATION_SPLIT)

我們留出訓練集的部分數(shù)據(jù)用于驗證。關鍵的思想是我們要基于這部分留出的訓練集數(shù)據(jù)做性能評估。對任何機器學習任務,這都是值得采用的最佳實踐方法,我們也將這一方法應用在所有的例子中。一旦模型訓練好,我們就可以在包含全新樣本的測試集上進行評估。這樣,我們就可以通過目標函數(shù)獲得最小值,并通過性能評估獲得最佳值。注意,訓練集和測試集應是嚴格分開的。在一個已經(jīng)用于訓練的樣例上進行模型的性能評估是沒有意義的。學習本質(zhì)上是一個推測未知事實的過程,而非記憶已知的內(nèi)容。score=model.evaluate(X_test,Y_test,verbose=VERBOSE)

print("Testscore:",score[0])

print('Testaccuracy:',score[1])

恭喜,你已在Keras中定義了你的第一個神經(jīng)網(wǎng)絡。僅幾行代碼,你的計算機已經(jīng)能識別手寫數(shù)字了。讓我們運行代碼,并看看其性能。1.3.3運行一個簡單的Keras網(wǎng)絡并創(chuàng)建基線讓我們看看代碼運行結(jié)果,如圖1.7所示。圖1.7首先,網(wǎng)絡結(jié)構(gòu)被鋪開,我們可以看到使用的不同類型的網(wǎng)絡層、它們的輸出形狀、需要優(yōu)化的參數(shù)個數(shù),以及它們的連接方式。之后,網(wǎng)絡在48000個樣本上進行訓練,12000個樣本被保留并用于驗證。一旦構(gòu)建好神經(jīng)網(wǎng)絡模型,就可以在10000個樣本上進行測試。如你所見,Keras內(nèi)部使用了TensorFlow作為后端系統(tǒng)進行計算?,F(xiàn)在,我們不探究內(nèi)部訓練細節(jié),但我們可以注意到該程序運行了200次迭代,每次迭代后,準確率都有所提高。訓練結(jié)束后,我們用測試數(shù)據(jù)對模型進行測試,其中訓練集上達到的準確率為92.36%,驗證集上的準確率為92.27%,測試集上的準確率為92.22%。這意味著10個手寫數(shù)字中只有不到一個沒有被正確識別。當然我們可以比這做得更好。在圖1.8中,我們可以看到測試的準確率。圖用隱藏層改進簡單網(wǎng)絡現(xiàn)在我們有了基線精度,訓練集上的準確率為92.36%,驗證集上的準確率為92.27%,測試集上的準確率為92.22%,這是一個很好的起點,當然我們還能對它進行提升,我們看一下如何改進。第一個改進方法是為我們的網(wǎng)絡添加更多的層。所以在輸入層之后,我們有了第一個具有N_HIDDEN個神經(jīng)元并將ReLU作為激活函數(shù)的dense層。這一個追加層被認為是隱藏的,因為它既不與輸入層也不與輸出層直接相連。在第一個隱藏層之后,是第二個隱藏層,這一隱藏層同樣具有N_HIDDEN個神經(jīng)元,其后是一個具有10個神經(jīng)元的輸出層,當相關數(shù)字被識別時,對應的神經(jīng)元就會被觸發(fā)。以下代碼定義了這個新網(wǎng)絡。from__future__importprint_function

importnumpyasnp

fromkeras.datasetsimportmnist

fromkeras.modelsimportSequential

fromkeras.layers.coreimportDense,Activation

fromkeras.optimizersimportSGD

fromkeras.utilsimportnp_utils

np.random.seed(1671)#重復性設置

#網(wǎng)絡和訓練

NB_EPOCH=20

BATCH_SIZE=128

VERBOSE=1

NB_CLASSES=10#輸出個數(shù)等于數(shù)字個數(shù)

OPTIMIZER=SGD()#優(yōu)化器,本章稍后介紹

N_HIDDEN=128

VALIDATION_SPLIT=0.2#訓練集用于驗證的劃分比例

#數(shù)據(jù):混合并劃分訓練集和測試集數(shù)據(jù)

(X_train,y_train),(X_test,y_test)=mnist.load_data()

#X_train是60000行28×28的數(shù)據(jù),變形為60000×784

RESHAPED=784

#

X_train=X_train.reshape(60000,RESHAPED)

X_test=X_test.reshape(10000,RESHAPED)

X_train=X_train.astype('float32')

X_test=X_test.astype('float32')

#歸一化

X_train/=255

X_test/=255

print(X_train.shape[0],'trainsamples')

print(X_test.shape[0],'testsamples')

#將類向量轉(zhuǎn)換為二值類別矩陣

Y_train=np_utils.to_categorical(y_train,NB_CLASSES)

Y_test=np_utils.to_categorical(y_test,NB_CLASSES)

#M_HIDDEN個隱藏層

#10個輸出

#最后是softmax激活函數(shù)

model=Sequential()

model.add(Dense(N_HIDDEN,input_shape=(RESHAPED,)))

model.add(Activation('relu'))

model.add(Dense(N_HIDDEN))

model.add(Activation('relu'))

model.add(Dense(NB_CLASSES))

model.add(Activation('softmax'))

model.summary()

pile(loss='categorical_crossentropy',

optimizer=OPTIMIZER,

metrics=['accuracy'])

history=model.fit(X_train,Y_train,

batch_size=BATCH_SIZE,epochs=NB_EPOCH,

verbose=VERBOSE,validation_split=VALIDATION_SPLIT)

score=model.evaluate(X_test,Y_test,verbose=VERBOSE)

print("Testscore:",score[0])

print('Testaccuracy:',score[1])

讓我們運行代碼并查看這一多層網(wǎng)絡獲取的結(jié)果。還不錯,通過增加兩個隱藏層,我們在訓練集上達到的準確率為94.50%,驗證集上為94.63%,測試集上為94.41%。這意味著相比之前的網(wǎng)絡,準確率提高了2.2%。然而,我們將迭代次數(shù)從200顯著減少到了20。這很好,但是我們要更進一步。如果你想,你可以自己嘗試,看看如果只添加一個隱藏層而非兩個,或者添加兩個以上的隱藏層結(jié)果會怎樣。我把這個實驗留作練習。圖1.9顯示了前例的輸出結(jié)果。圖用dropout進一步改進簡單網(wǎng)絡現(xiàn)在我們的基線在訓練集上的準確率為94.50%,驗證集上為94.63%,測試集上為94.41%。第二個改進方法很簡單。我們決定在內(nèi)部全連接的隱藏層上傳播的值里,按dropout概率隨機丟棄某些值。在機器學習中,這是一種眾所周知的正則化形式。很驚奇,這種隨機丟棄一些值的想法可以提高我們的性能。from__future__importprint_function

importnumpyasnp

fromkeras.datasetsimportmnist

fromkeras.modelsimportSequential

fromkeras.layers.coreimportDense,Dropout,Activation

fromkeras.optimizersimportSGD

fromkeras.utilsimportnp_utils

np.random.seed(1671)#重復性設置

#網(wǎng)絡和訓練

NB_EPOCH=250

BATCH_SIZE=128

VERBOSE=1

NB_CLASSES=10#輸出個數(shù)等于數(shù)字個數(shù)

OPTIMIZER=SGD()#優(yōu)化器,本章稍后介紹

N_HIDDEN=128

VALIDATION_SPLIT=0.2#訓練集用于驗證的劃分比例

DROPOUT=0.3

#數(shù)據(jù):混合并劃分訓練集和測試集數(shù)據(jù)

(X_train,y_train),(X_test,y_test)=mnist.load_data()

#X_train是60000行28×28的數(shù)據(jù),變形為60000×784

RESHAPED=784

#

X_train=X_train.reshape(60000,RESHAPED)

X_test=X_test.reshape(10000,RESHAPED)

X_train=X_train.astype('float32')

X_test=X_test.astype('float32')

#歸一化

X_train/=255

X_test/=255

#將類向量轉(zhuǎn)換為二值類別矩陣

Y_train=np_utils.to_categorical(y_train,NB_CLASSES)

Y_test=np_utils.to_categorical(y_test,NB_CLASSES)

#M_HIDDEN個隱藏層,10個輸出

model=Sequential()

model.add(Dense(N_HIDDEN,input_shape=(RESHAPED,)))

model.add(Activation('relu'))

model.add(Dropout(DROPOUT))

model.add(Dense(N_HIDDEN))

model.add(Activation('relu'))

model.add(Dropout(DROPOUT))

model.add(Dense(NB_CLASSES))

model.add(Activation('softmax'))

model.summary()

pile(loss='categorical_crossentropy',

optimizer=OPTIMIZER,

metrics=['accuracy'])

history=model.fit(X_train,Y_train,

batch_size=BATCH_SIZE,epochs=NB_EPOCH,

verbose=VERBOSE,validation_split=VALIDATION_SPLIT)

score=model.evaluate(X_test,Y_test,verbose=VERBOSE)

print("Testscore:",score[0])

print('Testaccuracy:',score[1])

讓我們將代碼像之前一樣運行20次迭代。我們看到網(wǎng)絡在訓練集上達到了91.54%的準確率,驗證集上為94.48%,測試集上為94.25%,如圖1.10所示。圖1.10注意,訓練集上的準確率仍應高于測試集上的準確率,否則說明我們的訓練時間還不夠長。所以我們試著將訓練輪數(shù)大幅增加至250,這時訓練集上的準確率達到了98.1%,驗證集上為97.73%,測試集上為97.7%,如圖1.11所示。圖1.11當訓練輪數(shù)增加時,觀察訓練集和測試集上的準確率是如何增加的,這一點很有用。你可以從圖1.12中看出,這兩條曲線在訓練約250輪時相交,而這一點后就沒必要進一步訓練了。圖1.12注意,我們往往會觀察到,內(nèi)部隱藏層中帶有隨機dropout層的網(wǎng)絡,可以對測試集中的全新樣本做出更好的推測。直觀地講,你可以想象成:正因為神經(jīng)元知道不能依賴于鄰近神經(jīng)元,它自身的能力才能更好發(fā)揮。測試時,先不加入dropout層,我們運行的是所有經(jīng)過高度調(diào)整過的神經(jīng)元。簡而言之,要測試網(wǎng)絡加入某些dropout功能時的表現(xiàn),這通常是一種很好的方法。1.3.6Keras中的不同優(yōu)化器測試我們已定義和使用了一個網(wǎng)絡,給出網(wǎng)絡如何訓練的直觀解釋非常有用。讓我們關注一種被稱為梯度下降(GradientDescent,GD)的流行的訓練方法。想象一個含有單一變量w的一般成本函數(shù)C(w),如圖1.13所示。圖1.13梯度下降可以看成一個要從山上到山谷的背包客,山上表示成函數(shù)C,山谷表示成最小值Cmin,背包客的起點為w0。背包客慢慢移動,對每一步r,梯度就是最大增量的方向。從數(shù)學上講,該方向就是在步r到達的點wr上求得的偏導數(shù)。因此,走相反的方向,背包客就可以向山谷移動。每一步,背包客都能在下一步之前判別步長,這就是梯度下降中講的學習率。注意,如果步長太小,背包客就會移動得很慢;如果過大,背包客又很可能錯過山谷?,F(xiàn)在,你應該記住sigmoid是一個連續(xù)函數(shù),并可以計算導數(shù)。可以證明sigmoid函數(shù)如下所示:它的導數(shù)如下:ReLU函數(shù)在點0處不可微,然而,我們可以將點0處的一階導數(shù)擴展到整個定義域,使其為0或1。這種和點相關的ReLU函數(shù)y=max(0,x)的導數(shù)如下:一旦我們有了導數(shù),就可以用梯度下降技術來優(yōu)化網(wǎng)絡。Keras使用它的后端(TensorFlow或者Theano)來幫助我們計算導數(shù),所以我們不用擔心如何實現(xiàn)或計算它。我們只需選擇激活函數(shù),Keras會替我們計算導數(shù)。神經(jīng)網(wǎng)絡本質(zhì)上是帶有幾千個甚至幾百萬個參數(shù)的多個函數(shù)的組合。每個網(wǎng)絡層計算一個函數(shù),使其錯誤率最低,以改善學習階段觀察到的準確率。當我們討論反向傳播時,我們會發(fā)現(xiàn)這個最小化過程比我們的簡單示例更加復雜。然而,它同樣基于降至山谷的直觀過程。Keras實現(xiàn)了梯度下降的一個快速變體,稱為隨機梯度下降(StochasticGradientDescent,SGD),以及RMSprop和Adam這兩種更先進的優(yōu)化技術。除SGD具有的加速度分量之外,RMSprop和Adam還包括了動量的概念(速度分量)。這樣可以通過更多的計算代價實現(xiàn)更快的收斂。Keras支持的優(yōu)化器的完整列表請參考官網(wǎng)。SGD是我們到目前為止的默認選擇?,F(xiàn)在讓我們嘗試另外兩個,這很簡單,我們只需要改幾行代碼:fromkeras.optimizersimportRMSprop,Adam

...

OPTIMIZER=RMSprop()#優(yōu)化器

好了,我們來進行測試,如圖1.14所示。圖1.14從圖1.14可以看出,RMSprop比SDG快,因為僅在20次迭代后我們就改進了SDG,并能在訓練集上達到97.97%的準確率,驗證集上為97.59%,測試集上為97.84%。為完整起見,讓我們看看準確率和損失函數(shù)如何隨訓練輪數(shù)的變化而改變,如圖1.15所示。圖1.15現(xiàn)在我們試試另一個優(yōu)化器Adam()。這相當簡單,如下:OPTIMIZER=Adam()#優(yōu)化器

正如我們所看到的,Adam稍好些。使用Adam,訓練20輪后,我們在訓練集上的準確率達到了98.28%,驗證集上達到了98.03%,測試集上達到了97.93%,如圖1.16所示。圖1.16這是我們修改過的第5個版本,請記住我們的初始基線是92.36%。到目前為止,我們做了漸進式的改進;然而,獲得更高的準確率現(xiàn)在越來越難。注意,我們使用了30%的dropout概率進行優(yōu)化。為完整起見,我們在選用Adam()作為優(yōu)化器的條件下,測試其他dropout概率下測試集上的準確率報表,如圖1.17所示。圖增加訓練輪數(shù)讓我們嘗試將訓練中使用的輪轉(zhuǎn)次數(shù)從20增加到200,不幸的是,這讓我們的計算時間增加了1倍,但網(wǎng)絡并沒有任何改善。這個實驗并沒成功,但我們知道了即使花更多的時間學習,也不一定會對網(wǎng)絡有所提高。學習更多的是關于采用巧妙的技術,而不是計算上花費多少時間。讓我們追蹤一下程序第6次修改的結(jié)果,如圖1.18所示。圖控制優(yōu)化器的學習率另外一個我們可以進行的嘗試是改變優(yōu)化器的學習參數(shù)。你可以從圖1.19中看出,最優(yōu)值接近0.001,這是優(yōu)化器的默認學習率。不錯,Adam優(yōu)化器表現(xiàn)得非常好。圖增加內(nèi)部隱藏神經(jīng)元的數(shù)量我們還可以做另一個嘗試,那就是改變內(nèi)部隱藏神經(jīng)元的數(shù)量。我們用不斷增加的隱藏神經(jīng)元匯總得出實驗結(jié)果。我們可以從圖1.20中看到,通過增加模型的復雜性,運行時間也顯著增加,因為有越來越多的參數(shù)需要優(yōu)化。然而,隨著網(wǎng)絡的增長,我們通過增加網(wǎng)絡規(guī)模獲得的收益也越來越少。圖1.20圖1.21顯示了隨著隱藏神經(jīng)元的增多,每次迭代所需的時間。圖1.21圖1.22顯示了隨著隱藏神經(jīng)元的增多,準確率的變化。圖0增加批處理的大小對訓練集中提供的所有樣例,同時對輸入中給出的所有特征,梯度下降都嘗試將成本函數(shù)最小化。隨機梯度下降開銷更小,它只考慮BATCH_SIZE個樣例。因此,讓我們看一下改變這個參數(shù)時的效果。如圖1.23所示,最優(yōu)的準確率在BATCH_SIZE=128時取得。圖1識別手寫數(shù)字的實驗總結(jié)現(xiàn)在我們總結(jié)一下:使用5種不同的修改,我們可以將性能從92.36%提高到97.93%。首先,我們在Keras中定義一個簡單層的網(wǎng)絡;然后,我們通過增加隱藏層提高性能;最后,我們通過添加隨機的dropout層及嘗試不同類型的優(yōu)化器改善了測試集上的性能。結(jié)果匯總?cè)绫?.1所示。表1.1模型/準確率訓練驗證測試Simple92.36%92.37%92.22%Twohidden(128)94.50%94.63%94.41%Dropout(30%)98.10%97.73%97.7%(200次)RMSprop97.97%97.59%97.84%(20次)Adam98.28%98.03%97.93%(20次)然而,接下來的兩個實驗沒有顯著提高。增加內(nèi)部神經(jīng)元的數(shù)量會產(chǎn)生更復雜的模型,并需要更昂貴的計算,但它只有微小的收益。即使增加訓練輪數(shù),也是同樣的結(jié)果。最后一個實驗是修改優(yōu)化器的BATCH_SIZE。1.3.12采用正則化方法避免過擬合直觀地說,良好的機器學習模型應在訓練數(shù)據(jù)上取得較低的誤差。在數(shù)學上,這等同于給定構(gòu)建好的機器學習模型,使其在訓練數(shù)據(jù)上的損失函數(shù)最小化,其公式表示如下:min:{loss(訓練數(shù)據(jù)|模型)}然而,這可能還不夠。為捕捉訓練數(shù)據(jù)內(nèi)在表達的所有關系,模型可能會變得過度復雜。而復雜性的增加可能會產(chǎn)生兩個負面后果。第一,復雜的模型可能需要大量的時間來執(zhí)行;第二,因其所有內(nèi)在關系都被記憶下來,復雜的模型可能在訓練數(shù)據(jù)上會取得優(yōu)秀的性能,但在驗證數(shù)據(jù)上的性能卻并不好,因為對于全新的數(shù)據(jù),模型不能進行很好的泛化。再次重申,學習更多的是關于泛化而非記憶。圖1.24表示了在驗證集和訓練集上均呈下降的損失函數(shù)。然而,由于過度擬合,驗證集上的某一點后,損失函數(shù)開始增加,如圖1.24所示。圖1.24根據(jù)經(jīng)驗,如果在訓練期間,我們看到損失函數(shù)在驗證集上初始下降后轉(zhuǎn)為增長,那就是一個過度訓練的模型復雜度問題。實際上,過擬合是機器學習中用于準確描述這一問題的名詞。為解決過擬合問題,我們需要一種捕捉模型復雜度的方法,即模型的復雜程度。解決方案會是什么呢?其實,模型不過是權重向量,因此,模型復雜度可以方便地表示成非零權重的數(shù)量。換句話說,如果我們有兩個模型M1和M2,在損失函數(shù)上幾乎實現(xiàn)了同樣的性能,那么我們應選擇最簡單的包含最小數(shù)量非零權重的模型。如下所示,我們可以使用超參數(shù)λ≥0來控制擁有簡單模型的重要性:min:{loss(訓練數(shù)據(jù)|模型)}+λ*complexity(模型)機器學習中用到了3種不同類型的正則化方法。L1正則化(也稱為lasso):模型復雜度表示為權重的絕對值之和L2正則化(也稱為ridge):模型復雜度表示為權重的平方和彈性網(wǎng)絡正則化:模型復雜度通過聯(lián)合前述兩種技術捕捉注意,相同的正則化方案可以獨立地應用于權重、模型和激活函數(shù)。因此,應用正則化方案會是一個提高網(wǎng)絡性能的好方法,特別是在明顯出現(xiàn)了過擬合的情況下。這些實驗可以留給對此感興趣的讀者作為練習。請注意,Keras同時支持L1、L2和彈性網(wǎng)絡這3種類型的正則化方法。加入正則化方法很簡單。舉個例子,這里我們在內(nèi)核(權重W)上使用了L2正則化方法:fromkerasimportregularizersmodel.add(Dense(64,input_dim=64,

kernel_regularizer=regularizers.l2(0.01)))

關于可用參數(shù)的完整說明,請參見Keras官網(wǎng)。1.3.13超參數(shù)調(diào)優(yōu)上述實驗讓我們了解了微調(diào)網(wǎng)絡的可能方式。然而,對一個例子有效的方法不一定對其他例子也有效。對于給定的網(wǎng)絡,實際上有很多可以優(yōu)化的參數(shù)(如隱藏神經(jīng)元的數(shù)量、BATCH_SIZE、訓練輪數(shù),以及更多關于網(wǎng)絡本身復雜度的參數(shù)等)。超參數(shù)調(diào)優(yōu)是找到使成本函數(shù)最小化的那些參數(shù)組合的過程。關鍵思想是,如果我們有n個參數(shù),可以想象成它們定義了一個n維空間,目標是找出空間中和成本函數(shù)最優(yōu)值對應的點。實現(xiàn)此目標的一種方法是在該空間中創(chuàng)建一個網(wǎng)格,并系統(tǒng)地檢查每個網(wǎng)格頂點的成本函數(shù)值。換句話說,這些參數(shù)被劃分成多個桶,并且通過蠻力法來檢查值的不同組合。1.3.14輸出預測當網(wǎng)絡訓練好后,它就可以用于預測。在Keras中,這很簡單。我們可以使用以下方法:#計算預測

predictions=model.predict(X)

對于給定的輸入,可以計算出幾種類型的輸出,包括以下方法。model.evaluate():用于計算損失值model.predict_classes():用于計算輸出類別model.predict_proba():用于計算類別概率1.4一種實用的反向傳播概述多層感知機通過稱為反向傳播的過程在訓練數(shù)據(jù)上學習。這是個錯誤一經(jīng)發(fā)現(xiàn)就逐漸改進的過程。讓我們看看它是如何工作的。請記住,每個神經(jīng)網(wǎng)絡層都有一組相關的權重,用于確定給定輸入集合的輸出值。此外,還請記住神經(jīng)網(wǎng)絡可以有多個隱藏層。開始時,所有的權重都是隨機分配的。然后,網(wǎng)絡被訓練集中的每個輸入激活:權重值從輸入階段開始向前傳播給隱藏層,隱藏層再向前傳播給進行輸出預測的輸出層(注意,在簡化圖1.25中,我們僅用綠色虛線表示幾個值,但實際上,所有值都是沿網(wǎng)絡前向傳播的)。圖1.25由于我們知道訓練集中的真實觀察值,因而可以計算預測中產(chǎn)生的誤差?;厮莸年P鍵點是將誤差反向傳播,并使用適當?shù)膬?yōu)化器算法,如梯度下降,來調(diào)整神經(jīng)網(wǎng)絡的權重,以減小誤差(同樣為了簡單起見,只表示出幾個錯誤值),如圖1.26所示。圖1.26將輸入到輸出的正向傳播和誤差的反向傳播過程重復幾次,直到誤差低于預定義的閾值。整個過程如圖1.27所示。圖1.27特征表示這里用于驅(qū)動學習過程的輸入和標簽。模型通過這樣的方式更新,損失函數(shù)被逐漸最小化。在神經(jīng)網(wǎng)絡中,真正重要的不是單個神經(jīng)元的輸出,而是在每層中調(diào)整的集體權重。因此,網(wǎng)絡以這樣的方式逐漸調(diào)整其內(nèi)部權重,預測正確的標簽數(shù)量也跟著增多。當然,使用正確的集合特征及高質(zhì)量的標簽數(shù)據(jù)是在學習過程中偏差最小化的基礎。1.5走向深度學習之路識別手寫數(shù)字的同時,我們得出結(jié)論,準確率越接近99%,提升就越困難。如果想要有更多的改進,我們肯定需要一個全新的思路。想一想,我們錯過了什么?基本的直覺是,目前為止,我們丟失了所有與圖像的局部空間相關的信息。特別地,這段代碼將位圖轉(zhuǎn)換成空間局部性消失的平面向量:#X_train是60000行28x28的數(shù)據(jù),變形為60000x784

X_train=X_train.reshape(60000,784)

X_test=X_test.reshape(10000,784)

然而,這并非我們大腦工作的方式。請記住,我們的想法是基于多個皮質(zhì)層,每一層都識別出越來越多的結(jié)構(gòu)化信息,并仍然保留了局部化信息。首先,我們看到單個的像素,然后從中識別出簡單的幾何形狀,最后識別出更多的復雜元素,如物體、面部、人體、動物等。在第3章“深度學習之卷積網(wǎng)絡”中,我們將看到一種特殊類型的深度學習網(wǎng)絡,這種網(wǎng)絡被稱為卷積神經(jīng)網(wǎng)絡(ConvolutionalNeuralNetwork,CNN),它同時考慮了兩個方面:既保留圖像(更一般地,任何類型的信息)中空間局部性的信息,也保留層次漸進的抽象學習的思想。一層時,你只能學習簡單模式;多層時,你可以學習多種模式。在學習CNN之前,我們需要了解Keras架構(gòu)方面的內(nèi)容,并對一些機器學習概念進行實用的介紹。這將是下一章的主題。1.6小結(jié)本章中,你學習了神經(jīng)網(wǎng)絡的基礎知識。具體包括:什么是感知機,什么是多層感知機,如何在Keras中定義神經(jīng)網(wǎng)絡,當確立了良好的基線后如何逐步改進性能,以及如何微調(diào)超參數(shù)空間。此外,你現(xiàn)在對一些有用的激活函數(shù)(sigmoid和ReLU)有了了解,還學習了如何基于反向傳播算法來訓練網(wǎng)絡,如梯度下降、隨機梯度下降,或更復雜的方法如Adam和RMSprop。在下一章中,我們將學習如何在AWS、微軟Azure、谷歌Cloud以及你自己的機器上安裝Keras。除此之外,我們還將給出KerasAPI的概述。第2章Keras安裝和API在上一章中,我們討論了神經(jīng)網(wǎng)絡的基本原理,并給出了幾個可用于識別MNIST手寫數(shù)字的神經(jīng)網(wǎng)絡實例。本章將給大家介紹如何安裝Keras、Theano和TensorFlow,并逐步生成一個可實際運行的環(huán)境,以使大家在短時間內(nèi)快速地由直觀印象進入到可運行的神經(jīng)網(wǎng)絡世界。我們還將介紹基于docker容器架構(gòu)下的安裝方法,以及谷歌GCP、亞馬遜AWS和微軟Azure云環(huán)境下的安裝。此外,我們會概括性介紹Keras的API,以及一些常見的使用操作,如加載和保存神經(jīng)網(wǎng)絡架構(gòu)和權重、早期停止、歷史信息保存、檢查點,以及與TensorBoard和Quiver的交互等。我們開始吧。到本章結(jié)束,我們將涵蓋以下主題:安裝和配置KerasKeras的架構(gòu)2.1安裝Keras下面的部分,我們會演示如何在多個不同的平臺上安裝Keras。2.1.1第1步——安裝依賴項首先,我們安裝numpy包,這個包為大型多維數(shù)組和矩陣以及高級數(shù)學函數(shù)提供了支持。然后,我們來安裝用于科學計算的scipy庫。之后,比較合適的是安裝scikit-learn包,這個包被認為是Python用于機器學習的“瑞士軍刀”。這里,我們用它來做數(shù)據(jù)探索。作為可選項,我們還可以安裝用于圖像處理的pillow包以及Keras模型存儲中用于數(shù)據(jù)序列化的h5py包。單一的命令行就可以完成所有安裝?;蛘撸覀円部梢园惭bAnacondaPython,它會自動安裝numpy、scipy、scikit-learn、h5py、pillow以及許多其他用于科學計算的包(更多信息,請參考《BatchNormalization:AcceleratingDeepNetworkTrainingbyReducingInternalCovariateShift》,作者S.Ioffe和C.Szegedy,arX/abs/1502.03167,2015)。你可以在AnacondaPython官方站點找到這些包。圖2.1展示了如何為我們的機器安裝這些包。圖第2步——安裝Theano我們可以借助pip安裝Theano,如圖2.2所示。圖第3步——安裝TensorFlow現(xiàn)在我們按照TensorFlow網(wǎng)站的指南來安裝TensorFlow。我們?nèi)詫⒔柚鷓ip來安裝正確的包,如圖2.3所示。例如,如果我們需要使用GPU,找到合適的包就很重要。圖第4步——安裝Keras現(xiàn)在,我們可以簡單地安裝Keras,然后來測試安裝好的環(huán)境,方法相當簡單,我們還是用pip,如圖2.4所示。圖第5步——測試Theano、TensorFlow和Keras現(xiàn)在來測試環(huán)境。我們先看看如何在Theano中定義sigmoid函數(shù),如你所見,非常簡單,我們只需寫下數(shù)據(jù)公式,并按矩陣元素作函數(shù)計算即可。打開Pythonshell,編寫圖2.5所示的代碼并運行就會得到結(jié)果。圖2.5現(xiàn)在Therno好了,我們來測試一下TensorFlow,如圖2.6所示,我們簡單地導入MNIST數(shù)據(jù)集,在第1章“神經(jīng)網(wǎng)絡基礎”中我們已經(jīng)看到一些可運行的Keras網(wǎng)絡實例。圖2.62.2配置KerasKeras有一個最小配置集文件。我們在vi中把這個文件打開,參數(shù)都很簡單,如表2.1所示。表2.1參數(shù)取值image_dim_ordering值為tf代表TensorFlow的圖像順序,值代表th代表Theano的圖像順序epsilon計算中使用的epsilon值floatx可為float32或float64backend可為tensorflow或theano參數(shù)image_dim_ordering的取值看起來有點不太直觀,值為th時,代表了圖像通道順序為(深、寬、高),取值為tf時順序為(寬、高、深)。圖2.7所示為我們本機的默認參數(shù)配置。圖2.7如果你安裝的TensorFlow版本啟用了GPU,那么當TensorFlow被設置為backend的時候,Keras就會自動使用你配置好的GPU。2.3在Docker上安裝Keras開始使用TensorFlow和Keras的比較簡單的方式是在Docker容器中運行。一個比較便捷的方案是使用社區(qū)創(chuàng)建的預定義的Docker深度學習鏡像,它包括了所有流行的深度學習框架(TensorFlow、Theano、Torch、Caffe等)。代碼文件請參考GitHub庫:/saiprashanths/dl-docker。假設你已經(jīng)安裝了Docker并運行起來(更多信息,請參考Docker官網(wǎng)),安裝非常簡單,如圖2.8所示。圖2.8我們從Git獲取鏡像后的編譯過程如圖2.9所示。圖2.9如圖2.10所示,我們看一下如何運行它。圖2.10我們可以從容器內(nèi)激活對JupyterNotebooks的支持(更多信息,請參考Jupyter官網(wǎng)),如圖2.11所示。圖2.11直接通過宿主機端口訪問,如圖2.12所示。圖2.12也可以通過圖2.13所示的命令訪問TensorBoard,我們將在下一節(jié)介紹這個命令。圖2.13運行完上面的命令后,你將被重定向到以下頁面,如圖2.14所示。圖2.142.4在谷歌CloudML上安裝Keras在谷歌Cloud上安裝Keras非常簡單。首先,我們要安裝谷歌Cloud(安裝文件下載,請參考/sdk/),它是谷歌CloudPlatform的一個命令行界面;然后,我們就可以使用CloudML,一個可以讓我們很容易通過TensorFlow構(gòu)建機器學習模型的托管服務。在使用Keras之前,讓我們利用谷歌Cloud上的TensorFlow訓練來自GitHub的MNIST可用實例。代碼是本地的,訓練在Cloud端進行,如圖2.15所示。圖2.15如圖2.16所示,你可以看見如何運行一個訓練會話。圖2.16我們可以通過TensorFlow查看交叉熵如何隨迭代遞減,如圖2.17所示。圖2.17如圖2.18所示,我們可以看到交叉熵的變化趨勢。圖2.18現(xiàn)在,我們想在TensorFlow上應用Keras,我們只需從PyPI上下載Keras源文件(下載請參考https://pypi.P/pypi/Keras/1.2.0或更新版本),并直接把Keras作為CloudML的解決方案包來使用即可,如圖2.19所示。圖2.19trainer.task2.py是一個實例腳本,如下所示。fromkeras.applications.vgg16importVGG16

fromkeras.modelsimportModel

fromkeras.preprocessingimportimage

fromkeras.applications.vgg16importpreprocess_input

importnumpyasnp

#預編譯并預訓練VGG16模型

base_model=VGG16(weights='imagenet',include_top=True)

fori,layerinenumerate(base_model.layers):

print(i,,layer.output_shape)

2.5在亞馬遜AWS上安裝Keras在Amazon云上安裝TensorFlow和Keras非常簡單。實際上,我們可以借助一個預編譯好并且開源、免費的叫作TFAMI.v3的AMI來完成(更多信息,請參考https:///ritchieng/tensorflow-aws-ami),如圖2.20所示。圖2.20AMI在5分鐘內(nèi)就可以啟用一個搭建好的TensorFlow環(huán)境,并支持TensorFlow、Keras、OpenAIGym,以及所有的依賴項。截至2017年1月,AMI支持下列技術:TensorFlow0.12Keras1.1.0TensorLayer1.2.7CUDA8.0CuDNN5.1Python2.7Ubuntu16.04此外,TFAMI.v3可以運行在P2計算實例上(更多信息,請參考亞馬遜AWS官網(wǎng)),如圖2.21所示。圖2.21P2實例的一些特征如下:IntelXeonE5-2686v4(Broadwell)處理器NVIDIAK80GPU,每個GPU有2496個并發(fā)核心和12GB內(nèi)存支持端到端的GPU通信提供增強的20Gbit/s的聚合網(wǎng)絡帶寬TFAMI.v3也能運行在G2計算實例上(更多信息,請參考亞馬遜AWS官網(wǎng)),G2實例的一些特征如下:IntelXeonE5-2670(SandyBridge)處理器NVIDIAGPU,每個GPU有1536個CUDA核心和4GB的顯存2.6在微軟Azure上安裝Keras在Azure上安裝Keras的一種方式是通過安裝Docker的支持,并獲得已容器化的TensorFlow和Keras版本。我們也可以通過網(wǎng)上找到一套用Docker安裝TensorFlow和Keras的說明,但本質(zhì)上和我們前面小節(jié)介紹過的一樣(更多信息,請參考https://blogs./uk_faculty_connection/2016/09/26/tensorflow-on-docker-with-microsoft-azure/)。如果只用Theano作唯一后端,那么你只需要點一下鼠標,從Cortana智能庫下載一個預編譯包就能運行Keras了(更多信息,請參考/Experiment/Theano-Keras-1)。下面的例子演示了如何把Theano和Keras作為一個ZIP文件直接導入AzureML,并用它們執(zhí)行Python腳本模塊。這個例子起因于HaiNing,它內(nèi)部是通過azureml_main()方法運行Keras代碼的。#腳本必須包含azureml_main函數(shù)

#它是模塊兒的入口

#導入要用到的庫

importpandasaspd

importtheano

importtheano.tensorasT

fromtheanoimportfunction

fromkeras.modelsimportSequential

fromkeras.layersimportDense,Activation

importnumpyasnp

#入口函數(shù)最多可包含兩個輸入?yún)?shù):

#Param<dataframe1>:apandas.DataFrame

#Param<dataframe2>:apandas.DataFrame

defazureml_main(dataframe1=None,dataframe2=None):

#這里開始執(zhí)行邏輯代碼

#print('Inputpandas.DataFrame#1:rnrn{0}'.format(dataframe1))

#如果三方輸入的zip文件已連接,將其解壓縮到目錄".ScriptBundle"。這個目錄會加入到sys.path。因此,如果你的zip文件中包含Python代碼文件mymodule.py,可以使用importmymodule導入

model=Sequential()

model.add(Dense(1,input_dim=784,activation="relu"))

pile(optimizer='rmsprop',loss='binary_crossentropy',

metrics=['accuracy'])

data=np.random.random((1000,784))

labels=np.random.randint(2,size=(1000,1))

model.fit(data,labels,nb_epoch=10,batch_size=32)

model.evaluate(data,labels)

returndataframe1,

圖2.22所示是一個通過微軟AzureML運行Theano和Keras的例子。圖2.222.7KerasAPIKeras是一個模塊化、最小化并且非常容易擴展的架構(gòu),它的開發(fā)者FrancoisChollet說:“當時開發(fā)這個庫的目的是為了快速的實驗,能夠在最短的時間里把想法轉(zhuǎn)換成結(jié)果,而這正是好的研究的關鍵。”Keras定義了運行于TensorFlow或Theano上的高端的神經(jīng)網(wǎng)絡。其具體特點如下。模塊化:一個模型就是一些獨立模塊的序列化或者圖形化組合,它們就像樂高積木一樣可以聯(lián)合起來搭建神經(jīng)網(wǎng)絡。換句話說,這個庫預定義了大量的不同類型的神經(jīng)網(wǎng)絡層的實現(xiàn),如成本函數(shù)、優(yōu)化器、初始化方案、激活函數(shù),以及正則化方案等。最小化:本庫使用Python實現(xiàn),每個模塊都簡短并自我描述。易擴展性:這個庫可以擴展出新的功能,我們將在第7章“其他深度學習模型”中講述。2.7.1從Keras架構(gòu)開始本節(jié)中,我們將看看用來定義神經(jīng)網(wǎng)絡的最重要的Keras組件。首先,我們會給出張量的定義;然后,我們討論組成預定義模塊的不同方式;最后,我們會總結(jié)最常用的部分。什么是張量Keras使用Theano或TensorFlow來進行極高效的張量計算。到底什么是張量呢?其實張量就是一個多維矩陣。兩種后端都能夠做有效的張量符號化計算,而這正是構(gòu)建神經(jīng)網(wǎng)絡的基礎組成部分。用Keras構(gòu)建模型用Keras構(gòu)建模型有兩種方式,即:序貫模型函數(shù)化模型以下進行詳細地介紹。1.序貫模型第一種方法就是序列化的組成,類似堆?;蜿犃?,我們把不同的預定義模型按照線性的管道層放到一起。在第1章“神經(jīng)網(wǎng)絡基礎”中,我們講到過幾個序列化管道的例子。舉個例子:model=Sequential()

model.add(Dense(N_HIDDEN,input_shape=(784,)))

model.add(Activation('relu'))

model.add(Dropout(DROPOUT))

model.add(Dense(N_HIDDEN))

model.add(Activation('relu'))

model.add(Dropout(DROPOUT))

model.add(Dense(nb_classes))

model.add(Activation('softmax'))

model.summary()

2.函數(shù)化模型第二種構(gòu)造模塊的方法是通過函數(shù)API。這種方法可以定義復雜的模型,如有向無環(huán)圖、共享層模型、多輸出模型等。在第7章“其他深度學習模型”中我們會看到這樣的例子。2.7.2預定義神經(jīng)網(wǎng)絡層概述Keras預定義了大量的神經(jīng)網(wǎng)絡層,我們來看一下最常使用的部分,并且看看哪些在接下來的章節(jié)中會較多用到。常規(guī)的dense層一個dense的模型就是一個全連接的模型。我們在第1章“神經(jīng)網(wǎng)絡基礎”中已經(jīng)看到過這樣的例子。下面是參數(shù)定義的原型:keras.layers.core.Dense(units,activation=None,use_bias=True,

kernel_initializer='glorot_uniform',bias_initializer='zeros',

kernel_regularizer=None,bias_regularizer=None,activity_regularizer=None,

kernel_constraint=None,bias_constraint=None)

循環(huán)神經(jīng)網(wǎng)絡:簡單RNN、LSTM和GRU循環(huán)神經(jīng)網(wǎng)絡(RecurrentNeuralNetwork,RNN)是一類利用了輸入內(nèi)容的有序化特性的神經(jīng)網(wǎng)絡。這樣的輸入可以是一段文本、一段演說、時間序列或者其他任何序列中元素對其之前的元素有依賴的內(nèi)容。我們將在第6章“循環(huán)神經(jīng)網(wǎng)絡——RNN”中討論SimpleRNN、LSTM和GRU這3種循環(huán)神經(jīng)網(wǎng)絡。下面是這些參數(shù)定義的原型。keras.layers.recurrent.Recurrent(return_sequences=False,

go_backwards=False,stateful=False,unroll=False,implementation=0)

keras.layers.recurrent.SimpleRNN(units,activation='tanh',use_bias=True,

kernel_initializer='glorot_uniform',recurrent_initializer='orthogonal',

bias_initializer='zeros',kernel_regularizer=None,

recurrent_regularizer=None,bias_regularizer=None,

activity_regularizer=None,kernel_constraint=None,

recurrent_constraint=None,bias_constraint=None,dropout=0.0,

recurrent_dropout=0.0)

keras.layers.recurrent.GRU(units,activation='tanh',

recurrent_activation='hard_sigmoid',use_bias=True,

kernel_initializer='glorot_uniform',recurrent_initializer='orthogonal',

bias_initializer='zeros',kernel_regularizer=None,

recurrent_regularizer=None,bias_regularizer=None,

activity_regularizer=None,kernel_constraint=None,

recurrent_constraint=None,bias_constraint=None,dropout=0.0,

recurrent_dropout=0.0)

keras.layers.recurrent.LSTM(units,activation='tanh',

recurrent_activation='hard_sigmoid',use_bias=True,

kernel_initializer='glorot_uniform',recurrent_initializer='orthogonal',

bias_initializer='zeros',unit_forget_bias=True,kernel_regularizer=None,

recurrent_regularizer=None,bias_regularizer=None,

activity_regularizer=None,kernel_constraint=None,

recurr

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論