日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人工智能 > pytorch >内容正文

pytorch

深度学习入门与快速实践

發(fā)布時(shí)間:2023/12/8 pytorch 85 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度学习入门与快速实践 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

深度學(xué)習(xí)介紹

以深度學(xué)習(xí)為主要力量的AI浪潮徐徐展開(kāi)

我們正處在一個(gè)巨變的時(shí)代,人工智能已經(jīng)成為了這個(gè)時(shí)代的主題。人工智能成為第四次工業(yè)革命的核心驅(qū)動(dòng)力,并將像機(jī)械化、電氣化、信息化一樣,最終會(huì)滲透到每一個(gè)行業(yè)的每一個(gè)角落。人工智能將重塑全球制造業(yè)競(jìng)爭(zhēng)新格局、引爆新一輪產(chǎn)業(yè)革命。以1956年的達(dá)特茅斯會(huì)議(Dartmouth Conference)為起點(diǎn),人工智能經(jīng)過(guò)了60余年的發(fā)展,經(jīng)歷了邏輯推理理論和專(zhuān)家系統(tǒng)的兩次繁榮,也經(jīng)歷過(guò)隨之而來(lái)的兩次寒冬。在最近的十年間,人工智能技術(shù)再次出現(xiàn)了前所未有的爆發(fā)性增長(zhǎng)和繁榮期。機(jī)器學(xué)習(xí)技術(shù)尤其是深度學(xué)習(xí)技術(shù)的興起是本次人工智能繁榮大潮的重要推動(dòng)力。

近年來(lái)深度學(xué)習(xí)發(fā)展神速,在語(yǔ)音、圖像、自然語(yǔ)言處理等技術(shù)上取得了前所未有的突破。本輪人工智能的快速發(fā)展離不開(kāi)三大關(guān)鍵要素:算力數(shù)據(jù)算法
首先,大規(guī)模、高性能的云端計(jì)算硬件集群是人工智能發(fā)展的強(qiáng)勁引擎。目前深度學(xué)習(xí)算法模型結(jié)構(gòu)復(fù)雜,規(guī)模大、參數(shù)多;模型的開(kāi)發(fā)門(mén)檻很高。面對(duì)這些挑戰(zhàn),高性能的硬件,如GPU/FPGA/ASIC等,尤其是面向人工智能應(yīng)用的專(zhuān)用芯片的發(fā)展,讓機(jī)器學(xué)習(xí)的訓(xùn)練速度數(shù)倍提升。
第二,數(shù)據(jù)是推動(dòng)人工智能發(fā)展的燃料,機(jī)器學(xué)習(xí)技術(shù)需要大量標(biāo)注數(shù)據(jù)來(lái)作訓(xùn)練模型,在海量數(shù)據(jù)樣本的基礎(chǔ)上挖掘信息,得到有用的知識(shí),從而做出決策。移動(dòng)互聯(lián)網(wǎng)、IoT物聯(lián)網(wǎng)的發(fā)展,不止讓手機(jī)這樣的移動(dòng)設(shè)備接入互聯(lián)網(wǎng),每一個(gè)音箱、每一個(gè)電視、每一個(gè)冰箱都可以接入云,獲得人工智能的能力和服務(wù)。用戶(hù)通過(guò)這些設(shè)備感受到AI帶來(lái)的便利,實(shí)際上背后是云上提供的服務(wù)。云是AI的container,如果將AI比作電的話(huà),云就是核電站,為各行各業(yè)提供源源不斷的智能核動(dòng)力。
第三,是不斷推陳出新的人工智能算法突破,從卷積神經(jīng)網(wǎng)絡(luò)(Convolutional neural network,簡(jiǎn)稱(chēng)CNN)到遞歸神經(jīng)網(wǎng)絡(luò)(Recurrent neural network,簡(jiǎn)稱(chēng)RNN),從生成式對(duì)抗網(wǎng)絡(luò)(Generative adversarial networks,簡(jiǎn)稱(chēng)GANs)到遷移學(xué)習(xí)(Transfer learning)。每一次新算法的提出或改進(jìn),帶來(lái)了應(yīng)用效果的大幅提升。人工智能技術(shù)在語(yǔ)音、圖像、自然語(yǔ)言等眾多領(lǐng)域的使用,推動(dòng)這次人工智能大潮的持續(xù)發(fā)展。[1]

深度學(xué)習(xí)基本概念

機(jī)器善于規(guī)則、人類(lèi)善于感知

