加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專(zhuān)業(yè)用戶(hù)
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 第1章  Pytorch介紹與基礎(chǔ)知識(shí)
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

PyTorch + OpenVINO? 開(kāi)發(fā)實(shí)戰(zhàn)系列教程 第一篇

2021/12/10
397
閱讀需 45 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

 

 

第1章  Pytorch介紹與基礎(chǔ)知識(shí)

大家好,本章是主要介紹一下深度學(xué)習(xí)框架Pytorch的的歷史與發(fā)展,主要模塊構(gòu)成與基礎(chǔ)操作代碼演示。重點(diǎn)介紹Pytorch的各個(gè)組件、編程方式、環(huán)境搭建、基礎(chǔ)操作代碼演示。本章對(duì)有Pytorch開(kāi)發(fā)經(jīng)驗(yàn)的讀者來(lái)說(shuō)可以直接跳過(guò);對(duì)初次接觸Pytorch的讀者來(lái)說(shuō),通過(guò)本章學(xué)習(xí)認(rèn)識(shí)Pytorch框架,搭建好Pytorch的開(kāi)發(fā)環(huán)境,通過(guò)一系列的基礎(chǔ)代碼練習(xí)與演示建立起對(duì)深度學(xué)習(xí)與Pytorch框架的感性認(rèn)知。

本書(shū)內(nèi)容以Python完成全部代碼構(gòu)建與程序演示。本章的主要目標(biāo)是幫助初次接觸Python與Pytorch的讀者搭建好開(kāi)發(fā)環(huán)境,認(rèn)識(shí)與理解Pytorch框架中常見(jiàn)的基礎(chǔ)操作函數(shù)、學(xué)會(huì)使用它們完成一些基礎(chǔ)的數(shù)據(jù)處理與流程處理,為后續(xù)內(nèi)容學(xué)習(xí)打下良好基礎(chǔ)。

好了,下面就讓我們來(lái)一起開(kāi)啟這段Pytorch框架的深度學(xué)習(xí)破冰之旅。

1.1 Pytorch介紹

Pytorch是開(kāi)放源代碼機(jī)器學(xué)習(xí)框架,目的是加速?gòu)难芯吭偷疆a(chǎn)品開(kāi)發(fā)的過(guò)程。其 SDK主要基于Python語(yǔ)言,而Python語(yǔ)言作為流行的人工智能開(kāi)發(fā)語(yǔ)言一直很受研究者與開(kāi)發(fā)者的歡迎。其模型訓(xùn)練支持CPU與GPU、支持分布式訓(xùn)練、云部署、針對(duì)深度學(xué)習(xí)特定領(lǐng)域有不同的豐富的擴(kuò)展庫(kù)。

1.1.1 Pytorch歷史

Pytorch在2016年由facebook發(fā)布的開(kāi)源機(jī)器學(xué)習(xí)(深度學(xué)習(xí))框架,Pytorch最初的來(lái)源歷史可以追溯到另外兩個(gè)機(jī)器學(xué)習(xí)框架,第一個(gè)是torch框架,第二個(gè)是Chainer,實(shí)現(xiàn)了Eager模式與自動(dòng)微分,Pytoch集成了這兩個(gè)框架的優(yōu)點(diǎn), 把Python語(yǔ)言作為框架的首選編程語(yǔ)言,所以它的名字是在torch的前面加上Py之后的Pytorch。由于Pytorch吸取了之前一些深度學(xué)習(xí)框架優(yōu)點(diǎn),開(kāi)發(fā)難度大大降低、很容易構(gòu)建各種深度學(xué)習(xí)模型并實(shí)現(xiàn)分布式的訓(xùn)練,因此一發(fā)布就引發(fā)學(xué)術(shù)界的追捧熱潮,成為深度學(xué)習(xí)研究者與愛(ài)好者的首選開(kāi)發(fā)工具。在pytorch發(fā)布之后兩年的2018年facebook又把caffe2項(xiàng)目整合到pytorch框架中,這樣pytorch就進(jìn)一步整合原來(lái)caffe開(kāi)發(fā)者生態(tài)社區(qū),因?yàn)槠溟_(kāi)發(fā)效率高、特別容易構(gòu)建各種復(fù)雜的深度學(xué)習(xí)模型網(wǎng)絡(luò),因此很快得到大量人工智能開(kāi)發(fā)者的認(rèn)可與追捧,也成為工業(yè)界最受歡迎的深度學(xué)習(xí)框架之一。

Pytorch發(fā)展至今,其版本跟功能幾經(jīng)迭代,針對(duì)不同的場(chǎng)景任務(wù)分裂出不同的分支擴(kuò)展庫(kù),比如針對(duì)自然語(yǔ)言處理(NLP)的torchtext、針對(duì)計(jì)算機(jī)視覺(jué)的torchvision、針對(duì)語(yǔ)音處理的torchaudio,這些庫(kù)支持快速模型訓(xùn)練與演示應(yīng)用,可以幫助開(kāi)發(fā)者快速搭建原型演示。此外在移動(dòng)端支持、模型部署的壓縮、量化、服務(wù)器端云化部署、推理端SDK支持等方面Pytorch也在不斷的演化改進(jìn)。

在操作系統(tǒng)與SDK支持方面,Pytorch從最初的單純支持Python語(yǔ)言到如今支持Python/C++/Java主流編程語(yǔ)言,目前已經(jīng)支持Linux、Windows、MacOS等主流的操作系統(tǒng)、同時(shí)全面支持Android與iOS移動(dòng)端部署。

