總結 | 深度學習之Pytorch入門教程
目錄
一、整體學習的建議
1.1 如何成為Pytorch大神?
1.2 如何讀Github代碼?
1.3 代碼能力太弱怎么辦?
二、Pytorch與TensorFlow概述
2.1 什么是Pytorch?
2.1.1 Pytorch兩個核心模塊
2.1.2 Pytorch可視化:Visdom
2.1.3 Pytorch的優缺點
2.2 什么是TensorFlow
2.2.1 TensorFlow兩個核心模塊
2.2.2 TensorFlow可視化:TensorBoard
2.2.3 TensorFlow的優缺點
2.3 Pytorch和TensorFlow對比
三、Pytorch的一些簡單命令
四、實現兩層神經網絡
4.1 如何用numpy實現兩層神經網絡
4.2 如何用torch實現兩層神經網絡
4.3 簡單的autograd
如何使用autograd簡化上面的兩層神經網絡?
最后pytorch的簡單代碼
五、Pytorch常用庫
5.1 Pytorch:nn
5.2 Pytorch:optim
5.3 Pytorch:nn Module
(本文筆記pdf版本可在【人工智能算法與Python大數據】后臺回復8003 獲取)
一、整體學習的建議
1.1 如何成為Pytorch大神?
打好深度學習基礎
學習Pytorch的官方tutorial
打開Github,多看看教程
使用?https://discuss.pytorch.org, 閱讀文檔
跑代碼,項目,-碼
復現,實現模型,自己創造
1.2 如何讀Github代碼?
首先讀簡單的代碼,比如三四個文件
然后十個文件
然后多個文件夾
整體套路是一樣的
1.3 代碼能力太弱怎么辦?
最簡單的辦法就行訓練
抄代碼,抄個100行,然后再寫,再抄
剛開始會不理解,后面要思考為什么這么寫
寫代碼的時候不要反復重復!Repeat no!
二、Pytorch與TensorFlow概述
2.1 什么是Pytorch?
Facebook開源,2017年,論文《PyTorch 中的自動微分》,地址:https://openreview.net/pdf?id=BJJsrmfCZ
類似于Numpy,可以使用GPU,運行在CUDA上
PyTorch框架和Python語言的整合更加緊密
Pytorch動態圖內置,可以定義深度學習模型,可靈活的進行訓練和應用
分布式訓練并行化時,利用Python對異步執行的本地支持
2.1.1 Pytorch兩個核心模塊
計算圖,按照需求動態構建,圖會隨著執行過程而改變
Autograd,執行動態圖的自動微分
2.1.2 Pytorch可視化:Visdom
管理整體環境
處理回調
繪制圖表細節
2.1.3 Pytorch的優缺點
優點:
類似Python的代碼
動態圖
輕松編輯
良好的文檔和社區支持
開源
很多項目都在使用
缺點:
可視化需要第三方
生產部署需要使用API服務器
2.2 什么是TensorFlow
谷歌開源,2015年,論文《TensorFlow:異構分布式系統上的大規模機器學習》,地址:http://download.tensorflow.org/paper/whitepaper2015.pdf
使用GPU增強訓練,使用的是內置的GPU進行加速
分布式訓練并行化時,必須手動編寫代碼,并微調每個操作
使用TensorFlow Fold庫實現動態圖
可實現并行化或依賴驅動式調度,訓練更快更有效率
2.2.1 TensorFlow兩個核心模塊
一個用于定義計算圖以及在各種不同硬件上執行這些圖的運行時間的軟件庫
一個計算圖,計算圖是以靜態方式定義。與外部通信通過tf.Sessionobject和tf.Placeholder
2.2.2 TensorFlow可視化:TensorBoard
分析程序
展示數據(圖像,文本,音頻)
可視化計算圖的操作和層數信息
跟蹤和實時可視化損失和準確度等相關指標
查看權重、偏差、張量等隨時間變化的直方圖
2.2.3 TensorFlow的優缺點
優點:
簡單的內置高級API
使用TensorBoard可視化訓練
通過TensorFlow serving容易實現生產部署
很容易的移動平臺支持
開源
良好的文檔和社區支持
缺點:
靜態圖
調試方法
難以快速修改
2.3 Pytorch和TensorFlow對比
1.學術界PyTorch已經全面超越TensorFlow,上手快,容易實現,驗證想法
2.工業界TensorFlow仍然廣泛應用,GPU部署方便
三、Pytorch的一些簡單命令
第一步,導入torch:
import torch
構造一個未被初始化的3x5的矩陣
x = torch.empty(3,5)
x
生成一個隨機初始化的3x5矩陣
x = torch.rand(3,5)
x
生成一個全部為0的矩陣
x = torch.zeros(3,5)
x
x.dtype
torch.float32
生成一個全部為0的矩陣,long的矩陣
x = torch.zeros(3,5,dtype = torch.long)
x
x.dtype
torch.int64
# 或者 x = torch.zeros(3,5).long()
直接通過數據構建tensor
x = torch.tensor([1.2,4])
x
tensor([1.2000,4.0000])
也可以通過已有tensor構建一個新的tensor
x = x.new_ones(3,5)
# 或者改變類型 x = x.new_ones(3,5,dtype=torch.double)
構建一個和上一個形狀相同的tensor
x = torch.randn_like(x, dtype=torch.float)
x
得到tensor的形狀
x.shape
torch.Size([3,5])
加法準則:
x + y
torch.add(x,y)
result = torch.empty(3,5)
torch.add(x,y, out = result)
result
# 效果與下面類似 result = x + y
in-place加法
注意,任何in-place的運算都會以結尾,比如x.copy(y) , ? x.t_() ?,這些都會改變x
y.add_(x)
y
# 注意,這里加了下劃線,就把y直接進行更改了,效果等價于 y=y+x
類似于Numpy的索引在Pytorch 的 tensor上面都可以使用,類比matlab
x[1:,1:]
Resizing,想要resize、reshape一個tensor,可以使用torch.view
x = torch.randn(4,4)
y = x.view(16)
y = x.view(2,8)
# 也可以用-1代表其中一個,它會自動計算 y = x.view(2,-1)和 x.view(2,8)功能類似
dir(x)可以看看x包含哪些功能
data
grad
怎么使用?
x.data
x.grad
x.item 把tensor變成數字
Numpy和tensor之間的相互轉換
a = tensor([1,1,1,1,1])
b = a.numpy()
b
array([1.,1.,1.,1.,1.], dtype=float32)
注意,這里a和b是共享空間的,其中一個變,整體都會變
把Numpy array 轉換成 Torch Tensor
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
b
如果我們有GPU,可以轉換為 CUDA Tensors
if torch.cuda.is_available() device = torch.device("cuda") y = torch.ones_like(x, device=device) x = x.to(device) z = x + y # 注意,這里是GPU的 print(z) # 轉換成CPU進行輸出的話 print(z.to("cpu", torch.double))
注意,如果是GPU的tensor,是沒辦法直接用.data這類操作,必須先轉換再操作
y.cpu().data.numpy()
numpy是CPU的庫,并沒有GPU的庫,所以如果想使用numpy,但是你默認GPU產生的是tensor
四、實現兩層神經網絡
4.1 如何用numpy實現兩層神經網絡
一個全連接ReLU神經網絡,一個隱藏層,沒有bias。用來從x預測y,使用L2 Loss。
# 定義一些基本的信息,64個輸入,每個輸入是1000維,hidden是100維,輸出是10維 N, D_in, H, D_out = 64, 1000, 100, 10 # 隨機創建一些訓練數據 # x是64個1000維,x是64x1000矩陣 # y是64個10維,y是64x10矩陣 x = np.random.randn(N, D_in)y = np.random.randn(N, D_out)# 隨機初始化權重 # w1是1000個100維,w1是1000x100矩陣 # w2是100個10維,w2是100x10矩陣 w1 = np.random.randn(D_in, H)w2 = np.random.randn(H, D_out)learning_rate = 1e-6 for t in range(500): # 前向傳播,h是64x1000x1000x100=64x100 # h_relu是看哪個激活了,還是64x100 # y_pred是64x100x100x10=64x10 h = x.dot(w1) # N * H h_relu = np.maximum(h, 0) # N * H y_pred = h_relu.dot(w2) # N * D_out # compute loss loss = np.square(y_pred - y).sum() print(it, loss) # Backward pass # 計算梯度,鏈式法則,挨個求導相乘 grad_y_pred = 2.0 * (y_pred - y) grad_w2 = h_relu.T.dot(grad_y_pred) grad_h_relu = grad_y_pred.dot(w2.T) grad_h = grad_h_relu.copy() grad_h[h<0] = 0 grad_w1 = x.T.dot(grad_h) # 更新w1和w2的權重 w1 -=learning_rate * grad_w1 w2 -=learning_rate * grad_w2
4.2 如何用torch實現兩層神經網絡
這里將numpy修改為pytorch做這件事
pytorch用的是tensors
# 定義一些基本的信息,64個輸入,每個輸入是1000維,hidden是100維,輸出是10維 N, D_in, H, D_out = 64, 1000, 100, 10 # 隨機創建一些訓練數據 # x是64個1000維,x是64x1000矩陣 # y是64個10維,y是64x10矩陣 # np.random要改為torch x = torch.randn(N, D_in)y = torch.randn(N, D_out)# 隨機初始化權重 # w1是1000個100維,w1是1000x100矩陣 # w2是100個10維,w2是100x10矩陣 w1 = torch.randn(D_in, H)w2 = torch.randn(H, D_out)learning_rate = 1e-6 for t in range(500): # 前向傳播,h是64x1000x1000x100=64x100 # h_relu是看哪個激活了,還是64x100 # y_pred是64x100x100x10=64x10 # .dot改為mm h = x.mm(w1) # N * H # maximum改為clamp,夾住 h_relu = h.clamp(min=0) # N * H y_pred = h_relu.mm(w2) # N * D_out # compute loss # 求平方在這里也要改 # loss = np.square(y_pred - y).sum() loss = (y_pred - y).pow(2).sum().item() print(it, loss) # Backward pass # 計算梯度,鏈式法則,挨個求導相乘 grad_y_pred = 2.0 * (y_pred - y) grad_w2 = h_relu.t().mm(grad_y_pred) grad_h_relu = grad_y_pred.mm(w2.t()) grad_h = grad_h_relu.clone() grad_h[h<0] = 0 grad_w1 = x.t().mm(grad_h) # 更新w1和w2的權重 w1 -=learning_rate * grad_w1 w2 -=learning_rate * grad_w2
4.3 簡單的autograd
x = torch.tensor(1., requires_grad=True)w = torch.tensor(2., requires_grad=True)b = torch.tensor(3., requires_grad=True)y = w*x + b # y = 2*1 + 3y.backward()# dy/dw=xprint(w.grad)print(x.grad)print(b.grad)# 結果tensor(1.)tensor(2.)tensor(1 . )
如何使用autograd簡化上面的兩層神經網絡?
# 定義一些基本的信息,64個輸入,每個輸入是1000維,hidden是100維,輸出是10維 N, D_in, H, D_out = 64, 1000, 100, 10 # 隨機創建一些訓練數據 # x是64個1000維,x是64x1000矩陣 # y是64個10維,y是64x10矩陣 # np.random要改為torch x = torch.randn(N, D_in)y = torch.randn(N, D_out)# 隨機初始化權重 # w1是1000個100維,w1是1000x100矩陣 # w2是100個10維,w2是100x10矩陣 w1 = torch.randn(D_in, H, requires_grad=True)w2 = torch.randn(H, D_out, requires_grad=True)learning_rate = 1e-6 for t in range(500): # 前向傳播,h是64x1000x1000x100=64x100 # h_relu是看哪個激活了,還是64x100 # y_pred是64x100x100x10=64x10 # .dot改為mm # h = x.mm(w1) # N * H # h_relu = h.clamp(min=0) # N * H # y_pred = h_relu.mm(w2) # N * D_out # 把上面三行合并為1行 y_pred =x.mm(w1).clamp(min=0).mm(w2) # compute loss # 求平方在這里也要改 loss = (y_pred - y).pow(2).sum() # 這是計算圖 print(it, loss.item()) # Backward pass # 計算梯度,鏈式法則,挨個求導相乘 # grad_y_pred = 2.0 * (y_pred - y) # grad_w2 = h_relu.t().mm(grad_y_pred) # grad_h_relu = grad_y_pred.mm(w2.t()) # grad_h = grad_h_relu.clone() # grad_h[h<0] = 0 # grad_w1 = x.t().mm(grad_h) # 這些求梯度的全部不要 loss.backward() # 更新w1和w2的權重 # 為了減少內存,取消計算圖的儲存 with torch.no_grad(): w1 -=learning_rate * w1.grad w2 -=learning_rate * w2.grad # 每次清零 w1.grad.zero_() w2.grad.zero_()
最后pytorch的簡單代碼
# 定義一些基本的信息,64個輸入,每個輸入是1000維,hidden是100維,輸出是10維 N, D_in, H, D_out = 64, 1000, 100, 10 x = torch.randn(N, D_in)y = torch.randn(N, D_out)w1 = torch.randn(D_in, H, requires_grad=True)w2 = torch.randn(H, D_out, requires_grad=True)learning_rate = 1e-6 for t in range(500): y_pred =x.mm(w1).clamp(min=0).mm(w2) loss = (y_pred - y).pow(2).sum() # 這是計算圖 print(it, loss.item()) loss.backward() # 更新w1和w2的權重 with torch.no_grad(): w1 -=learning_rate * w1.grad w2 -=learning_rate * w2.grad # 每次清零 w1.grad.zero_() w2.grad.zero_()
五、Pytorch常用庫
5.1 Pytorch:nn
使用pytorch:nn庫來構建網絡
使用Pytorch autograd 來構建計算圖和計算梯度
import torch.nn as nn# 定義一些基本的信息,64個輸入,每個輸入是1000維,hidden是100維,輸出是10維 N, D_in, H, D_out = 64, 1000, 100, 10 x = torch.randn(N, D_in)y = torch.randn(N, D_out)# 不用這么繁瑣頂定義這個w1,w2 # w1 = torch.randn(D_in, H, requires_grad=True) # w2 = torch.randn(H, D_out, requires_grad=True) model = torch.nn.Sequential( torch.nn.Linear(D_in,H), #w_1 * x +b_1 torch.nn.ReLU(); torch.nn.Linear(H, D_out))# model = model.cuda() loss_fn = nn.MSELoss(reduction='sum')learning_rate = 1e-6 for t in range(500): # y_pred =x.mm(w1).clamp(min=0).mm(w2) y_pred = model(x) # model.forward() loss = loss_fn(y_pred,y) print(it, loss.item()) model.zero_grad loss.backward() # 更新w1和w2的權重 with torch.no_grad(): for param in model.parameters(): param -= learning_rate * param.grad
初始化數據,可能影響訓練效果 ,這里可對weight進行初始化
modelmodel[0].weight可能初始化問題會影響訓練效果可在model和loss_fn中間加:torch.nn.init.normal_(model[0].weight) #第一層 torch.nn.init.normal_(model[2].weight) #第二層
5.2 Pytorch:optim
不用手動更新模型的weights,而是使用optim這個包來幫助我們更新參數
optim這個包提供了各種不同的模型優化方法,包括SGD+momentum,RMSProp,Adam等等
import torch.nn as nn# 定義一些基本的信息,64個輸入,每個輸入是1000維,hidden是100維,輸出是10維 N, D_in, H, D_out = 64, 1000, 100, 10 x = torch.randn(N, D_in)y = torch.randn(N, D_out)# 不用這么繁瑣頂定義這個w1,w2 # w1 = torch.randn(D_in, H, requires_grad=True) # w2 = torch.randn(H, D_out, requires_grad=True) model = torch.nn.Sequential( torch.nn.Linear(D_in,H), #w_1 * x +b_1 torch.nn.ReLU(); torch.nn.Linear(H, D_out))# model = model.cuda() loss_fn = nn.MSELoss(reduction='sum')learning_rate = 1e-4 optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)# 或者優化方法 # learning_rate = 1e-6 # optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate) learning_rate = 1e-6 for t in range(500): y_pred = model(x) # model.forward() loss = loss_fn(y_pred,y) print(it, loss.item()) # 求導之前把數據清空 optimizer.zero_grad() loss.backward() # 更新w1和w2的權重 optimizer.step()
5.3 Pytorch:nn Module
import torch.nn as nn 定義一些基本的信息,64個輸入,每個輸入是1000維,hidden是100維,輸出是10維N, Din, H, D_out = 64, 1000, 100, 10x = torch.randn(N, D_in)y = torch.randn(N, D_out)class TwoLayerNet(torch.nn.Module): def _init(self, Din, H, D_out): super(TwoLayerNet, self)._init() # 定義模型框架 self.linear1 = torch.nn.Linear(D_in, H, bias=False) self.linear2 = torch.nn.Linear(H, D_out, bias=False) def forward(self, x) # 定義前向傳播 y_pred = self.linear2(self.linear1(x).clamp(min=0)) return y_pred model = TwoLayerNet(D_in, H, D_out))loss_fn = nn.MSELoss(reduction=’sum’)learning_rate = 1e-4optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)learning_rate = 1e-6for t in range(500): y_pred = model(x) # model.forward() loss = loss_fn(y_pred,y) print(it, loss.item()) # 求導之前把數據清空 optimizer.zero_grad() loss.backward() # 更新w1和w2的權重 optimizer.step()
pytorch 深度學習
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。