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

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

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

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

 

 

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

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

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

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

1.1 Pytorch介紹

Pytorch是開放源代碼機器學(xué)習(xí)框架,目的是加速從研究原型到產(chǎn)品開發(fā)的過程。其 SDK主要基于Python語言,而Python語言作為流行的人工智能開發(fā)語言一直很受研究者與開發(fā)者的歡迎。其模型訓(xùn)練支持CPU與GPU、支持分布式訓(xùn)練、云部署、針對深度學(xué)習(xí)特定領(lǐng)域有不同的豐富的擴展庫。

1.1.1 Pytorch歷史

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

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

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

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

1.1.2  Pytorch的模塊與功能

Pytorch當(dāng)前支持絕大數(shù)的深度學(xué)習(xí)常見的算子操作,基于相關(guān)的功能模塊可以快速整合數(shù)據(jù)、構(gòu)建與設(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)、損失功能、支持自定義的模型類(Module)等。通過它們就可以實現(xiàn)大多數(shù)的模型結(jié)構(gòu)搭建與生成。

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

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

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

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

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

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

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

1.2  環(huán)境搭建

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

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

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

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中的矩形框,必須手動選擇上“add Python3.6 to PATH”之后再點擊【Install Now】默認安裝完成即可。

3. 安裝好Python語言包支持以后可以通過命令行來驗證測試安裝是否成功,首先通過cmd打開Window命令行窗口,然后輸入Python,顯示如下:

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

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

4. 安裝好Python語言包支持之后,只要運行下面的命令行即可完成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支持版本的命令行如下(沒有GPU顯示支持):

pip install torch torchvision torchaudio

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

>>> import torch

>>> torch._ _version_ _

'1.9.0+cu102'

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

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

1.     導(dǎo)入第三方軟件倉庫

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

2.     更新與安裝python3.6

sudo apt-get update

sudo apt-get install python3.6

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

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

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

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

5.     檢查與驗證

zhigang@ubuntu:~$ python -V

Python 3.6.5

成功完成上述五個步驟的命令行執(zhí)行就完成了Python語言包依賴安裝,然后安裝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安裝校驗測試。這樣我們就完成了Pytorch的環(huán)境搭建,這里有個很特別的地方需要注意,就是Pytorch的GPU版本需要CUDA驅(qū)動支持與CUDA庫的安裝配置支持。關(guān)于這塊的安裝強烈建議參照英偉達官方網(wǎng)站的安裝指導(dǎo)與開發(fā)者手冊。

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

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

張量

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

圖1-3(張量表示)

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

算子/操作數(shù)

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

計算圖

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

圖1-4(計算圖示意)

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

自動微分

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

1.4  Pytorch基礎(chǔ)操作

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

1.4.1  PyCharm的安裝與配置

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

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

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

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

點擊【New Project】,輸入項目名稱,顯示如下:

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

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

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

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

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

import torch

print(torch.__version__)

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

1.9.0+cu102

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

1.4.2  張量定義與聲明

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

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

print(a, a.dtype)

運行結(jié)果

tensor([[2., 3.],

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

其中torch.Tensor是torch.FloatTensor的別名,所以默認的數(shù)據(jù)類型是flaot32,這點從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)

運行結(jié)果:

tensor([[1, 2],

[3, 4],

[5, 6],

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

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

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

print(c)

運行結(jié)果:

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

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

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

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

print(d)

運行結(jié)果:

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

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

上面都是創(chuàng)建常量數(shù)組的方式。在實際的開發(fā)中,經(jīng)常需要隨機初始化一些張量變量,創(chuàng)建張量并隨機初始化的方式主要通過torch.rand函數(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)

運行結(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首先隨機初始化種子之后再輸出、v3是函數(shù)torch.randint創(chuàng)建的隨機數(shù)組,它的前面兩個值0跟255表示整數(shù)的取值范圍為0~255之間,最后一個(4,4)表示創(chuàng)建4x4大小的數(shù)組。

1.4.3  張量操作

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

計算圖操作

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

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)

運行結(jié)果如下:

y:  tensor([[ 5.8000],

[12.4000]])

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

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

在實際的開發(fā)過程中,我們經(jīng)常需要在不同類型的數(shù)據(jù)張量中切換,因此數(shù)據(jù)類型轉(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())

運行結(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)

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

維度轉(zhuǎn)換

在Pytorch開發(fā)中另外一個常見的基礎(chǔ)操作就是圖象維度轉(zhuǎn)換與升降維度操作,Pytorch中實現(xiàn)對張量數(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)

運行結(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ù)之外,還有另外一個基于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())

運行結(jié)果如下:

torch.Size([4, 4])

torch.Size([2, 8])

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

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

其它屬性操作

通道交換與尋找最大值是Pytorch中處理張量數(shù)據(jù)常用操作之一,這兩個相關(guān)函數(shù)名稱分別是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))

運行結(jié)果如下:

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

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

tensor(3)

tensor([3, 2])

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

CPU與GPU運算支持

Pytorch支持CPU與GPU計算,默認創(chuàng)建的tensor是CPU版本的,要想使用GPU版本,首先需要檢測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)

以上代碼查詢CUDA支持,如果支持打印GPU名稱并把變量x變成GPU支持?jǐn)?shù)據(jù),并打印輸出。運行結(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默認是CPU類型數(shù)據(jù),y是直接創(chuàng)建的GPU類型數(shù)據(jù)。

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

1.5 線性回歸預(yù)測

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

1.5.1 線性回歸過程

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

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

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

y=kx+b

(公式1-1)

假設(shè)我們有二維的坐標(biāo)點數(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

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

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

(公式1-2)

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

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

(公式1-3)

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

1.5.2 線性回歸代碼演示

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

第一步:構(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是一個自定義的類,繼承了torch.nn.Module,其中torch.nn.Linear就表示構(gòu)建了公式1-1的線性模型,重載方法forward,表示根據(jù)模型計算返回預(yù)測結(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完成自動梯度求解并根據(jù)公式1-3的方式來更新每個參數(shù)。

第四步:開始迭代訓(xùn)練過程

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ù)測得到回歸直線并顯示,代碼如下:

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()

運行結(jié)果如下:

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

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

1.6  小結(jié)

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

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

相關(guān)推薦

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

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