在版本發(fā)布管理方面,Pytorch分為三種不同的版本分別是穩(wěn)定版本(Stable Release)、Beta版本、原型版本(Prototype)。其中穩(wěn)定版本長(zhǎng)期支持維護(hù)沒(méi)有明顯的性能問(wèn)題與缺陷,理論上支持向后兼容的版本;Beta版本是基于用戶(hù)反饋的改動(dòng)版本,可能有API/SDK函數(shù)改動(dòng),性能有進(jìn)一步需要提升的空間;原型版本是新功能還不可以,需要開(kāi)發(fā)不能通過(guò)pip方式直接安裝。

1.1.2  Pytorch的模塊與功能

Pytorch當(dāng)前支持絕大數(shù)的深度學(xué)習(xí)常見(jiàn)的算子操作,基于相關(guān)的功能模塊可以快速整合數(shù)據(jù)、構(gòu)建與設(shè)計(jì)模型、實(shí)現(xiàn)模型訓(xùn)練、導(dǎo)出與部署等操作。這些功能的相關(guān)模塊主要有如下:

torch.nn包,里面主要包含構(gòu)建卷積神經(jīng)網(wǎng)絡(luò)的各種算子操作,主要包括卷積操作(Conv2d、Conv1d、Conv3d)激活函數(shù)、序貫?zāi)P?Sequential)、功能函數(shù)(functional)、損失功能、支持自定義的模型類(lèi)(Module)等。通過(guò)它們就可以實(shí)現(xiàn)大多數(shù)的模型結(jié)構(gòu)搭建與生成。

torch.utils包,里面主要包括訓(xùn)練模型的輸入數(shù)據(jù)處理類(lèi)、pytorch自帶的模型庫(kù)、模型訓(xùn)練時(shí)候可視化支持組件、檢查點(diǎn)與性能相關(guān)的組件功能。重要的類(lèi)有數(shù)據(jù)集類(lèi)(Dataset), 數(shù)據(jù)加載類(lèi)(DataLoader)、自定義編程的可視化支持組件tensorboard相關(guān)類(lèi)、

torch開(kāi)頭的一些包與功能,主要包括支持模型導(dǎo)出功能的torch.onnx模塊、優(yōu)化器torch.optim模塊、支持GPU訓(xùn)練torch.cuda模塊,這些都是會(huì)經(jīng)常用的。

此外本書(shū)當(dāng)中還會(huì)重點(diǎn)關(guān)注的torchvison庫(kù)中的一些常見(jiàn)模型庫(kù)與功能函數(shù),主要包括對(duì)象檢測(cè)模塊與模型庫(kù)、圖象數(shù)據(jù)增強(qiáng)與預(yù)處理模塊等。

以上并不是pytorch框架中全部模塊與功能說(shuō)明,作者這里只列出了跟本書(shū)內(nèi)容關(guān)聯(lián)密切必須掌握的一些模塊功能,希望讀者可以更好的針對(duì)性學(xué)習(xí),掌握這些知識(shí)。

1.1.3  Pytorch框架現(xiàn)狀與趨勢(shì)

Pytorch是深度學(xué)習(xí)框架的后起之秀,它參考了市場(chǎng)上早期框架包括torch、caffe、tensorflow的經(jīng)驗(yàn)教訓(xùn),從一開(kāi)始設(shè)計(jì)就特別注重開(kāi)發(fā)者體驗(yàn)與生產(chǎn)效率提升,一經(jīng)發(fā)布就引發(fā)追捧熱潮,可以說(shuō)“出道即巔峰”。Pytorch雖然來(lái)自臉書(shū)實(shí)驗(yàn)室,但是它也吸引外部公司包括特斯拉、優(yōu)步、亞馬遜、微軟、阿里等積極支持,其平緩的學(xué)習(xí)曲線,簡(jiǎn)潔方便的函數(shù)與模型構(gòu)建在短時(shí)間內(nèi)吸引了大量學(xué)術(shù)研究者與工業(yè)界開(kāi)發(fā)者的追捧。

當(dāng)前無(wú)論是在學(xué)術(shù)界還是工業(yè)界Pytorch已經(jīng)是主流深度學(xué)習(xí)框架之一,而且大有后來(lái)居上之勢(shì),因此隨著人工智能賦能各行各業(yè),Pytorch框架必然會(huì)更加得到開(kāi)發(fā)者的青睞,成為人工智能(AI)開(kāi)發(fā)者必備技能之一。同時(shí)Pytorch也會(huì)在部署跟推理方面會(huì)更加完善與方便,加強(qiáng)支持移動(dòng)端,嵌入式端等應(yīng)用場(chǎng)景,相信掌握Pytorch框架的開(kāi)發(fā)技術(shù)人才也會(huì)得到豐厚回報(bào)。

1.2  環(huán)境搭建

Pytorch的開(kāi)發(fā)環(huán)境搭建十分的簡(jiǎn)潔,它的依賴(lài)只有Python語(yǔ)言SDK,只要有了Python語(yǔ)言包支持,無(wú)論是在windows平臺(tái)、ubuntu平臺(tái)還是Mac平臺(tái)都靠一條命令行就可以完成安裝。首先是安裝Python語(yǔ)言包支持,當(dāng)前Pytorch支持的Python語(yǔ)言版本與系統(tǒng)對(duì)應(yīng)列表如下:

表-1(參考Pytorch官網(wǎng)與Github)

