pytorch源碼
1. 如何有效地閱讀PyTorch的源代碼
庫本身的代碼,比較簡單易讀,我作為python菜鳥,也能看懂。目前model有sequential和grapgh兩種,前者並不是指recurrent而是說網路是一層層堆的(也包括recurrent).其他的主要概念包括layer,regularizer, optimizer,objective都分離開。layer用於build每層的輸出函數,model會用最後一層的輸出,根據objective和每個layer的regularizer來確定最終的cost,然後在update時用optimizer來更新參數。把這四個看下加上model里的fit函數,就會用theano啦。很多模型都能cover,seq2seq這種也有現成的可用。建議不要光看example,多看看github上的 issues討論,實在找不到,直接提問。效率方面,我不懂theano怎麼優化,感覺keras的這種封裝,沒什麼成本,跟自己用原生theano是一樣的。當然,theano本身就好慢啊。。估計是我不懂用吧。。
2. Pytorch_循環神經網路RNN
RNN是Recurrent Neural Networks的縮寫,即循環神經網路,它常用於解決序列問題。RNN有記憶功能,除了當前輸入,還把上下文環境作為預測的依據。它常用於語音識別、翻譯等場景之中。
RNN是序列模型的基礎,盡管能夠直接調用現成的RNN演算法,但後續的復雜網路很多構建在RNN網路的基礎之上,如Attention方法需要使用RNN的隱藏層數據。RNN的原理並不復雜,但由於其中包括循環,很難用語言或者畫圖來描述,最好的方法是自己手動編寫一個RNN網路。本篇將介紹RNN網路的原理及具體實現。
在學習循環神經網路之前,先看看什麼是序列。序列sequence簡稱seq,是有先後順序的一組數據。自然語言處理是最為典型的序列問題,比如將一句話翻譯成另一句話時,其中某個詞彙的含義不僅取決於它本身,還與它前後的多個單詞相關。類似的,如果想預測電影的情節發展,不僅與當前的畫面有關,還與當前的一系列前情有關。在使用序列模型預測的過程中,輸入是序列,而輸出是一個或多個預測值。
在使用深度學習模型解決序列問題時, 最容易混淆的是,序列與序列中的元素 。在不同的場景中,定義序列的方式不同,當分析單詞的感情色彩時,一個單詞是一個序列seq;當分析句子感情色彩時,一個句子是一個seq,其中的每個單詞是序列中的元素;當分析文章感情色彩時,一篇文章是一個seq。簡單地說,seq是最終使用模型時的輸入數據,由一系列元素組成。
當分析句子的感情色彩時,以句為seq,而句中包含的各個單詞的含義,以及單詞間的關系是具體分析的對象,此時,單詞是序列中的元素,每一個單詞又可有多維特徵。從單詞中提取特徵的方法將在後面的自然語言處理中介紹。
RNN有很多種形式,單個輸入單個輸入;多個輸入多個輸出,單個輸入多個輸出等等。
舉個最簡單的例子:用模型預測一個四字短語的感情色彩,它的輸入為四個元素X={x1,x2,x3,x4},它的輸出為單個值Y={y1}。字的排列順序至關重要,比如「從好變壞」和「從壞變好」,表達的意思完全相反。之所以輸入輸出的個數不需要一一對應,是因為中間的隱藏層,變向存儲中間信息。
如果把模型設想成黑盒,如下圖所示:
如果模型使用全連接網路,在每次迭代時,模型將計算各個元素x1,x2...中各個特徵f1,f2...代入網路,求它們對結果y的貢獻度。
RNN網路則要復雜一些,在模型內部,它不是將序列中所有元素的特徵一次性輸入模型,而是每一次將序列中單個元素的特徵輸入模型,下圖描述了RNN的數據處理過程,左圖為分步展示,右圖將所有時序步驟抽象成單一模塊。
第一步:將第一個元素x1的特徵f1,f2...輸入模型,模型根據輸入計算出隱藏層h。
第二步:將第二個元素x2的特徵輸入模型,模型根據輸入和上一步產生的h再計算隱藏層h,其它元素以此類推。
第三步:將最後一個元素xn的特徵輸入模型,模型根據輸入和上一步產生的h計算隱藏層h和預測值y。
隱藏層h可視為將序列中前面元素的特徵和位置通過編碼向前傳遞,從而對輸出y發生作用,隱藏層的大小決定了模型攜帶信息量的多少。隱藏層也可以作為模型的輸入從外部傳入,以及作為模型的輸出返回給外部調用。
本例仍使用上篇中的航空乘客序列數據,分別用兩種方法實現RNN:自己編寫程序實現RNN模型,以及調用Pytorch提供的RNN模型。前一種方法主要用於剖析原理,後一種用於展示常用的調用方法。
首先導入頭文件,讀取乘客數據,做歸一化處理,並將數據切分為測試集和訓練集,與之前不同的是加入了create_dataset函數,用於生成序列數據,序列的輸入部分,每個元素中包括兩個特徵:前一個月的乘客量prev和月份值mon,這里的月份值並不是關鍵特徵,主要用於在常式中展示如何使用多個特徵。
第一步:實現模型類,此例中的RNN模型除了全連接層,還生成了一個隱藏層,並在下一次前向傳播時將隱藏層輸出的數據與輸入數據組合後再代入模型運算。
第二步,訓練模型,使用全部數據訓練500次,在每次訓練時,內部for循環將序列中的每個元素代入模型,並將模型輸出的隱藏層和下一個元素一起送入下一次迭代。
第三步:預測和作圖,預測的過程與訓練一樣,把全部數據拆分成元素代入模型,並將每一次預測結果存儲在數組中,並作圖顯示。
需要注意的是,在訓練和預測過程中,每一次開始輸入新序列之前,都重置了隱藏層,這是由於隱藏層的內容只與當前序列相關,序列之間並無連續性。
程序輸出結果如下圖所示:
經過500次迭代,使用RNN的效果明顯優於上一篇中使用全連接網路的擬合效果,還可以通過調整超參數以及選擇不同特徵,進一步優化。
使用Pytorch提供的RNN模型,torch.nn.RNN類可直接使用,是循環網路最常用的解決方案。RNN,LSTM,GRU等循環網路都實現在同一源碼文件torch/nn/moles/rnn.py中。
第一步:創建模型,模型包含兩部分,第一部分是Pytorch提供的RNN層,第二部分是一個全連接層,用於將RNN的輸出轉換成輸出目標的維度。
Pytorch的RNN前向傳播允許將隱藏層數據h作為參數傳入模型,並將模型產生的h和y作為函數返回值。形如: pred, h_state = model(x, h_state)
什麼情況下需要接收隱藏層的狀態h_state,並轉入下一次迭代呢?當處理單個seq時,h在內部前向傳遞;當序列與序列之間也存在前後依賴關系時,可以接收h_state並傳入下一步迭代。另外,當模型比較復雜如LSTM模型包含眾多參數,傳遞會增加模型的復雜度,使訓練過程變慢。本例未將隱藏層轉到模型外部,這是由於模型內部實現了對整個序列的處理,而非處理單個元素,而每次代入的序列之間又沒有連續性。
第二步:訓練模型,與上例中把序列中的元素逐個代入模型不同,本例一次性把整個序列代入了模型,因此,只有一個for循環。
Pythorch支持批量處理,前向傳遞時輸入數據格式是[seq_len, batch_size, input_dim),本例中輸入數據的維度是[100, 1, 2],input_dim是每個元素的特徵數,batch_size是訓練的序列個數,seq_len是序列的長度,這里使用70%作為訓練數據,seq_len為100。如果數據維度的順序與要求不一致,一般使用transpose轉換。
第三步:預測和作圖,將全部數據作為序列代入模型,並用預測值作圖。
程序輸出結果如下圖所示:
可以看到,經過500次迭代,在前100個元素的訓練集上擬合得很好,但在測試集效果較差,可能存在過擬合。
3. 《深度學習框架PyTorch:入門與實踐》epub下載在線閱讀,求百度網盤雲資源
《深度學習框架PyTorch:入門與實踐》(陳雲)電子書網盤下載免費在線閱讀
資源鏈接:
鏈接:https://pan..com/s/1H1PSIo3KOOWh87ZtyR4oKQ
書名:深度學習框架PyTorch:入門與實踐
作者:陳雲
豆瓣評分:6.7
出版社:電子工業出版社
出版年份:2018-1
頁數:300
內容簡介:
《深度學習框架PyTorch:入門與實踐》從多維數組Tensor開始,循序漸進地帶領讀者了解PyTorch各方面的基礎知識。結合基礎知識和前沿研究,帶領讀者從零開始完成幾個經典有趣的深度學習小項目,包括GAN生成動漫頭像、AI濾鏡、AI寫詩等。《深度學習框架PyTorch:入門與實踐》沒有簡單機械地介紹各個函數介面的使用,而是嘗試分門別類、循序漸進地向讀者介紹PyTorch的知識,希望讀者對PyTorch有一個完整的認識。
《深度學習框架PyTorch:入門與實踐》內容由淺入深,無論是深度學習的初學者,還是第一次接觸PyTorch的研究人員,都能在學習本書的過程中快速掌握PyTorch。即使是有一定PyTorch使用經驗的用戶,也能夠從本書中獲得對PyTorch不一樣的理解。
作者簡介:
陳雲
Python程序員、Linux愛好者和PyTorch源碼貢獻者。主要研究方向包括計算機視覺和機器學習。「2017知乎看山杯機器學習挑戰賽」一等獎,「2017天池醫療AI大賽」第八名。 熱衷於推廣PyTorch,並有豐富的使用經驗,活躍於PyTorch論壇和知乎相關板塊。
4. 求教pytorch這段代碼的意思learning_rate = 1e-6
pytorch中這段代碼的意思是把學習率learning_rate設為0.000001
但是設置學習率不是給learning_rate賦值就可以完成的,
在pytorch中設置learning_rate有六種方法(這里的LR就是LearningRate的縮寫)
1等步長間隔調整學習率
optim.lr_scheler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1)
2cosine學習率
optim.lr_scheler.CosineAnnealingLR(optimizer, T_max, eta_min=0)
3指數衰減學習率
optim.lr_scheler.ExponentialLR(optimizer, gamma, last_epoch=-1)
4自適應調整學習率
optim.lr_scheler.ReceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10,verbose=False, threshold=1e-4, threshold_mode='rel',cooldown=0, min_lr=0, eps=1e-8)
5非等間隔調整學習率
optim.lr_scheler.MultiStepLR(optimizer, milestones, gamma=0.1, last_epoch=-1)
6自定義網路層隔學習率
optim.lr_scheler.LambdaLR( optimizer, lr_lambda, last_epoch=-1)
我給你一個等步長間隔調整學習率的例子,你看看吧
import torch
import torch.optim as optim
from torch.optim import lr_scheler
from torchvision.models import AlexNet
model = AlexNet(num_classes=2)
optimizer = optim.SGD(params = model.parameters(), lr=0.05)
#每10次迭代,lr = lr * gamma
scheler = lr_scheler.StepLR(optimizer, step_size=10, gamma=0.1)
for epoch in range(40):
scheler.step()
lr = scheler.get_lr()
print(epoch, scheler.get_lr()[0])
源代碼(注意源代碼的縮進)
5. torch支持python嗎
PyTorch 是 Torch7 團隊開發的,從它的名字就可以看出,其與 Torch 的不同之處在於 PyTorch 使用了 Python 作為開發語言。
所謂「Python first」,同樣說明它是一個以Python 優先的深度學習框架,不僅能夠實現強大的GPU 加速,同時還支持動態神經網路,這是現在很多主流框架比如Tensorflow 等都不支持的。
PyTorch 既可以看做加入了GPU 支持的numpy,同時也可以看成一個擁有自動求導功能的強大的深度神經網路,除了Facebook 之外,它還已經被Twitter、CMU 和Salesforce 等機構採用。
相關推薦:《Python教程》
為何要使用PyTorch
面對如此多的深度學習框架,我們為何要選擇PyTorch 呢?Tensorflow 不是深度學習框架默認的老大嗎,為什麼不直接選擇Tensorflow 而是要選擇PyTorch 呢?下面分4個方面來介紹為何要使用PyTorch。
(1)掌握一個框架並不能一勞永逸,現在深度學習並沒有誰擁有絕對的壟斷地位,就算是Google 也沒有,所以只學習Tensorflow 並不夠。同時現在的研究者使用各個框架的都有,如果你要去看他們實現的代碼,至少也需要了解他們使用的框架,所以多學一個框架,以備不時之需。
(2)Tensorflow 與Caffe 都是命令式的編程語言,而且是靜態的,首先必須構建一個神經網路,然後一次又一次使用同樣的結構,如果想要改變網路的結構,就必須從頭開始。但是對於PyTorch,通過一種反向自動求導的技術,可以讓你零延遲地任意改變神經網路的行為,盡管這項技術不是PyTorch 獨有,但目前為止它實現是最快的,能夠為你任何瘋狂想法的實現獲得最高的速度和最佳的靈活性,這也是PyTorch 對比Tensorflow 最大的優勢。
(3)PyTorch 的設計思路是線性、直觀且易於使用的,當你執行一行代碼時,它會忠實地執行,並沒有非同步的世界觀,所以當你的代碼出現Bug 的時候,可以通過這些信息輕鬆快捷地找到出錯的代碼,不會讓你在Debug 的時候因為錯誤的指向或者非同步和不透明的引擎浪費太多的時間。
(4)PyTorch 的代碼相對於Tensorflow 而言,更加簡潔直觀,同時對於Tensorflow高度工業化的很難看懂的底層代碼,PyTorch 的源代碼就要友好得多,更容易看懂。深入API,理解PyTorch 底層肯定是一件令人高興的事。一個底層架構能夠看懂的框架,你對其的理解會更深。
最後,我們簡要總結一下PyTorch 的特點:
·支持GPU;
·動態神經網路;
·Python 優先;
·命令式體驗;
·輕松擴展。
擁有著如此多優點的.PyTorch 也有著它的缺點,因為這款框架比較新,所以使用的人也就比較少,這也就使得它的社區沒有那麼強大,但是PyTorch 提供了一個官方的論壇,大多數碰到的問題都可以去裡面搜索,裡面的答案一般都是由作者或者其他PyTorch 使用者提供的,論壇的更新也特別頻繁,同時也可以去Github 上面提Issue,一般很快就會得到開發者的回應,也算是一定程度上解決了社區的問題。
6. 如何有效地閱讀PyTorch的源代碼
最近剛開始使用theano, 經驗不多,連個基本的模型都跑不通,於是去看了下Keras,源碼比較簡潔,可以當作theano的示例教程來看,感受如下:
文檔看似很全,每個layer是幹啥的,每個參數是啥都寫了,但是不去讀代碼,實際很多人是無法從文檔理解其具體用法的。這點看issue里的討論里可以看出。同樣,example似乎很多,而且都能直接run,還都是real world的數據集,看似很好,但是實際上,對於新手,如果需要的模型跟example里的不完全一樣,不容易搞懂到底需要把輸入輸出的數據搞成啥格式。舉個例子,example都是做的classification的,沒有做sequence labeling的例子,如果想拿來做個pos tagging,不知道數據如何組織。當然,這些其實花一天讀下代碼或者好好翻翻issue討論就可以解決了,但我相信不少人不會去認真讀代碼或者看討論,而是直接換個工具。我感覺目前的doc只有懂了代碼的人才能看懂,不懂得看文檔還是沒啥用。
2.項目很簡單所以開發者不多,但是很活躍,每天都有新東西加進去。今天增加了一個新的分支後端可以用theano或者tensorflow了,不過貌似由於不支持scan,backend用tensorflow的沒實現recurrent layer。他們也意識到文檔的問題,覺得需要為小白用戶多加點tutorial而不是光給develop看。
我沒用過其他的framework,僅說keras拿來學習theano基本用法,很不錯
庫本身的代碼,比較簡單易讀,我作為python菜鳥,也能看懂。目前model有sequential和grapgh兩種,前者並不是指recurrent而是說網路是一層層堆的(也包括recurrent).其他的主要概念包括layer,regularizer, optimizer,objective都分離開。layer用於build每層的輸出函數,model會用最後一層的輸出,根據objective和每個layer的regularizer來確定最終的cost,然後在update時用optimizer來更新參數。把這四個看下加上model里的fit函數,就會用theano啦。很多模型都能cover,seq2seq這種也有現成的可用。建議不要光看example,多看看github上的 issues討論,實在找不到,直接提問。效率方面,我不懂theano怎麼優化,感覺keras的這種封裝,沒什麼成本,跟自己用原生theano是一樣的。當然,theano本身就好慢啊。。估計是我不懂用吧。。
用於測試函數式返回的數值是否有錯。如果有錯,該函數返回
7. 如何有效地閱讀PyTorch的源代碼
運行 python setup.py build ,生成一遍 (非 install,防止覆蓋已安裝的pytorch)
順著 setup.py build 命令看安裝過程,順著安裝過程看相關實現代碼
順著 __init__.py 看 python 中 import torch 時,怎麼把 C\C++ 代碼實現的函數與類載入起來的、python層引入了哪些庫
8. 如何在pycharm中尋找pytorch或tensorflow中的源函數
找到所要查找的函數或屬性,滑鼠右擊,go to , declaration,查找原函數源碼
9. pytorch用什麼顯卡
1. 利用CUDA_VISIBLE_DEVICES設置可用顯卡
在CUDA中設定可用顯卡,一般有2種方式:
(1) 在代碼中直接指定
import os
os.environ['CUDA_VISIBLE_DEVICES'] = gpu_ids
(2) 在命令行中執行代碼時指定
CUDA_VISIBLE_DEVICES=gpu_ids python3 train.py
如果使用sh腳本文件運行代碼,則有3種方式可以設置
(3) 在命令行中執行腳本文件時指定:
CUDA_VISIBLE_DEVICES=gpu_ids sh run.sh
(4) 在sh腳本中指定:
source bashrc
export CUDA_VISIBLE_DEVICES=gpu_ids && python3 train.py
(5) 在sh腳本中指定
source bashrc
CUDA_VISIBLE_DEVICES=gpu_ids python3 train.py
如果同時使用多個設定可用顯卡的指令,比如
source bashrc
export CUDA_VISIBLE_DEVICES=gpu_id1 && CUDA_VISIBLE_DEVICES=gpu_id2 python3 train.py
那麼高優先順序的指令會覆蓋第優先順序的指令使其失效。優先順序順序為:不使用sh腳本 (1)>(2); 使用sh腳本(1)>(5)>(4)>(3)
個人感覺在煉丹時建議大家從(2)(3)(4)(5)中選擇一個指定可用顯卡,不要重復指定以防造成代碼的混亂。方法(1)雖然優先順序最高,但是需要修改源代碼,所以不建議使用。
2 .cuda()方法和torch.cuda.set_device()
我們還可以使用.cuda()[包括model.cuda()/loss.cuda()/tensor.cuda()]方法和torch.cuda.set_device()來把模型和數據載入到對應的gpu上。
(1) .cuda()
以model.cuda()為例,載入方法為:
model.cuda(gpu_id) # gpu_id為int類型變數,只能指定一張顯卡
model.cuda('cuda:'+str(gpu_ids)) #輸入參數為str類型,可指定多張顯卡
model.cuda('cuda:1,2') #指定多張顯卡的一個示例
(2) torch.cuda.set_device()
使用torch.cuda.set_device()可以更方便地將模型和數據載入到對應GPU上, 直接定義模型之前加入一行代碼即可
torch.cuda.set_device(gpu_id) #單卡
torch.cuda.set_device('cuda:'+str(gpu_ids)) #可指定多卡
但是這種寫法的優先順序低,如果model.cuda()中指定了參數,那麼torch.cuda.set_device()會失效,而且pytorch的官方文檔中明確說明,不建議用戶使用該方法。
第1節和第2節所說的方法同時使用是並不會沖突,而是會疊加。比如在運行代碼時使用
CUDA_VISIBLE_DEVICES=2,3,4,5 python3 train.py
而在代碼內部又指定
model.cuda(1)
loss.cuda(1)
tensor.cuda(1)
那麼代碼會在GPU3上運行。原理是CUDA_VISIBLE_DEVICES使得只有GPU2,3,4,5可見,那麼這4張顯卡,程序就會把它們看成GPU0,1,2,3,.cuda(1)把模型/loss/數據都載入到了程序所以為的GPU1上,則實際使用的顯卡是GPU3。
如果利用.cuda()或torch.cuda.set_device()把模型載入到多個顯卡上,而實際上只使用一張顯卡運行程序的話,那麼程序會把模型載入到第一個顯卡上,比如如果在代碼中指定了
model.cuda('cuda:2,1')
在運行代碼時使用
CUDA_VISIBLE_DEVICES=2,3,4,5 python3 train.py
這一指令,那麼程序最終會在GPU4上運行。
3.多卡數據並行torch.nn.DataParallel
多卡數據並行一般使用
torch.nn.DataParallel(model,device_ids)
其中model是需要運行的模型,device_ids指定部署模型的顯卡,數據類型是list
device_ids中的第一個GPU(即device_ids[0])和model.cuda()或torch.cuda.set_device()中的第一個GPU序號應保持一致,否則會報錯。此外如果兩者的第一個GPU序號都不是0,比如設置為:
model=torch.nn.DataParallel(model,device_ids=[2,3])
model.cuda(2)
那麼程序可以在GPU2和GPU3上正常運行,但是還會佔用GPU0的一部分顯存(大約500M左右),這是由於pytorch本身的bug導致的(截止1.4.0,沒有修復這個bug)。
device_ids的默認值是使用可見的GPU,不設置model.cuda()或torch.cuda.set_device()等效於設置了model.cuda(0)
4. 多卡多線程並行torch.nn.parallel.DistributedDataParallel
(這個我是真的沒有搞懂,,,,)
參考了這篇文章和這個代碼,關於GPU的指定,多卡多線程中有2個地方需要設置
torch.cuda.set_device(args.local_rank)
torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.local_rank])
模型/loss/tensor設置為.cuda()或.cuda(args.local_rank)均可,不影響正常運行。
5. 推薦設置方式:
(1) 單卡
使用CUDA_VISIBLE_DEVICES指定GPU,不要使用torch.cuda.set_device(),不要給.cuda()賦值。
(2) 多卡數據並行
直接指定CUDA_VISIBLE_DEVICES,通過調整可見顯卡的順序指定載入模型對應的GPU,不要使用torch.cuda.set_device(),不要給.cuda()賦值,不要給torch.nn.DataParallel中的device_ids賦值。比如想在GPU1,2,3中運行,其中GPU2是存放模型的顯卡,那麼直接設置
CUDA_VISIBLE_DEVICES=2,1,3
(3) 多卡多線程
10. pytorch python 什麼關系
PyTorch is a deep learning framework that puts Python first.
We are in an early-release Beta. Expect some adventures.
Python[1] (英國發音:/ˈpaɪθən/ 美國發音:/ˈpaɪθɑːn/), 是一種面向對象的解釋型計算機程序設計語言,由荷蘭人Guido van Rossum於1989年發明,第一個公開發行版發行於1991年。
Python是純粹的自由軟體, 源代碼和解釋器CPython遵循 GPL(GNU General Public License)協議[2] 。Python語法簡潔清晰,特色之一是強制用空白符(white space)作為語句縮進。
Python具有豐富和強大的庫。它常被昵稱為膠水語言,能夠把用其他語言製作的各種模塊(尤其是C/C++)很輕松地聯結在一起。常見的一種應用情形是,使用Python快速生成程序的原型(有時甚至是程序的最終界面),然後對其中[3] 有特別要求的部分,用更合適的語言改寫,比如3D游戲中的圖形渲染模塊,性能要求特別高,就可以用C/C++重寫,而後封裝為Python可以調用的擴展類庫。需要注意的是在您使用擴展類庫時可能需要考慮平台問題,某些可能不提供跨平台的實現。
7月20日,IEEE發布2017年編程語言排行榜:Python高居首位[4] 。