機(jī)器善于計(jì)算。只要問(wèn)題能夠被一系列的數(shù)學(xué)規(guī)則形式化描述,那么通過(guò)編程的方法就可以進(jìn)行運(yùn)算,例如求解線(xiàn)性方程組,求解行星的運(yùn)動(dòng)軌跡。如果這些讓人類(lèi)手算的話(huà)會(huì)非常痛苦而且容易出錯(cuò)。為了盡量模擬人類(lèi)的行為,人們開(kāi)始研究機(jī)器學(xué)習(xí)。然而傳統(tǒng)人工智能依賴(lài)科學(xué)家輸入的規(guī)則模型,它只有在解決一些規(guī)則比較清楚的問(wèn)題時(shí)才比較有效,比如擊敗卡斯帕羅夫的“深藍(lán)”就是這樣一種“人工智能”。但是對(duì)于直覺(jué)性問(wèn)題,例如分辨圖片中的是貓還是狗,從不同的口音中聽(tīng)出對(duì)方的實(shí)際想表達(dá)的意思,通過(guò)語(yǔ)氣來(lái)表達(dá)自己的情緒,這些對(duì)于人來(lái)說(shuō)非常容易的事情,對(duì)于傳統(tǒng)人工智能來(lái)說(shuō)就非常困難。因?yàn)檫@種認(rèn)知類(lèi)問(wèn)題只有一個(gè)模糊的概念,沒(méi)有清楚簡(jiǎn)單的規(guī)則。
[2]

人工智能的目標(biāo)就是去解決人容易執(zhí)行,但是很難形式化描述的任務(wù)。相對(duì)于傳統(tǒng)的機(jī)器學(xué)習(xí)方法,深度學(xué)習(xí)方法是用來(lái)解決直覺(jué)問(wèn)題的好方法。深度神經(jīng)網(wǎng)絡(luò)大大優(yōu)化了機(jī)器學(xué)習(xí)的效果,使人工智能技術(shù)獲得了突破性進(jìn)展。在此基礎(chǔ)上,圖像識(shí)別、語(yǔ)音識(shí)別、機(jī)器翻譯等都取得了長(zhǎng)足進(jìn)步。語(yǔ)音輸入比打字快得多,機(jī)器翻譯讓我們基本可以看懂一篇外文資訊,圖像識(shí)別則早已可以憑借一張少年時(shí)期的照片就在一堆成人照片中準(zhǔn)確找到這個(gè)人,甚至可以把很模糊的照片恢復(fù)成清晰且準(zhǔn)確的照片。神經(jīng)網(wǎng)絡(luò)的特點(diǎn)就是它不需要人類(lèi)提前告知規(guī)則,它會(huì)自己從海量的基礎(chǔ)數(shù)據(jù)里識(shí)別模式(規(guī)則)。[3]

深度學(xué)習(xí)與神經(jīng)網(wǎng)絡(luò)

深度學(xué)習(xí)技術(shù)是構(gòu)建在傳統(tǒng)神經(jīng)網(wǎng)絡(luò)技術(shù)基礎(chǔ)之上的。可以粗略的認(rèn)為當(dāng)傳統(tǒng)神經(jīng)網(wǎng)絡(luò)夠“深”的時(shí)候就是深度學(xué)習(xí)了。圖中的網(wǎng)絡(luò)的層次比較少,也就是這個(gè)網(wǎng)絡(luò)比較淺,可以想象當(dāng)網(wǎng)絡(luò)層次達(dá)到幾十層上百層的時(shí)候,那么這就是一個(gè)深層次網(wǎng)絡(luò)了。用深層次網(wǎng)絡(luò)解決問(wèn)題就是深度學(xué)習(xí)技術(shù)。

人工神經(jīng)網(wǎng)絡(luò)是受到生物神經(jīng)網(wǎng)絡(luò)的啟發(fā)而發(fā)明的。生物神經(jīng)網(wǎng)絡(luò)是由無(wú)數(shù)個(gè)神經(jīng)元相互連接進(jìn)而組成的一個(gè)復(fù)雜網(wǎng)絡(luò)。人工神經(jīng)網(wǎng)絡(luò)模擬了這個(gè)過(guò)程,在邏輯上我們模擬出很多的神經(jīng)元,然后讓這些神經(jīng)元聯(lián)系成網(wǎng)絡(luò)。在深度學(xué)習(xí)領(lǐng)域,通常用神經(jīng)網(wǎng)絡(luò)這個(gè)詞來(lái)指代人工神經(jīng)網(wǎng)絡(luò)。這里要強(qiáng)調(diào)一下:人工神經(jīng)網(wǎng)絡(luò)和生物神經(jīng)網(wǎng)絡(luò)僅僅是啟發(fā)關(guān)系,內(nèi)部原理是不同的,因?yàn)槲覀內(nèi)祟?lèi)目前還沒(méi)有把生物神經(jīng)網(wǎng)絡(luò)的內(nèi)在全部機(jī)制完全探明。

復(fù)雜的神經(jīng)系統(tǒng)是由簡(jiǎn)單的神經(jīng)元相連組成。神經(jīng)元就像圖中這樣,枝枝杈杈很多,看上去一邊比較粗大一邊比較纖細(xì)。粗大的這邊的結(jié)構(gòu)叫做軸突,纖細(xì)這邊叫做樹(shù)突。信號(hào)就是由一個(gè)細(xì)胞的軸突通過(guò)突觸將信號(hào)傳遞給另一個(gè)細(xì)胞的樹(shù)突。當(dāng)無(wú)數(shù)個(gè)這樣的神經(jīng)元聯(lián)系在一起的時(shí)候就構(gòu)成了神經(jīng)網(wǎng)絡(luò)。

神經(jīng)元

