深度學(xué)習(xí)入門(mén)(基于Python的理論與實(shí)現(xiàn))_第1頁(yè)
深度學(xué)習(xí)入門(mén)(基于Python的理論與實(shí)現(xiàn))_第2頁(yè)
深度學(xué)習(xí)入門(mén)(基于Python的理論與實(shí)現(xiàn))_第3頁(yè)
深度學(xué)習(xí)入門(mén)(基于Python的理論與實(shí)現(xiàn))_第4頁(yè)
深度學(xué)習(xí)入門(mén)(基于Python的理論與實(shí)現(xiàn))_第5頁(yè)
已閱讀5頁(yè),還剩246頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

深度學(xué)習(xí)入門(mén)基于Python的理論與實(shí)現(xiàn)目錄\h第1章Python入門(mén)\h1.1Python是什么\h1.2Python的安裝\h1.2.1Python版本\h1.2.2使用的外部庫(kù)\h1.2.3Anaconda發(fā)行版\h1.3Python解釋器\h1.3.1算術(shù)計(jì)算\h1.3.2數(shù)據(jù)類型\h1.3.3變量\h1.3.4列表\h1.3.5字典\h1.3.6布爾型\h1.3.7if語(yǔ)句\h1.3.8for語(yǔ)句\h1.3.9函數(shù)\h1.4Python腳本文件\h1.4.1保存為文件\h1.4.2類\h1.5NumPy\h1.5.1導(dǎo)入NumPy\h1.5.2生成NumPy數(shù)組\h1.5.3NumPy的算術(shù)運(yùn)算\h1.5.4NumPy的N維數(shù)組\h1.5.5廣播\h1.5.6訪問(wèn)元素\h1.6Matplotlib\h1.6.1繪制簡(jiǎn)單圖形\h1.6.2pyplot的功能\h1.6.3顯示圖像\h1.7小結(jié)\h第2章感知機(jī)\h2.1感知機(jī)是什么\h2.2簡(jiǎn)單邏輯電路\h2.2.1與門(mén)\h2.2.2與非門(mén)和或門(mén)\h2.3感知機(jī)的實(shí)現(xiàn)\h2.3.1簡(jiǎn)單的實(shí)現(xiàn)\h2.3.2導(dǎo)入權(quán)重和偏置\h2.3.3使用權(quán)重和偏置的實(shí)現(xiàn)\h2.4感知機(jī)的局限性\h2.4.1異或門(mén)\h2.4.2線性和非線性\h2.5多層感知機(jī)\h2.5.1已有門(mén)電路的組合\h2.5.2異或門(mén)的實(shí)現(xiàn)\h2.6從與非門(mén)到計(jì)算機(jī)\h2.7小結(jié)\h第3章神經(jīng)網(wǎng)絡(luò)\h3.1從感知機(jī)到神經(jīng)網(wǎng)絡(luò)\h3.1.1神經(jīng)網(wǎng)絡(luò)的例子\h3.1.2復(fù)習(xí)感知機(jī)\h3.1.3激活函數(shù)登場(chǎng)\h3.2激活函數(shù)\h3.2.1sigmoid函數(shù)\h3.2.2階躍函數(shù)的實(shí)現(xiàn)\h3.2.3階躍函數(shù)的圖形\h3.2.4sigmoid函數(shù)的實(shí)現(xiàn)\h3.2.5sigmoid函數(shù)和階躍函數(shù)的比較\h3.2.6非線性函數(shù)\h3.2.7ReLU函數(shù)\h3.3多維數(shù)組的運(yùn)算\h3.3.1多維數(shù)組\h3.3.2矩陣乘法\h3.3.3神經(jīng)網(wǎng)絡(luò)的內(nèi)積\h3.43層神經(jīng)網(wǎng)絡(luò)的實(shí)現(xiàn)\h3.4.1符號(hào)確認(rèn)\h3.4.2各層間信號(hào)傳遞的實(shí)現(xiàn)\h3.4.3代碼實(shí)現(xiàn)小結(jié)\h3.5輸出層的設(shè)計(jì)\h3.5.1恒等函數(shù)和softmax函數(shù)\h3.5.2實(shí)現(xiàn)softmax函數(shù)時(shí)的注意事項(xiàng)\h3.5.3softmax函數(shù)的特征\h3.5.4輸出層的神經(jīng)元數(shù)量\h3.6手寫(xiě)數(shù)字識(shí)別\h3.6.1MNIST數(shù)據(jù)集\h3.6.2神經(jīng)網(wǎng)絡(luò)的推理處理\h3.6.3批處理\h3.7小結(jié)\h第4章神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)\h4.1從數(shù)據(jù)中學(xué)習(xí)\h4.1.1數(shù)據(jù)驅(qū)動(dòng)\h4.1.2訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù)\h4.2損失函數(shù)\h4.2.1均方誤差\h4.2.2交叉熵誤差\h4.2.3mini-batch學(xué)習(xí)\h4.2.4mini-batch版交叉熵誤差的實(shí)現(xiàn)\h4.2.5為何要設(shè)定損失函數(shù)\h4.3數(shù)值微分\h4.3.1導(dǎo)數(shù)\h4.3.2數(shù)值微分的例子\h4.3.3偏導(dǎo)數(shù)\h4.4梯度\h4.4.1梯度法\h4.4.2神經(jīng)網(wǎng)絡(luò)的梯度\h4.5學(xué)習(xí)算法的實(shí)現(xiàn)\h4.5.12層神經(jīng)網(wǎng)絡(luò)的類\h4.5.2mini-batch的實(shí)現(xiàn)\h4.5.3基于測(cè)試數(shù)據(jù)的評(píng)價(jià)\h4.6小結(jié)\h第5章誤差反向傳播法\h5.1計(jì)算圖\h5.1.1用計(jì)算圖求解\h5.1.2局部計(jì)算\h5.1.3為何用計(jì)算圖解題\h5.2鏈?zhǔn)椒▌t\h5.2.1計(jì)算圖的反向傳播\h5.2.2什么是鏈?zhǔn)椒▌t\h5.2.3鏈?zhǔn)椒▌t和計(jì)算圖\h5.3反向傳播\h5.3.1加法節(jié)點(diǎn)的反向傳播\h5.3.2乘法節(jié)點(diǎn)的反向傳播\h5.3.3蘋(píng)果的例子\h5.4簡(jiǎn)單層的實(shí)現(xiàn)\h5.4.1乘法層的實(shí)現(xiàn)\h5.4.2加法層的實(shí)現(xiàn)\h5.5激活函數(shù)層的實(shí)現(xiàn)\h5.5.1ReLU層\h5.5.2Sigmoid層\h5.6Affine/Softmax層的實(shí)現(xiàn)\h5.6.1Affine層\h5.6.2批版本的Affine層\h5.6.3Softmax-with-Loss層\h5.7誤差反向傳播法的實(shí)現(xiàn)\h5.7.1神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)的全貌圖\h5.7.2對(duì)應(yīng)誤差反向傳播法的神經(jīng)網(wǎng)絡(luò)的實(shí)現(xiàn)\h5.7.3誤差反向傳播法的梯度確認(rèn)\h5.7.4使用誤差反向傳播法的學(xué)習(xí)\h5.8小結(jié)\h第6章與學(xué)習(xí)相關(guān)的技巧\h6.1參數(shù)的更新\h6.1.1探險(xiǎn)家的故事\h6.1.2SGD\h6.1.3SGD的缺點(diǎn)\h6.1.4Momentum\h6.1.5AdaGrad\h6.1.6Adam\h6.1.7使用哪種更新方法呢\h6.1.8基于MNIST數(shù)據(jù)集的更新方法的比較\h6.2權(quán)重的初始值\h6.2.1可以將權(quán)重初始值設(shè)為0嗎\h6.2.2隱藏層的激活值的分布\h6.2.3ReLU的權(quán)重初始值\h6.2.4基于MNIST數(shù)據(jù)集的權(quán)重初始值的比較\h6.3BatchNormalization\h6.3.1BatchNormalization的算法\h6.3.2BatchNormalization的評(píng)估\h6.4正則化\h6.4.1過(guò)擬合\h6.4.2權(quán)值衰減\h6.4.3Dropout\h6.5超參數(shù)的驗(yàn)證\h6.5.1驗(yàn)證數(shù)據(jù)\h6.5.2超參數(shù)的最優(yōu)化\h6.5.3超參數(shù)最優(yōu)化的實(shí)現(xiàn)\h6.6小結(jié)\h第7章卷積神經(jīng)網(wǎng)絡(luò)\h7.1整體結(jié)構(gòu)\h7.2卷積層\h7.2.1全連接層存在的問(wèn)題\h7.2.2卷積運(yùn)算\h7.2.3填充\h7.2.4步幅\h7.2.53維數(shù)據(jù)的卷積運(yùn)算\h7.2.6結(jié)合方塊思考\h7.2.7批處理\h7.3池化層\h7.4卷積層和池化層的實(shí)現(xiàn)\h7.4.14維數(shù)組\h7.4.2基于im2col的展開(kāi)\h7.4.3卷積層的實(shí)現(xiàn)\h7.4.4池化層的實(shí)現(xiàn)\h7.5CNN的實(shí)現(xiàn)\h7.6CNN的可視化\h7.6.1第1層權(quán)重的可視化\h7.6.2基于分層結(jié)構(gòu)的信息提取\h7.7具有代表性的CNN\h7.7.1LeNet\h7.7.2AlexNet\h7.8小結(jié)\h第8章深度學(xué)習(xí)\h8.1加深網(wǎng)絡(luò)\h8.1.1向更深的網(wǎng)絡(luò)出發(fā)\h8.1.2進(jìn)一步提高識(shí)別精度\h8.1.3加深層的動(dòng)機(jī)\h8.2深度學(xué)習(xí)的小歷史\h8.2.1ImageNet\h8.2.2VGG\h8.2.3GoogLeNet\h8.2.4ResNet\h8.3深度學(xué)習(xí)的高速化\h8.3.1需要努力解決的問(wèn)題\h8.3.2基于GPU的高速化\h8.3.3分布式學(xué)習(xí)\h8.3.4運(yùn)算精度的位數(shù)縮減\h8.4深度學(xué)習(xí)的應(yīng)用案例\h8.4.1物體檢測(cè)\h8.4.2圖像分割\h8.4.3圖像標(biāo)題的生成\h8.5深度學(xué)習(xí)的未來(lái)\h8.5.1圖像風(fēng)格變換\h8.5.2圖像的生成\h8.5.3自動(dòng)駕駛\h8.5.4DeepQ-Network(強(qiáng)化學(xué)習(xí))\h8.6小結(jié)\h附錄ASoftmax-with-Loss層的計(jì)算圖\hA.1正向傳播\hA.2反向傳播\hA.3小結(jié)