當(dāng)前最新穩(wěn)定版本是Pytorch 1.9.0、長(zhǎng)期支持版本是Pytorch1.8.2(LTS),此外Python語(yǔ)言支持版本3.6表示支持3.6.x版本,其中x表示3.6版本下的各個(gè)小版本,依此類(lèi)推3.7、3.8同樣如此。本書(shū)代碼演示以Python3.6.5版本作為Python支持語(yǔ)言包。它在Windows系統(tǒng)下的安裝過(guò)程非常簡(jiǎn)單,只需如下幾步:

1. 下載Python3.6.5安裝包,地址為:

https://www.python.org/ftp/python/3.6.5/python-3.6.5-amd64.exe

2. 下載之后,雙擊exe文件安裝,顯示的界面如下:

圖1-1(Python3.6.5安裝界面)

注意:圖1-1中的矩形框,必須手動(dòng)選擇上“add Python3.6 to PATH”之后再點(diǎn)擊【Install Now】默認(rèn)安裝完成即可。

3. 安裝好Python語(yǔ)言包支持以后可以通過(guò)命令行來(lái)驗(yàn)證測(cè)試安裝是否成功,首先通過(guò)cmd打開(kāi)Window命令行窗口,然后輸入Python,顯示如下:

圖1-2(驗(yàn)證Python命令行模式)

如果顯示圖1-2所示的信息表示已經(jīng)安裝成功Python語(yǔ)言包支持;如果輸入Python之后顯示信息為“'python' 不是內(nèi)部或外部命令,也不是可運(yùn)行的程序”則說(shuō)明第二步中沒(méi)有勾選上“add Python3.6 to PATH”,此時(shí)請(qǐng)手動(dòng)把python.exe所在路徑添加到Windows系統(tǒng)的環(huán)境變量中去之后再次執(zhí)行即可。

4. 安裝好Python語(yǔ)言包支持之后,只要運(yùn)行下面的命令行即可完成Pytorch框架的安裝,GPU支持版本的命令行如下(需要GPU顯卡支持):

pip install torch==1.9.0+cu102 torchvision==0.10.0+cu102 torchaudio===0.9.0 -f 

https://download.pytorch.org/whl/torch_stable.html

CPU支持版本的命令行如下(沒(méi)有GPU顯示支持):

pip install torch torchvision torchaudio

5. 在執(zhí)行第三步的基礎(chǔ)上,在命令行中輸入下面兩行代碼,執(zhí)行結(jié)果如下:

>>> import torch

>>> torch._ _version_ _

'1.9.0+cu102'

其中第一行表示導(dǎo)入pytorch的包支持,第二行表示版本查詢(xún),第三行是執(zhí)行結(jié)果(GPU版本)。

現(xiàn)在很多開(kāi)發(fā)者喜歡使用Ubuntu開(kāi)發(fā)系統(tǒng),在Ubuntu系統(tǒng)下如下正確安裝與配置Pytorch,第一步同樣是安裝python語(yǔ)言依賴(lài)包Python3.6,主要是執(zhí)行一系列的安裝命令行,具體步驟如下:

1.     導(dǎo)入第三方軟件倉(cāng)庫(kù)

sudo add-apt-repository ppa:jonathonf/python-3.6

2.     更新與安裝python3.6

sudo apt-get update

sudo apt-get install python3.6

3.     刪除默認(rèn)python版本設(shè)置

zhigang@ubuntu:/usr/bin$ sudo rm python

4.     把安裝好的3.6設(shè)置為默認(rèn)版本

zhigang@ubuntu:/usr/bin$ sudo ln -s python3.6 /usr/bin/python

5.     檢查與驗(yàn)證

zhigang@ubuntu:~$ python -V

Python 3.6.5

成功完成上述五個(gè)步驟的命令行執(zhí)行就完成了Python語(yǔ)言包依賴(lài)安裝,然后安裝Pytorch框架,CPU版本執(zhí)行命令行如下:

pip3 install torch==1.9.0+cpu torchvision==0.10.0+cpu torchaudio==0.9.0 -f https://download.pytorch.org/whl/torch_stable.html

GPU版本執(zhí)行命令行如下:

pip3 install torch torchvision torchaudio

然后執(zhí)行與Windows下相同的命令行完成pytorch安裝校驗(yàn)測(cè)試。這樣我們就完成了Pytorch的環(huán)境搭建,這里有個(gè)很特別的地方需要注意,就是Pytorch的GPU版本需要CUDA驅(qū)動(dòng)支持與CUDA庫(kù)的安裝配置支持。關(guān)于這塊的安裝強(qiáng)烈建議參照英偉達(dá)官方網(wǎng)站的安裝指導(dǎo)與開(kāi)發(fā)者手冊(cè)。

1.3  Pytorch基礎(chǔ)術(shù)語(yǔ)與概念

很多人開(kāi)始學(xué)習(xí)深度學(xué)習(xí)框架面臨的第一個(gè)問(wèn)題就是專(zhuān)業(yè)術(shù)語(yǔ)理解跟基本的編程概念與傳統(tǒng)面向?qū)ο缶幊滩灰粯?,這個(gè)是初學(xué)者面臨的第一個(gè)學(xué)習(xí)障礙。在主流的面向?qū)ο缶幊陶Z(yǔ)言中,結(jié)構(gòu)化代碼最常見(jiàn)的關(guān)鍵字是if、else、while、for等關(guān)鍵字,而在深度學(xué)習(xí)框架中編程模式主要是基于計(jì)算圖、張量數(shù)據(jù)、自動(dòng)微分、優(yōu)化器等組件構(gòu)成。面向?qū)ο缶幊踢\(yùn)行的結(jié)果是交互式可視化的,而深度學(xué)習(xí)通過(guò)訓(xùn)練模型生成模型文件,然后再使用模型預(yù)測(cè),本質(zhì)數(shù)據(jù)流圖的方式工作。所以學(xué)習(xí)深度學(xué)習(xí)首先必須厘清深度學(xué)習(xí)編程中計(jì)算圖、張量數(shù)據(jù)、自動(dòng)微分、優(yōu)化器這些基本術(shù)語(yǔ)概念,下面分別解釋如下:

張量

張量是深度學(xué)習(xí)編程框架中需要理解最重要的一個(gè)概念,張量的本質(zhì)是數(shù)據(jù),在深度學(xué)習(xí)框架中一切的數(shù)據(jù)都可以看成張量。深度學(xué)習(xí)中的計(jì)算圖是以張量數(shù)據(jù)為輸入,通過(guò)算子運(yùn)算,實(shí)現(xiàn)對(duì)整個(gè)計(jì)算圖參數(shù)的評(píng)估優(yōu)化。但是到底什么是張量?可以看下面這張圖:

圖1-3(張量表示)

上圖1-3中標(biāo)量、向量、數(shù)組、3D、4D、5D數(shù)據(jù)矩陣在深度學(xué)習(xí)框架中都被稱(chēng)為張量??梢?jiàn)在深度學(xué)習(xí)框架中所有的數(shù)據(jù)都是張量形式存在,張量是深度學(xué)習(xí)數(shù)據(jù)組織與存在一種數(shù)據(jù)類(lèi)型。

算子/操作數(shù)

深度學(xué)習(xí)主要是針對(duì)張量的數(shù)據(jù)操作、這些數(shù)據(jù)操作從簡(jiǎn)單到復(fù)雜、多數(shù)都是以矩陣計(jì)算的形式存在,最常見(jiàn)的矩陣操作就是加減乘除、此外卷積、池化、激活、也是模型構(gòu)建中非常有用的算子/操作數(shù)。Pytorch支持自定義算子操作,可以通過(guò)自定義算子實(shí)現(xiàn)復(fù)雜的網(wǎng)絡(luò)結(jié)構(gòu),構(gòu)建一些特殊的網(wǎng)絡(luò)模型。張量跟算子/操作數(shù)一起構(gòu)成了計(jì)算圖,它們是也是計(jì)算圖的基本組成要素。

計(jì)算圖

深度學(xué)習(xí)是基于計(jì)算圖完成模型構(gòu)建,實(shí)現(xiàn)數(shù)據(jù)在各個(gè)計(jì)算圖節(jié)點(diǎn)之間流動(dòng),最終輸出,因此計(jì)算圖又被稱(chēng)為數(shù)據(jù)流圖。根據(jù)構(gòu)建計(jì)算圖的方式不同還可以分為靜態(tài)圖與動(dòng)態(tài)圖,Pytorch默認(rèn)是基于動(dòng)態(tài)圖的方式構(gòu)建計(jì)算圖,動(dòng)態(tài)圖采用類(lèi)似python語(yǔ)法,可以隨時(shí)運(yùn)行,靈活修改調(diào)整;而靜態(tài)圖則是效率優(yōu)先,但是在圖構(gòu)建完成之前無(wú)法直接運(yùn)行??梢钥闯鰟?dòng)態(tài)圖更加趨向于開(kāi)發(fā)者平時(shí)接觸的面向?qū)ο蟮木幊谭绞?,也更容易被開(kāi)發(fā)者理解與接受。下圖是一個(gè)簡(jiǎn)單的計(jì)算圖示例:

圖1-4(計(jì)算圖示意)

圖1-4中最底層三個(gè)節(jié)點(diǎn)表示計(jì)算圖的輸入張量數(shù)據(jù)節(jié)點(diǎn)(a、b、c)、剩下節(jié)點(diǎn)表示操作、帶箭頭的線段表示數(shù)據(jù)的流向。

自動(dòng)微分

使用Pytorch構(gòu)建神經(jīng)網(wǎng)絡(luò)(計(jì)算圖)模型之后,一般都是通過(guò)反向傳播進(jìn)行訓(xùn)練,使用反向傳播算法對(duì)神經(jīng)網(wǎng)絡(luò)中每個(gè)參數(shù)根據(jù)損失函數(shù)功能根據(jù)梯度進(jìn)行參數(shù)值的調(diào)整。為了計(jì)算這些梯度完成參數(shù)調(diào)整,深度學(xué)習(xí)框架中都會(huì)自帶一個(gè)叫做自動(dòng)微分的內(nèi)置模塊,來(lái)自動(dòng)計(jì)算神經(jīng)網(wǎng)絡(luò)模型訓(xùn)練時(shí)候的各個(gè)參數(shù)梯度值并完成參數(shù)值更新,這種技術(shù)就是深度學(xué)習(xí)框架中的自動(dòng)微分。

1.4  Pytorch基礎(chǔ)操作

前面我們已經(jīng)安裝并驗(yàn)證好了Pytorch框架,解釋了深度學(xué)習(xí)框架中一些常見(jiàn)術(shù)語(yǔ)與基本概念。本節(jié)重點(diǎn)介紹Pytorch中一些基本的數(shù)據(jù)定義與類(lèi)型轉(zhuǎn)換、算子操作、通過(guò)它們幫助讀者進(jìn)一步了解Pytorch開(kāi)發(fā)基礎(chǔ)知識(shí),為后續(xù)章節(jié)學(xué)習(xí)打下良好基礎(chǔ)。在正式開(kāi)始這些基礎(chǔ)操作之前,我們首先需要有一個(gè)合適的集成開(kāi)發(fā)環(huán)境(IDE),本書(shū)的源代碼是基于Python實(shí)現(xiàn),演示的集成開(kāi)發(fā)環(huán)境(IDE)是PyCharm。