生物神經(jīng)網(wǎng)絡(luò)的最小單元是神經(jīng)元,而人工神經(jīng)網(wǎng)絡(luò)的單元是感知機(jī)。生物的神經(jīng)元是一端接受化學(xué)信號(hào),經(jīng)過(guò)加工從另一端釋放出來(lái)。而感知機(jī)是一端接受一個(gè)向量作為輸入,經(jīng)過(guò)一定加工,另一端釋放出去一個(gè)標(biāo)量。

而一個(gè)神經(jīng)元內(nèi)部事實(shí)上經(jīng)歷了兩個(gè)運(yùn)算過(guò)程,線(xiàn)性運(yùn)算和非線(xiàn)性運(yùn)算。這兩個(gè)運(yùn)算的復(fù)合就構(gòu)成了一個(gè)神經(jīng)元的運(yùn)算過(guò)程。線(xiàn)性運(yùn)算就是最簡(jiǎn)單的加權(quán)求和,而非線(xiàn)性運(yùn)算所使用的函數(shù)也被稱(chēng)作激活函數(shù)或者激勵(lì)函數(shù)。關(guān)于激活函數(shù)在后面還會(huì)繼續(xù)討論。注意,在線(xiàn)性運(yùn)算中的向量 w 和 偏置 b 就是該網(wǎng)絡(luò)的參數(shù)。其中,w 表示權(quán)重, b 表示偏置。

輸入層、輸出層、隱藏層、全連接網(wǎng)絡(luò)

通常一個(gè)深度學(xué)習(xí)網(wǎng)絡(luò)就是一個(gè)多層的神經(jīng)網(wǎng)絡(luò),那么很自然就會(huì)想到,多深算“深”呢?這個(gè)度量標(biāo)準(zhǔn)目前還沒(méi)有定論,有的學(xué)者認(rèn)為超過(guò)3層的為深層網(wǎng)絡(luò),有的學(xué)者認(rèn)為超過(guò)5層為深層網(wǎng)絡(luò)。無(wú)論多深,網(wǎng)絡(luò)所具有的基本結(jié)構(gòu)的是一致的。輸入數(shù)據(jù)的那層別稱(chēng)作輸入層,輸出預(yù)測(cè)結(jié)果的一層(也就是網(wǎng)絡(luò)的最后一層)被稱(chēng)作輸出層,而夾在兩層之間的層次被稱(chēng)作隱藏層。輸入層通常不算做網(wǎng)絡(luò)的一部分。如果網(wǎng)絡(luò)中的每一個(gè)神經(jīng)元都和上層的所有神經(jīng)元相連也和下一層的所有神經(jīng)元相連,那么這樣的網(wǎng)絡(luò)就被稱(chēng)作全連接網(wǎng)絡(luò)。有時(shí),我們也把全連接網(wǎng)絡(luò)認(rèn)為是一種經(jīng)典的深度神經(jīng)網(wǎng)絡(luò)(Deep Neural Networks,DNN)。通常情況下,談及DNN就是指全連接網(wǎng)絡(luò)(除了DNN網(wǎng)絡(luò)還有CNN、RNN等網(wǎng)絡(luò)結(jié)構(gòu))。下圖就是一個(gè)4層的全連接網(wǎng)絡(luò)。

神經(jīng)網(wǎng)絡(luò)運(yùn)算三部曲

神經(jīng)網(wǎng)絡(luò)運(yùn)算由三步過(guò)程組成:正向傳播反向傳播梯度下降
正向傳播的主要目的:計(jì)算預(yù)測(cè)值。反向傳播的主要目的:得到參數(shù)的偏導(dǎo)數(shù)(也就是 w 和 b 的偏導(dǎo)數(shù))。梯度下降的主要目的:更新參數(shù),進(jìn)而將損失函數(shù)的函數(shù)值盡量降低。

正向傳播
主要過(guò)程為:采集客觀數(shù)據(jù) x。將 x 輸入網(wǎng)絡(luò),從輸入層開(kāi)始一層一層的計(jì)算到輸出層,這一路下來(lái)會(huì)得到預(yù)測(cè)值 y^\hat{y}y^?

反向傳播
主要過(guò)程為:在正向傳播得到預(yù)測(cè)值 y^\hat{y}y^? 后,用該值與采集回來(lái)的標(biāo)簽值 y 做比較,進(jìn)而度量預(yù)測(cè)值的準(zhǔn)確性,如果 y^\hat{y}y^? 與 y 的差距很小,那么說(shuō)明預(yù)測(cè)的較為精準(zhǔn),如果 y^\hat{y}y^? 與 y 的差距很大,說(shuō)明預(yù)測(cè)的不準(zhǔn)確。這個(gè)用來(lái)度量 y^\hat{y}y^? 與 y 的差距的函數(shù)稱(chēng)為損失函數(shù)。關(guān)于損失函數(shù),后面會(huì)繼續(xù)討論。由損失函數(shù)做為起點(diǎn),沿著網(wǎng)絡(luò)反向傳播求得每個(gè)參數(shù)(w和b)的偏導(dǎo)數(shù)的過(guò)程,稱(chēng)為反向傳播過(guò)程。