注:原文檔電子版,非掃描,需要的請(qǐng)下載本文檔后留言謝謝。第1章Python入門(mén)Python這一編程語(yǔ)言已經(jīng)問(wèn)世20多年了,在這期間,Python不僅完成了自身的進(jìn)化,還獲得了大量的用戶。現(xiàn)在,Python作為最具人氣的編程語(yǔ)言,受到了許多人的喜愛(ài)。接下來(lái)我們將使用Python實(shí)現(xiàn)深度學(xué)習(xí)系統(tǒng)。不過(guò)在這之前,本章將簡(jiǎn)單地介紹一下Python,看一下它的使用方法。已經(jīng)掌握了Python、NumPy、Matplotlib等知識(shí)的讀者,可以跳過(guò)本章,直接閱讀后面的章節(jié)。1.1Python是什么Python是一個(gè)簡(jiǎn)單、易讀、易記的編程語(yǔ)言,而且是開(kāi)源的,可以免費(fèi)地自由使用。Python可以用類似英語(yǔ)的語(yǔ)法編寫(xiě)程序,編譯起來(lái)也不費(fèi)力,因此我們可以很輕松地使用Python。特別是對(duì)首次接觸編程的人士來(lái)說(shuō),Python是最合適不過(guò)的語(yǔ)言。事實(shí)上,很多高校和大專院校的計(jì)算機(jī)課程均采用Python作為入門(mén)語(yǔ)言。此外,使用Python不僅可以寫(xiě)出可讀性高的代碼,還可以寫(xiě)出性能高(處理速度快)的代碼。在需要處理大規(guī)模數(shù)據(jù)或者要求快速響應(yīng)的情況下,使用Python可以穩(wěn)妥地完成。因此,Python不僅受到初學(xué)者的喜愛(ài),同時(shí)也受到專業(yè)人士的喜愛(ài)。實(shí)際上,Google、Microsoft、Facebook等戰(zhàn)斗在IT行業(yè)最前沿的企業(yè)也經(jīng)常使用Python。再者,在科學(xué)領(lǐng)域,特別是在機(jī)器學(xué)習(xí)、數(shù)據(jù)科學(xué)領(lǐng)域,Python也被大量使用。Python除了高性能之外,憑借著NumPy、SciPy等優(yōu)秀的數(shù)值計(jì)算、統(tǒng)計(jì)分析庫(kù),在數(shù)據(jù)科學(xué)領(lǐng)域占有不可動(dòng)搖的地位。深度學(xué)習(xí)的框架中也有很多使用Python的場(chǎng)景,比如Caffe、TensorFlow、Chainer、Theano等著名的深度學(xué)習(xí)框架都提供了Python接口。因此,學(xué)習(xí)Python對(duì)使用深度學(xué)習(xí)框架大有益處。綜上,Python是最適合數(shù)據(jù)科學(xué)領(lǐng)域的編程語(yǔ)言。而且,Python具有受眾廣的優(yōu)秀品質(zhì),從初學(xué)者到專業(yè)人士都在使用。因此,為了完成本書(shū)的從零開(kāi)始實(shí)現(xiàn)深度學(xué)習(xí)的目標(biāo),Python可以說(shuō)是最合適的工具。1.2Python的安裝下面,我們首先將Python安裝到當(dāng)前環(huán)境(電腦)上。這里說(shuō)明一下安裝時(shí)需要注意的一些地方。1.2.1Python版本Python有Python2.x和Python3.x兩個(gè)版本。如果我們調(diào)查一下目前Python的使用情況,會(huì)發(fā)現(xiàn)除了最新的版本3.x以外,舊的版本2.x仍在被大量使用。因此,在安裝Python時(shí),需要慎重選擇安裝Python的哪個(gè)版本。這是因?yàn)閮蓚€(gè)版本之間沒(méi)有兼容性(嚴(yán)格地講,是沒(méi)有“向后兼容性”),也就是說(shuō),會(huì)發(fā)生用Python3.x寫(xiě)的代碼不能被Python2.x執(zhí)行的情況。本書(shū)中使用Python3.x,只安裝了Python2.x的讀者建議另外安裝一下Python3.x。1.2.2使用的外部庫(kù)本書(shū)的目標(biāo)是從零開(kāi)始實(shí)現(xiàn)深度學(xué)習(xí)。因此,除了NumPy庫(kù)和Matplotlib庫(kù)之外,我們極力避免使用外部庫(kù)。之所以使用這兩個(gè)庫(kù),是因?yàn)樗鼈兛梢杂行У卮龠M(jìn)深度學(xué)習(xí)的實(shí)現(xiàn)。NumPy是用于數(shù)值計(jì)算的庫(kù),提供了很多高級(jí)的數(shù)學(xué)算法和便利的數(shù)組(矩陣)操作方法。本書(shū)中將使用這些便利的方法來(lái)有效地促進(jìn)深度學(xué)習(xí)的實(shí)現(xiàn)。Matplotlib是用來(lái)畫(huà)圖的庫(kù)。使用Matplotlib能將實(shí)驗(yàn)結(jié)果可視化,并在視覺(jué)上確認(rèn)深度學(xué)習(xí)運(yùn)行期間的數(shù)據(jù)。本書(shū)將使用下列編程語(yǔ)言和庫(kù)。Python3.x(2016年8月時(shí)的最新版本是3.5)NumPyMatplotlib下面將為需要安裝Python的讀者介紹一下Python的安裝方法。已經(jīng)安裝了Python的讀者,請(qǐng)?zhí)^(guò)這一部分內(nèi)容。1.2.3Anaconda發(fā)行版Python的安裝方法有很多種,本書(shū)推薦使用Anaconda這個(gè)發(fā)行版。發(fā)行版集成了必要的庫(kù),使用戶可以一次性完成安裝。Anaconda是一個(gè)側(cè)重于數(shù)據(jù)分析的發(fā)行版,前面說(shuō)的NumPy、Matplotlib等有助于數(shù)據(jù)分析的庫(kù)都包含在其中1。1Anaconda作為一個(gè)針對(duì)數(shù)據(jù)分析的發(fā)行版,包含了許多有用的庫(kù),而本書(shū)中實(shí)際上只會(huì)使用其中的NumPy庫(kù)和Matplotlib庫(kù)。因此,如果想保持輕量級(jí)的開(kāi)發(fā)環(huán)境,單獨(dú)安裝這兩個(gè)庫(kù)也是可以的?!g者注如前所述,本書(shū)將使用Python3.x版本,因此Anaconda發(fā)行版也要安裝3.x的版本。請(qǐng)讀者從官方網(wǎng)站下載與自己的操作系統(tǒng)相應(yīng)的發(fā)行版,然后安裝。1.3Python解釋器完成Python的安裝后,要先確認(rèn)一下Python的版本。打開(kāi)終端(Windows中的命令行窗口),輸入python--version命令,該命令會(huì)輸出已經(jīng)安裝的Python的版本信息。

$

python--version

Python3.4.1::Anaconda2.1.0(x86_64)

如上所示,顯示了Python3.4.1(根據(jù)實(shí)際安裝的版本,版本號(hào)可能不同),說(shuō)明已正確安裝了Python3.x。接著輸入python,啟動(dòng)Python解釋器。

$

python

Python3.4.1|Anaconda2.1.0(x86_64)|(default,Sep102014,17:24:09)

[GCC4.2.1(AppleInc.build5577)]ondarwin

Type"help","copyright","credits"or"license"formoreinformation.

>>>

Python解釋器也被稱為“對(duì)話模式”,用戶能夠以和Python對(duì)話的方式進(jìn)行編程。比如,當(dāng)用戶詢問(wèn)“1+2等于幾?”的時(shí)候,Python解釋器會(huì)回答“3”,所謂對(duì)話模式,就是指這樣的交互?,F(xiàn)在,我們實(shí)際輸入一下看看。

>>>

1+2

3

Python解釋器可以像這樣進(jìn)行對(duì)話式(交互式)的編程。下面,我們使用這個(gè)對(duì)話模式,來(lái)看幾個(gè)簡(jiǎn)單的Python編程的例子。1.3.1算術(shù)計(jì)算加法或乘法等算術(shù)計(jì)算,可按如下方式進(jìn)行。

>>>

1-2

-1

>>>

4*5

20

>>>

7/5

1.4

>>>

3**2

9

*表示乘法,/表示除法,**表示乘方(3**2是3的2次方)。另外,在Python2.x中,整數(shù)除以整數(shù)的結(jié)果是整數(shù),比如,7÷5的結(jié)果是1。但在Python3.x中,整數(shù)除以整數(shù)的結(jié)果是小數(shù)(浮點(diǎn)數(shù))。1.3.2數(shù)據(jù)類型編程中有數(shù)據(jù)類型(datatype)這一概念。數(shù)據(jù)類型表示數(shù)據(jù)的性質(zhì),有整數(shù)、小數(shù)、字符串等類型。Python中的type()函數(shù)可以用來(lái)查看數(shù)據(jù)類型。

>>>

type(10)

<class'int'>

>>>

type(2.718)

<class'float'>

>>>

type("hello")

<class'str'>

根據(jù)上面的結(jié)果可知,10是int類型(整型),2.718是float類型(浮點(diǎn)型),"hello"是str(字符串)類型。另外,“類型”和“類”這兩個(gè)詞有時(shí)用作相同的意思。這里,對(duì)于輸出結(jié)果<class'int'>,可以將其解釋成“10是int類(類型)”。1.3.3變量可以使用x或y等字母定義變量(variable)。此外,可以使用變量進(jìn)行計(jì)算,也可以對(duì)變量賦值。

>>>

x=10

#初始化

>>>

print(x)

#輸出x

10

>>>

x=100

#賦值

>>>

print(x)

100

>>>

y=3.14

>>>

x*y

314.0

>>>

type(x*y)

<class'float'>