1.4.1  PyCharm的安裝與配置

首先是從Pycharm官方網(wǎng)站上下載Pycharm,版本有專(zhuān)業(yè)版與社區(qū)版之分,社區(qū)版免費(fèi)使用而專(zhuān)業(yè)版則需要付費(fèi)使用。Pycharm官方網(wǎng)站如下:

https://www.jetbrains.com/pycharm/

點(diǎn)擊就可以下載專(zhuān)業(yè)版試用或者社區(qū)免費(fèi)版,默認(rèn)安裝之后就可以通過(guò)桌面圖標(biāo)雙擊打開(kāi)如下:

圖1-5(Pycharm導(dǎo)航頁(yè)面)

點(diǎn)擊【New Project】,輸入項(xiàng)目名稱(chēng),顯示如下:

圖1-6(創(chuàng)建新項(xiàng)目)

點(diǎn)擊【Create】按鈕完成項(xiàng)目創(chuàng)建,選擇文件(File)->設(shè)置(Setting)選項(xiàng):

圖1-7(設(shè)置選項(xiàng))

圖1-8(設(shè)置系統(tǒng)Python解釋器)

完成之后,在項(xiàng)目中創(chuàng)建一個(gè)空的python文件命名為main.py,然后直接輸入下面兩行測(cè)試代碼:

import torch

print(torch.__version__)

執(zhí)行測(cè)試(作者筆記本):

1.9.0+cu102

這樣我們就完成了PyCharm IDE開(kāi)發(fā)環(huán)境配置與項(xiàng)目創(chuàng)建。

1.4.2  張量定義與聲明

張量在Pytorch深度學(xué)習(xí)框架中表示的數(shù)據(jù),有幾種不同的方式來(lái)創(chuàng)建與聲明張量數(shù)據(jù),一種是通過(guò)常量數(shù)值來(lái)直接聲明為tensor數(shù)據(jù),代碼如下:

a = torch.tensor([[2., 3.], [4., 5.]])

print(a, a.dtype)

運(yùn)行結(jié)果

tensor([[2., 3.],

[4., 5.]]) torch.float32

其中torch.Tensor是torch.FloatTensor的別名,所以默認(rèn)的數(shù)據(jù)類(lèi)型是flaot32,這點(diǎn)從a.dtype的打印結(jié)果上也得了印證。此外torch.Tensor函數(shù)還支持從Numpy數(shù)組直接轉(zhuǎn)換為張量數(shù)據(jù),這種定義聲明張量數(shù)據(jù)的代碼如下:

b = torch.tensor(np.array([[1,2],[3,4],[5,6],[7, 8]]))

print(b)

運(yùn)行結(jié)果:

tensor([[1, 2],

[3, 4],

[5, 6],

[7, 8]], dtype=torch.int32)

根據(jù)數(shù)據(jù)類(lèi)型的自動(dòng)識(shí)別,轉(zhuǎn)換為torch.int32的數(shù)據(jù)類(lèi)型。除了直接聲明常量數(shù)組的方式,Pytorch框架還支持類(lèi)似Matlab方式的數(shù)組初始化方式,可以定義數(shù)組的維度,然后初始化為零,相關(guān)的演示代碼如下:

c = torch.zeros([2, 4], dtype=torch.float32)

print(c)

運(yùn)行結(jié)果:

tensor([[0., 0., 0., 0.],

[0., 0., 0., 0.]])

初始化了一個(gè)兩行四列值全部為零的數(shù)組。torch.zeros表示初始化全部為零,torch.ones表示初始化全部為1,torch.ones的代碼演示如下:

d = torch.ones([2, 4], dtype=torch.float32)

print(d)

運(yùn)行結(jié)果:

tensor([[1., 1., 1., 1.],

[1., 1., 1., 1.]])

上面都是創(chuàng)建常量數(shù)組的方式。在實(shí)際的開(kāi)發(fā)中,經(jīng)常需要隨機(jī)初始化一些張量變量,創(chuàng)建張量并隨機(jī)初始化的方式主要通過(guò)torch.rand函數(shù)實(shí)現(xiàn)。用該函數(shù)創(chuàng)建張量的代碼演示如下:

v1 = torch.rand((2, 3))

print("v1 = ", v1)

torch.initial_seed()

v2 = torch.rand((2, 3))

print("v2 = ", v2)

v3 = torch.randint(0, 255, (4, 4))

print("v3 = ", v3)

運(yùn)行結(jié)果:

v1 =  tensor([[0.5257, 0.4236, 0.0409],

[0.3271, 0.6173, 0.8080]])

v2 =  tensor([[0.9671, 0.6011, 0.3136],

[0.7428, 0.9261, 0.6602]])

v3 =  tensor([[181, 170,  49,  82],

[209,  25,   0, 210],

[ 65, 220,  93,  11],

[133, 102,  64, 230]])

其中v1是直接輸出、v2首先隨機(jī)初始化種子之后再輸出、v3是函數(shù)torch.randint創(chuàng)建的隨機(jī)數(shù)組,它的前面兩個(gè)值0跟255表示整數(shù)的取值范圍為0~255之間,最后一個(gè)(4,4)表示創(chuàng)建4x4大小的數(shù)組。

1.4.3  張量操作

通過(guò)前面一小節(jié),我們已經(jīng)學(xué)會(huì)了在Pytorch中如何創(chuàng)建張量,本節(jié)將介紹張量常見(jiàn)的算子操作,通過(guò)這些操作進(jìn)一步加深對(duì)Pytorch的理解。