梯度下降
主要過(guò)程為:在得到了所有參數(shù)的偏導(dǎo)數(shù)后,也就得到了梯度,沿著梯度反方向前進(jìn)一小步,也就是向損失函數(shù)最小值的方向更靠近了一步。這個(gè)最小化的過(guò)程也被稱(chēng)作優(yōu)化。具體的優(yōu)化策略有很多種,這里不再展開(kāi)詳述。

激活函數(shù)

一個(gè)神經(jīng)元中包含兩個(gè)運(yùn)算過(guò)程:線(xiàn)性運(yùn)算和非線(xiàn)性運(yùn)算。線(xiàn)性運(yùn)算就是固定的(寫(xiě)死的)的加權(quán)求和,而非線(xiàn)性運(yùn)算過(guò)程是用戶(hù)可配置的。常用的線(xiàn)性激活函數(shù)有三種:sigmoid、tanh 和 relu。下面分別介紹一下這三種激活激活函數(shù)。
Sigmoid 函數(shù)主要作用就是把某實(shí)數(shù)映射到區(qū)間(0,1)內(nèi),觀察圖像會(huì)發(fā)現(xiàn)Sigmoid函數(shù)可以很好的完成這個(gè)工作,當(dāng)值較大時(shí),趨近于1,當(dāng)值較小時(shí),趨近于0。sigmoid早期最流行的激活函數(shù),激活函數(shù)的代名詞

Tanh 函數(shù) 也稱(chēng)為雙切正切函數(shù),范圍在-1到1之間,隨著x的增大或減小,函數(shù)趨于平緩,導(dǎo)函數(shù)趨近于0。sigmoid 函數(shù) 和 tanh 函數(shù)都可以用來(lái)做二分類(lèi)問(wèn)題的輸出層的激活函數(shù)。可以用做網(wǎng)絡(luò)內(nèi)部神經(jīng)元的激活函數(shù)。

Relu 函數(shù)。由于 sigmoid 函數(shù) 和 tanh 函數(shù)的都有飽和區(qū)(導(dǎo)數(shù)很小區(qū)域 0 的位置成為飽和區(qū),觀察函數(shù)圖像可以很容易發(fā)現(xiàn),當(dāng) x 大于 5 函數(shù)的導(dǎo)數(shù)就趨于 0 了)。所以,在反向傳播的時(shí)候很容發(fā)生偏導(dǎo)數(shù)非常小的現(xiàn)象,那么進(jìn)而會(huì)導(dǎo)致在梯度下降的時(shí)候,參數(shù)(w和b)更新速度過(guò)于緩慢的現(xiàn)象。為了克服這種現(xiàn)象,于是有了 Relu 函數(shù)。事實(shí)上,relu 函數(shù)是目前使用最多的激活函數(shù)。如果開(kāi)發(fā)者不知道該配置什么樣的激活函數(shù)比較好,那么就可以嘗試配置 relu 函數(shù)。


標(biāo)準(zhǔn) Relu 函數(shù)也不是完美的,可以觀察到 Relu 在拐點(diǎn)處不可導(dǎo),并且在 x 小于 0 的時(shí)候函數(shù)值為0,這樣在反向傳播的時(shí)候,就會(huì)把信息丟失。于是就又有了 Relu 的變種:LeakyRelu、參數(shù)化Relu、隨機(jī)化Relu等,這里不再展開(kāi),但是目前在工業(yè)上用的最多的還是標(biāo)準(zhǔn) Relu。

損失函數(shù)

需要定義一個(gè)損失函數(shù)(Loss function or Error function)用于對(duì)參數(shù) w 和 b 進(jìn)行優(yōu)化,而損失函數(shù)的選擇需要具體問(wèn)題具體分析,在不同問(wèn)題場(chǎng)景下采用不同的函數(shù)。常見(jiàn)的損失函數(shù)為均方誤差損失函數(shù)交叉熵?fù)p失函數(shù)
均方誤差損失函數(shù)
回歸主要解決的是對(duì)具體數(shù)值的預(yù)測(cè),解決回歸問(wèn)題的神經(jīng)網(wǎng)絡(luò)一般只有一個(gè)輸出節(jié)點(diǎn),這個(gè)節(jié)點(diǎn)的輸出值就是預(yù)測(cè)值。對(duì)于回歸問(wèn)題,最常用的損失函數(shù)是均方誤差(MSE),定義為:

交叉熵?fù)p失函數(shù)
交叉熵是一個(gè)信息論中的概念,它原來(lái)是用來(lái)估算平均編碼長(zhǎng)度的。給定兩個(gè)概率分布 p 和 q,通過(guò) q 來(lái)表示 p 的交叉熵為:

注意,交叉熵刻畫(huà)的是兩個(gè)概率分布之間的距離,或可以說(shuō)它刻畫(huà)的是通過(guò)概率分布q來(lái)表達(dá)概率分布p的困難程度,p代表正確答案,q代表的是預(yù)測(cè)值,交叉熵越小,兩個(gè)概率的分布約接近。[4]
通常交叉熵?fù)p失函數(shù)是和激活函數(shù) softmax 共同使用(也就是將 softmax 設(shè)置為輸出層的激活函數(shù))。關(guān)于 softmax 函數(shù)相關(guān)內(nèi)容這里就不再展開(kāi)。

PaddlePaddle 工具介紹