Python是屬于“動(dòng)態(tài)類型語(yǔ)言”的編程語(yǔ)言,所謂動(dòng)態(tài),是指變量的類型是根據(jù)情況自動(dòng)決定的。在上面的例子中,用戶并沒(méi)有明確指出“x的類型是int(整型)”,是Python根據(jù)x被初始化為10,從而判斷出x的類型為int的。此外,我們也可以看到,整數(shù)和小數(shù)相乘的結(jié)果是小數(shù)(數(shù)據(jù)類型的自動(dòng)轉(zhuǎn)換)。另外,“#”是注釋的意思,它后面的文字會(huì)被Python忽略。1.3.4列表除了單一的數(shù)值,還可以用列表(數(shù)組)匯總數(shù)據(jù)。

>>>

a=[1,2,3,4,5]

#生成列表

>>>

print(a)

#輸出列表的內(nèi)容

[1,2,3,4,5]

>>>

len(a)

#獲取列表的長(zhǎng)度

5

>>>

a[0]

#訪問(wèn)第一個(gè)元素的值

1

>>>

a[4]

5

>>>

a[4]=99

#賦值

>>>

print(a)

[1,2,3,4,99]

元素的訪問(wèn)是通過(guò)a[0]這樣的方式進(jìn)行的。[]中的數(shù)字稱為索引(下標(biāo)),索引從0開(kāi)始(索引0對(duì)應(yīng)第一個(gè)元素)。此外,Python的列表提供了切片(slicing)這一便捷的標(biāo)記法。使用切片不僅可以訪問(wèn)某個(gè)值,還可以訪問(wèn)列表的子列表(部分列表)。

>>>

print(a)

[1,2,3,4,99]

>>>

a[0:2]

#獲取索引為0到2(不包括2?。┑脑?/p>

[1,2]

>>>

a[1:]

#獲取從索引為1的元素到最后一個(gè)元素

[2,3,4,99]

>>>

a[:3]

#獲取從第一個(gè)元素到索引為3(不包括3!)的元素

[1,2,3]

>>>

a[:-1]

#獲取從第一個(gè)元素到最后一個(gè)元素的前一個(gè)元素之間的元素

[1,2,3,4]

>>>

a[:-2]

#獲取從第一個(gè)元素到最后一個(gè)元素的前二個(gè)元素之間的元素

[1,2,3]

進(jìn)行列表的切片時(shí),需要寫(xiě)成a[0:2]這樣的形式。a[0:2]用于取出從索引為0的元素到索引為2的元素的前一個(gè)元素之間的元素。另外,索引-1對(duì)應(yīng)最后一個(gè)元素,-2對(duì)應(yīng)最后一個(gè)元素的前一個(gè)元素。1.3.5字典列表根據(jù)索引,按照0,1,2,...的順序存儲(chǔ)值,而字典則以鍵值對(duì)的形式存儲(chǔ)數(shù)據(jù)。字典就像《新華字典》那樣,將單詞和它的含義對(duì)應(yīng)著存儲(chǔ)起來(lái)。

>>>

me={'height':180}

#生成字典

>>>

me['height']

#訪問(wèn)元素

180

>>>

me['weight']=70

#添加新元素

>>>

print(me)

{'height':180,'weight':70}

1.3.6布爾型Python中有bool型。bool型取True或False中的一個(gè)值。針對(duì)bool型的運(yùn)算符包括and、or和not(針對(duì)數(shù)值的運(yùn)算符有+、-、*、/等,根據(jù)不同的數(shù)據(jù)類型使用不同的運(yùn)算符)。

>>>

hungry=True

#餓了?

>>>

sleepy=False

#困了?

>>>

type(hungry)

<class'bool'>

>>>

nothungry

False

>>>

hungryandsleepy

#餓并且困

False

>>>

hungryorsleepy

#餓或者困

True

1.3.7if語(yǔ)句根據(jù)不同的條件選擇不同的處理分支時(shí)可以使用if/else語(yǔ)句。

>>>

hungry=True

>>>

ifhungry:

...

print("I'mhungry")

...

I'mhungry

>>>

hungry=False

>>>

ifhungry:

...

print("I'mhungry")

#使用空白字符進(jìn)行縮進(jìn)

...

else:

...

print("I'mnothungry")

...

print("I'msleepy")

...

I'mnothungry

I'msleepy

Python中的空白字符具有重要的意義。上面的if語(yǔ)句中,ifhungry:下面的語(yǔ)句開(kāi)頭有4個(gè)空白字符。它是縮進(jìn)的意思,表示當(dāng)前面的條件(ifhungry)成立時(shí),此處的代碼會(huì)被執(zhí)行。這個(gè)縮進(jìn)也可以用tab表示,Python中推薦使用空白字符。Python使用空白字符表示縮進(jìn)。一般而言,每縮進(jìn)一次,使用4個(gè)空白字符。1.3.8for語(yǔ)句進(jìn)行循環(huán)處理時(shí)可以使用for語(yǔ)句。

>>>

foriin[1,2,3]:

...

print(i)

...

1

2

3

這是輸出列表[1,2,3]中的元素的例子。使用for…in…:語(yǔ)句結(jié)構(gòu),可以按順序訪問(wèn)列表等數(shù)據(jù)集合中的各個(gè)元素。1.3.9函數(shù)可以將一連串的處理定義成函數(shù)(function)。

>>>

defhello():

...

print("HelloWorld!")

...

>>>

hello()

HelloWorld!

此外,函數(shù)可以取參數(shù)。

>>>

defhello(object):

...

print("Hello"+object+"!")

...

>>>

hello("cat")

Hellocat!

另外,字符串的拼接可以使用+。關(guān)閉Python解釋器時(shí),Linux或MacOSX的情況下輸入Ctrl-D(按住Ctrl,再按D鍵);Windows的情況下輸入Ctrl-Z,然后按Enter鍵。1.4Python腳本文件到目前為止,我們看到的都是基于Python解釋器的例子。Python解釋器能夠以對(duì)話模式執(zhí)行程序,非常便于進(jìn)行簡(jiǎn)單的實(shí)驗(yàn)。但是,想進(jìn)行一連串的處理時(shí),因?yàn)槊看味夹枰斎氤绦颍圆惶奖?。這時(shí),可以將Python程序保存為文件,然后(集中地)運(yùn)行這個(gè)文件。下面,我們來(lái)看一個(gè)Python腳本文件的例子。1.4.1保存為文件打開(kāi)文本編輯器,新建一個(gè)hungry.py的文件。hungry.py只包含下面一行語(yǔ)句。print("I'mhungry!")

接著,打開(kāi)終端(Windows中的命令行窗口),移至hungry.py所在的位置。然后,將hungry.py文件名作為參數(shù),運(yùn)行python命令。這里假設(shè)hungry.py在~/deep-learning-from-scratch/ch01目錄下(在本書(shū)提供的源代碼中,hungry.py文件位于ch01目錄下)。

$

cd~/deep-learning-from-scratch/ch01

#移動(dòng)目錄

$

pythonhungry.py

I'mhungry!

這樣,使用pythonhungry.py命令就可以執(zhí)行這個(gè)Python程序了。1.4.2類前面我們了解了int和str等數(shù)據(jù)類型(通過(guò)type()函數(shù)可以查看對(duì)象的類型)。這些數(shù)據(jù)類型是“內(nèi)置”的數(shù)據(jù)類型,是Python中一開(kāi)始就有的數(shù)據(jù)類型?,F(xiàn)在,我們來(lái)定義新的類。如果用戶自己定義類的話,就可以自己創(chuàng)建數(shù)據(jù)類型。此外,也可以定義原創(chuàng)的方法(類的函數(shù))和屬性。Python中使用class關(guān)鍵字來(lái)定義類,類要遵循下述格式(模板)。class類名:

def__init__(self,參數(shù),…):#構(gòu)造函數(shù)

...

def方法名1(self,參數(shù),…):#方法1

...

def方法名2(self,參數(shù),…):#方法2

...

這里有一個(gè)特殊的init方法,這是進(jìn)行初始化的方法,也稱為構(gòu)造函數(shù)(constructor),只在生成類的實(shí)例時(shí)被調(diào)用一次。此外,在方法的第一個(gè)參數(shù)中明確地寫(xiě)入表示自身(自身的實(shí)例)的self是Python的一個(gè)特點(diǎn)(學(xué)過(guò)其他編程語(yǔ)言的人可能會(huì)覺(jué)得這種寫(xiě)self的方式有一點(diǎn)奇怪)。下面我們通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)創(chuàng)建一個(gè)類。這里將下面的程序保存為man.py。classMan:

def__init__(self,name):

=name

print("Initialized!")

defhello(self):

print("Hello"++"!")

defgoodbye(self):

print("Good-bye"++"!")

m=Man("David")

m.hello()

m.goodbye()

從終端運(yùn)行man.py。

$

pythonman.py

Initialized!

HelloDavid!

Good-byeDavid!

這里我們定義了一個(gè)新類Man。上面的例子中,類Man生成了實(shí)例(對(duì)象)m。類Man的構(gòu)造函數(shù)(初始化方法)會(huì)接收參數(shù)name,然后用這個(gè)參數(shù)初始化實(shí)例變量。實(shí)例變量是存儲(chǔ)在各個(gè)實(shí)例中的變量。Python中可以像這樣,通過(guò)在self后面添加屬性名來(lái)生成或訪問(wèn)實(shí)例變量。1.5NumPy在深度學(xué)習(xí)的實(shí)現(xiàn)中,經(jīng)常出現(xiàn)數(shù)組和矩陣的計(jì)算。NumPy的數(shù)組類(numpy.array)中提供了很多便捷的方法,在實(shí)現(xiàn)深度學(xué)習(xí)時(shí),我們將使用這些方法。本節(jié)我們來(lái)簡(jiǎn)單介紹一下后面會(huì)用到的NumPy。1.5.1導(dǎo)入NumPyNumPy是外部庫(kù)。這里所說(shuō)的“外部”是指不包含在標(biāo)準(zhǔn)版Python中。因此,我們首先要導(dǎo)入NumPy庫(kù)。

>>>

importnumpyasnp

Python中使用import語(yǔ)句來(lái)導(dǎo)入庫(kù)。這里的importnumpyasnp,直譯的話就是“將numpy作為np導(dǎo)入”的意思。通過(guò)寫(xiě)成這樣的形式,之后NumPy相關(guān)的方法均可通過(guò)np來(lái)調(diào)用。1.5.2生成NumPy數(shù)組要生成NumPy數(shù)組,需要使用np.array()方法。np.array()接收Python列表作為參數(shù),生成NumPy數(shù)組(numpy.ndarray)。

>>>

x=np.array([1.0,2.0,3.0])

>>>

print(x)

[1.2.3.]