計(jì)算圖操作

還記得圖1-4的計(jì)算圖嗎?這里我們就通過(guò)代碼構(gòu)建這樣一個(gè)計(jì)算圖,完成一系列基于張量的算子操作,演示代碼如下:

a = torch.tensor([[2., 3.], [4., 5.]])

b = torch.tensor([[10, 20], [30, 40]])

c = torch.tensor([[0.1], [0.2]])

x = a + b

y = torch.matmul(x, c)

print("y: ", y)

運(yùn)行結(jié)果如下:

y:  tensor([[ 5.8000],

[12.4000]])

上面得代碼中x是a加b的結(jié)果,y是a加b之和與c的矩陣乘法的最終輸出結(jié)果。

數(shù)據(jù)類(lèi)型轉(zhuǎn)換

在實(shí)際的開(kāi)發(fā)過(guò)程中,我們經(jīng)常需要在不同類(lèi)型的數(shù)據(jù)張量中切換,因此數(shù)據(jù)類(lèi)型轉(zhuǎn)換函數(shù)也是必修的,代碼演示如下:

m = torch.tensor([1.,2.,3.,4.,5.,6], dtype=torch.float32)

print(m, m.dtype)

print(m.int())

print(m.long())

print(m.double())

運(yùn)行結(jié)果如下:

tensor([1., 2., 3., 4., 5., 6.]) torch.float32

tensor([1, 2, 3, 4, 5, 6], dtype=torch.int32)

tensor([1, 2, 3, 4, 5, 6])

tensor([1., 2., 3., 4., 5., 6.], dtype=torch.float64)

可見(jiàn),在PyTorch中實(shí)現(xiàn)數(shù)據(jù)類(lèi)型轉(zhuǎn)換非常的便捷, m.int()表示轉(zhuǎn)換偉32位整型、m.double()表示轉(zhuǎn)換位64位浮點(diǎn)數(shù)類(lèi)型、m.long()表示64位整型。

維度轉(zhuǎn)換

在Pytorch開(kāi)發(fā)中另外一個(gè)常見(jiàn)的基礎(chǔ)操作就是圖象維度轉(zhuǎn)換與升降維度操作,Pytorch中實(shí)現(xiàn)對(duì)張量數(shù)據(jù)的維度轉(zhuǎn)換與升降的代碼演示如下:

a = torch.arange(12.)

a = torch.reshape(a, (3, 4))

print("a: ", a)

a = torch.reshape(a, (-1, 6))

print("a: ", a)

a = torch.reshape(a, (-1, ))

print("a: ", a)

a = torch.reshape(a, (1, 1, 3, 4))

print("a: ", a)

運(yùn)行結(jié)果如下:

a:  tensor([[ 0.,  1.,  2.,  3.],

[ 4.,  5.,  6.,  7.],

[ 8.,  9., 10., 11.]])

a:  tensor([[ 0.,  1.,  2.,  3.,  4.,  5.],

[ 6.,  7.,  8.,  9., 10., 11.]])

a:  tensor([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11.])

a:  tensor([[[[ 0.,  1.,  2.,  3.],

[ 4.,  5.,  6.,  7.],

[ 8.,  9., 10., 11.]]]])

其中a是聲明的張量數(shù)據(jù),torch.reshape(a, (3, 4))意思轉(zhuǎn)換為3行4列的二維數(shù)組、torch.reshape(a, (-1, 6))表示轉(zhuǎn)為每行6列的二維數(shù)組,其中-1表示從列數(shù)推理得到行數(shù)、torch.reshape(a, (-1, ))表示直接轉(zhuǎn)換為一行、torch.reshape(a, (1, 1, 3, 4))表示轉(zhuǎn)為1x1x3x4的四維張量。除了torch.reshape函數(shù)之外,還有另外一個(gè)基于tensor的維度轉(zhuǎn)換方法tensor.view(), 它的用法代碼演示如下:

x = torch.randn(4, 4)

print(x.size())

x = x.view(-1, 8)

print(x.size())

x = x.view(1, 1, 4, 4)

print(x.size())

運(yùn)行結(jié)果如下:

torch.Size([4, 4])

torch.Size([2, 8])

torch.Size([1, 1, 4, 4])

其中torch.randn(4, 4)是創(chuàng)建一個(gè)4x4的隨機(jī)張量;x.view(-1, 8)表示轉(zhuǎn)換為每行八列的,-1表示自動(dòng)計(jì)算行數(shù);x.view(1, 1, 4, 4)表示轉(zhuǎn)換為1x1x4x4的四維張量。其中torch.size表示輸出數(shù)組維度大小。

其它屬性操作

通道交換與尋找最大值是Pytorch中處理張量數(shù)據(jù)常用操作之一,這兩個(gè)相關(guān)函數(shù)名稱(chēng)分別是torch.transpose與torch.argmax,支持張量直接操作。代碼演示如下:

x = torch.randn(5, 5, 3)

print(x.size())

x = x.transpose(2, 0)

print(x.size())

x = torch.tensor([2., 3., 4.,12., 3., 5., 8., 1.])

print(torch.argmax(x))

x = x.view(-1, 4)

print(x.argmax(1))

運(yùn)行結(jié)果如下:

torch.Size([5, 5, 3])

torch.Size([3, 5, 5])

tensor(3)

tensor([3, 2])