做深度學(xué)習(xí)是一個(gè)復(fù)雜的過(guò)程。理論上,開(kāi)發(fā)者可以自己使用 Python 的 numpy 庫(kù),自己從頭開(kāi)始編寫(xiě)網(wǎng)絡(luò)結(jié)構(gòu)、正向傳播過(guò)程、反向傳播過(guò)程、梯度下降的優(yōu)化過(guò)程、以及對(duì)GPU、FPGA、NPU的底層適配優(yōu)化等工作。但是,自己來(lái)做這些事情實(shí)在工作量太過(guò)龐大,會(huì)把自己寶貴的時(shí)間浪費(fèi)在底層代碼的編寫(xiě)。作為開(kāi)發(fā)者,首要任務(wù)是完成自己的業(yè)務(wù)邏輯,讓自己的公司的業(yè)務(wù)盡快上線(xiàn)盡早盡好的為客戶(hù)提供服務(wù)。所以,很多大廠和前輩編寫(xiě)很多非常棒的深度學(xué)習(xí)框架,使得開(kāi)發(fā)者能夠聚焦于自己的業(yè)務(wù)。目前主流的框架有 PaddlePaddle、TensorFlow、Pythorch 等,其中 PaddlePaddle 是一個(gè)易學(xué)、易用的開(kāi)源深度學(xué)習(xí)框架,能夠讓開(kāi)發(fā)者和企業(yè)安全、高效地實(shí)現(xiàn)自己的AI想法[5]。PaddlePaddle 是百度開(kāi)發(fā)、開(kāi)放、開(kāi)源的。

使用深度學(xué)習(xí)實(shí)現(xiàn)房?jī)r(jià)預(yù)測(cè)----數(shù)據(jù)準(zhǔn)備

數(shù)據(jù)集介紹

我們使用從UCI Housing Data Set(http://paddlemodels.bj.bcebos.com/uci_housing/housing.data)獲得的波士頓房?jī)r(jià)數(shù)據(jù)集進(jìn)行模型的訓(xùn)練和預(yù)測(cè)。下面的散點(diǎn)圖展示了使用模型對(duì)部分房屋價(jià)格進(jìn)行的預(yù)測(cè)。其中,每個(gè)點(diǎn)的橫坐標(biāo)表示同一類(lèi)房屋真實(shí)價(jià)格的中位數(shù),縱坐標(biāo)表示線(xiàn)性回歸模型根據(jù)特征預(yù)測(cè)的結(jié)果,當(dāng)二者值完全相等的時(shí)候就會(huì)落在虛線(xiàn)上。所以模型預(yù)測(cè)得越準(zhǔn)確,則點(diǎn)離虛線(xiàn)越近。

這份數(shù)據(jù)集共506行,每行包含了波士頓郊區(qū)的一類(lèi)房屋的相關(guān)信息及該類(lèi)房屋價(jià)格的中位數(shù)。其各維屬性的意義如下:

屬性名解釋類(lèi)型
CRIM該鎮(zhèn)的人均犯罪率連續(xù)值
ZN占地面積超過(guò)25,000平方呎的住宅用地比例連續(xù)值
INDUS非零售商業(yè)用地比例連續(xù)值
CHAS是否鄰近 Charles River離散值,1=鄰近;0=不鄰近
NOX一氧化氮濃度連續(xù)值
RM每棟房屋的平均客房數(shù)連續(xù)值
AGE1940年之前建成的自用單位比例連續(xù)值
DIS到波士頓5個(gè)就業(yè)中心的加權(quán)距離連續(xù)值
RAD到徑向公路的可達(dá)性指數(shù)連續(xù)值
TAX全值財(cái)產(chǎn)稅率連續(xù)值
PTRATIO學(xué)生與教師的比例連續(xù)值
B1000(BK - 0.63)^2,其中BK為黑人占比連續(xù)值
LSTAT低收入人群占比連續(xù)值
MEDV同類(lèi)房屋價(jià)格的中位數(shù)連續(xù)值

數(shù)據(jù)預(yù)處理

連續(xù)值與離散值
觀察一下數(shù)據(jù),我們的第一個(gè)發(fā)現(xiàn)是:所有的13維屬性中,有12維的連續(xù)值和1維的離散值(CHAS)。離散值雖然也常使用類(lèi)似0、1、2這樣的數(shù)字表示,但是其含義與連續(xù)值是不同的,因?yàn)檫@里的差值沒(méi)有實(shí)際意義。例如,我們用0、1、2來(lái)分別表示紅色、綠色和藍(lán)色的話(huà),我們并不能因此說(shuō)“藍(lán)色和紅色”比“綠色和紅色”的距離更遠(yuǎn)。所以通常對(duì)一個(gè)有dd個(gè)可能取值的離散屬性,我們會(huì)將它們轉(zhuǎn)為dd個(gè)取值為0或1的二值屬性或者將每個(gè)可能取值映射為一個(gè)多維向量。不過(guò)就這里而言,因?yàn)镃HAS本身就是一個(gè)二值屬性,就省去了這個(gè)麻煩。

屬性的歸一化
另外一個(gè)稍加觀察即可發(fā)現(xiàn)的事實(shí)是,各維屬性的取值范圍差別很大(例如下圖)。