>>>

type(x)

<class'numpy.ndarray'>

1.5.3NumPy的算術(shù)運(yùn)算下面是NumPy數(shù)組的算術(shù)運(yùn)算的例子。

>>>

x=np.array([1.0,2.0,3.0])

>>>

y=np.array([2.0,4.0,6.0])

>>>

x+y

#對(duì)應(yīng)元素的加法

array([3.,6.,9.])

>>>

x-y

array([-1.,-2.,-3.])

>>>

x*y

#element-wiseproduct

array([2.,8.,18.])

>>>

x/y

array([0.5,0.5,0.5])

這里需要注意的是,數(shù)組x和數(shù)組y的元素個(gè)數(shù)是相同的(兩者均是元素個(gè)數(shù)為3的一維數(shù)組)。當(dāng)x和y的元素個(gè)數(shù)相同時(shí),可以對(duì)各個(gè)元素進(jìn)行算術(shù)運(yùn)算。如果元素個(gè)數(shù)不同,程序就會(huì)報(bào)錯(cuò),所以元素個(gè)數(shù)保持一致非常重要。另外,“對(duì)應(yīng)元素的”的英文是element-wise,比如“對(duì)應(yīng)元素的乘法”就是element-wiseproduct。NumPy數(shù)組不僅可以進(jìn)行element-wise運(yùn)算,也可以和單一的數(shù)值(標(biāo)量)組合起來(lái)進(jìn)行運(yùn)算。此時(shí),需要在NumPy數(shù)組的各個(gè)元素和標(biāo)量之間進(jìn)行運(yùn)算。這個(gè)功能也被稱為廣播(詳見(jiàn)后文)。

>>>

x=np.array([1.0,2.0,3.0])

>>>

x/2.0

array([0.5,1.,1.5])

1.5.4NumPy的N維數(shù)組NumPy不僅可以生成一維數(shù)組(排成一列的數(shù)組),也可以生成多維數(shù)組。比如,可以生成如下的二維數(shù)組(矩陣)。

>>>

A=np.array([[1,2],[3,4]])

>>>

print(A)

[[12]

[34]]

>>>

A.shape

(2,2)

>>>

A.dtype

dtype('int64')

這里生成了一個(gè)2×2的矩陣A。另外,矩陣A的形狀可以通過(guò)shape查看,矩陣元素的數(shù)據(jù)類型可以通過(guò)dtype查看。下面,我們來(lái)看一下矩陣的算術(shù)運(yùn)算。

>>>

B=np.array([[3,0],[0,6]])

>>>

A+B

array([[4,2],

[3,10]])

>>>

A*B

array([[3,0],

[0,24]])

和數(shù)組的算術(shù)運(yùn)算一樣,矩陣的算術(shù)運(yùn)算也可以在相同形狀的矩陣間以對(duì)應(yīng)元素的方式進(jìn)行。并且,也可以通過(guò)標(biāo)量(單一數(shù)值)對(duì)矩陣進(jìn)行算術(shù)運(yùn)算。這也是基于廣播的功能。

>>>

print(A)

[[12]

[34]]

>>>

A*10

array([[10,20],

[30,40]])

NumPy數(shù)組(np.array)可以生成N維數(shù)組,即可以生成一維數(shù)組、二維數(shù)組、三維數(shù)組等任意維數(shù)的數(shù)組。數(shù)學(xué)上將一維數(shù)組稱為向量,將二維數(shù)組稱為矩陣。另外,可以將一般化之后的向量或矩陣等統(tǒng)稱為張量(tensor)。本書(shū)基本上將二維數(shù)組稱為“矩陣”,將三維數(shù)組及三維以上的數(shù)組稱為“張量”或“多維數(shù)組”。1.5.5廣播NumPy中,形狀不同的數(shù)組之間也可以進(jìn)行運(yùn)算。之前的例子中,在2×2的矩陣A和標(biāo)量10之間進(jìn)行了乘法運(yùn)算。在這個(gè)過(guò)程中,如圖1-1所示,標(biāo)量10被擴(kuò)展成了2×2的形狀,然后再與矩陣A進(jìn)行乘法運(yùn)算。這個(gè)巧妙的功能稱為廣播(broadcast)。圖1-1廣播的例子:標(biāo)量10被當(dāng)作2×2的矩陣我們通過(guò)下面這個(gè)運(yùn)算再來(lái)看一個(gè)廣播的例子。

>>>

A=np.array([[1,2],[3,4]])

>>>

B=np.array([10,20])

>>>

A*B

array([[10,40],

[30,80]])

在這個(gè)運(yùn)算中,如圖1-2所示,一維數(shù)組B被“巧妙地”變成了和二位數(shù)組A相同的形狀,然后再以對(duì)應(yīng)元素的方式進(jìn)行運(yùn)算。圖1-2廣播的例子2綜上,因?yàn)镹umPy有廣播功能,所以不同形狀的數(shù)組之間也可以順利地進(jìn)行運(yùn)算。1.5.6訪問(wèn)元素元素的索引從0開(kāi)始。對(duì)各個(gè)元素的訪問(wèn)可按如下方式進(jìn)行。

>>>

X=np.array([[51,55],[14,19],[0,4]])

>>>

print(X)

[[5155]

[1419]

[04]]

>>>

X[0]

#第0行

array([51,55])

>>>

X[0][1]

#(0,1)的元素

55

也可以使用for語(yǔ)句訪問(wèn)各個(gè)元素。

>>>

forrowinX:

...

print(row)

...

[5155]

[1419]

[04]

除了前面介紹的索引操作,NumPy還可以使用數(shù)組訪問(wèn)各個(gè)元素。

>>>

X=X.flatten()

#將X轉(zhuǎn)換為一維數(shù)組

>>>

print(X)

[5155141904]

>>>

X[np.array([0,2,4])]

#獲取索引為0、2、4的元素

array([51,14,0])

運(yùn)用這個(gè)標(biāo)記法,可以獲取滿足一定條件的元素。例如,要從X中抽出大于15的元素,可以寫(xiě)成如下形式。

>>>

X>15

array([True,True,False,True,False,False],dtype=bool)

>>>

X[X>15]

array([51,55,19])

對(duì)NumPy數(shù)組使用不等號(hào)運(yùn)算符等(上例中是X>15),結(jié)果會(huì)得到一個(gè)布爾型的數(shù)組。上例中就是使用這個(gè)布爾型數(shù)組取出了數(shù)組的各個(gè)元素(取出True對(duì)應(yīng)的元素)。Python等動(dòng)態(tài)類型語(yǔ)言一般比C和C++等靜態(tài)類型語(yǔ)言(編譯型語(yǔ)言)運(yùn)算速度慢。實(shí)際上,如果是運(yùn)算量大的處理對(duì)象,用C/C++寫(xiě)程序更好。為此,當(dāng)Python中追求性能時(shí),人們會(huì)用C/C++來(lái)實(shí)現(xiàn)處理的內(nèi)容。Python則承擔(dān)“中間人”的角色,負(fù)責(zé)調(diào)用那些用C/C++寫(xiě)的程序。NumPy中,主要的處理也都是通過(guò)C或C++實(shí)現(xiàn)的。因此,我們可以在不損失性能的情況下,使用Python便利的語(yǔ)法。1.6Matplotlib在深度學(xué)習(xí)的實(shí)驗(yàn)中,圖形的繪制和數(shù)據(jù)的可視化非常重要。Matplotlib是用于繪制圖形的庫(kù),使用Matplotlib可以輕松地繪制圖形和實(shí)現(xiàn)數(shù)據(jù)的可視化。這里,我們來(lái)介紹一下圖形的繪制方法和圖像的顯示方法。1.6.1繪制簡(jiǎn)單圖形可以使用matplotlib的pyplot模塊繪制圖形。話不多說(shuō),我們來(lái)看一個(gè)繪制sin函數(shù)曲線的例子。importnumpyasnp

importmatplotlib.pyplotasplt

#生成數(shù)據(jù)

x=np.arange(0,6,0.1)#以0.1為單位,生成0到6的數(shù)據(jù)

y=np.sin(x)

#繪制圖形

plt.plot(x,y)

plt.show()

這里使用NumPy的arange方法生成了[0,0.1,0.2,…,5.8,5.9]的數(shù)據(jù),將其設(shè)為x。對(duì)x的各個(gè)元素,應(yīng)用NumPy的sin函數(shù)np.sin(),將x、y的數(shù)據(jù)傳給plt.plot方法,然后繪制圖形。最后,通過(guò)plt.show()顯示圖形。運(yùn)行上述代碼后,就會(huì)顯示圖1-3所示的圖形。圖1-3sin函數(shù)的圖形1.6.2pyplot的功能在剛才的sin函數(shù)的圖形中,我們嘗試追加cos函數(shù)的圖形,并嘗試使用pyplot的添加標(biāo)題和x軸標(biāo)簽名等其他功能。importnumpyasnp

importmatplotlib.pyplotasplt

#生成數(shù)據(jù)

x=np.arange(0,6,0.1)#以0.1為單位,生成0到6的數(shù)據(jù)

y1=np.sin(x)

y2=np.cos(x)

#繪制圖形

plt.plot(x,y1,label="sin")

plt.plot(x,y2,linestyle="--",label="cos")#用虛線繪制

plt.xlabel("x")#x軸標(biāo)簽

plt.ylabel("y")#y軸標(biāo)簽

plt.title('sin&cos')#標(biāo)題

plt.legend()

plt.show()

結(jié)果如圖1-4所示,我們看到圖的標(biāo)題、軸的標(biāo)簽名都被標(biāo)出來(lái)了。圖1-4sin函數(shù)和cos函數(shù)的圖形1.6.3顯示圖像pyplot中還提供了用于顯示圖像的方法imshow()。另外,可以使用matplotlib.image模塊的imread()方法讀入圖像。下面我們來(lái)看一個(gè)例子。importmatplotlib.pyplotasplt

frommatplotlib.imageimportimread

img=imread('lena.png')#讀入圖像(設(shè)定合適的路徑!)

plt.imshow(img)

plt.show()