運(yùn)行結(jié)果的第一行對(duì)應(yīng)是聲明的張量x的維度信息、第二行是調(diào)用transpose方法完成通道交換之后x輸出的維度信息;第三行是針對(duì)x調(diào)用argmax得到最大值對(duì)應(yīng)索引(12對(duì)應(yīng)索引值為3)、第四行是進(jìn)行維度變換之后針對(duì)二維數(shù)據(jù)(2x4)的第二個(gè)維度調(diào)用argmax得到的輸出,分別是12與8對(duì)應(yīng)的索引值[3,2]。

CPU與GPU運(yùn)算支持

Pytorch支持CPU與GPU計(jì)算,默認(rèn)創(chuàng)建的tensor是CPU版本的,要想使用GPU版本,首先需要檢測(cè)GPU支持,然后轉(zhuǎn)換為GPU數(shù)據(jù),或者直接創(chuàng)建為GPU版本數(shù)據(jù),代碼演示如下:

gpu = torch.cuda.is_available()

for i in range(torch.cuda.device_count()):

print(torch.cuda.get_device_name(i))

if gpu:

print(x.cuda())

y = torch.tensor([1, 2, 3, 4], device="cuda:0")

print("y: ", y)

以上代碼查詢(xún)CUDA支持,如果支持打印GPU名稱(chēng)并把變量x變成GPU支持?jǐn)?shù)據(jù),并打印輸出。運(yùn)行結(jié)果如下:

GeForce GTX 1050 Ti

tensor([[ 2.,  3.,  4., 12.],

[ 3.,  5.,  8.,  1.]], device='cuda:0')

y:  tensor([1, 2, 3, 4], device='cuda:0')

這里x默認(rèn)是CPU類(lèi)型數(shù)據(jù),y是直接創(chuàng)建的GPU類(lèi)型數(shù)據(jù)。

以上都是一些最基礎(chǔ)跟使用頻率較高的Pytorch基礎(chǔ)操作,了解并掌握這些函數(shù)有助于進(jìn)一步學(xué)習(xí)本書(shū)后續(xù)章節(jié)知識(shí),更多關(guān)于Pytorch基礎(chǔ)操作的函數(shù)知識(shí)與參數(shù)說(shuō)明,讀者可以直接參見(jiàn)官方的開(kāi)發(fā)文檔。

1.5 線性回歸預(yù)測(cè)

上一小節(jié)介紹了Pytorch框架各種基礎(chǔ)操作,本節(jié)我們學(xué)習(xí)一個(gè)堪稱(chēng)是深度學(xué)習(xí)版本的Hello World程序,幫助讀者理解模型訓(xùn)練與參數(shù)優(yōu)化等基本概念,開(kāi)始我們學(xué)習(xí)Pytorch框架編程的愉快旅程。

1.5.1 線性回歸過(guò)程

很坦誠(chéng)的說(shuō),有很多資料把線性回歸表述的很復(fù)雜、一堆公式推導(dǎo)讓初學(xué)者望而生畏,無(wú)法準(zhǔn)確快速理解線性回歸,這里作者將通過(guò)一個(gè)碼農(nóng)的獨(dú)特視角來(lái)解釋線性回歸概念。線性回歸的本質(zhì)就是根據(jù)給出二維數(shù)據(jù)集來(lái)擬合生成一條直線,簡(jiǎn)單的圖示如下:

圖1-9(線性回歸與非線性回歸)

圖1-9左側(cè)是圖中得圓點(diǎn)表示xy二維坐標(biāo)點(diǎn)數(shù)據(jù)集,直線是根據(jù)線性回歸算法生成的。右側(cè)則是一個(gè)根據(jù)坐標(biāo)點(diǎn)數(shù)據(jù)集生成一個(gè)非線性回歸的例子。現(xiàn)在我們已經(jīng)可以很直觀的了解什么線性回歸了,腦子里面可能會(huì)有個(gè)大大的疑問(wèn)(?),線性回歸是怎么找到這條直線的?答案就是通過(guò)Pytorch構(gòu)建一個(gè)簡(jiǎn)單的計(jì)算圖來(lái)不斷學(xué)習(xí),最終得到一個(gè)足夠逼近真實(shí)直線參數(shù)方程,這個(gè)過(guò)程也可以被稱(chēng)為線性回歸的學(xué)習(xí)/訓(xùn)練過(guò)程。最終根據(jù)得到的參數(shù)就可以繪制回歸直線。那這個(gè)計(jì)算圖到底是怎么樣的?答案就是很簡(jiǎn)單的數(shù)學(xué)知識(shí),最常見(jiàn)的直線方程如下:

y=kx+b

(公式1-1)

假設(shè)我們有二維的坐標(biāo)點(diǎn)數(shù)據(jù)集:

x: 1,2,0.5,2.5,2.6,3.1

y: 3.7,4.6,1.65,5.68,5.98,6.95

我們通過(guò)隨機(jī)賦值初始k、b兩個(gè)參數(shù),根據(jù)公式1-1,x會(huì)生成一個(gè)對(duì)應(yīng)輸出,它跟真實(shí)值y之間的差值我們稱(chēng)為損失,最常見(jiàn)的為均值平方損失(MSE),表示如下:

MSE=1/n ∑?〖(y-y ?)〗^2

(公式1-2)

然后我們可以通過(guò)下面的公式來(lái)更新k、b兩個(gè)參數(shù):

更新參數(shù)(k",b")=參數(shù)(k,b)-學(xué)習(xí)率*對(duì)應(yīng)參數(shù)梯度

(公式1-3)

