版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
計算機視覺實戰(zhàn)基于TensorFlow2目錄TOC\h\h第一部分TensorFlow2和應(yīng)用于計算機視覺的深度學(xué)習(xí)\h第1章計算機視覺和神經(jīng)網(wǎng)絡(luò)\h1.1技術(shù)要求\h1.2廣義計算機視覺\h1.2.1計算機視覺概述\h1.2.2主要任務(wù)及其應(yīng)用\h1.3計算機視覺簡史\h1.3.1邁出成功的第一步\h1.3.2深度學(xué)習(xí)的興起\h1.4開始學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)\h1.4.1建立神經(jīng)網(wǎng)絡(luò)\h1.4.2訓(xùn)練神經(jīng)網(wǎng)絡(luò)\h1.5本章小結(jié)\h問題\h進一步閱讀\h第2章TensorFlow基礎(chǔ)和模型訓(xùn)練\h2.1技術(shù)要求\h2.2TensorFlow2和Keras入門\h2.2.1TensorFlow\h2.2.2基于Keras的簡單計算機視覺模型\h2.3TensorFlow2和Keras詳述\h2.3.1核心概念\h2.3.2高級概念\h2.4TensorFlow生態(tài)系統(tǒng)\h2.4.1TensorBoard\h2.4.2TensorFlow插件和擴展\h2.4.3TensorFlowLite和TensorFlow.js\h2.4.4在何處運行模型\h2.5本章小結(jié)\h問題\h第3章現(xiàn)代神經(jīng)網(wǎng)絡(luò)\h3.1技術(shù)要求\h3.2卷積神經(jīng)網(wǎng)絡(luò)\h3.2.1用于多維數(shù)據(jù)的神經(jīng)網(wǎng)絡(luò)\h3.2.2CNN操作\h3.2.3有效感受野\h3.2.4在TensorFlow中使用CNN\h3.3訓(xùn)練過程微調(diào)\h3.3.1現(xiàn)代網(wǎng)絡(luò)優(yōu)化器\h3.3.2正則化方法\h3.4本章小結(jié)\h問題\h進一步閱讀\h第二部分先進的經(jīng)典識別問題解決方案\h第4章主流分類工具\h4.1技術(shù)要求\h4.2了解高級CNN架構(gòu)\h4.2.1VGG:CNN的標準架構(gòu)\h4.2.2GoogLeNet和Inception模塊\h4.2.3ResNet:殘差網(wǎng)絡(luò)\h4.3利用遷移學(xué)習(xí)\h4.3.1概述\h4.3.2基于TensorFlow和Keras的遷移學(xué)習(xí)\h4.4本章小結(jié)\h問題\h進一步閱讀\h第5章目標檢測模型\h5.1技術(shù)要求\h5.2目標檢測介紹\h5.2.1背景\h5.2.2模型的性能評價\h5.3YOLO:快速目標檢測算法\h5.3.1YOLO介紹\h5.3.2使用YOLO推理\h5.3.3訓(xùn)練YOLO\h5.4FasterR-CNN:強大的目標檢測模型\h5.4.1FasterR-CNN通用架構(gòu)\h5.4.2訓(xùn)練FasterR-CNN\h5.4.3TensorFlow目標檢測API\h5.5本章小結(jié)\h問題\h進一步閱讀\h第6章圖像增強和分割\h6.1技術(shù)要求\h6.2使用編碼器-解碼器進行圖像變換\h6.2.1編碼器-解碼器概述\h6.2.2基本示例:圖像去噪\h6.2.3卷積編碼器-解碼器\h6.3理解語義分割\h6.3.1使用編碼器-解碼器進行目標分割\h6.3.2比較困難的實例分割\h6.4本章小結(jié)\h問題\h進一步閱讀\h第三部分高級概念和計算機視覺新進展\h第7章在復(fù)雜和稀缺數(shù)據(jù)集上訓(xùn)練\h7.1技術(shù)要求\h7.2高效數(shù)據(jù)服務(wù)\h7.2.1TensorFlow數(shù)據(jù)API\h7.2.2設(shè)置輸入流水線\h7.2.3優(yōu)化和監(jiān)控輸入流水線\h7.3如何處理稀缺數(shù)據(jù)\h7.3.1增強數(shù)據(jù)集\h7.3.2渲染合成數(shù)據(jù)集\h7.3.3利用域適應(yīng)和生成模型(VAE和GAN)\h7.4本章小結(jié)\h問題\h進一步閱讀\h第8章視頻和循環(huán)神經(jīng)網(wǎng)絡(luò)\h8.1技術(shù)要求\h8.2RNN簡介\h8.2.1基本形式\h8.2.2對RNN的基本理解\h8.2.3學(xué)習(xí)RNN權(quán)重\h8.2.4長短期記憶單元\h8.3視頻分類\h8.3.1計算機視覺應(yīng)用于視頻\h8.3.2使用LSTM分類視頻\h8.4本章小結(jié)\h問題\h進一步閱讀\h第9章優(yōu)化模型并在移動設(shè)備上部署\h9.1技術(shù)要求\h9.2優(yōu)化計算和占用的磁盤空間\h9.2.1測量推理速度\h9.2.2提高模型推理速度\h9.2.3當模型依舊很慢時\h9.2.4減小模型大小\h9.3基于終端設(shè)備的機器學(xué)習(xí)\h9.3.1考慮因素\h9.3.2實踐\h9.4app示例:識別面部表情\h9.4.1MobileNet簡介\h9.4.2在終端設(shè)備上部署模型\h9.5本章小結(jié)\h問題\h附錄第一部分TensorFlow2和應(yīng)用于計算機視覺的深度學(xué)習(xí)本部分將介紹計算機視覺和深度學(xué)習(xí)的基礎(chǔ)知識,并給出具體的TensorFlow例子。第1章將帶你了解神經(jīng)網(wǎng)絡(luò)的內(nèi)部原理。第2章介紹TensorFlow2和Keras的特性,以及它們的關(guān)鍵概念和生態(tài)系統(tǒng)。第3章介紹計算機視覺專家采用的機器學(xué)習(xí)技術(shù)。本部分包含以下幾章:·第1章計算機視覺和神經(jīng)網(wǎng)絡(luò)·第2章TensorFlow基礎(chǔ)和模型訓(xùn)練·第3章現(xiàn)代神經(jīng)網(wǎng)絡(luò)第1章
計算機視覺和神經(jīng)網(wǎng)絡(luò)近年來,計算機視覺已經(jīng)成為技術(shù)創(chuàng)新的關(guān)鍵領(lǐng)域,越來越多的應(yīng)用重塑了商業(yè)和生活的方方面面。在開啟本書前,我們將簡要介紹這個領(lǐng)域及其歷史,以便了解更多背景知識。然后將介紹人工神經(jīng)網(wǎng)絡(luò)以及它們是如何徹底改變計算機視覺的。因為相信可以在實踐中學(xué)習(xí),所以在第1章結(jié)束的時候,將從無到有實現(xiàn)我們自己的網(wǎng)絡(luò)!本章將涵蓋以下主題:·計算機視覺以及為什么它是一個迷人的當代研究領(lǐng)域?!と绾螐氖止ぴO(shè)計的局部描述符發(fā)展成深度神經(jīng)網(wǎng)絡(luò)?!な裁词巧窠?jīng)網(wǎng)絡(luò),以及如何實現(xiàn)自己的網(wǎng)絡(luò)以執(zhí)行基本識別任務(wù)。1.1技術(shù)要求在本書中,我們將使用Python3.5(或更高版本)。作為一種通用編程語言,Python已經(jīng)成為數(shù)據(jù)科學(xué)家的主要工具,這得益于它有用的內(nèi)置特性和眾所周知的庫。在這個介紹性的章節(jié)中,我們將只使用兩個基礎(chǔ)庫——numpy和matplotlib。雖然它們都可以從\h/和/上找到并安裝,但是,我們建議使用Anaconda(\h)。Anaconda是一個免費的Python發(fā)行版,可以簡化包的管理和部署。完整的安裝說明以及隨本章提供的所有代碼都可以在GitHub存儲庫中找到(\h/PacktPublishing/Hands-On-Computer-Vision-with-TensorFlow-2/tree/master/Chapter01)。我們假設(shè)讀者已經(jīng)對Python有了一定的了解,并且對圖像表示(像素、通道等)和矩陣運算(查看維數(shù)、計算乘積等)有了基本的理解。1.2廣義計算機視覺計算機視覺如今應(yīng)用廣泛、無處不在,以至于不同的專家對它的定義可能會有很大的不同。在本節(jié)中,我們將全面介紹計算機視覺,突出它的應(yīng)用領(lǐng)域和面臨的挑戰(zhàn)。1.2.1計算機視覺概述計算機視覺很難定義,因為它處于幾個研究和開發(fā)領(lǐng)域的交叉領(lǐng)域,比如計算機科學(xué)(算法、數(shù)據(jù)處理和圖形)、物理學(xué)(光學(xué)和傳感器)、數(shù)學(xué)(微積分和信息論)和生物學(xué)(視覺刺激和神經(jīng)處理)。從本質(zhì)上講,計算機視覺可以概括為從數(shù)字圖像中自動提取信息。當涉及視覺時,我們的大腦會創(chuàng)造奇跡。我們能夠破譯眼睛不斷捕捉到的視覺刺激,能夠立即分辨出一個物體與另一個物體的區(qū)別,能夠認出只見過一面的人的臉,等等,這些能力都是令人難以置信的。對于計算機來說,圖像只是像素塊,是紅綠藍值的矩陣,沒有其他意義。計算機視覺的目標是教會計算機如何理解這些像素,就像人類(和其他生物)那樣,甚至比人類做得更好。的確,自深度學(xué)習(xí)興起以來,計算機視覺已經(jīng)有了長足的進步,它已經(jīng)開始在一些任務(wù)(比如人臉識別或手寫文字識別)上表現(xiàn)出了超越人類的性能。在大型IT公司的推動下,研究社區(qū)變得異?;钴S,數(shù)據(jù)和視覺傳感器的可用性也越來越高,越來越多雄心勃勃的問題正在被解決——基于視覺的自動駕駛導(dǎo)航、基于內(nèi)容的圖像和視頻檢索、自動注釋和增強等。對于專家和新手來說,這確實是一個激動人心的時代。1.2.2主要任務(wù)及其應(yīng)用每天都有基于計算機視覺的新產(chǎn)品出現(xiàn)(例如,工業(yè)控制系統(tǒng)、交互式智能手機應(yīng)用程序或監(jiān)控系統(tǒng)),它們涵蓋了廣泛的任務(wù)領(lǐng)域。本節(jié)將討論其中主要的任務(wù),詳細介紹它們在現(xiàn)實問題中的應(yīng)用。內(nèi)容識別計算機視覺的一個核心目標是理解圖像,也就是說,從像素中提取有意義的語義信息(比如圖像中的對象及其位置和數(shù)量)。這個一般性問題可以分為幾個子領(lǐng)域,大致包含目標分類、目標識別、目標檢測和定位、目標和實例分割以及姿態(tài)估計。目標分類目標分類(或圖像分類)是在預(yù)定義的集合中為圖像分配適當?shù)臉撕灒ɑ蝾悇e)的任務(wù),如圖1-1所示。圖1-1應(yīng)用于圖像集的人和汽車標簽分類器示例早在2012年,它已經(jīng)作為深度卷積神經(jīng)網(wǎng)絡(luò)應(yīng)用于計算機視覺的第一個成功案例而聞名(將在本章后面介紹)。自那時起,這個領(lǐng)域就開始飛速發(fā)展,目前已經(jīng)在各類特定用例中都表現(xiàn)出了超越人類能力的性能(一個著名的例子是犬種的分類——深度學(xué)習(xí)方法在識別人類“最好的朋友”的區(qū)分特征方面非常有效)。常見的應(yīng)用包括文本數(shù)字化(使用字符識別)和圖像數(shù)據(jù)庫的自動注釋。在第4章中,我們將介紹先進的分類方法及其對計算機視覺的影響。目標識別目標分類方法是從預(yù)定義的集合中分配標簽,而目標識別(或?qū)嵗诸悾┓椒▌t學(xué)習(xí)去識別某一類的特定實例。例如,可以配置目標分類工具來返回包含人臉的圖像,而目標識別方法則聚焦于人臉的特征來識別某個人,并在其他圖像中識別他們(即在所有圖像中識別每個人臉,如圖1-2所示)。圖1-2應(yīng)用于肖像的識別器示例因此,可以將目標識別看作對數(shù)據(jù)集進行聚類的過程,通常會用到一些數(shù)據(jù)集分析概念(將在第6章介紹)。目標檢測和定位另一項任務(wù)是檢測圖像中的特定元素。它通常應(yīng)用于監(jiān)控應(yīng)用甚至先進的相機應(yīng)用中的面部檢測、醫(yī)學(xué)上的癌細胞檢測、工業(yè)廠房中受損部件的檢測等。檢測通常是進一步計算的第一步,提供更小的圖像塊以分別進行分析(例如,為面部識別剪裁圖像中某人的面部,或為增強現(xiàn)實應(yīng)用提供一個圍繞對象的邊界框來評估其姿態(tài)),如圖1-3所示。圖1-3汽車檢測器示例,它返回候選物的邊界框先進的解決方案將在第5章中詳細介紹。目標和實例分割分割可以看作一種更高級的檢測類型。與簡單地為識別的元素提供邊界框不同,分割方法返回掩膜,用于標記屬于特定類或某一類的特定實例的所有像素(參見圖1-4)。這使得任務(wù)變得更加復(fù)雜,實際上,這也是計算機視覺方面少數(shù)幾個深度神經(jīng)網(wǎng)絡(luò)與人類表現(xiàn)仍相去甚遠的領(lǐng)域之一(人類大腦在繪制視覺元素的精確邊界或輪廓方面確實非常高效)。目標分割和實例分割如圖1-4所示。圖1-4汽車的目標分割方法與實例分割方法結(jié)果對比在圖1-4中,目標分割算法為所有屬于汽車類的像素返回一個掩膜,而實例分割算法為它識別的每個汽車實例返回一個不同的掩膜。這對于機器人或智能汽車來說是一項關(guān)鍵任務(wù),這樣它們就可以理解周圍的環(huán)境(例如,識別車輛前方的所有元素)。它也可用于醫(yī)學(xué)圖像,在醫(yī)學(xué)掃描中,精確分割不同的組織可以輔助更快地診斷和更便捷地可視化(比如給每個器官賦予不同的顏色或清除視圖中的干擾)。這將在第6章結(jié)合自主駕駛應(yīng)用實例進行講解。姿態(tài)估計根據(jù)目標任務(wù)的不同,姿態(tài)估計可能有不同的含義。對于剛體,姿態(tài)估計通常是指物體在三維空間中相對于攝像機的位置和方向的估計。這對機器人特別有用,這樣它們就可以與環(huán)境進行交互(挑選對象、避免碰撞等)。它也經(jīng)常被用在增強現(xiàn)實中,在物體上疊加3D信息。對于非剛體元素,姿態(tài)估計也可以表示其子部件相對位置的估計。更具體地說,當將人視為非剛性目標時,典型的應(yīng)用是對人的姿勢(站立、坐著、跑步等)的識別或手語理解。這些不同的情況如圖1-5所示。圖1-5剛體和非剛體姿態(tài)估計示例在這兩種情況下,對于全部或部分元素,算法的任務(wù)是根據(jù)它們在圖像中的2D表示,評估它們在3D世界中相對于攝像機的實際位置和方向。視頻分析計算機視覺不僅適用于單個圖像,也適用于視頻。視頻流有時需要逐幀分析,而有些任務(wù)要求你將圖像序列作為一個整體來考慮其在時間上的一致性(這是第8章的主題之一)。實例跟蹤一些關(guān)于視頻流的任務(wù)可以通過單獨研究每一幀來完成(無記憶地),但是更有效的方法要么考慮以前圖像的推論來指導(dǎo)新圖像的處理,要么將完整的圖像序列作為預(yù)測的輸入。跟蹤,即在視頻流中定位特定元素,就是這種任務(wù)的一個很好的例子。通過對每一幀進行檢測和識別,可以逐幀跟蹤。然而,使用以前的結(jié)果來對實例的運動進行建模以部分預(yù)測它們在未來幀中的位置會更加有效。因此,運動連續(xù)性是這里的一個關(guān)鍵詞,盡管它并不總是成立(例如對于快速移動的對象)。動作識別另一方面,動作識別則屬于只能通過一系列圖像來解決的任務(wù)。就像當單詞被分開和無序時無法理解句子含義一樣,如果不學(xué)習(xí)連續(xù)的圖像序列,那么也不能識別動作(參見圖1-6)。圖1-6貝拉克·奧巴馬是在揮手、指著什么人、驅(qū)趕蚊子,還是做別的什么?只有完整的幀序列才能幫助標記這個動作識別動作識別動作意味著在預(yù)定義的集合中識別特定的動作(例如,人類的動作——跳舞、游泳、畫正方形或畫圓)。應(yīng)用范圍包括監(jiān)視(如檢測異?;蚩梢傻男袨椋┖腿藱C交互(如手勢控制設(shè)備)等。既然目標識別可以分為目標分類、檢測、分割等,那么動作識別同樣如此(動作分類、檢測等)。運動估計有些方法不試圖識別移動的元素,而是專注于估算視頻中捕獲的實際速度或軌跡。相對于所表現(xiàn)的場景,評估相機本身的運動也是很常見的。運動估計在娛樂行業(yè)特別有用,例如,為了應(yīng)用視覺效果或者在電視流(如體育廣播)中覆蓋3D信息而進行動作捕捉。圖片內(nèi)容感知除了分析其內(nèi)容外,計算機視覺方法也可以用來改善圖像本身。越來越多的基礎(chǔ)圖像處理工具(如用于圖像去噪的低通濾波器)正在被更智能的方法所取代,這些方法能夠利用圖像內(nèi)容的先驗知識來提高其視覺質(zhì)量。例如,如果一個方法知道了一只鳥通常是什么樣子的,它就可以根據(jù)這些知識用鳥類圖像中的相干像素代替噪聲像素。這個概念適用于任何類型的圖像恢復(fù),無論是去噪、去模糊,還是分辨率增強(超分辨率,如圖1-7所示)等。圖1-7圖像超分辨率傳統(tǒng)方法與深度學(xué)習(xí)方法的比較(注意在第二張圖片中細節(jié)是多么清晰)一些攝影或藝術(shù)應(yīng)用程序也使用了內(nèi)容感知算法,比如智能人像或智能美容模式,旨在增強模特的一些特征,再比如智能刪除/編輯工具,可以用一些連貫的背景來替代不需要的元素以去除它們。在第6章以及第7章中,我們將演示如何建立和使用這樣的生成方法。場景重建最后,雖然我們不會在本書中處理場景重建問題,但還是要簡單介紹一下。場景重建的任務(wù)是根據(jù)給定的一個或多個圖像恢復(fù)場景的三維幾何形狀。一個簡單的例子是基于人類視覺的立體匹配。它是在一個場景的兩個不同視點的圖像中尋找對應(yīng)元素的過程,從而得出每個可視化元素之間的距離。更先進的方法是獲取多個圖像并將其內(nèi)容匹配在一起,從而獲得目標場景的三維模型。這可以應(yīng)用于物體、人、建筑物等的三維掃描。1.3計算機視覺簡史溫故而知新?!鬃訛榱烁玫乩斫庥嬎銠C視覺的現(xiàn)狀和當前的挑戰(zhàn),建議快速地看一看它是如何誕生以及在過去的幾十年里是如何發(fā)展的。1.3.1邁出成功的第一步科學(xué)家們一直夢想著研發(fā)包括視覺智能在內(nèi)的人工智能技術(shù)。計算機視覺的起步就是由這個想法驅(qū)動的。低估感知任務(wù)在人工智能(ArtificialIntelligence,AI)研究領(lǐng)域,計算機視覺作為一個專門的領(lǐng)域早在20世紀60年代就開始被研究人員所關(guān)注了。象征主義哲學(xué)認為下棋和其他純粹的智力活動是人類智力的縮影,而這些研究人員深受象征主義哲學(xué)的影響,低估了低等動物功能(如感知能力)的復(fù)雜性。這些研究人員是如何相信他們能夠通過1966年的一個夏季項目再現(xiàn)人類感知的呢?這是計算機視覺界的一個著名軼事。馬文·明斯基(MarvinMinsky)是最早提出基于感知構(gòu)建人工智能系統(tǒng)的方法的研究人員之一(見“Stepstowardartificialintelligence”,ProceedingsoftheIRE,1961)。他認為,利用諸如模式識別、學(xué)習(xí)、規(guī)劃和歸納等較基礎(chǔ)的功能,有可能制造出能夠解決各種各樣問題的機器。然而,這一理論直到20世紀80年代才得到適當?shù)奶剿?。?984年的“Locomotion,Vision,andIntelligence”一文中,漢斯·莫拉韋克(HansMoravec)指出,神經(jīng)系統(tǒng)在進化的過程中逐步發(fā)展到能夠處理感知任務(wù)(人類大腦中超過30%的部分用于處理視覺任務(wù)?。?。正如他所指出的,即使計算機在算術(shù)方面表現(xiàn)很出色,它們也無法與我們的感知能力競爭。從這個意義上,利用計算機編程來解決純粹的智力任務(wù)(例如下棋)并不一定有助于開發(fā)一般意義上的智能系統(tǒng)或與人類智能相關(guān)的智能系統(tǒng)。人工選定局部特征受人類感知的啟發(fā),計算機視覺的基本機制很簡單,而且自早期以來并沒有太大的發(fā)展——其思想始終是首先從原始像素中提取有意義的特征,然后將這些特征與已知的標記特征進行匹配,以實現(xiàn)圖像識別。在計算機視覺中,特征是從與當前任務(wù)相關(guān)的數(shù)據(jù)中提取出來的一段信息(通常用數(shù)學(xué)表示為一個一維或二維向量)。特征可以是圖像中的一些關(guān)鍵點、特定的邊緣、可識別的色塊等。它們應(yīng)當很容易從新的圖像中獲得,并包含進一步識別圖像所需的信息。過去,研究人員常常提出越來越復(fù)雜的特征。邊緣和線的提取首先用于場景的基本幾何理解或字符識別。然后,紋理和照明信息也被考慮在內(nèi),形成了早期的對象分類器。20世紀90年代,基于統(tǒng)計分析(如主成分分析(PrincipalComponentAnalysis,PCA))的特征,首次成功地應(yīng)用于復(fù)雜的識別問題,如人臉分類。一個經(jīng)典的例子是馬修·特克(MatthewTurk)和亞歷克斯·彭特蘭(AlexPentland)提出的特征臉(Eigenface)算法(EigenfacesforRecognition,MITPress,1991)。在給定人臉圖像數(shù)據(jù)庫的情況下,通過PCA可以計算人臉圖像的均值和特征向量/圖像(也稱為特征量/圖)。從理論上講,這一組特征圖像可以被線性地組合起來,以重建原始數(shù)據(jù)集的人臉或?qū)崿F(xiàn)更多處理。換句話說,每個人臉圖像都可以通過特征圖像的加權(quán)來近似(參見圖1-8)。這意味著可以簡單地通過每個特征圖像的重建權(quán)值列表來定義特定的人臉。因此,對一幅新的人臉圖像進行分類,只需將其分解為特征圖像,獲得其權(quán)值向量,并與已知人臉的向量進行比較:圖1-8將一幅人像圖像分解為均值圖像和特征圖像的加權(quán)和(平均圖像和特征圖像是在一個更大的人臉數(shù)據(jù)集上計算所得的)另一種出現(xiàn)于20世紀90年代末并徹底改變了該領(lǐng)域的方法是尺度不變特征變換(ScaleInvariantFeatureTransform,SIFT)。正如其名稱所表明的,這個方法由DavidLowe提出(見論文“DistinctiveImageFeaturesfromScale-InvariantKeypoints”,Elsevier),它通過一組對尺度和方向變化具有魯棒性的特征來表示可視對象。簡單地說,該方法在圖像中尋找一些關(guān)鍵點(搜索其梯度中的不連續(xù)點),在每個關(guān)鍵點周圍提取一個圖塊,并為每個關(guān)鍵點計算一個特征向量(例如,圖塊或其梯度中的值的直方圖)。然后,可以使用圖像的局部特征及其對應(yīng)的關(guān)鍵點來匹配其他圖像中的類似視覺元素。在圖1-9中,我們使用OpenCV將SIFT方法應(yīng)用于圖像(\h/3.1.0/da/df5/tutorial_py_sift_intro.html)。對于每一個局部化的關(guān)鍵點,圓的半徑表示特征計算所考慮的圖塊的大小,直線表示特征的方向(即鄰域梯度的主方向)。圖1-9從給定圖像中提取的SIFT關(guān)鍵點(使用OpenCV)隨著時間的推移,研究人員逐漸開發(fā)出了更先進的算法——使用更具魯棒性的算法提取關(guān)鍵點或者計算并結(jié)合有區(qū)別的特征——但是整個過程(從一張圖像中提取特征,并將其與其他圖像的特征進行比較)基本是相同的。添加一些機器學(xué)習(xí)技術(shù)然而,研究人員很快就發(fā)現(xiàn),在識別任務(wù)中,提取魯棒的、有區(qū)別的特征只是完成了一半的工作。例如,來自同一類的不同元素可能看起來非常不同(例如不同外觀的狗),它們只共享一小部分公共特征。因此,不同于圖像匹配任務(wù),更高階的語義分類等問題不能只通過比較被查詢圖像與已標記圖像的像素特征來解決(如果必須完成每一幅圖像同一個大型標簽數(shù)據(jù)集比較,那么考慮到處理時長,這個過程也可以作為次優(yōu)解決方案)。這就是機器學(xué)習(xí)的切入點。20世紀90年代隨著越來越多的研究人員試圖解決圖像分類問題,更多基于特征的統(tǒng)計方法開始出現(xiàn)。支持向量機(SupportVectorMachine,SVM)由VladimirVapnik和CorinnaCortes\h[1]標準化,長期以來是學(xué)習(xí)從復(fù)雜結(jié)構(gòu)(如圖像)到簡單標簽(如類)映射的默認解決方案。給定一組圖像特征及其二值標簽(例如,貓或非貓,如圖1-10所示),可以對SVM進行優(yōu)化,使其能夠根據(jù)提取的特征訓(xùn)練將一個類與另一個類分離的函數(shù)。一旦得到了這個函數(shù),只需將它應(yīng)用到未知圖像的特征向量上,就可以將圖像映射到這兩個類中的一個(后來研究人員提出SVM也可以擴展到多個類)。在圖1-10中,我們訓(xùn)練SVM回歸一個線性函數(shù),讓該函數(shù)根據(jù)從兩類圖像中提取的特征(在本例中,特征是個二值向量)將兩個類分離開來。圖1-10支持向量機回歸的線性函數(shù)(請注意,如果基于內(nèi)核技巧,支持向量機還可以為不同的類找到非線性的解決方案)還有許多其他機器學(xué)習(xí)算法在過去幾年也被計算機視覺研究人員所采用,比如隨機森林、詞袋模型、貝葉斯模型,當然還有神經(jīng)網(wǎng)絡(luò)。\h[1]見論文“Support-vectornetworks”(Springer,1995)。1.3.2深度學(xué)習(xí)的興起那么,神經(jīng)網(wǎng)絡(luò)是如何稱霸計算機視覺,成為今天我們熟知的深度學(xué)習(xí)的呢?本節(jié)給出了一些答案,詳細介紹了這個強大工具的技術(shù)發(fā)展史。早期嘗試和失敗令人驚訝的是,人工神經(jīng)網(wǎng)絡(luò)甚至出現(xiàn)在現(xiàn)代計算機視覺之前。它們的發(fā)展是一個典型的發(fā)明時間過早的例子。感知機的興起和衰落20世紀50年代,F(xiàn)rankRosenblatt提出了感知機(perceptron),這是一種機器學(xué)習(xí)算法,靈感來自神經(jīng)元和第一個神經(jīng)網(wǎng)絡(luò)的底層塊\h[1]。通過適當?shù)膶W(xué)習(xí)過程,這種方法能夠識別字母。然而,這種炒作是短暫的。MarvinMinsky(人工智能之父之一)和SeymorPapert很快證明了感知機無法學(xué)習(xí)像XOR這樣簡單的函數(shù)(異或函數(shù),給定兩個二進制輸入值,如果有且只有1個輸入值為1,則返回1,否則返回0)。在今天,這對我們來說是非常容易理解的——因為當時的感知機是用線性函數(shù)建模的,而XOR是非線性函數(shù)——但在當時,在很多年里它阻礙了研究人員做進一步的研究。太大以至于無法擴展直到20世紀70年代末80年代初,神經(jīng)網(wǎng)絡(luò)才重新引起人們的注意。幾篇研究論文介紹了如何使用相當簡單的反向傳播機制來訓(xùn)練具有多層感知機的神經(jīng)網(wǎng)絡(luò)。我們將在下一節(jié)中詳細介紹,這個訓(xùn)練通過計算網(wǎng)絡(luò)誤差并通過各個感知機層進行反向傳播來使用導(dǎo)數(shù)更新它們的參數(shù)。不久之后,第一個卷積神經(jīng)網(wǎng)絡(luò)(ConvolutionalNeuralNetwork,CNN),即當前主流識別方法的鼻祖,被開發(fā)出來并應(yīng)用于手寫字符的識別,取得了一定的成功。但是,這些方法計算量大,無法擴展應(yīng)用到更大的問題。取而代之,研究人員采用了更輕量級的機器學(xué)習(xí)方法,如支持向量機,于是神經(jīng)網(wǎng)絡(luò)的應(yīng)用又停滯了十幾年。那么,是什么讓它們重新回到人們的視野并發(fā)展成了如今的深度學(xué)習(xí)呢?回歸的理由回歸的原因有兩個,根源于互聯(lián)網(wǎng)和硬件性能的爆炸式發(fā)展?;ヂ?lián)網(wǎng):數(shù)據(jù)科學(xué)的新黃金國互聯(lián)網(wǎng)不僅是一場通信革命,它也深刻地改變了數(shù)據(jù)科學(xué)。通過將圖片和內(nèi)容上傳到網(wǎng)上,科學(xué)家們分享圖片和內(nèi)容變得更加容易,并逐步導(dǎo)致了用于實驗和基準測試的公共數(shù)據(jù)集的產(chǎn)生。此外,不僅是研究人員,很快全世界的每個人都開始以指數(shù)級的速度在網(wǎng)上添加新的內(nèi)容,共享圖片、視頻等。這開啟了大數(shù)據(jù)和數(shù)據(jù)科學(xué)的黃金時代,而互聯(lián)網(wǎng)就成了其中新的黃金國。僅僅通過為不斷在網(wǎng)上發(fā)表的內(nèi)容添加索引,就可以了解到圖像和視頻數(shù)據(jù)集已經(jīng)達到了之前從未想象過的大小,從Caltech-101(1萬幅圖片,由LiFei-Fei等發(fā)布于2003年,Elsevier)到ImageNet(1400多萬圖片,由JiaDeng及其他人發(fā)布于2009年,IEEE)或Youtube-8M(800多萬視頻,由SamiAbu-El-Haija等發(fā)布于2016年,Google)。即使是公司和政府也很快認識到收集和發(fā)布數(shù)據(jù)集以促進其特定領(lǐng)域創(chuàng)新的眾多優(yōu)勢(例如,英國政府發(fā)布的用于視頻監(jiān)控的i-LIDS數(shù)據(jù)集,以及由臉書和微軟等贊助的用于圖像字幕的COCO數(shù)據(jù)集)。隨著如此多的可用數(shù)據(jù)覆蓋了如此多的用例,打開了新的大門(數(shù)據(jù)饑渴類型的算法,即需要大量訓(xùn)練樣本才能成功收斂的算法終于可以成功應(yīng)用了),也提出了新的挑戰(zhàn)(例如,如何有效地處理所有這些信息)。比以往任何時候都更強大幸運的是,由于互聯(lián)網(wǎng)的蓬勃發(fā)展,計算能力也隨之蓬勃發(fā)展。硬件變得越來越便宜,速度也越來越快,這似乎遵循了著名的摩爾定律(即處理器速度每兩年將會翻一番——這是近40年來的真理,盡管現(xiàn)在觀察到的增長有所減速)。隨著計算機運行速度的加快,它們的設(shè)計也變得更加適合計算機視覺。這要感謝電子游戲。圖形處理單元(GraphicsProcessingUnit,GPU)是一種計算機組件,即一種專門用來處理運行3D游戲所需運算的芯片。GPU被優(yōu)化用來生成或處理圖像,并行化這些繁重的矩陣運算。盡管第一個GPU是在20世紀80年代構(gòu)想出來的,但它們確是在2000年才變得便宜和流行的。2007年,主要的GPU設(shè)計公司之一英偉達(NVIDIA)發(fā)布了第一個CUDA版本,這是一種允許開發(fā)者直接為兼容的GPU編程的編程語言。不久之后,類似的語言O(shè)penCL也出現(xiàn)了。有了這些新工具,人們開始利用GPU的力量來完成新的任務(wù),比如機器學(xué)習(xí)和計算機視覺。深度學(xué)習(xí)或人工神經(jīng)網(wǎng)絡(luò)的重塑數(shù)據(jù)饑渴、計算密集型的算法終于有了施展身手的條件。伴隨著大數(shù)據(jù)和云計算,深度學(xué)習(xí)突然變得無處不在。是什么讓學(xué)習(xí)變得有深度?事實上,“深度學(xué)習(xí)”這個術(shù)語早在20世紀80年代就已經(jīng)被創(chuàng)造出來了,那時神經(jīng)網(wǎng)絡(luò)第一次以兩三層神經(jīng)元堆疊起來的形式重新出現(xiàn)。與早期的、更簡單的解決方案不同,深度學(xué)習(xí)重組了更深層次的神經(jīng)網(wǎng)絡(luò),即具有多個隱藏層的網(wǎng)絡(luò)——在輸入和輸出之間設(shè)置了額外的層。每一層處理它的輸入并將結(jié)果傳遞給下一層,所有這些層都經(jīng)過訓(xùn)練以提取越來越抽象的信息。例如,神經(jīng)網(wǎng)絡(luò)的第一層將學(xué)會對圖像的基本特征(如邊緣、線條或顏色梯度)做出反應(yīng);下一層將學(xué)習(xí)使用這些線索來提取更高級的特征;以此類推,直到最后一層,該層將推斷出所需的輸出(例如預(yù)測的類或檢測結(jié)果)。然而,當GeoffHinton和他的同事提出了一個有效的解決方案來訓(xùn)練這些更深層次的模型,每次一層,直至達到期望的深度時,深度學(xué)習(xí)才真正開始被使用\h[2]。深度學(xué)習(xí)的時代隨著神經(jīng)網(wǎng)絡(luò)的研究再次回到正軌,深度學(xué)習(xí)技術(shù)開始蓬勃發(fā)展,直到2012年取得重大突破才最終讓它真正嶄露頭角。自從ImageNet發(fā)布以來,每年都會組織一場競賽(ImageNet大型視覺識別挑戰(zhàn)(ImageNetLargeScaleVisualRecognitionChallenge,ILSVRC),\h/challenges/LSVRC/),研究人員可以提交他們最新的分類算法,并將它們在ImageNet上的性能表現(xiàn)與其他算法進行比較。2010年和2011年的獲勝方案分類誤差分別為28%和26%,采用了SIFT特征和SVM等傳統(tǒng)概念。然后到了2012年,一個新的研究團隊將識別誤差降低到了驚人的16%,將其他所有參賽者遠遠甩在了后面。AlexKrizhevsky、IlyaSutskever和GeoffHinton在他們描述這一成果的論文“ImagenetClassificationwithDeepConvolutionalNeuralNetworks”(NIPS,2012)中提出了現(xiàn)代識別方法的基礎(chǔ)。他們構(gòu)想了一個8層的神經(jīng)網(wǎng)絡(luò)(后來命名為AlexNet),包括幾個卷積層和其他現(xiàn)代組件,如dropout和修正線性激活單元(RectifiedLinearactivationUnit,ReLU),這些都將在第3章中詳細介紹,因為它們已成為計算機視覺的核心。更重要的是,他們使用CUDA來實現(xiàn)他們的方法,這樣它就可以在GPU上運行,最終使得在合理的時間內(nèi),在像ImageNet這么大的數(shù)據(jù)集上迭代完成深度神經(jīng)網(wǎng)絡(luò)訓(xùn)練成為可能。同年,Google演示了云計算的技術(shù)進步如何應(yīng)用于計算機視覺。使用從YouTube視頻中提取的1000萬張隨機圖像數(shù)據(jù)集,教一個神經(jīng)網(wǎng)絡(luò)識別包含貓的圖像,并將1.6萬多臺機器的訓(xùn)練過程并行化,最終將準確率提高了一倍。由此開啟了我們目前所處的深度學(xué)習(xí)時代。每個人都參與進來,提出了越來越深的模型、更先進的訓(xùn)練方案,以及更輕量級的適用便攜設(shè)備的解決方案。這是一個令人興奮的時代,因為深度學(xué)習(xí)解決方案變得越有效,就有越多的人試圖將它們應(yīng)用到新的應(yīng)用和領(lǐng)域。通過本書,我們希望傳遞一些當前的熱情,并提供一個有關(guān)現(xiàn)代方法和細節(jié)的概述,以便于你制定深度學(xué)習(xí)解決方案。\h[1]見論文“ThePerceptron:AProbabilisticModelforInformationStorageandOrganizationintheBrain”(AmericanPsychologicalAssociation,1958)。\h[2]見論文“AFastLearningAlgorithmforDeepBeliefNets”(MITPress,2006)。1.4開始學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)現(xiàn)在,我們知道神經(jīng)網(wǎng)絡(luò)是深度學(xué)習(xí)的核心,是現(xiàn)代計算機視覺的強大工具。但它們到底是什么呢?它們是如何工作的?下面,我們將不僅討論它們效率背后的理論解釋,而且還將直接將這些知識用于一個識別任務(wù)的簡單網(wǎng)絡(luò)的實現(xiàn)和應(yīng)用。1.4.1建立神經(jīng)網(wǎng)絡(luò)人工神經(jīng)網(wǎng)絡(luò)(ArtificialNeuralNetwork,ANN)或神經(jīng)網(wǎng)絡(luò)(NeuralNetwork,NN)是強大的機器學(xué)習(xí)工具,擅長處理信息、識別常見模式或檢測新模式以及模擬復(fù)雜的過程。這些優(yōu)勢得益于它們的結(jié)構(gòu),我們接下來將揭示這一點。模擬神經(jīng)元眾所周知,神經(jīng)元是思想和反應(yīng)的基本單元。但是它們實際上是如何工作的,以及應(yīng)如何模擬它們,對研究人員來說并不是顯而易見的。生物啟發(fā)的確,人工神經(jīng)網(wǎng)絡(luò)靈感多少來自動物大腦的工作模式。大腦是一個由神經(jīng)元組成的復(fù)雜網(wǎng)絡(luò),每個神經(jīng)元相互傳遞信息,并將感官輸入(如電信號和化學(xué)信號)轉(zhuǎn)化為思想和行動。每個神經(jīng)元的電輸入來自它的樹突,樹突是一種細胞纖維,它將來自突觸(與前一神經(jīng)元相連的節(jié)點)的電信號傳遞到神經(jīng)元胞體(神經(jīng)元的主體)。如果累積的電刺激超過特定閾值,細胞就會被激活,電脈沖通過細胞的軸突(神經(jīng)元的輸出電纜,連接其他神經(jīng)元的突觸)進一步傳播到下一個神經(jīng)元。因此,每個神經(jīng)元都可以被看作是一個非常簡單的信號處理單元,一旦堆疊在一起,就可以實現(xiàn)我們現(xiàn)在的思想。數(shù)學(xué)模型受其生物表示的啟發(fā)(見圖1-11),人工神經(jīng)元有幾個輸入(每個數(shù)據(jù)都有一個序號),將輸入累加在一起,最后使用一個激活函數(shù)(activationfunction)來獲得輸出信號,輸出可以傳遞給網(wǎng)絡(luò)中的下一個神經(jīng)元(這可以視為一個有向圖)。圖1-11簡化的生物神經(jīng)元(左)和人工神經(jīng)元(右)通常以加權(quán)方式計算輸入求和。每個輸入都是按照特定于輸入的權(quán)重放大或縮小的。這些權(quán)重是在網(wǎng)絡(luò)訓(xùn)練階段進行優(yōu)化調(diào)整的參數(shù),以使神經(jīng)元對適當?shù)奶卣髯龀龇磻?yīng)。通常,另一個參數(shù)(神經(jīng)元的偏置)也被訓(xùn)練并用于這個求和過程。它的值只是作為偏移量加到加權(quán)和中。我們來快速地用數(shù)學(xué)方法表示這個過程。假設(shè)我們有一個神經(jīng)元,它有兩個輸入值,x0和x1。這些值的加權(quán)系數(shù)分別為w0和w1,可選的偏置為b。為了簡化,將輸入值表示為水平向量x,將權(quán)重表示為垂直向量w:因此,整個運算可以簡單地表示為:z=x·w+b這一步很簡單,不是嗎?兩個向量之間的點積負責加權(quán)求和:現(xiàn)在輸入已經(jīng)被縮放和相加成結(jié)果z了,我們需要對它應(yīng)用激活函數(shù)來得到神經(jīng)元的輸出?;氐脚c生物神經(jīng)元的類比,它的激活函數(shù)將是一個二元函數(shù),當y超過閾值t時,返回一個電脈沖(即1),否則返回0(通常情況下t=0)。如果將其用數(shù)學(xué)公式表示,那么激活函數(shù)y=f(z)可以表示為:階躍函數(shù)是原始感知機的關(guān)鍵組成部分,但研究人員早期就已經(jīng)引入了更高級的激活函數(shù),它們具有更好的特性,如非線性(用于對更復(fù)雜的行為建模)和連續(xù)可微性(這對于訓(xùn)練過程很重要,將在后面解釋)。最常見的激活函數(shù)如下:·sigmoid函數(shù):·雙曲正切函數(shù):·修正線性單元:上述常見激活函數(shù)的示意圖如圖1-12所示。圖1-12常見激活函數(shù)示意圖對于所有的神經(jīng)網(wǎng)絡(luò),基本都是以上的邏輯!這樣我們就模擬了一個簡單的人工神經(jīng)元。它能夠接收一個信號,處理它,并輸出一個值,這個值可以被前向傳遞(前向傳遞是機器學(xué)習(xí)中常用的術(shù)語)給其他神經(jīng)元,從而構(gòu)建一個網(wǎng)絡(luò)。將多個沒有非線性激活函數(shù)的神經(jīng)元鏈接起來,本質(zhì)上仍相當于一個神經(jīng)元。例如,如果有一個參數(shù)為wA和bA的線性神經(jīng)元,其后鏈接一個參數(shù)為wB和bB的線性神經(jīng)元,那么yB=wB·yA+bB=wB·(wA·x+bA)+bB=w·x+b其中,w=wA·wB,b=bA+bB。因此,如果想要創(chuàng)建復(fù)雜的模型,非線性激活函數(shù)是必要的。實現(xiàn)以上模型可以簡便地基于Python實現(xiàn)(使用numpy進行向量和矩陣運算):如上段代碼所示,這是對我們之前定義的數(shù)學(xué)模型的直接改編。使用這個人工神經(jīng)元也很簡單。我們來實例化一個感知機(使用階躍函數(shù)為激活方法的神經(jīng)元),并通過它前向傳遞一個隨機輸入:在進入下一節(jié)開始擴大它們的規(guī)模之前,建議先花點時間用不同的輸入和神經(jīng)元參數(shù)進行一些實驗。將神經(jīng)元分層組合在一起通常,神經(jīng)網(wǎng)絡(luò)被組織成多層,也就是說,每層的神經(jīng)元通常接收相同的輸入并應(yīng)用相同的操作(例如,盡管每個神經(jīng)元首先用自己特定的權(quán)重來對輸入求和,但是它們應(yīng)用相同的激活函數(shù))。數(shù)學(xué)模型在網(wǎng)絡(luò)中,信息從輸入層流向輸出層,中間有一個或多個隱藏層。在圖1-13中,3個神經(jīng)元A、B、C分別屬于輸入層,神經(jīng)元H屬于輸出層或激活層,神經(jīng)元D、E、F、G屬于隱藏層。第一層輸入x的維度為2,第二層(隱藏層)將前一層的三個激活值作為輸入,以此類推。這類每個神經(jīng)元均連接到前一層的所有值的網(wǎng)絡(luò),被稱為全連接或稠密網(wǎng)絡(luò)。圖1-13有兩個輸入值和一個最終輸出的三層神經(jīng)網(wǎng)絡(luò)同樣,通過用向量和矩陣表示這些元素來簡化計算表達。以下操作由第一層完成:zA=x·wA+bAzB=x·wB+bBzC=x·wC+bC這可以表示為:z=x·W+b為了得到前面的方程,必須定義如下的變量:因此,第一層的激活函數(shù)可以寫成一個向量y=f(z)=(f(zA)f(zB)f(zC)),它可以作為輸入向量直接傳遞到下一層,以此類推,直到最后一層。實現(xiàn)與單個神經(jīng)元一樣,這個模型也可以用Python實現(xiàn)。事實上,我們甚至不需要對Neuron類做太多的編輯:我們只需要改變一些變量的維度來反映一個層內(nèi)神經(jīng)元的多樣性。有了這個實現(xiàn),每層甚至可以一次處理多個輸入!傳遞一個列向量x(向量形狀是1×s,其中s是x中數(shù)值的個數(shù))或一組列向量(向量形狀為n×s,其中n是樣本的數(shù)量)不會改變?nèi)魏侮P(guān)于矩陣的計算,并且網(wǎng)絡(luò)的層都將正確輸出疊加的結(jié)果(假設(shè)每一行與b相加):一組輸入數(shù)據(jù)通常稱為一批(batch)。有了這個實現(xiàn),只需將全連接的層連接在一起就可以構(gòu)建簡單的神經(jīng)網(wǎng)絡(luò)。將網(wǎng)絡(luò)應(yīng)用于分類我們已經(jīng)知道了如何定義層,但還沒有將其初始化并連接到計算機視覺網(wǎng)絡(luò)中。為了演示如何做到這一點,我們將處理一個著名的識別任務(wù)。設(shè)置任務(wù)對手寫數(shù)字的圖像進行分類(即識別圖像中是否包含0或1等)是計算機視覺中的一個歷史性問題。修正的美國國家標準與技術(shù)研究院(ModifiedNationalInstituteofStandardsandTechnology,MNIST)數(shù)據(jù)集(\h/exdb/mnist/)包含70000張灰度數(shù)字圖像(像素為28×28),多年來一直作為參考,方便研究人員通過這個識別任務(wù)測試他們的算法(YannLeCun和CorinnaCortes享有這個數(shù)據(jù)集的所有版權(quán),數(shù)據(jù)集如圖1-14所示)。圖1-14MNIST數(shù)據(jù)集中每個數(shù)字的10個樣本對于數(shù)字分類,我們需要的是一個將這些圖像中的一個作為輸入并返回一個輸出向量,該向量表示網(wǎng)絡(luò)認為的這些圖像與每個類對應(yīng)的概率。輸入向量有28×28=784個值,而輸出有10個值(對于從0到9的10個不同數(shù)字)。在輸入和輸出之間,由我們來定義隱藏層的數(shù)量和它們的大小。要預(yù)測圖像的類別,只需通過網(wǎng)絡(luò)前向傳遞圖像向量,收集輸出,然后返回置信度得分最高的類別即可。這些置信度得分通常被轉(zhuǎn)化為概率值,以簡化后續(xù)的計算或解釋。例如,假設(shè)一個分類網(wǎng)絡(luò)給類“狗”賦值為9,給另一個類“貓”賦值為1。這就是說,根據(jù)這個網(wǎng)絡(luò),圖像顯示的是狗的概率為9/10,顯示的是貓的概率為1/10。在實現(xiàn)解決方案之前,先通過加載MNIST數(shù)據(jù)來完成用于訓(xùn)練和測試算法的數(shù)據(jù)準備。為了簡單起見,我們將使用由MarcGarcia開發(fā)的Pythonmnist模塊(\h/datapythonista/mnist)(根據(jù)BSD3-Clause的新/修訂許可,已經(jīng)安裝在本章的源目錄中):關(guān)于數(shù)據(jù)集預(yù)處理和可視化的更詳盡操作可以在本章的源代碼中找到。實現(xiàn)網(wǎng)絡(luò)對于神經(jīng)網(wǎng)絡(luò)本身,我們必須把層組合在一起,并添加一些算法在整個網(wǎng)絡(luò)上進行前向傳遞,然后根據(jù)輸出向量來預(yù)測分類。在實現(xiàn)各層之后,下面的代碼就不言自明了:我們剛剛實現(xiàn)了一個前饋神經(jīng)網(wǎng)絡(luò),可以用來分類!是時候把它應(yīng)用到我們的問題上了:我們的準確率只有12.06%。這可能看起來令人失望,因為它的準確性僅略好于隨機猜測。但是這是有意義的——因為此時的網(wǎng)絡(luò)是由隨機參數(shù)定義的。我們需要根據(jù)用例來訓(xùn)練它,這就是下一節(jié)中需要處理的任務(wù)。1.4.2訓(xùn)練神經(jīng)網(wǎng)絡(luò)神經(jīng)網(wǎng)絡(luò)是一種特殊的算法,因為它們需要訓(xùn)練,也就是說,它們需要通過從可用的數(shù)據(jù)中學(xué)習(xí)來針對特定的任務(wù)進行參數(shù)優(yōu)化。一旦網(wǎng)絡(luò)被優(yōu)化至在訓(xùn)練數(shù)據(jù)集上表現(xiàn)良好,它們就可以在新的、類似的數(shù)據(jù)上使用,從而提供令人滿意的結(jié)果(如果訓(xùn)練正確的話)。在解決MNIST任務(wù)之前,我們將介紹一些理論背景,涵蓋不同的學(xué)習(xí)策略,并介紹實際中是如何進行訓(xùn)練的。然后,將直接把這些概念應(yīng)用到示例中,以便我們的簡單網(wǎng)絡(luò)最終學(xué)會如何解決識別任務(wù)!學(xué)習(xí)策略當涉及神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)時,根據(jù)任務(wù)和訓(xùn)練數(shù)據(jù)的可用性,主要有三種學(xué)習(xí)范式。有監(jiān)督學(xué)習(xí)有監(jiān)督學(xué)習(xí)(supervisedlearning)可能是最常見的,當然也是最容易掌握的學(xué)習(xí)范式。當我們想要教會神經(jīng)網(wǎng)絡(luò)兩種模式之間的映射關(guān)系(例如,將圖像映射到它們的類標簽或它們的語義掩膜)時,適合使用有監(jiān)督學(xué)習(xí)。它需要訪問一個包含圖像及其真值標簽(例如每張圖像的類信息或語義掩膜)的訓(xùn)練數(shù)據(jù)集。這樣一來,訓(xùn)練就很簡單了:·將圖像提供給網(wǎng)絡(luò),并收集其結(jié)果(即預(yù)測標簽)?!ぴu估網(wǎng)絡(luò)的損失,即將預(yù)測結(jié)果與真值標簽進行比較時的錯誤程度?!は鄳?yīng)地調(diào)整網(wǎng)絡(luò)參數(shù)以減少損失?!ぶ貜?fù)以上操作直至網(wǎng)絡(luò)收斂,也就是說,直到它在這批訓(xùn)練數(shù)據(jù)上不能再進一步改進為止。這種學(xué)習(xí)策略確實可以形容為“有監(jiān)督的”,因為有一個實體(即我們)通過對每個預(yù)測結(jié)果提供反饋(根據(jù)真值標簽計算出的損失)來監(jiān)督網(wǎng)絡(luò)的訓(xùn)練情況,以便該算法可以通過重復(fù)訓(xùn)練(觀察某次訓(xùn)練是正確的或錯誤的,然后再試一次)來學(xué)習(xí)。無監(jiān)督學(xué)習(xí)然而,當沒有任何真值信息可用時,如何訓(xùn)練網(wǎng)絡(luò)?答案是采用無監(jiān)督學(xué)習(xí)(unsupervisedlearning)。它的思想是創(chuàng)建一個函數(shù),僅根據(jù)網(wǎng)絡(luò)的輸入和相應(yīng)的輸出來計算網(wǎng)絡(luò)的損失。這種策略非常適用于聚類(將具有相似屬性的圖像分組在一起)或壓縮(減少內(nèi)容大小,同時保留一些屬性)等應(yīng)用程序。對于聚類,損失函數(shù)可以衡量來自某一類相似圖像與其他類圖像的比較情況。對于壓縮,損失函數(shù)可以衡量壓縮后的數(shù)據(jù)與原始數(shù)據(jù)相比,重要屬性的保留程度。無監(jiān)督學(xué)習(xí)需要一些關(guān)于用例的專業(yè)知識,才能提出有意義的損失函數(shù)。強化學(xué)習(xí)強化學(xué)習(xí)(reinforcementlearning)是一種交互式策略。智能體在環(huán)境中導(dǎo)航(例如,機器人在房間中移動或電子游戲角色通過關(guān)卡)。智能體有一個預(yù)定義的、可執(zhí)行的動作列表(走、轉(zhuǎn)、跳等),并且在每個動作之后,它會進入一個新的狀態(tài)。有些狀態(tài)可以帶來“獎勵”,這些獎勵可以是即時的,也可以是延遲的,可以是正面的,也可以是負面的(例如,游戲角色獲得額外物品時的正面獎勵,游戲角色被敵人擊中時的負面獎勵)。在每個時刻,神經(jīng)網(wǎng)絡(luò)只提供來自環(huán)境的觀察(例如,機器人的視覺輸入或視頻游戲屏幕)和獎勵反饋(胡蘿卜和大棒)。由此,它必須了解什么能帶來更高的獎勵并據(jù)此為智能體制定最佳的短期或長期策略。換句話說,它必須評估出能使其最終獎勵最大化的一系列行為。強化學(xué)習(xí)是一個強大的學(xué)習(xí)范式,但是很少用于計算機視覺用例。雖然我們鼓勵機器學(xué)習(xí)愛好者學(xué)習(xí)更多的知識,但在這里我們不會再做進一步介紹。訓(xùn)練時間不管學(xué)習(xí)策略是什么,大致的訓(xùn)練步驟都是一樣的。給定一些訓(xùn)練數(shù)據(jù),網(wǎng)絡(luò)進行預(yù)測并接收一些反饋(如損失函數(shù)的結(jié)果),然后用這些反饋更新網(wǎng)絡(luò)的參數(shù)。然后重復(fù)這些步驟,直到無法進一步優(yōu)化網(wǎng)絡(luò)為止。本節(jié)將詳細介紹并實現(xiàn)這個過程,從損失計算到優(yōu)化權(quán)重。評估損失損失函數(shù)的目標是評估網(wǎng)絡(luò)在其當前權(quán)重下的性能。更正式地說,這個函數(shù)將預(yù)測效果表示為網(wǎng)絡(luò)參數(shù)(比如它的權(quán)重和偏置)的函數(shù)。損失越小,針對該任務(wù)的參數(shù)就越好。因為損失函數(shù)代表了網(wǎng)絡(luò)的目標(例如,返回正確的標簽,壓縮圖像同時保留內(nèi)容,等等),所以有多少任務(wù)就有多少不同的函數(shù)。盡管如此,有些損失函數(shù)比其他函數(shù)更常用一些,比如平方和函數(shù),也稱為L2損失函數(shù)(基于L2范數(shù)),它在有監(jiān)督學(xué)習(xí)中無處不在。這個函數(shù)簡單地計算輸出向量y的每個元素(網(wǎng)絡(luò)估計的每個類的概率)和真值ytrue向量(除了正確的類之外,該目標向量中對應(yīng)的其余每個類都是空值)的每個元素之間的差的平方:還有許多其他性質(zhì)不同的損失函數(shù),如計算矢量之間絕對差的L1損失,如二進制交叉熵(BinaryCross-Entropy,BCE)損失,它把預(yù)測概率轉(zhuǎn)換為對數(shù),然后與預(yù)期的值進行比較:對數(shù)運算將概率從[0,1]轉(zhuǎn)換為[-∞,0],因此將結(jié)果乘以-1,神經(jīng)網(wǎng)絡(luò)在學(xué)習(xí)如何正確預(yù)測時損失值的區(qū)間就可以變換為[0,+∞]。請注意,交叉熵函數(shù)也可以應(yīng)用于多分類的問題(不僅僅局限于兩類)。人們通常會將損失值除以向量中元素的數(shù)量,也就是說,計算平均值而不是損失總和。均方誤差(Mean-SquareError,MSE)是L2損失的平均值,平均絕對誤差(Mean-AbsoluteError,MAE)是L1損失的平均值?,F(xiàn)在,我們將以L2損失為例,并在后面的理論解釋和MNIST分類器訓(xùn)練中用到它。反向傳播損失如何更新網(wǎng)絡(luò)參數(shù),才能使其損失最???對于每個參數(shù),我們需要知道的是改變它的值會如何影響損失。如果知道哪些變化會使損失減少,那么只需重復(fù)應(yīng)用這些變化,直到損失達到最小即可。這正是損失函數(shù)梯度的原理,也是梯度下降的過程。在每次訓(xùn)練迭代中,計算損失函數(shù)對網(wǎng)絡(luò)各參數(shù)的導(dǎo)數(shù)。這些導(dǎo)數(shù)表示需要對參數(shù)進行哪些小的更改(由于梯度表示函數(shù)上升的方向,而我們希望最小化它,因此這里有一個為-1的系數(shù))。它可以看作是沿著損失函數(shù)關(guān)于每個參數(shù)的斜率逐步下降,因此這個迭代過程被稱為梯度下降(見圖1-15)。圖1-15優(yōu)化神經(jīng)網(wǎng)絡(luò)參數(shù)P的梯度下降過程示意圖現(xiàn)在的問題是,如何計算所有這些導(dǎo)數(shù)(即斜率值,以作為每個參數(shù)的函數(shù))?這時鏈式法則就派上用場了。并不需要太深入的微積分知識,鏈式法則可以告訴我們,關(guān)于k層參數(shù)的導(dǎo)數(shù)可以簡單地用該層的輸入和輸出值(xk,yk),以及k+1層的導(dǎo)數(shù)來計算。更正式地說,對于該層的權(quán)值Wk,有以下公式:式中,l′k+1是k+1層對輸入的導(dǎo)數(shù),xk+1=yk,fk′是這層激活函數(shù)的導(dǎo)數(shù),xT是x的轉(zhuǎn)置。請注意,zk表示k層的加權(quán)和的結(jié)果(即在該層的激活函數(shù)輸入之前),其定義見1.4.1節(jié)。最后,符號表示兩個向量或矩陣之間對應(yīng)元素相乘,它也被稱為哈達瑪積。如下式所示,哈達瑪積基本就是將各對應(yīng)元素成對相乘:回到鏈式法則,對偏置的導(dǎo)數(shù)也可以用類似的方法計算:最后,為便于你能夠掌握得更加詳盡,還有以下等式:這些計算可能看起來很復(fù)雜,但我們只需要理解它們所代表的內(nèi)涵——我們可以一層一層地、逆向地計算每個參數(shù)如何遞歸地影響損失(使用某一層的導(dǎo)數(shù)來計算前一層的導(dǎo)數(shù))。我們也可以通過將神經(jīng)網(wǎng)絡(luò)表示為計算圖,即作為數(shù)學(xué)運算的圖形鏈接在一起,來說明該概念。(執(zhí)行第一層的加權(quán)求和,將其結(jié)果傳遞給第一個激活函數(shù),然后將輸出傳遞給第二層進行操作,以此類推)。因此,計算整個神經(jīng)網(wǎng)絡(luò)關(guān)于某些輸入的結(jié)果就包含了通過這個計算圖來前向傳遞數(shù)據(jù),而獲得關(guān)于它的每個參數(shù)的導(dǎo)數(shù)則包含了將產(chǎn)生的損失在計算圖中的向后傳播,因此這個過程被稱為反向傳播。為了從輸出層開始這個過程,我們需要損失本身對輸出值的導(dǎo)數(shù)(參考前面的方程)。因此,損失函數(shù)的推導(dǎo)是很容易的。例如,L2損失的導(dǎo)數(shù)為:正如之前提到的,一旦知道了每個參數(shù)的損失的導(dǎo)數(shù),只需要相應(yīng)地更新它們即可:如上所示,在更新參數(shù)之前,導(dǎo)數(shù)通常要乘以一個因子。這個因子被稱為學(xué)習(xí)率。它有助于控制在每次迭代中更新每個參數(shù)的強度。較大的學(xué)習(xí)率可能允許網(wǎng)絡(luò)學(xué)習(xí)得更快,但有可能使步伐太大造成網(wǎng)絡(luò)錯過最小損失值。因此,應(yīng)該謹慎地設(shè)置它的值。完整的訓(xùn)練過程如下:1)選擇n幅圖像用于下一次訓(xùn)練并將它們輸入到網(wǎng)絡(luò)中。2)利用鏈式法則求出對各層參數(shù)的導(dǎo)數(shù),計算并反向傳播損失。3)根據(jù)相應(yīng)的導(dǎo)數(shù)值更新參數(shù)(根據(jù)學(xué)習(xí)率控制更新尺度)。4)重復(fù)步驟1~3來遍歷整個訓(xùn)練集。5)重復(fù)步驟1~4,直到收斂或直到迭代完固定的次數(shù)為止。整個訓(xùn)練集上的一次完整迭代(步驟1~4)稱為一輪(epoch)。如果n=1,則在剩余的圖像中隨機選取訓(xùn)練樣本,這個過程稱為隨機梯度下降(StochasticGradientDescent,SGD),它易于實現(xiàn)和可視化,但速度較慢(更新次數(shù)較多)、噪聲較大。人們傾向于選擇小批量隨機梯度下降(mini-batchstochasticgradientdescent)。它意味著使用更多的(n更大)值(受計算機能力的限制),這時的梯度是具有n個隨機訓(xùn)練樣本的每個小批(或更簡單地稱為批)上的平均梯度(這樣噪聲更?。?。如今,不管n為多少,SGD這個術(shù)語都已被廣泛使用。在本節(jié)中,我們討論了如何訓(xùn)練神經(jīng)網(wǎng)絡(luò)。是時候把這些知識付諸實踐了!訓(xùn)練網(wǎng)絡(luò)分類到目前為止,我們只實現(xiàn)了網(wǎng)絡(luò)及其層的前饋功能。首先,更新FullyConnectedLayer類,以便添加反向傳播和優(yōu)化算法:本節(jié)中提供的代碼經(jīng)過了簡化,并去掉了注釋,以保持合適的長度。完整的源代碼可以在本書的GitHub庫中找到,同時還可找到一個JupyterNotebook,它將所有內(nèi)容連接在了一起?,F(xiàn)在,我們需要通過一層一層地加載算法以實現(xiàn)反向傳播和優(yōu)化,并利用最終的算法來覆蓋完整的訓(xùn)練(步驟1~5),因此相應(yīng)地對SimpleNetwork類進行更新:一切準備就緒!我們可以訓(xùn)練神經(jīng)網(wǎng)絡(luò),并看看它的表現(xiàn)如何:如果你的計算機有足夠的算力來完成這個訓(xùn)練(這個簡單的實現(xiàn)沒有利用GPU),那么就將得到該神經(jīng)網(wǎng)絡(luò),它能夠以94.8%的準確率對手寫數(shù)字進行分類!訓(xùn)練注意事項:欠擬合和過擬合我們邀請你嘗試一下剛剛實現(xiàn)的框架,嘗試不同的超參數(shù)(層大小、學(xué)習(xí)率、批大小等)。選擇合適的網(wǎng)絡(luò)拓撲(以及其他超參數(shù))可能需要大量的調(diào)整和測試。雖然輸入層和輸出層的大小是由用例情況(例如,對于分類,輸入大小是圖像的像素數(shù)量,而輸出大小是待預(yù)測的類的數(shù)量)決定的,隱藏層仍應(yīng)該經(jīng)過精心設(shè)計。舉例來說,如果網(wǎng)絡(luò)的層數(shù)太少或?qū)犹?,那么準確率可能會停滯不前。這意味著網(wǎng)絡(luò)是欠擬合的,也就是說,它沒有足夠的參數(shù)來處理復(fù)雜任務(wù)。在這種情況下,唯一的解決方案是采用更適合用例的新架構(gòu)。另一方面,如果網(wǎng)絡(luò)太復(fù)雜或訓(xùn)練數(shù)據(jù)集太小,網(wǎng)絡(luò)可能會針對訓(xùn)練數(shù)據(jù)產(chǎn)生過擬合。這意味著該網(wǎng)絡(luò)將很好地適應(yīng)訓(xùn)練分布(即其特定的噪聲、細節(jié)等),但不能泛化到新的樣本(因為這些新圖像可能有稍微不同的噪聲)。圖1-16展示了這兩個問題之間的區(qū)別。最左側(cè)的回歸方法沒有足夠的參數(shù)來模擬數(shù)據(jù)的變化,而最右側(cè)的方法則由于參數(shù)太多,失去了泛化能力。圖1-16欠擬合和過擬合的常見示意圖雖然收集更大、更多樣化的訓(xùn)練數(shù)據(jù)集似乎是過擬合的合理解決方案,但在實踐中并不總是可行的(例如,由于目標對象存在訪問限制)。另一種解決方案是調(diào)整網(wǎng)絡(luò)或其訓(xùn)練,以限制網(wǎng)絡(luò)學(xué)習(xí)的細節(jié)。這些方法將在第3章詳細介紹,屆時還會在該章介紹其他先進的神經(jīng)網(wǎng)絡(luò)解決方案。1.5本章小結(jié)我們在第1章中討論了很多內(nèi)容。我們介紹了計算機視覺、它的挑戰(zhàn),以及一些過往的算法,如SIFT和SVM。我們熟悉了神經(jīng)網(wǎng)絡(luò)以及它們是如何建立、訓(xùn)練和應(yīng)用的。從零開始實現(xiàn)了我們自己的分類器網(wǎng)絡(luò),我們現(xiàn)在應(yīng)該可以更好地理解了機器學(xué)習(xí)框架是如何工作的。有了這些知識,我們現(xiàn)在已經(jīng)準備了開啟下一章的TensorFlow之旅。問題1.下列哪項任務(wù)不屬于計算機視覺?·類似于查詢的網(wǎng)絡(luò)搜索圖像·從圖像序列中重建三維場景·視頻角色的動畫2.最初的感知機使用的是哪個激活函數(shù)?3.假設(shè)要訓(xùn)練一種算法來檢測手寫數(shù)字是否是4,應(yīng)該如何調(diào)整本章中的網(wǎng)絡(luò)來完成這項任務(wù)?進一步閱讀·SandipanDey編著的Hands-OnImageProcessingwithPython(\h/big-data-and-business-intelligence/hands-image-processing-python):一本關(guān)于圖像處理以及如何使用Python實現(xiàn)數(shù)據(jù)可視化的好書籍?!abrielGarrido和PrateekJoshi編著的OpenCV3.xwithPythonByExample-SecondEdition(\h/application-development/opencv-3x-python-example-second-edition):另一本比較新的介紹著名計算機視覺庫OpenCV的著作,OpenCV多年前已被廣泛使用(它實現(xiàn)了本章中介紹的一些傳統(tǒng)方法,如邊緣檢測、SIFT、SVM等)。第2章
TensorFlow基礎(chǔ)和模型訓(xùn)練TensorFlow是研究人員和機器學(xué)習(xí)從業(yè)人員使用的數(shù)值處理庫。雖然可以使用TensorFlow來執(zhí)行任何數(shù)值運算,但它主要是用于訓(xùn)練和運行深度神經(jīng)網(wǎng)絡(luò)。本章將介紹TensorFlow2的核心概念,并引導(dǎo)你完成一個簡單的示例。本章將涵蓋以下主題:·TensorFlow2和Keras入門?!?chuàng)建和訓(xùn)練簡單的計算機視覺模型?!ensorFlow和Keras的核心概念?!ensorFlow生態(tài)系統(tǒng)。2.1技術(shù)要求在本書中,我們將使用TensorFlow2。針對不同平臺的詳細安裝說明參見\h/install。如果你計劃使用計算機的GPU,請確保安裝相應(yīng)版本的tensorflow-gpu。它必須與CUDA工具箱一起安裝,CUDA由NVIDIA提供(\h/cuda-zone)。GitHub上的README也提供了安裝說明,參見\h/PacktPublishing/Hands-On-Computer-Vision-with-TensorFlow-2/tree/master/Chapter02。2.2TensorFlow2和Keras入門在詳細介紹TensorFlow的核心概念之前,首先對框架和基本示例進行簡要介紹。2.2.1TensorFlowTensorFlow最初由Google開發(fā),旨在讓研究人員和開發(fā)人員進行機器學(xué)習(xí)研究。它最初被定義為描述機器學(xué)習(xí)算法的接口,以及執(zhí)行該算法的實現(xiàn)。TensorFlow的主要預(yù)期目標是簡化機器學(xué)習(xí)解決方案在各種平臺上的部署,如計算機CPU、計算機GPU、移動設(shè)備以及最近的瀏覽器中的部署。最重要的是,TensorFlow提供了許多有用的功能來創(chuàng)建機器學(xué)習(xí)模型并大規(guī)模運行它們。TensorFlow2于2019年發(fā)布,它專注于易用性,并能保持良好的性能??稍诒緯母戒洸殚員ensorFlow1.0概念的介紹。這個庫于2015年11月開源。從那時起,它已被世界各地的用戶改進和使用。它被認為是開展研究的首選平臺之一。就GitHub活躍度而言,它也是最活躍的深度學(xué)習(xí)框架之一。TensorFlow既可供初學(xué)者使用,也可供專家使用。TensorFlowAPI具有不同級別的復(fù)雜度,從而使初學(xué)者可以從簡單的API開始,同時也可以讓專家創(chuàng)建非常復(fù)雜的模型。我們來探索一下這些不同級別的模型。TensorFlow主要架構(gòu)TensorFlow架構(gòu)(見圖2-1)具有多個抽象層級。我們首先介紹底層,然后逐漸通往最上層。圖2-1TensorFlow架構(gòu)圖大多數(shù)深度學(xué)習(xí)計算都是用C++編碼的。為了在GPU上進行運算,TensorFlow使用了由NVIDIA開發(fā)的庫CUDA。這就是如果想要利用GPU功能就需要安裝CUDA,以及不能使用其他硬件制造商GPU的原因。然后,Python底層API(low-levelAPI)封裝了C++源代碼。當調(diào)用TensorFlow的Python方法時,通常會在后臺調(diào)用C++代碼。這個封裝層使用戶可以更快地工作,因為Python被認為更易于使用并且不需要編譯。該Python封裝器可以創(chuàng)建非?;镜倪\算,例如矩陣乘法和加法。最上層是高級API(high-levelAPI),由Keras和評估器API(estimatorAPI)兩個組件組成。Keras是TensorFlow的一個用戶友好型、模塊化且可擴展的封裝器(見下一節(jié)),評估器API包含多個預(yù)制組件,可讓你輕松地構(gòu)建機器學(xué)習(xí)模型。你可以將它們視為構(gòu)建塊或模板。在深度學(xué)習(xí)中,模型通常是指經(jīng)過數(shù)據(jù)訓(xùn)練的神經(jīng)網(wǎng)絡(luò)。模型由架構(gòu)、矩陣權(quán)重和參數(shù)組成。Keras介紹Keras于2015年首次發(fā)布,它被設(shè)計為一種接口,可用于使用神經(jīng)網(wǎng)絡(luò)進行快速實驗。因此,它依賴TensorFlow或Theano(另一個深度學(xué)習(xí)框架,現(xiàn)已棄用)來運行深度學(xué)習(xí)操作。Keras以其用戶友好性著稱,是初學(xué)者的首選庫。自2017年以來,TensorFlow完全集成了Keras,這意味著無須安裝TensorFlow以外的任何庫就可使用它。在本書中,我們將依賴tf.keras而不是Keras的獨立版本。這兩個版本之間有一些細微的差異,例如與TensorFlow的其他模塊的兼容性以及模型的保存方式。因此,讀者必須確保使用正確的版本,具體方法如下:·在代碼中,導(dǎo)入tf.keras而不是keras?!g覽TensorFlow網(wǎng)站上的tf.keras文檔,而不是keras.io文檔?!ぴ谑褂猛獠縆eras庫時,請確保它們與tf.keras兼容?!つ承┍4娴哪P驮贙eras版本之間可能不兼容。這兩個版本在可預(yù)見的未來將繼續(xù)共存,而tf.keras與TensorFlow集成將越來越密切。為了說明Keras的強大功能和簡單性,我們將使用該庫實現(xiàn)一個簡單的神經(jīng)網(wǎng)絡(luò)。2.2.2基于Keras的簡單計算機視覺模型在深入探討TensorFlow的核心概念之前,我們先從一個計算機視覺的經(jīng)典示例開始,它使用數(shù)據(jù)集MNIST(見第1章)進行數(shù)字識別。準備數(shù)據(jù)首先,導(dǎo)入數(shù)據(jù)。它由用于訓(xùn)練集的60000幅圖像和用于測試集的10000幅圖像組成:常見的做法是使用別名tf來導(dǎo)入TensorFlow,從而加快讀取和鍵入速度。通常用x表示輸入數(shù)據(jù),用y表示標簽。tf.keras.datasets模塊提供快速訪問,以下載和實例化一些經(jīng)典數(shù)據(jù)集。使用load_data導(dǎo)入數(shù)據(jù)后,請注意,我們將數(shù)組除以255.0,得到的數(shù)字范圍為[0,1]而不是[0,255]。將數(shù)據(jù)歸一化在[0,1]范圍或[-1,1]范圍是一種常見的做法。構(gòu)建模型現(xiàn)在,我們可以繼續(xù)構(gòu)建實際模型。我們將使用一個非常簡單的架構(gòu),該架構(gòu)由兩個全連接層(也稱為稠密層)組成。在詳細介紹架構(gòu)之前,我們來看一下代碼??梢钥吹?,Keras代碼非常簡潔:由于模型是層的線性堆棧,因此我們首先調(diào)用Sequential函數(shù)。然后,依次添加每一層。模型由兩個全連接層組成。我們逐層構(gòu)建:·展平層(Flatten):它將接受表示圖像像素的二維矩陣,并將其轉(zhuǎn)換為一維數(shù)組。我們需要在添加全連接層之前執(zhí)行此操作。28×28的圖像被轉(zhuǎn)換為大小為784的向量?!ご笮?28的稠密層(Dense):它使用大小為128×784的權(quán)重矩陣和大小為128的偏置矩陣,將784個像素值轉(zhuǎn)換為128個激活值。這意味著有100480個參數(shù)?!ご笮?0的稠密層(Dense):它將把128個激活值轉(zhuǎn)變?yōu)樽罱K預(yù)測。注意,因為概率總和為1,所以我們將使用softmax激活函數(shù)。softmax函數(shù)獲取某層的輸出,并返回總和為1的概率。它是分類模型最后一層的選擇的激活函數(shù)。請注意,使用model.summary()可以獲得有關(guān)模型、輸出及其權(quán)重的描述。下面是輸出:設(shè)置好架構(gòu)并初始化權(quán)重后,模型現(xiàn)在就可以針對所選任務(wù)進行訓(xùn)練了。訓(xùn)練模型Keras讓訓(xùn)練變得非常簡單:在剛剛創(chuàng)建的模型上調(diào)用.compile()是一個必需的步驟。必須指定幾個參數(shù):·優(yōu)化器(optimizer):運行梯度下降的組件?!p失(loss):優(yōu)化的指標。在本例中,選擇交叉熵,就像上一章一樣?!ぴu估指標(metrics):在訓(xùn)練過程進行評估的附加評估函數(shù),以進一步查看有關(guān)模型性能(與損失不同,它們不在優(yōu)化過程中使用)。名為sparse_categorical_crossentropy的Keras損失執(zhí)行與categorical_crossentropy相同的交叉熵運算,但是前者直接將真值標簽作為輸入,而后者則要求真值標簽先變成獨熱(one-hot)編碼。因此,使用sparse_...損失可以免于手動轉(zhuǎn)換標簽的麻煩。將'sgd'傳遞給Keras等同于傳遞tf.keras.optimizers.SGD()。前一個選項更易于閱讀,而后一個選項則可以指定參數(shù),如自定義學(xué)習(xí)率。傳遞給Keras方法的損失、評估指標和大多數(shù)參數(shù)也是如此。然后,我們調(diào)用.fit()方法。它與另一個流行的機器學(xué)習(xí)庫scikit-learn中所使用的接口非常相似。我們將訓(xùn)練5輪,這意味著將對整個訓(xùn)練數(shù)據(jù)集進行5次迭代。請注意,我們將verbose設(shè)置為1。這將讓我們獲得一個進度條,其中包含先前選擇的指標、損失和預(yù)計完成時間(EstimatedTimeofArrival,ETA)。ETA是對輪次結(jié)束之前剩余時間的估計。進度條如圖2-2所示。圖2-2Keras在詳細模式下顯示的進度條屏幕截圖模型性能如第1章中所述,你會注意到模型是過擬合的——即訓(xùn)練準確率大于測試準確率。如果對模型訓(xùn)練5輪,則最終在測試集上的準確率為97%。這比上一章(95%)高了約2個百分點。最先進的算法可達到99.79%的準確率。我們遵循了三個主要步驟:1)加載數(shù)據(jù):在本例中,數(shù)據(jù)集已經(jīng)可用。在未來的項目中,你可能需要其他的步驟來收集和清理數(shù)據(jù)。2)創(chuàng)建模型:使用Keras可以讓這一步驟變得容易——按順序添加層即可定義模型的架構(gòu)。然后,選擇損失、優(yōu)化器和評估指標進行監(jiān)控。3)訓(xùn)練模型:模型第一次運行效果很好。在更復(fù)雜的數(shù)據(jù)集上,通常需要在訓(xùn)練過程中微調(diào)參數(shù)。借助TensorFlow的高級API——Keras,整個過程非常簡單。在這個簡單API的背后,該庫隱藏了很多復(fù)雜操作。2.3TensorFlow2和Keras詳述我們介紹了TensorFlow的一般架構(gòu),并使用Keras訓(xùn)練了第一個模型?,F(xiàn)在,我們來看TensorFlow2的主要概念。我們將詳細介紹TensorFlow的幾個貫穿全書的核心概念,然后再介紹一些高級概念。雖然本書的其余部分中可能并未全部使用它們,但是讀者可能會發(fā)現(xiàn)這對于理解GitHub上提供的一些開源模型或?qū)爝M行更深入的了解是很有用的。2.3.1核心概念該框架的新版本于2019年春發(fā)布,它致力于提高簡單性和易用性。本節(jié)將介紹TensorFlow所依賴的概念,并介紹它們是如何從版本1演變到版本2的。張量TensorFlow的名稱來自名為張量(tensor)的數(shù)學(xué)對象。你可以將張量描繪為N維數(shù)組。張量可以是標量、向量、三維矩陣或N維矩陣。作為TensorFlow的基本組件,Tensor對象用于存儲數(shù)學(xué)上的值。它可以包含固定值(使用tf.constant創(chuàng)建)或變量值(使用tf.Variable創(chuàng)建)。在本書中,tensor表示數(shù)學(xué)概念,而Tensor(字母T大寫)對應(yīng)于TensorFlow對象。每個Tensor對象具有:·類型(Type):string、float32、float16或int8等數(shù)據(jù)類型?!ば螤睿⊿hape):數(shù)據(jù)的維度。例如,對于標量,形狀為();對于大小為n的向量,形狀為(n);對于大小為n×m的二維矩陣,形狀為(n,m)?!るA(Rank):維數(shù),標量為0階,向量為1階,二維矩陣為2階。一些Tensor可以具有部分未知的形狀。例如,接受可變大小圖像的模型的輸入形狀可以為(None,None,3)。由于圖像的高度和寬度事先是未知的,因此前兩個維度設(shè)置為None。但是,通道數(shù)(3,對應(yīng)于紅色、藍色和綠色)是已知的,因此已設(shè)置。TensorFlow圖TensorFlow使用Tensor作為輸入和輸出。將輸入轉(zhuǎn)換為輸出的組件稱為操作。因此,計算機視覺模型由多個操作組成。TensorFlow使用有向無環(huán)圖(DirectedAcyclicGraph,DAG)表示這些操作,DAG也稱為圖。在TensorFlow2中,沒有了圖操作,框架更易于使用。盡管如此,圖的概念對于理解TensorFlow的真正工作原理仍然很重要。使用Keras構(gòu)建前面的示例時,TensorFlow實際上構(gòu)建了一個圖,如圖2-3所示。圖2-3與示例模型相對應(yīng)的簡化圖。實際上,每個節(jié)點都由更小的操作(例如矩陣乘法和加法)組成盡管非常簡單,但是此圖以操作的形式表示了模型的不同層。依賴圖有許多優(yōu)點,允許TensorFlow執(zhí)行以下操作:·在CPU上運行部分操作,在GPU上運行另一部分操作?!ぴ诜植际侥P偷那闆r下,在不同的機器上運行圖的不同部分?!?yōu)化圖以避免不必要的操作,從而獲得更好的計算性能。此外,圖的概念允許TensorFlow模型是可移植的。單個圖定義可以在任何類型的設(shè)備上運行。在TensorFlow2中,圖的創(chuàng)建不再由用戶處理。雖然在TensorFlow1中管理圖曾經(jīng)是一項復(fù)雜的任務(wù),但新版本大大提高了可用性,同時仍保持了性能。下一節(jié)將深入探討TensorFlow的內(nèi)部工作原理,并簡要地說明如何創(chuàng)建圖。延遲執(zhí)行和即時執(zhí)行比較TensorFlow2中的主要變化是即時執(zhí)行(eagerexecution)。歷史上,TensorFlow1在默認情況下總是使用延遲執(zhí)行(lazyexecution)。它之所以稱為延遲,是因為直到被明確請求,操作才由框架運行。我們用一個非常簡單的示例(即將兩個向量的值相加)來說明延遲執(zhí)行和即時執(zhí)行之間的區(qū)別:請注意,由于TensorFlow重載了許多Python操作符,因此tf.add(a,b)可以使用a+b代替。前面代碼的輸出取決于TensorFlow的版本。使用TensorFlow1(默認模式為延遲執(zhí)行)時,輸出為:但是,使用TensorFlow2(默認模式是即時執(zhí)行)時,將獲得以下輸出:
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 產(chǎn)教融合中的資源共享與優(yōu)勢互補策略
- 2025年婦產(chǎn)科工作計劃格式范例
- Unit1 My classroom(說課稿)-2024-2025學(xué)年人教PEP版英語四年級上冊
- 小學(xué)四年級下冊數(shù)學(xué)期末試卷分析
- 2025年生產(chǎn)主管的工作計劃
- Unit2 Different families Part A Letters and sounds(說課稿)-2024-2025學(xué)年人教PEP版(2024)英語三年級上冊
- 2025年法律援助中心工作計劃
- 2025年員工個人月工作總結(jié)與下月工作計劃
- 2025年小學(xué)一年級班主任工作計劃范文
- Unit7 Section B 2a-2c 說課稿-2024-2025學(xué)年人教新目標八年級英語下冊
- 2025版工業(yè)制造工程墊資建設(shè)合同2篇
- ISO 56001-2024《創(chuàng)新管理體系-要求》專業(yè)解讀與應(yīng)用實踐指導(dǎo)材料之4:4組織環(huán)境-4.2理解相關(guān)方的需求和期望(雷澤佳編制-2025B0)
- 2024年一級支行行長競聘演講稿例文(4篇)
- 健身房銷售人員培訓(xùn)
- 菌種保存管理
- 四年級數(shù)學(xué)(上)計算題專項練習(xí)及答案
- 廣東省廣州市2022-2023學(xué)年高二上學(xué)期期末考試化學(xué)試題
- 人教版-六年級上數(shù)學(xué)-扇形統(tǒng)計圖單元測試(含答案)
- 2023年題工會基礎(chǔ)知識試題及答案
- 期末測試卷(試題)-2024-2025學(xué)年四年級上冊數(shù)學(xué)滬教版
- 抗壓偏壓混凝土柱承載力計算表格
評論
0/150
提交評論