運(yùn)行上述代碼后,會(huì)顯示圖1-5所示的圖像。圖1-5顯示圖像這里,我們假定圖像lena.png在當(dāng)前目錄下。讀者根據(jù)自己的環(huán)境,可能需要變更文件名或文件路徑。另外,本書(shū)提供的源代碼中,在dataset目錄下有樣本圖像lena.png。比如,在通過(guò)Python解釋器從ch01目錄運(yùn)行上述代碼的情況下,將圖像的路徑'lena.png'改為'../dataset/lena.png',即可正確運(yùn)行。1.7小結(jié)本章重點(diǎn)介紹了實(shí)現(xiàn)深度學(xué)習(xí)(神經(jīng)網(wǎng)絡(luò))所需的編程知識(shí),以為學(xué)習(xí)深度學(xué)習(xí)做好準(zhǔn)備。從下一章開(kāi)始,我們將通過(guò)使用Python實(shí)際運(yùn)行代碼,逐步了解深度學(xué)習(xí)。本章只介紹了關(guān)于Python的最低限度的知識(shí),想進(jìn)一步了解Python的讀者,可以參考下面這些圖書(shū)。首先推薦《Python語(yǔ)言及其應(yīng)用》[1]一書(shū)。這是一本詳細(xì)介紹從Python編程的基礎(chǔ)到應(yīng)用的實(shí)踐性的入門(mén)書(shū)。關(guān)于NumPy,《利用Python進(jìn)行數(shù)據(jù)分析》[2]一書(shū)中進(jìn)行了簡(jiǎn)單易懂的總結(jié)。此外,“ScipyLectureNotes”[3]這個(gè)網(wǎng)站上也有以科學(xué)計(jì)算為主題的NumPy和Matplotlib的詳細(xì)介紹,有興趣的讀者可以參考。下面,我們來(lái)總結(jié)一下本章所學(xué)的內(nèi)容,如下所示。本章所學(xué)的內(nèi)容Python是一種簡(jiǎn)單易記的編程語(yǔ)言。Python是開(kāi)源的,可以自由使用。本書(shū)中將使用Python3.x實(shí)現(xiàn)深度學(xué)習(xí)。本書(shū)中將使用NumPy和Matplotlib這兩種外部庫(kù)。Python有“解釋器”和“腳本文件”兩種運(yùn)行模式。Python能夠?qū)⒁幌盗刑幚砑蔀楹瘮?shù)或類等模塊。NumPy中有很多用于操作多維數(shù)組的便捷方法。

第2章感知機(jī)本章將介紹感知機(jī)1(perceptron)這一算法。感知機(jī)是由美國(guó)學(xué)者FrankRosenblatt在1957年提出來(lái)的。為何我們現(xiàn)在還要學(xué)習(xí)這一很久以前就有的算法呢?因?yàn)楦兄獧C(jī)也是作為神經(jīng)網(wǎng)絡(luò)(深度學(xué)習(xí))的起源的算法。因此,學(xué)習(xí)感知機(jī)的構(gòu)造也就是學(xué)習(xí)通向神經(jīng)網(wǎng)絡(luò)和深度學(xué)習(xí)的一種重要思想。1嚴(yán)格地講,本章中所說(shuō)的感知機(jī)應(yīng)該稱為“人工神經(jīng)元”或“樸素感知機(jī)”,但是因?yàn)楹芏嗷镜奶幚矶际枪餐ǖ模赃@里就簡(jiǎn)單地稱為“感知機(jī)”。本章我們將簡(jiǎn)單介紹一下感知機(jī),并用感知機(jī)解決一些簡(jiǎn)單的問(wèn)題。希望讀者通過(guò)這個(gè)過(guò)程能熟悉感知機(jī)。2.1感知機(jī)是什么感知機(jī)接收多個(gè)輸入信號(hào),輸出一個(gè)信號(hào)。這里所說(shuō)的“信號(hào)”可以想象成電流或河流那樣具備“流動(dòng)性”的東西。像電流流過(guò)導(dǎo)線,向前方輸送電子一樣,感知機(jī)的信號(hào)也會(huì)形成流,向前方輸送信息。但是,和實(shí)際的電流不同的是,感知機(jī)的信號(hào)只有“流/不流”(1/0)兩種取值。在本書(shū)中,0對(duì)應(yīng)“不傳遞信號(hào)”,1對(duì)應(yīng)“傳遞信號(hào)”。圖2-1是一個(gè)接收兩個(gè)輸入信號(hào)的感知機(jī)的例子。、是輸入信號(hào),y是輸出信號(hào),、是權(quán)重(w是weight的首字母)。圖中的○稱為“神經(jīng)元”或者“節(jié)點(diǎn)”。輸入信號(hào)被送往神經(jīng)元時(shí),會(huì)被分別乘以固定的權(quán)重(、)。神經(jīng)元會(huì)計(jì)算傳送過(guò)來(lái)的信號(hào)的總和,只有當(dāng)這個(gè)總和超過(guò)了某個(gè)界限值時(shí),才會(huì)輸出1。這也稱為“神經(jīng)元被激活”。這里將這個(gè)界限值稱為閾值,用符號(hào)θ表示。圖2-1有兩個(gè)輸入的感知機(jī)感知機(jī)的運(yùn)行原理只有這些!把上述內(nèi)容用數(shù)學(xué)式來(lái)表示,就是式(2.1)。感知機(jī)的多個(gè)輸入信號(hào)都有各自固有的權(quán)重,這些權(quán)重發(fā)揮著控制各個(gè)信號(hào)的重要性的作用。也就是說(shuō),權(quán)重越大,對(duì)應(yīng)該權(quán)重的信號(hào)的重要性就越高。權(quán)重相當(dāng)于電流里所說(shuō)的電阻。電阻是決定電流流動(dòng)難度的參數(shù),電阻越低,通過(guò)的電流就越大。而感知機(jī)的權(quán)重則是值越大,通過(guò)的信號(hào)就越大。不管是電阻還是權(quán)重,在控制信號(hào)流動(dòng)難度(或者流動(dòng)容易度)這一點(diǎn)上的作用都是一樣的。2.2簡(jiǎn)單邏輯電路2.2.1與門(mén)現(xiàn)在讓我們考慮用感知機(jī)來(lái)解決簡(jiǎn)單的問(wèn)題。這里首先以邏輯電路為題材來(lái)思考一下與門(mén)(ANDgate)。與門(mén)是有兩個(gè)輸入和一個(gè)輸出的門(mén)電路。圖2-2這種輸入信號(hào)和輸出信號(hào)的對(duì)應(yīng)表稱為“真值表”。如圖2-2所示,與門(mén)僅在兩個(gè)輸入均為1時(shí)輸出1,其他時(shí)候則輸出0。圖2-2與門(mén)的真值表下面考慮用感知機(jī)來(lái)表示這個(gè)與門(mén)。需要做的就是確定能滿足圖2-2的真值表的、、θ的值。那么,設(shè)定什么樣的值才能制作出滿足圖2-2的條件的感知機(jī)呢?實(shí)際上,滿足圖2-2的條件的參數(shù)的選擇方法有無(wú)數(shù)多個(gè)。比如,當(dāng)時(shí),可以滿足圖2-2的條件。此外,當(dāng)為(0.5,0.5,0.8)或者(1.0,1.0,1.0)時(shí),同樣也滿足與門(mén)的條件。設(shè)定這樣的參數(shù)后,僅當(dāng)和同時(shí)為1時(shí),信號(hào)的加權(quán)總和才會(huì)超過(guò)給定的閾值θ。2.2.2與非門(mén)和或門(mén)接著,我們?cè)賮?lái)考慮一下與非門(mén)(NANDgate)。NAND是NotAND的意思,與非門(mén)就是顛倒了與門(mén)的輸出。用真值表表示的話,如圖2-3所示,僅當(dāng)和同時(shí)為1時(shí)輸出0,其他時(shí)候則輸出1。那么與非門(mén)的參數(shù)又可以是什么樣的組合呢?圖2-3與非門(mén)的真值表要表示與非門(mén),可以用這樣的組合(其他的組合也是無(wú)限存在的)。實(shí)際上,只要把實(shí)現(xiàn)與門(mén)的參數(shù)值的符號(hào)取反,就可以實(shí)現(xiàn)與非門(mén)。接下來(lái)看一下圖2-4所示的或門(mén)。或門(mén)是“只要有一個(gè)輸入信號(hào)是1,輸出就為1”的邏輯電路。那么我們來(lái)思考一下,應(yīng)該為這個(gè)或門(mén)設(shè)定什么樣的參數(shù)呢?圖2-4或門(mén)的真值表這里決定感知機(jī)參數(shù)的并不是計(jì)算機(jī),而是我們?nèi)?。我們看著真值表這種“訓(xùn)練數(shù)據(jù)”,人工考慮(想到)了參數(shù)的值。而機(jī)器學(xué)習(xí)的課題就是將這個(gè)決定參數(shù)值的工作交由計(jì)算機(jī)自動(dòng)進(jìn)行。學(xué)習(xí)是確定合適的參數(shù)的過(guò)程,而人要做的是思考感知機(jī)的構(gòu)造(模型),并把訓(xùn)練數(shù)據(jù)交給計(jì)算機(jī)。如上所示,我們已經(jīng)知道使用感知機(jī)可以表示與門(mén)、與非門(mén)、或門(mén)的邏輯電路。這里重要的一點(diǎn)是:與門(mén)、與非門(mén)、或門(mén)的感知機(jī)構(gòu)造是一樣的。實(shí)際上,3個(gè)門(mén)電路只有參數(shù)的值(權(quán)重和閾值)不同。也就是說(shuō),相同構(gòu)造的感知機(jī),只需通過(guò)適當(dāng)?shù)卣{(diào)整參數(shù)的值,就可以像“變色龍演員”表演不同的角色一樣,變身為與門(mén)、與非門(mén)、或門(mén)。2.3感知機(jī)的實(shí)現(xiàn)2.3.1簡(jiǎn)單的實(shí)現(xiàn)現(xiàn)在,我們用Python來(lái)實(shí)現(xiàn)剛才的邏輯電路。這里,先定義一個(gè)接收參數(shù)x1和x2的AND函數(shù)。defAND(x1,x2):

w1,w2,theta=0.5,0.5,0.7

tmp=x1*w1+x2*w2

iftmp<=theta:

return0

eliftmp>theta:

return1

在函數(shù)內(nèi)初始化參數(shù)w1、w2、theta,當(dāng)輸入的加權(quán)總和超過(guò)閾值時(shí)返回1,否則返回0。我們來(lái)確認(rèn)一下輸出結(jié)果是否如圖2-2所示。AND(0,0)#輸出0

AND(1,0)#輸出0

AND(0,1)#輸出0

AND(1,1)#輸出1

果然和我們預(yù)想的輸出一樣!這樣我們就實(shí)現(xiàn)了與門(mén)。按照同樣的步驟,也可以實(shí)現(xiàn)與非門(mén)和或門(mén),不過(guò)讓我們來(lái)對(duì)它們的實(shí)現(xiàn)稍作修改。2.3.2導(dǎo)入權(quán)重和偏置剛才的與門(mén)的實(shí)現(xiàn)比較直接、容易理解,但是考慮到以后的事情,我們將其修改為另外一種實(shí)現(xiàn)形式。在此之前,首先把式(2.1)的θ換成-b,于是就可以用式(2.2)來(lái)表示感知機(jī)的行為。式(2.1)和式(2.2)雖然有一個(gè)符號(hào)不同,但表達(dá)的內(nèi)容是完全相同的。此處,b稱為偏置,和稱為權(quán)重。如式(2.2)所示,感知機(jī)會(huì)計(jì)算輸入信號(hào)和權(quán)重的乘積,然后加上偏置,如果這個(gè)值大于0則輸出1,否則輸出0。下面,我們使用NumPy,按式(2.2)的方式實(shí)現(xiàn)感知機(jī)。在這個(gè)過(guò)程中,我們用Python的解釋器逐一確認(rèn)結(jié)果。

>>>

importnumpyasnp

>>>

x=np.array([0,1])

#輸入

>>>

w=np.array([0.5,0.5])

#權(quán)重

>>>

b=-0.7

#偏置

>>>

w*x

array([0.,0.5])

>>>

np.sum(w*x)

0.5

>>>

np.sum(w*x)+b

-0.19999999999999996#大約為-0.2(由浮點(diǎn)小數(shù)造成的運(yùn)算誤差)

如上例所示,在NumPy數(shù)組的乘法運(yùn)算中,當(dāng)兩個(gè)數(shù)組的元素個(gè)數(shù)相同時(shí),各個(gè)元素分別相乘,因此w*x的結(jié)果就是它們的各個(gè)元素分別相乘([0,1]*[0.5,0.5]=>[0,0.5])。之后,np.sum(w*x)再計(jì)算相乘后的各個(gè)元素的總和。最后再把偏置加到這個(gè)加權(quán)總和上,就完成了式(2.2)的計(jì)算。2.3.3使用權(quán)重和偏置的實(shí)現(xiàn)使用權(quán)重和偏置,可以像下面這樣實(shí)現(xiàn)與門(mén)。defAND(x1,x2):

x=np.array([x1,x2])

w=np.array([0.5,0.5])

b=-0.7

tmp=np.sum(w*x)+b

iftmp<=0:

return0

else:

return1

這里把-θ命名為偏置b,但是請(qǐng)注意,偏置和權(quán)重、的作用是不一樣的。具體地說(shuō),和是控制輸入信號(hào)的重要性的參數(shù),而偏置是調(diào)整神經(jīng)元被激活的容易程度(輸出信號(hào)為1的程度)的參數(shù)。比如,若b為-0.1,則只要輸入信號(hào)的加權(quán)總和超過(guò)0.1,神經(jīng)元就會(huì)被激活。但是如果b為-20.0,則輸入信號(hào)的加權(quán)總和必須超過(guò)20.0,神經(jīng)元才會(huì)被激活。像這樣,偏置的值決定了神經(jīng)元被激活的容易程度。另外,這里我們將和稱為權(quán)重,將b稱為偏置,但是根據(jù)上下文,有時(shí)也會(huì)將b、、這些參數(shù)統(tǒng)稱為權(quán)重。偏置這個(gè)術(shù)語(yǔ),有“穿木屐”2的效果,即在沒(méi)有任何輸入時(shí)(輸入為0時(shí)),給輸出穿上多高的木屐(加上多大的值)的意思。實(shí)際上,在式(2.2)的的計(jì)算中,當(dāng)輸入和為0時(shí),只輸出偏置的值。2因?yàn)槟惧斓牡妆容^厚,穿上它后,整個(gè)人也會(huì)顯得更高。——譯者注接著,我們繼續(xù)實(shí)現(xiàn)與非門(mén)和或門(mén)。