例如,屬性B的取值范圍是[0.32, 396.90],而屬性NOX的取值范圍是[0.3850, 0.8170]。這里就要用到一個(gè)常見(jiàn)的操作-歸一化(normalization)了。歸一化的目標(biāo)是把各位屬性的取值范圍放縮到差不多的區(qū)間,例如[-0.5,0.5]。這里我們使用一種很常見(jiàn)的操作方法:減掉均值,然后除以原取值范圍。

做歸一化至少有以下3個(gè)理由:

  • 過(guò)大或過(guò)小的數(shù)值范圍會(huì)導(dǎo)致計(jì)算時(shí)的浮點(diǎn)上溢或下溢。
  • 不同的數(shù)值范圍會(huì)導(dǎo)致不同屬性對(duì)模型的重要性不同(至少在訓(xùn)練的初始階段如此),而這個(gè)隱含的假設(shè)常常是不合理的。這會(huì)對(duì)優(yōu)化的過(guò)程造成困難,使訓(xùn)練時(shí)間大大的加長(zhǎng)。
  • 很多的機(jī)器學(xué)習(xí)技巧/模型(例如L1,L2正則項(xiàng))都基于這樣的假設(shè):所有的屬性取值都差不多是以0為均值且取值范圍相近的。
  • 劃分訓(xùn)練集測(cè)試集

    通常情況下,開(kāi)發(fā)者在對(duì)數(shù)據(jù)集進(jìn)行過(guò)必要的預(yù)處理之后,就需要講數(shù)據(jù)集分為兩部分:訓(xùn)練集測(cè)試集

    • 訓(xùn)練集:用于調(diào)整模型的參數(shù),即進(jìn)行模型的訓(xùn)練。
    • 測(cè)試集:用來(lái)測(cè)試,查看模型效果,用來(lái)模擬如果模型上線(xiàn)后的效果。
      那么有多少數(shù)據(jù)應(yīng)該放入訓(xùn)練集呢,又有多少數(shù)據(jù)應(yīng)該放入測(cè)試集呢?分割數(shù)據(jù)的比例要考慮到兩個(gè)因素:更多的訓(xùn)練數(shù)據(jù)會(huì)降低參數(shù)估計(jì)的方差,從而得到更可信的模型;而更多的測(cè)試數(shù)據(jù)會(huì)降低測(cè)試誤差的方差,從而得到更可信的測(cè)試誤差。在數(shù)據(jù)集的量不大的情況下,這個(gè)比例通常是7:3或者8:2。在這個(gè)例子中我們?cè)O(shè)置的分割比例為8:2。

    在更復(fù)雜的模型訓(xùn)練過(guò)程中,我們往往還會(huì)多使用一種數(shù)據(jù)集:驗(yàn)證集。因?yàn)閺?fù)雜的模型中常常還有一些超參數(shù)(Hyperparameter)需要調(diào)節(jié),所以我們會(huì)嘗試多種超參數(shù)的組合來(lái)分別訓(xùn)練多個(gè)模型,然后對(duì)比它們?cè)隍?yàn)證集上的表現(xiàn)選擇相對(duì)最好的一組超參數(shù),最后才使用這組參數(shù)下訓(xùn)練的模型在測(cè)試集上評(píng)估測(cè)試誤差。由于本章訓(xùn)練的模型比較簡(jiǎn)單,我們暫且忽略掉這個(gè)過(guò)程。

    訓(xùn)練誤差與測(cè)試誤差

    此外,訓(xùn)練誤差和測(cè)試誤差也是開(kāi)發(fā)者必須了解的概念:

    • 模型在訓(xùn)練集上的誤差被稱(chēng)為訓(xùn)練誤差
    • 模型在測(cè)試集上的誤差被稱(chēng)為測(cè)試誤差
      我們訓(xùn)練模型的目的是為了通過(guò)從訓(xùn)練數(shù)據(jù)中找到規(guī)律來(lái)預(yù)測(cè)未知的新數(shù)據(jù),所以測(cè)試誤差是更能反映模型表現(xiàn)的指標(biāo)。

    使用深度學(xué)習(xí)實(shí)現(xiàn)房?jī)r(jià)預(yù)測(cè)----上代碼

    代碼概覽

    深度學(xué)習(xí)過(guò)程事實(shí)上可以劃分為兩個(gè)過(guò)程:訓(xùn)練和預(yù)測(cè)(預(yù)測(cè)也稱(chēng)作推理)。通常這兩個(gè)過(guò)程不是在同一臺(tái)機(jī)器上完成更不會(huì)在同一個(gè)進(jìn)程中完成,但是,為了講解方便代碼簡(jiǎn)便,我們下面的代碼是在同一個(gè)進(jìn)程中順序執(zhí)行。
    在本例中,我們將代碼分為了3個(gè)部分:通用內(nèi)容準(zhǔn)備、訓(xùn)練過(guò)程代碼、預(yù)測(cè)過(guò)程代碼

    通用內(nèi)容準(zhǔn)備

  • 引入需要使用到的庫(kù)
  • import paddle import paddle.fluid as fluid import numpy import math import sys from __future__ import print_function
  • 準(zhǔn)備數(shù)據(jù)集
  • BATCH_SIZE = 20 #定義 mini-batch 的大小train_reader = paddle.batch(paddle.reader.shuffle(paddle.dataset.uci_housing.train(), buf_size=500), # 用來(lái)打亂順序的 buffer 的大小為 500batch_size=BATCH_SIZE)test_reader = paddle.batch(paddle.reader.shuffle(paddle.dataset.uci_housing.test(), buf_size=500),batch_size=BATCH_SIZE)

    我們通過(guò) uci_housing 模塊引入了數(shù)據(jù)集合 UCI Housing Data Set

    其中,在uci_housing模塊中封裝了:
    數(shù)據(jù)下載的過(guò)程。下載數(shù)據(jù)保存在~/.cache/paddle/dataset/uci_housing/housing.data。
    數(shù)據(jù)預(yù)處理的過(guò)程。
    接下來(lái)我們定義了用于訓(xùn)練的數(shù)據(jù)提供器。提供器每次讀入一個(gè)大小為BATCH_SIZE的數(shù)據(jù)批次。如果用戶(hù)希望加一些隨機(jī)性,它可以同時(shí)定義一個(gè)批次大小和一個(gè)緩存大小。這樣的話(huà),每次數(shù)據(jù)提供器會(huì)從緩存中隨機(jī)讀取批次大小那么多的數(shù)據(jù)。

  • 定義網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)
  • x = fluid.layers.data(name='x', shape=[13], dtype='float32') y = fluid.layers.data(name='y', shape=[1], dtype='float32') y_predict = fluid.layers.fc(input=x, size=1, act=None)

    訓(xùn)練程序的目的是定義一個(gè)訓(xùn)練模型的網(wǎng)絡(luò)結(jié)構(gòu)。對(duì)于線(xiàn)性回歸來(lái)講,它就是一個(gè)從輸入到輸出的簡(jiǎn)單的全連接層。更加復(fù)雜的結(jié)構(gòu),比如卷積神經(jīng)網(wǎng)絡(luò),遞歸神經(jīng)網(wǎng)絡(luò)這里不再展開(kāi)。

    main_program = fluid.default_main_program() startup_program = fluid.default_startup_program()

    這兩句的作用是獲得 default_main_program 和 default_startup_program 的 Python 級(jí)別的引用。default_startup_program 的主要作用是初始化參數(shù),而 default_main_program 的主要作用是管理所有的變量和算子。作為初學(xué)者理解到這一層已經(jīng)足夠,PaddlePaddle 內(nèi)部的機(jī)制非常復(fù)雜,該框架對(duì)開(kāi)發(fā)者僅僅暴露了很少的部分,復(fù)雜的機(jī)制都包裹在后臺(tái)。由于 PaddlePaddle 是開(kāi)源的,有興趣深入了解其框架底層實(shí)現(xiàn)的開(kāi)發(fā)者可以訪問(wèn)其 github (https://github.com/PaddlePaddle/Paddle)。

    cost = fluid.layers.square_error_cost(input=y_predict, label=y) avg_loss = fluid.layers.mean(cost)

    訓(xùn)練程序必須返回平均損失作為第一個(gè)返回值,因?yàn)樗鼤?huì)被后面反向傳播算法所用到。

  • 定義優(yōu)化方式
  • sgd_optimizer = fluid.optimizer.SGD(learning_rate=0.001) sgd_optimizer.minimize(avg_loss)#clone a test_program test_program = main_program.clone(for_test=True)

    這里使用了隨機(jī)梯度下降(SGD)作為優(yōu)化器 ,learning_rate 是訓(xùn)練的速度,與網(wǎng)絡(luò)的訓(xùn)練收斂速度有關(guān)系。test_program=main_program.clone(for_test=True) 的作用是為后面邊訓(xùn)練邊測(cè)試做準(zhǔn)備(把環(huán)境拷貝了一份出來(lái))

  • 定義運(yùn)算場(chǎng)所
  • use_cuda = False place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace() exe = fluid.Executor(place)

    我們可以定義運(yùn)算是發(fā)生在CPU還是GPU

    # Plot data from paddle.utils.plot import Plotertrain_prompt = "Train cost" test_prompt = "Test cost" plot_prompt = Ploter(train_prompt, test_prompt)

    展現(xiàn)運(yùn)算過(guò)程有兩種方式:1.打印 log 的方式 2.繪制圖像的方式。相比較來(lái)說(shuō),繪制圖像的方式更加直觀。上面的代碼就是為繪制圖像做準(zhǔn)備。

    訓(xùn)練過(guò)程代碼

  • 定義訓(xùn)練輪數(shù)和 train_test 函數(shù)
  • num_epochs = 100 #設(shè)置訓(xùn)練的輪數(shù)# 在訓(xùn)練過(guò)程中打印出測(cè)試的 loss def train_test(executor, program, reader, feeder, fetch_list):accumulated = 1 * [0]count = 0for data_test in reader():outs = executor.run(program=program,feed=feeder.feed(data_test),fetch_list=fetch_list)accumulated = [x_c[0] + x_c[1][0] for x_c in zip(accumulated, outs)]count += 1return [x_d / count for x_d in accumulated]

    訓(xùn)練需要有一個(gè)訓(xùn)練程序和一些必要參數(shù),并構(gòu)建了一個(gè)獲取訓(xùn)練過(guò)程中測(cè)試誤差的函數(shù)

  • 訓(xùn)練主循環(huán)
  • %matplotlib inline # Specify the directory to save the parameters params_dirname = "fit_a_line.inference.model" feeder = fluid.DataFeeder(place=place, feed_list=[x, y]) naive_exe = fluid.Executor(place) naive_exe.run(startup_program) step = 0exe_test = fluid.Executor(place)# main train loop. for pass_id in range(num_epochs):for data_train in train_reader():avg_loss_value, = exe.run(main_program,feed=feeder.feed(data_train),fetch_list=[avg_loss])if step % 10 == 0: # record a train cost every 10 batchesplot_prompt.append(train_prompt, step, avg_loss_value[0])plot_prompt.plot()if step % 100 == 0: # record a test cost every 100 batchestest_metics = train_test(executor=exe_test,program=test_program,reader=test_reader,fetch_list=[avg_loss.name],feeder=feeder)plot_prompt.append(test_prompt, step, test_metics[0])plot_prompt.plot()# If the accuracy is good enough, we can stop the training.if test_metics[0] < 10.0:breakstep += 1if math.isnan(float(avg_loss_value[0])):sys.exit("got NaN loss, training failed.")if params_dirname is not None:# We can save the trained parameters for the inferences laterfluid.io.save_inference_model(params_dirname, ['x'],[y_predict], exe)

    PaddlePaddle 提供了讀取數(shù)據(jù)者發(fā)生器機(jī)制來(lái)讀取訓(xùn)練數(shù)據(jù)。讀取數(shù)據(jù)者會(huì)一次提供多列數(shù)據(jù),因此我們需要一個(gè) Python 的 list 來(lái)定義讀取順序。我們構(gòu)建一個(gè)循環(huán)來(lái)進(jìn)行訓(xùn)練,直到訓(xùn)練結(jié)果足夠好或者循環(huán)次數(shù)足夠多。 如果訓(xùn)練順利,可以把訓(xùn)練參數(shù)保存到 params_dirname。

    預(yù)測(cè)過(guò)程代碼

    需要構(gòu)建一個(gè)使用訓(xùn)練好的參數(shù)來(lái)進(jìn)行預(yù)測(cè)的程序,訓(xùn)練好的參數(shù)位置在params_dirname

  • 準(zhǔn)備預(yù)測(cè)環(huán)境
  • infer_exe = fluid.Executor(place) inference_scope = fluid.core.Scope()

    類(lèi)似于訓(xùn)練過(guò)程,預(yù)測(cè)器需要一個(gè)預(yù)測(cè)程序來(lái)做預(yù)測(cè)。我們可以稍加修改我們的訓(xùn)練程序來(lái)把預(yù)測(cè)值包含進(jìn)來(lái)。

  • 預(yù)測(cè)
  • with fluid.scope_guard(inference_scope):[inference_program, feed_target_names,fetch_targets] = fluid.io.load_inference_model(params_dirname, infer_exe)batch_size = 10infer_reader = paddle.batch(paddle.dataset.uci_housing.test(), batch_size=batch_size)infer_data = next(infer_reader())infer_feat = numpy.array([data[0] for data in infer_data]).astype("float32")infer_label = numpy.array([data[1] for data in infer_data]).astype("float32")assert feed_target_names[0] == 'x'results = infer_exe.run(inference_program,feed={feed_target_names[0]: numpy.array(infer_feat)},fetch_list=fetch_targets)print("infer results: (House Price)")for idx, val in enumerate(results[0]):print("%d: %.2f" % (idx, val))print("\nground truth:")for idx, val in enumerate(infer_label):print("%d: %.2f" % (idx, val))

    通過(guò)fluid.io.load_inference_model,預(yù)測(cè)器會(huì)從params_dirname中讀取已經(jīng)訓(xùn)練好的模型,來(lái)對(duì)從未遇見(jiàn)過(guò)的數(shù)據(jù)進(jìn)行預(yù)測(cè)。

    完整代碼請(qǐng)參考:
    https://github.com/PaddlePaddle/book/blob/develop/01.fit_a_line/train.py
    更多 PaddlePaddle 示例請(qǐng)參考:
    https://github.com/PaddlePaddle/book/

    參考資料

    [1]《PaddlePaddle深度學(xué)習(xí)實(shí)戰(zhàn)》 劉祥龍等著 2018
    [2]《白話(huà)深度學(xué)習(xí)與TensorFlow》 高揚(yáng)等著,萬(wàn)娟 繪 2017
    [3]《深度學(xué)習(xí)實(shí)戰(zhàn)》楊云等著 2017
    [4] https://en.wikipedia.org/wiki/Cross_entropy
    [5] http://www.paddlepaddle.org/zh
    圖片部分來(lái)源于網(wǎng)絡(luò),侵刪

    總結(jié)

    以上是生活随笔為你收集整理的深度学习入门与快速实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。