其中學(xué)習(xí)率通常用表示,對(duì)應(yīng)的每個(gè)參數(shù)梯度則根據(jù)深度學(xué)習(xí)框架的自動(dòng)微分機(jī)制得到的,這樣就實(shí)現(xiàn)了線性回歸模型模型的構(gòu)建與訓(xùn)練過(guò)程,最終根據(jù)輸入的迭代次數(shù)運(yùn)行輸出就獲取了回歸直線的兩個(gè)參數(shù)。完成了線性回歸的求解。

1.5.2 線性回歸代碼演示

通過(guò)前面一小節(jié)的學(xué)習(xí)讀者應(yīng)該了什么是線性回歸、線性回歸是如何工作的,現(xiàn)在我們已經(jīng)迫不及待的想在Pytorch中通過(guò)代碼來(lái)驗(yàn)證我們上面的理論解釋了。Pytorch提供了豐富的函數(shù)組件可以幫助我們快速搭建線性回歸模型并完成訓(xùn)練預(yù)測(cè)。

第一步:構(gòu)建數(shù)據(jù)集

x = np.array([1,2,0.5,2.5,2.6,3.1], dtype=np.float32).reshape((-1, 1))

y = np.array([3.7,4.6,1.65,5.68,5.98,6.95], dtype=np.float32).reshape(-1, 1)

第二步:根據(jù)公式1-1構(gòu)建線性回歸模型

class LinearRegressionModel(torch.nn.Module):

def __init__(self, input_dim, output_dim):

super(LinearRegressionModel, self).__init__()

self.linear = torch.nn.Linear(input_dim, output_dim)

def forward(self, x):

out = self.linear(x)

return out

LinearRegressionModel是一個(gè)自定義的類(lèi),繼承了torch.nn.Module,其中torch.nn.Linear就表示構(gòu)建了公式1-1的線性模型,重載方法forward,表示根據(jù)模型計(jì)算返回預(yù)測(cè)結(jié)果。

第三步:創(chuàng)建損失功能與優(yōu)化器

input_dim = 1

output_dim = 1

model = LinearRegressionModel(input_dim, output_dim)

criterion = torch.nn.MSELoss()

learning_rate = 0.01

optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

其中MSELoss跟公式1-2表述一致、優(yōu)化器optimizer完成自動(dòng)梯度求解并根據(jù)公式1-3的方式來(lái)更新每個(gè)參數(shù)。

第四步:開(kāi)始迭代訓(xùn)練過(guò)程

for epoch in range(100):

epoch += 1

# Convert numpy array to torch Variable

inputs = torch.from_numpy(x).requires_grad_()

labels = torch.from_numpy(y)

# Clear gradients w.r.t. parameters

optimizer.zero_grad()

# Forward to get output

outputs = model(inputs)

# Calculate Loss

loss = criterion(outputs, labels)

# Getting gradients w.r.t. parameters

loss.backward()

# Updating parameters

optimizer.step()

print('epoch {}, loss {}'.format(epoch, loss.item()))

這部分的代碼注釋都很清楚了,這里就不再贅述。

第五步:根據(jù)訓(xùn)練得到的參數(shù),使用模型預(yù)測(cè)得到回歸直線并顯示,代碼如下:

predicted = model(torch.from_numpy(x).requires_grad_()).data.numpy()

# Plot true data

plt.plot(x, y, 'go', label='True data', alpha=0.5)

# Plot predictions

plt.plot(x, predicted_y, '--', label='Predictions', alpha=0.5)

# Legend and plot

plt.legend(loc='best')

plt.show()

運(yùn)行結(jié)果如下:

圖1-10中點(diǎn)表示訓(xùn)練數(shù)據(jù),直線表示線性回歸預(yù)測(cè)。

總結(jié)線性回歸這個(gè)入門(mén)級(jí)別例子演示,我們從中可以學(xué)習(xí)到一些基本組件函數(shù),它們就是模型創(chuàng)建、損失函數(shù)、學(xué)習(xí)率、優(yōu)化器,它們都是Pytroch開(kāi)發(fā)中必須掌握的基本組件函數(shù)與方法,學(xué)會(huì)使用它們可以事半功倍,減少代碼量,提升開(kāi)發(fā)效率。

1.6  小結(jié)

本章是Pytorch框架與基礎(chǔ)知識(shí)的介紹,通過(guò)本章學(xué)習(xí)了解Pytorch框架的歷史與發(fā)展、理解深度學(xué)習(xí)框架常見(jiàn)的術(shù)語(yǔ)與詞匯含義;安裝Python SDK、掌握Pytorch安裝命令行、Pycharm IDE安裝與配置。學(xué)會(huì)使用Pytorch創(chuàng)建基本的張量、能夠完成常見(jiàn)的張量數(shù)據(jù)操作、最后通過(guò)一個(gè)具有代表性的線性回歸的例子,幫助大家真正打開(kāi)Pytroch框架開(kāi)發(fā)的大門(mén)。

本章的目標(biāo)是幫助初學(xué)者厘清深度學(xué)習(xí)框架基本概念、基礎(chǔ)組件與基礎(chǔ)數(shù)據(jù)操作、同時(shí)通過(guò)案例激發(fā)起大家進(jìn)一步學(xué)習(xí)的興趣。

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

英特爾致力于加快智能設(shè)備的開(kāi)發(fā)和部署,通過(guò)智能多層系統(tǒng)和端到端分析,在智能駕駛、智能零售、智能安防、智能制造等領(lǐng)域,推動(dòng)企業(yè)業(yè)務(wù)轉(zhuǎn)型,改善人們的生活和工作方式,英特爾驅(qū)動(dòng)物聯(lián)網(wǎng)變革。