defNAND(x1,x2):

x=np.array([x1,x2])

w=np.array([-0.5,-0.5])

#僅權(quán)重和偏置與AND不同!

b=0.7

tmp=np.sum(w*x)+b

iftmp<=0:

return0

else:

return1

defOR(x1,x2):

x=np.array([x1,x2])

w=np.array([0.5,0.5])

#僅權(quán)重和偏置與AND不同!

b=-0.2

tmp=np.sum(w*x)+b

iftmp<=0:

return0

else:

return1

我們?cè)?.2節(jié)介紹過(guò),與門(mén)、與非門(mén)、或門(mén)是具有相同構(gòu)造的感知機(jī),區(qū)別只在于權(quán)重參數(shù)的值。因此,在與非門(mén)和或門(mén)的實(shí)現(xiàn)中,僅設(shè)置權(quán)重和偏置的值這一點(diǎn)和與門(mén)的實(shí)現(xiàn)不同。2.4感知機(jī)的局限性到這里我們已經(jīng)知道,使用感知機(jī)可以實(shí)現(xiàn)與門(mén)、與非門(mén)、或門(mén)三種邏輯電路?,F(xiàn)在我們來(lái)考慮一下異或門(mén)(XORgate)。2.4.1異或門(mén)異或門(mén)也被稱為邏輯異或電路。如圖2-5所示,僅當(dāng)或中的一方為1時(shí),才會(huì)輸出1(“異或”是拒絕其他的意思)。那么,要用感知機(jī)實(shí)現(xiàn)這個(gè)異或門(mén)的話,應(yīng)該設(shè)定什么樣的權(quán)重參數(shù)呢?圖2-5異或門(mén)的真值表實(shí)際上,用前面介紹的感知機(jī)是無(wú)法實(shí)現(xiàn)這個(gè)異或門(mén)的。為什么用感知機(jī)可以實(shí)現(xiàn)與門(mén)、或門(mén),卻無(wú)法實(shí)現(xiàn)異或門(mén)呢?下面我們嘗試通過(guò)畫(huà)圖來(lái)思考其中的原因。首先,我們?cè)囍鴮⒒蜷T(mén)的動(dòng)作形象化?;蜷T(mén)的情況下,當(dāng)權(quán)重參數(shù)時(shí),可滿足圖2-4的真值表?xiàng)l件。此時(shí),感知機(jī)可用下面的式(2.3)表示。式(2.3)表示的感知機(jī)會(huì)生成由直線分割開(kāi)的兩個(gè)空間。其中一個(gè)空間輸出1,另一個(gè)空間輸出0,如圖2-6所示。圖2-6感知機(jī)的可視化:灰色區(qū)域是感知機(jī)輸出0的區(qū)域,這個(gè)區(qū)域與或門(mén)的性質(zhì)一致或門(mén)在時(shí)輸出0,在為(0,1)、(1,0)、(1,1)時(shí)輸出1。圖2-6中,○表示0,△表示1。如果想制作或門(mén),需要用直線將圖2-6中的○和△分開(kāi)。實(shí)際上,剛才的那條直線就將這4個(gè)點(diǎn)正確地分開(kāi)了。那么,換成異或門(mén)的話會(huì)如何呢?能否像或門(mén)那樣,用一條直線作出分割圖2-7中的○和△的空間呢?圖2-7○和△表示異或門(mén)的輸出。可否通過(guò)一條直線作出分割○和△的空間呢?想要用一條直線將圖2-7中的○和△分開(kāi),無(wú)論如何都做不到。事實(shí)上,用一條直線是無(wú)法將○和△分開(kāi)的。2.4.2線性和非線性圖2-7中的○和△無(wú)法用一條直線分開(kāi),但是如果將“直線”這個(gè)限制條件去掉,就可以實(shí)現(xiàn)了。比如,我們可以像圖2-8那樣,作出分開(kāi)○和△的空間。圖2-8使用曲線可以分開(kāi)○和△感知機(jī)的局限性就在于它只能表示由一條直線分割的空間。圖2-8這樣彎曲的曲線無(wú)法用感知機(jī)表示。另外,由圖2-8這樣的曲線分割而成的空間稱為非線性空間,由直線分割而成的空間稱為線性空間。線性、非線性這兩個(gè)術(shù)語(yǔ)在機(jī)器學(xué)習(xí)領(lǐng)域很常見(jiàn),可以將其想象成圖2-6和圖2-8所示的直線和曲線。2.5多層感知機(jī)感知機(jī)不能表示異或門(mén)讓人深感遺憾,但也無(wú)需悲觀。實(shí)際上,感知機(jī)的絕妙之處在于它可以“疊加層”(通過(guò)疊加層來(lái)表示異或門(mén)是本節(jié)的要點(diǎn))。這里,我們暫且不考慮疊加層具體是指什么,先從其他視角來(lái)思考一下異或門(mén)的問(wèn)題。2.5.1已有門(mén)電路的組合異或門(mén)的制作方法有很多,其中之一就是組合我們前面做好的與門(mén)、與非門(mén)、或門(mén)進(jìn)行配置。這里,與門(mén)、與非門(mén)、或門(mén)用圖2-9中的符號(hào)表示。另外,圖2-9中與非門(mén)前端的○表示反轉(zhuǎn)輸出的意思。圖2-9與門(mén)、與非門(mén)、或門(mén)的符號(hào)那么,請(qǐng)思考一下,要實(shí)現(xiàn)異或門(mén)的話,需要如何配置與門(mén)、與非門(mén)和或門(mén)呢?這里給大家一個(gè)提示,用與門(mén)、與非門(mén)、或門(mén)代替圖2-10中的各個(gè)“?”,就可以實(shí)現(xiàn)異或門(mén)。圖2-10將與門(mén)、與非門(mén)、或門(mén)代入到“?”中,就可以實(shí)現(xiàn)異或門(mén)!2.4節(jié)講到的感知機(jī)的局限性,嚴(yán)格地講,應(yīng)該是“單層感知機(jī)無(wú)法表示異或門(mén)”或者“單層感知機(jī)無(wú)法分離非線性空間”。接下來(lái),我們將看到通過(guò)組合感知機(jī)(疊加層)就可以實(shí)現(xiàn)異或門(mén)。異或門(mén)可以通過(guò)圖2-11所示的配置來(lái)實(shí)現(xiàn)。這里,和表示輸入信號(hào),y表示輸出信號(hào)。和是與非門(mén)和或門(mén)的輸入,而與非門(mén)和或門(mén)的輸出則是與門(mén)的輸入。圖2-11通過(guò)組合與門(mén)、與非門(mén)、或門(mén)實(shí)現(xiàn)異或門(mén)現(xiàn)在,我們來(lái)確認(rèn)一下圖2-11的配置是否真正實(shí)現(xiàn)了異或門(mén)。這里,把作為與非門(mén)的輸出,把作為或門(mén)的輸出,填入真值表中。結(jié)果如圖2-12所示,觀察、、y,可以發(fā)現(xiàn)確實(shí)符合異或門(mén)的輸出。圖2-12異或門(mén)的真值表2.5.2異或門(mén)的實(shí)現(xiàn)下面我們?cè)囍肞ython來(lái)實(shí)現(xiàn)圖2-11所示的異或門(mén)。使用之前定義的AND函數(shù)、NAND函數(shù)、OR函數(shù),可以像下面這樣(輕松地)實(shí)現(xiàn)。defXOR(x1,x2):

s1=NAND(x1,x2)

s2=OR(x1,x2)

y=AND(s1,s2)

returny

這個(gè)XOR函數(shù)會(huì)輸出預(yù)期的結(jié)果。XOR(0,0)#輸出0

XOR(1,0)#輸出1

XOR(0,1)#輸出1

XOR(1,1)#輸出0

這樣,異或門(mén)的實(shí)現(xiàn)就完成了。下面我們?cè)囍酶兄獧C(jī)的表示方法(明確地顯示神經(jīng)元)來(lái)表示這個(gè)異或門(mén),結(jié)果如圖2-13所示。圖2-13用感知機(jī)表示異或門(mén)如圖2-13所示,異或門(mén)是一種多層結(jié)構(gòu)的神經(jīng)網(wǎng)絡(luò)。這里,將最左邊的一列稱為第0層,中間的一列稱為第1層,最右邊的一列稱為第2層。圖2-13所示的感知機(jī)與前面介紹的與門(mén)、或門(mén)的感知機(jī)(圖2-1)形狀不同。實(shí)際上,與門(mén)、或門(mén)是單層感知機(jī),而異或門(mén)是2層感知機(jī)。疊加了多層的感知機(jī)也稱為多層感知機(jī)(multi-layeredperceptron)。圖2-13中的感知機(jī)總共由3層構(gòu)成,但是因?yàn)閾碛袡?quán)重的層實(shí)質(zhì)上只有2層(第0層和第1層之間,第1層和第2層之間),所以稱為“2層感知機(jī)”。不過(guò),有的文獻(xiàn)認(rèn)為圖2-13的感知機(jī)是由3層構(gòu)成的,因而將其稱為“3層感知機(jī)”。在圖2-13所示的2層感知機(jī)中,先在第0層和第1層的神經(jīng)元之間進(jìn)行信號(hào)的傳送和接收,然后在第1層和第2層之間進(jìn)行信號(hào)的傳送和接收,具體如下所示。第0層的兩個(gè)神經(jīng)元接收輸入信號(hào),并將信號(hào)發(fā)送至第1層的神經(jīng)元。第1層的神經(jīng)元將信號(hào)發(fā)送至第2層的神經(jīng)元,第2層的神經(jīng)元輸出y。這種2層感知機(jī)的運(yùn)行過(guò)程可以比作流水線的組裝作業(yè)。第1段(第1層)的工人對(duì)傳送過(guò)來(lái)的零件進(jìn)行加工,完成后再傳送給第2段(第2層)的工人。第2層的工人對(duì)第1層的工人傳過(guò)來(lái)的零件進(jìn)行加工,完成這個(gè)零件后出貨(輸出)。像這樣,在異或門(mén)的感知機(jī)中,工人之間不斷進(jìn)行零件的傳送。通過(guò)這樣的結(jié)構(gòu)(2層結(jié)構(gòu)),感知機(jī)得以實(shí)現(xiàn)異或門(mén)。這可以解釋為“單層感知機(jī)無(wú)法表示的東西,通過(guò)增加一層就可以解決”。也就是說(shuō),通過(guò)疊加層(加深層),感知機(jī)能進(jìn)行更加靈活的表示。2.6從與非門(mén)到計(jì)算機(jī)多層感知機(jī)可以實(shí)現(xiàn)比之前見(jiàn)到的電路更復(fù)雜的電路。比如,進(jìn)行加法運(yùn)算的加法器也可以用感知機(jī)實(shí)現(xiàn)。此外,將二進(jìn)制轉(zhuǎn)換為十進(jìn)制的編碼器、滿足某些條件就輸出1的電路(用于等價(jià)檢驗(yàn)的電路)等也可以用感知機(jī)表示。實(shí)際上,使用感知機(jī)甚至可以表示計(jì)算機(jī)!計(jì)算機(jī)是處理信息的機(jī)器。向計(jì)算機(jī)中輸入一些信息后,它會(huì)按照某種既定的方法進(jìn)行處理,然后輸出結(jié)果。所謂“按照某種既定的方法進(jìn)行處理”是指,計(jì)算機(jī)和感知機(jī)一樣,也有輸入和輸出,會(huì)按照某個(gè)既定的規(guī)則進(jìn)行計(jì)算。人們一般會(huì)認(rèn)為計(jì)算機(jī)內(nèi)部進(jìn)行的處理非常復(fù)雜,而令人驚訝的是,實(shí)際上只需要通過(guò)與非門(mén)的組合,就能再現(xiàn)計(jì)算機(jī)進(jìn)行的處理。這一令人吃驚的事實(shí)說(shuō)明了什么呢?說(shuō)明使用感知機(jī)也可以表示計(jì)算機(jī)。前面也介紹了,與非門(mén)可以使用感知機(jī)實(shí)現(xiàn)。也就是說(shuō),如果通過(guò)組合與非門(mén)可以實(shí)現(xiàn)計(jì)算機(jī)的話,那么通過(guò)組合感知機(jī)也可以表示計(jì)算機(jī)(感知機(jī)的組合可以通過(guò)疊加了多層的單層感知機(jī)來(lái)表示)。說(shuō)到僅通過(guò)與非門(mén)的組合就能實(shí)現(xiàn)計(jì)算機(jī),大家也許一下子很難相信。建議有興趣的讀者看一下《計(jì)算機(jī)系統(tǒng)要素:從零開(kāi)始構(gòu)建現(xiàn)代計(jì)算機(jī)》。這本書(shū)以深入理解計(jì)算機(jī)為主題,論述了通過(guò)NAND構(gòu)建可運(yùn)行俄羅斯方塊的計(jì)算機(jī)的過(guò)程。此書(shū)能讓讀者真實(shí)體會(huì)到,通過(guò)簡(jiǎn)單的NAND元件就可以實(shí)現(xiàn)計(jì)算機(jī)這樣復(fù)雜的系統(tǒng)。綜上,多層感知機(jī)能夠進(jìn)行復(fù)雜的表示,甚至可以構(gòu)建計(jì)算機(jī)。那么,什么構(gòu)造的感知機(jī)才能表示計(jì)算機(jī)呢?層級(jí)多深才可以構(gòu)建計(jì)算機(jī)呢?理論上可以說(shuō)2層感知機(jī)就能構(gòu)建計(jì)算機(jī)。這是因?yàn)?,已有研究證明,2層感知機(jī)(嚴(yán)格地說(shuō)是激活函數(shù)使用了非線性的sigmoid函數(shù)的感知機(jī),具體請(qǐng)參照下一章)可以表示任意函數(shù)。但是,使用2層感知機(jī)的構(gòu)造,通過(guò)設(shè)定合適的權(quán)重來(lái)構(gòu)建計(jì)算機(jī)是一件非常累人的事情。實(shí)際上,在用與非門(mén)等低層的元件構(gòu)建計(jì)算機(jī)的情況下,分階段地制作所需的零件(模塊)會(huì)比較自然,即先實(shí)現(xiàn)與門(mén)和或門(mén),然后實(shí)現(xiàn)半加器和全加器,接著實(shí)現(xiàn)算數(shù)邏輯單元(ALU),然后實(shí)現(xiàn)CPU。因此,通過(guò)感知機(jī)表示計(jì)算機(jī)時(shí),使用疊加了多層的構(gòu)造來(lái)實(shí)現(xiàn)是比較自然的流程。本書(shū)中不會(huì)實(shí)際來(lái)實(shí)現(xiàn)計(jì)算機(jī),但是希望讀者能夠記住,感知機(jī)通過(guò)疊加層能夠進(jìn)行非線性的表示,理論上還可以表示計(jì)算機(jī)進(jìn)行的處理。2.7小結(jié)本章我們學(xué)習(xí)了感知機(jī)。感知機(jī)是一種非常簡(jiǎn)單的算法,大家應(yīng)該很快就能理解它的構(gòu)造。感知機(jī)是下一章要學(xué)習(xí)的神經(jīng)網(wǎng)絡(luò)的基礎(chǔ),因此本章的內(nèi)容非常重要。本章所學(xué)的內(nèi)容感知機(jī)是具有輸入和輸出的算法。給定一個(gè)輸入后,將輸出一個(gè)既定的值。感知機(jī)將權(quán)重和偏置設(shè)定為參數(shù)。使用感知機(jī)可以表示與門(mén)和或門(mén)等邏輯電路。異或門(mén)無(wú)法通過(guò)單層感知機(jī)來(lái)表示。使用2層感知機(jī)可以表示異或門(mén)。單層感知機(jī)只能表示線性空間,而多層感知機(jī)可以表示非線性空間。多層感知機(jī)(在理論上)可以表示計(jì)算機(jī)。

第3章神經(jīng)網(wǎng)絡(luò)上一章我們學(xué)習(xí)了感知機(jī)。關(guān)于感知機(jī),既有好消息,也有壞消息。好消息是,即便對(duì)于復(fù)雜的函數(shù),感知機(jī)也隱含著能夠表示它的可能性。上一章已經(jīng)介紹過(guò),即便是計(jì)算機(jī)進(jìn)行的復(fù)雜處理,感知機(jī)(理論上)也可以將其表示出來(lái)。壞消息是,設(shè)定權(quán)重的工作,即確定合適的、能符合預(yù)期的輸入與輸出的權(quán)重,現(xiàn)在還是由人工進(jìn)行的。上一章中,我們結(jié)合與門(mén)、或門(mén)的真值表人工決定了合適的權(quán)重。神經(jīng)網(wǎng)絡(luò)的出現(xiàn)就是為了解決剛才的壞消息。具體地講,神經(jīng)網(wǎng)絡(luò)的一個(gè)重要性質(zhì)是它可以自動(dòng)地從數(shù)據(jù)中學(xué)習(xí)到合適的權(quán)重參數(shù)。本章中,我們會(huì)先介紹神經(jīng)網(wǎng)絡(luò)的概要,然后重點(diǎn)關(guān)注神經(jīng)網(wǎng)絡(luò)進(jìn)行識(shí)別時(shí)的處理。在下一章中,我們將了解如何從數(shù)據(jù)中學(xué)習(xí)權(quán)重參數(shù)。3.1從感知機(jī)到神經(jīng)網(wǎng)絡(luò)神經(jīng)網(wǎng)絡(luò)和上一章介紹的感知機(jī)有很多共同點(diǎn)。這里,我們主要以兩者的差異為中心,來(lái)介紹神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)。3.1.1神經(jīng)網(wǎng)絡(luò)的例子用圖來(lái)表示神經(jīng)網(wǎng)絡(luò)的話,如圖3-1所示。我們把最左邊的一列稱為輸入層,最右邊的一列稱為輸出層,中間的一列稱為中間層。中間層有時(shí)也稱為隱藏層。“隱藏”一詞的意思是,隱藏層的神經(jīng)元(和輸入層、輸出層不同)肉眼看不見(jiàn)。另外,本書(shū)中把輸入層到輸出層依次稱為第0層、第1層、第2層(層號(hào)之所以從0開(kāi)始,是為了方便后面基于Python進(jìn)行實(shí)現(xiàn))。圖3-1中,第0層對(duì)應(yīng)輸入層,第1層對(duì)應(yīng)中間層,第2層對(duì)應(yīng)輸出層。圖3-1神經(jīng)網(wǎng)絡(luò)的例子圖3-1中的網(wǎng)絡(luò)一共由3層神經(jīng)元構(gòu)成,但實(shí)質(zhì)上只有2層神經(jīng)元有權(quán)重,因此將其稱為“2層網(wǎng)絡(luò)”。請(qǐng)注意,有的書(shū)也會(huì)根據(jù)構(gòu)成網(wǎng)絡(luò)的層數(shù),把圖3-1的網(wǎng)絡(luò)稱為“3層網(wǎng)絡(luò)”。本書(shū)將根據(jù)實(shí)質(zhì)上擁有權(quán)重的層數(shù)(輸入層、隱藏層、輸出層的總數(shù)減去1后的數(shù)量)來(lái)表示網(wǎng)絡(luò)的名稱。只看圖3-1的話,神經(jīng)網(wǎng)絡(luò)的形狀類似上一章的感知機(jī)。實(shí)際上,就神經(jīng)元的連接方式而言,與上一章的感知機(jī)并沒(méi)有任何差異。那么,神經(jīng)網(wǎng)絡(luò)中信號(hào)是如何傳遞的呢?3.1.2復(fù)習(xí)感知機(jī)在觀察神經(jīng)網(wǎng)絡(luò)中信號(hào)的傳遞方法之前,我們先復(fù)習(xí)一下感知機(jī)。現(xiàn)在來(lái)思考一下圖3-2中的網(wǎng)絡(luò)結(jié)構(gòu)。圖3-2復(fù)習(xí)感知機(jī)圖3-2中的感知機(jī)接收和兩個(gè)輸入信號(hào),輸出y。如果用數(shù)學(xué)式來(lái)表示圖3-2中的感知機(jī),則如式(3.1)所示。b是被稱為偏置的參數(shù),用于控制神經(jīng)元被激活的容易程度;而和是表示各個(gè)信號(hào)的權(quán)重的參數(shù),用于控制各個(gè)信號(hào)的重要性。順便提一下,在圖3-2的網(wǎng)絡(luò)中,偏置b并沒(méi)有被畫(huà)出來(lái)。如果要明確地表示出b,可以像圖3-3那樣做。圖3-3中添加了權(quán)重為b的輸入信號(hào)1。這個(gè)感知機(jī)將、、1三個(gè)信號(hào)作為神經(jīng)元的輸入,將其和各自的權(quán)重相乘后,傳送至下一個(gè)神經(jīng)元。在下一個(gè)神經(jīng)元中,計(jì)算這些加權(quán)信號(hào)的總和。如果這個(gè)總和超過(guò)0,則輸出1,否則輸出0。另外,由于偏置的輸入信號(hào)一直是1,所以為了區(qū)別于其他神經(jīng)元,我們?cè)趫D中把這個(gè)神經(jīng)元整個(gè)涂成灰色?,F(xiàn)在將式(3.1)改寫(xiě)成更加簡(jiǎn)潔的形式。為了簡(jiǎn)化式(3.1),我們用一個(gè)函數(shù)來(lái)表示這種分情況的動(dòng)作(超過(guò)0則輸出1,否則輸出0)。引入新函數(shù)h(x),將式(3.1)改寫(xiě)成下面的式(3.2)和式(3.3)。圖3-3明確表示出偏置式(3.2)中,輸入信號(hào)的總和會(huì)被函數(shù)h(x)轉(zhuǎn)換,轉(zhuǎn)換后的值就是輸出y。然后,式(3.3)所表示的函數(shù)h(x),在輸入超過(guò)0時(shí)返回1,否則返回0。因此,式(3.1)和式(3.2)、式(3.3)做的是相同的事情。3.1.3激活函數(shù)登場(chǎng)剛才登場(chǎng)的h(x)函數(shù)會(huì)將輸入信號(hào)的總和轉(zhuǎn)換為輸出信號(hào),這種函數(shù)一般稱為激活函數(shù)(activationfunction)。如“激活”一詞所示,激活函數(shù)的作用在于決定如何來(lái)激活輸入信號(hào)的總和?,F(xiàn)在來(lái)進(jìn)一步改寫(xiě)式(3.2)。式(3.2)分兩個(gè)階段進(jìn)行處理,先計(jì)算輸入信號(hào)的加權(quán)總和,然后用激活函數(shù)轉(zhuǎn)換這一總和。因此,如果將式(3.2)寫(xiě)得詳細(xì)一點(diǎn),則可以分成下面兩個(gè)式子。首先,式(3.4)計(jì)算加權(quán)輸入信號(hào)和偏置的總和,記為a。然后,式(3.5)用h()函數(shù)將a轉(zhuǎn)換為輸出y。之前的神經(jīng)元都是用一個(gè)○表示的,如果要在圖中明確表示出式(3.4)和式(3.5),則可以像圖3-4這樣做。圖3-4明確顯示激活函數(shù)的計(jì)算過(guò)程如圖3-4所示,表示神經(jīng)元的○中明確顯示了激活函數(shù)的計(jì)算過(guò)程,即信號(hào)的加權(quán)總和為節(jié)點(diǎn)a,然后節(jié)點(diǎn)a被激活函數(shù)h()轉(zhuǎn)換成節(jié)點(diǎn)y。本書(shū)中,“神經(jīng)元”和“節(jié)點(diǎn)”兩個(gè)術(shù)語(yǔ)的含義相同。這里,我們稱a和y為“節(jié)點(diǎn)”,其實(shí)它和之前所說(shuō)的“神經(jīng)元”含義相同。通常如圖3-5的左圖所示,神經(jīng)元用一個(gè)○表示。本書(shū)中,在可以明確神經(jīng)網(wǎng)絡(luò)的動(dòng)作的情況下,將在圖中明確顯示激活函數(shù)的計(jì)算過(guò)程,如圖3-5的右圖所示。圖3-5左圖是一般的神經(jīng)元的圖,右圖是在神經(jīng)元內(nèi)部明確顯示激活函數(shù)的計(jì)算過(guò)程的圖(a表示輸入信號(hào)的總和,h()表示激活函數(shù),y表示輸出)下面,我們將仔細(xì)介紹激活函數(shù)。激活函數(shù)是連接感知機(jī)和神經(jīng)網(wǎng)絡(luò)的橋梁。本書(shū)在使用“感知機(jī)”一詞時(shí),沒(méi)有嚴(yán)格統(tǒng)一它所指的算法。一般而言,“樸素感知機(jī)”是指單層網(wǎng)絡(luò),指的是激活函數(shù)使用了階躍函數(shù)1的模型?!岸鄬痈兄獧C(jī)”是指神經(jīng)網(wǎng)絡(luò),即使用sigmoid函數(shù)(后述)等平滑的激活函數(shù)的多層網(wǎng)絡(luò)。1階躍函數(shù)是指一旦輸入超過(guò)閾值,就切換輸出的函數(shù)。3.2激活函數(shù)式(3.3)表示的激活函數(shù)以閾值為界,一旦輸入超過(guò)閾值,就切換輸出。這樣的函數(shù)稱為“階躍函數(shù)”。因此,可以說(shuō)感知機(jī)中使用了階躍函數(shù)作為激活函數(shù)。也就是說(shuō),在激活函數(shù)的眾多候選函數(shù)中,感知機(jī)使用了階躍函數(shù)。那么,如果感知機(jī)使用其他函數(shù)作為激活函數(shù)的話會(huì)怎么樣呢?實(shí)際上,如果將激活函數(shù)從階躍函數(shù)換成其他函數(shù),就可以進(jìn)入神經(jīng)網(wǎng)絡(luò)的世界了。下面我們就來(lái)介紹一下神經(jīng)網(wǎng)絡(luò)使用的激活函數(shù)。3.2.1sigmoid函數(shù)神經(jīng)網(wǎng)絡(luò)中經(jīng)常使用的一個(gè)激活函數(shù)就是式(3.6)表示的sigmoid函數(shù)(sigmoidfunction)。式(3.6)中的exp(-x)表示的意思。e是納皮爾常數(shù)2.7182...。式(3.6)表示的sigmoid函數(shù)看上去有些復(fù)雜,但它也僅僅是個(gè)函數(shù)而已。而函數(shù)就是給定某個(gè)輸入后,會(huì)返回某個(gè)輸出的轉(zhuǎn)換器。比如,向sigmoid函數(shù)輸入1.0或2.0后,就會(huì)有某個(gè)值被輸出,類似h(1.0)=0.731...、h(2.0)=0.880...這樣。神經(jīng)網(wǎng)絡(luò)中用sigmoid函數(shù)作為激活函數(shù),進(jìn)行信號(hào)的轉(zhuǎn)換,轉(zhuǎn)換后的信號(hào)被傳送給下一個(gè)神經(jīng)元。實(shí)際上

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論