pytorch 學習
pytorch 學習筆記(一)
pytorch
是一個動態的建圖的工具。不像Tensorflow
那樣,先建圖,然後通過feed
和run
重複執行建好的圖。相對來說,pytorch
具有更好的靈活性。
編寫一個深度網路需要關注的地方是:
1. 網路的引數應該由什麼物件儲存
2. 如何構建網路
3. 如何計算梯度和更新引數
資料放在什麼物件中
pytorch
中有兩種變數型別,一個是Tensor
,一個是Variable
。
Tensor
: 就像ndarray
一樣,一維Tensor
叫Vector
,二維Tensor
叫Matrix
,三維及以上稱為Tensor
Variable
:是Tensor
的一個wrapper
,不僅儲存了值,而且儲存了這個值的creator
,需要BP
的網路都是Variable
參與運算
import torch
x = torch.Tensor(2,3,4) # torch.Tensor(shape) 建立出一個未初始化的Tensor,但是還是可以列印出值的,這個應該是這塊記憶體之前的資料
x # 這種方式建立出來的Tensor更多是用來接受其他資料的計算值的
- 1
- 2
- 3
(0 ,.,.) =
1.00000e-37 *
1.5926 0.0000 0.0000 0.0000
0.0000 0.0000 0.0000 0.0000
0.0000 0.0000 0.0000 0.0000
(1 ,.,.) =
1.00000e-37 *
0.0000 0.0000 0.0000 0.0000
0.0000 0.0000 0.0000 0.0000
0.0000 0.0000 0.0000 0.0000
[torch.FloatTensor of size 2x3x4]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
x.size()
- 1
torch.Size([2, 3, 4])
- 1
- 2
a = torch.rand(2,3,4)
b = torch.rand(2,3,4)
_=torch.add(a,b, out=x) # 使用Tensor()方法建立出來的Tensor用來接收計算結果,當然torch.add(..)也會返回計算結果的
x
- 1
- 2
- 3
- 4
(0 ,.,.) =
0.9815 0.0833 0.8217 1.1280
0.7810 1.2586 1.0243 0.7924
1.0200 1.0463 1.4997 1.0994
(1 ,.,.) =
0.8031 1.4283 0.6245 0.9617
1.3551 1.9094 0.9046 0.5543
1.2838 1.7381 0.6934 0.8727
[torch.FloatTensor of size 2x3x4]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
a.add_(b) # 所有帶 _ 的operation,都會更改呼叫物件的值,
#例如 a=1;b=2; a.add_(b); a就是3了,沒有 _ 的operation就沒有這種效果,只會返回運算結果
torch.cuda.is_available()
- 1
- 2
- 3
True
- 1
- 2
自動求導
pytorch
的自動求導工具包在torch.autograd
中
from torch.autograd import Variable
x = torch.rand(5)
x = Variable(x,requires_grad = True)
y = x * 2
grads = torch.FloatTensor([1,2,3,4,5])
y.backward(grads)#如果y是scalar的話,那麼直接y.backward(),然後通過x.grad方式,就可以得到var的梯度
x.grad #如果y不是scalar,那麼只能通過傳參的方式給x指定梯度
- 1
- 2
- 3
- 4
- 5
- 6
- 7
Variable containing:
2
4
6
8
10
[torch.FloatTensor of size 5]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
neural networks
使用torch.nn
包中的工具來構建神經網路
構建一個神經網路需要以下幾步:
- 定義神經網路的
權重
,搭建網路結構 - 遍歷整個資料集進行訓練
- 將資料輸入神經網路
- 計算loss
- 計算網路權重的梯度
- 更新網路權重
- weight = weight + learning_rate * gradient
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):#需要繼承這個類
def __init__(self):
super(Net, self).__init__()
#建立了兩個卷積層,self.conv1, self.conv2,注意,這些層都是不包含啟用函式的
self.conv1 = nn.Conv2d(1, 6, 5) # 1 input image channel, 6 output channels, 5x5 square convolution kernel
self.conv2 = nn.Conv2d(6, 16, 5)
#三個全連線層
self.fc1 = nn.Linear(16*5*5, 120) # an affine operation: y = Wx + b
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x): #注意,2D卷積層的輸入data維數是 batchsize*channel*height*width
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2)) # Max pooling over a (2, 2) window
x = F.max_pool2d(F.relu(self.conv2(x)), 2) # If the size is a square you can only specify a single number
x = x.view(-1, self.num_flat_features(x))
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
def num_flat_features(self, x):
size = x.size()[1:] # all dimensions except the batch dimension
num_features = 1
for s in size:
num_features *= s
return num_features
net = Net()
net
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
Net (
(conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
(conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
(fc1): Linear (400 -> 120)
(fc2): Linear (120 -> 84)
(fc3): Linear (84 -> 10)
)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
len(list(net.parameters())) #為什麼是10呢? 因為不僅有weights,還有bias, 10=5*2。
#list(net.parameters())返回的learnable variables 是按照建立的順序來的
#list(net.parameters())返回 a list of torch.FloatTensor objects
- 1
- 2
- 3
10
- 1
- 2
input = Variable(torch.randn(1, 1, 32, 32))
out = net(input) #這個地方就神奇了,明明沒有定義__call__()函式啊,所以只能猜測是父類實現了,並且裡面還呼叫了forward函式
out #檢視原始碼之後,果真如此。那麼,forward()是必須要宣告的了,不然會報錯
out.backward(torch.randn(1, 10))
- 1
- 2
- 3
- 4
使用loss criterion 和 optimizer訓練網路
torch.nn
包下有很多loss標準。同時torch.optimizer
幫助完成更新權重的工作。這樣就不需要手動更新引數了
learning_rate = 0.01
for f in net.parameters():
f.data.sub_(f.grad.data * learning_rate) # 有了optimizer就不用寫這些了
- 1
- 2
- 3
import torch.optim as optim
# create your optimizer
optimizer = optim.SGD(net.parameters(), lr = 0.01)
# in your training loop:
optimizer.zero_grad() # 如果不置零,Variable 的梯度在每次 backward 的時候都會累加。
output = net(input) # 這裡就體現出來動態建圖了,你還可以傳入其他的引數來改變網路的結構
loss = criterion(output, target)
loss.backward()
optimizer.step() # Does the update
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
整體NN結構
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):#需要繼承這個類
def __init__(self):
super(Net, self).__init__()
#建立了兩個卷積層,self.conv1, self.conv2,注意,這些層都是不包含啟用函式的
self.conv1 = nn.Conv2d(1, 6, 5) # 1 input image channel, 6 output channels, 5x5 square convolution kernel
self.conv2 = nn.Conv2d(6, 16, 5)
#三個全連線層
self.fc1 = nn.Linear(16*5*5, 120) # an affine operation: y = Wx + b
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x): #注意,2D卷積層的輸入data維數是 batchsize*channel*height*width
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2)) # Max pooling over a (2, 2) window
x = F.max_pool2d(F.relu(self.conv2(x)), 2) # If the size is a square you can only specify a single number
x = x.view(-1, self.num_flat_features(x))
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
def num_flat_features(self, x):
size = x.size()[1:] # all dimensions except the batch dimension
num_features = 1
for s in size:
num_features *= s
return num_features
net = Net()
# create your optimizer
optimizer = optim.SGD(net.parameters(), lr = 0.01)
# in your training loop:
for i in range(num_iteations):
optimizer.zero_grad() # zero the gradient buffers,如果不歸0的話,gradients會累加
output = net(input) # 這裡就體現出來動態建圖了,你還可以傳入其他的引數來改變網路的結構
loss = criterion(output, target)
loss.backward() # 得到grad,i.e.給Variable.grad賦值
optimizer.step() # Does the update,i.e. Variable.data -= learning_rate*Variable.grad
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
其它
- 關於求梯度,只有我們定義的Variable才會被求梯度,由
creator
創造的不會去求梯度 - 自己定義Variable的時候,記得Variable(Tensor, requires_grad = True),這樣才會被求梯度,不然的話,是不會求梯度的
# numpy to Tensor
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a) # 如果a 變的話, b也會跟著變,說明b只是儲存了一個地址而已,並沒有深拷貝
print(b)# Variable只是儲存Tensor的地址,如果Tensor變的話,Variable也會跟著變
- 1
- 2
- 3
- 4
- 5
- 6
- 7
a = np.ones(5)
b = torch.from_numpy(a)# ndarray --> Tensor
a_ = b.numpy() # Tensor --> ndarray
np.add(a, 1, out=a)# 這個和 a = np.add(a,1)有什麼區別呢?
# a = np.add(a,1) 只是將a中儲存的指標指向新計算好的資料上去
# np.add(a, 1, out=a) 改變了a指向的資料
- 1
- 2
- 3
- 4
- 5
- 6
# 將Tensor放到Cuda上
if torch.cuda.is_available():
x = x.cuda()
y = y.cuda()
x + y
- 1
- 2
- 3
- 4
- 5
# torch.Tensor(1,2,3) 與 torch.Tensor([1,2,3]) 的區別
torch.Tensor(1,2,3) # 生成一個 shape 為 [1,2,3] 的 tensor
torch.Tensor([1,2,3]) # 生成一個值為 [1,2,3] 的 tensor
- 1
- 2
- 3
# tensor 與 numpy
import torch
from torch.autograd import Variable
import numpy as np
n1 = np.array([1., 2.]).astype(np.float32)
# t1 = torch.FloatTensor(n1)
t1 = torch.from_numpy(n1)
n1[0] = 2.
print(t1)
# 可以看出,當使用 無論是使用 FloatTensor 還是 from_numpy 來建立 tensor
# tensor 只是指向了 初始的值而已,而沒有自己再開闢空間。
# FloatTensor(2,3,2) 這個不一樣,它是開闢了一個 空間。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
如遇無法下載pytorch安裝包問題
[連結:http://pan.baidu.com/s/1c2cSoX6 密碼:ckf8]
相關文章
- pytorch學習筆記PyTorch筆記
- PyTorch:學習資源PyTorch
- PyTorch 學習筆記PyTorch筆記
- 深度學習框架Pytorch學習筆記深度學習框架PyTorch筆記
- 通過示例學習PYTORCHPyTorch
- 《PyTorch》Part5 PyTorch之遷移學習PyTorch遷移學習
- (pytorch-深度學習系列)pytorch資料操作PyTorch深度學習
- 【Pytorch教程】迅速入門Pytorch深度學習框架PyTorch深度學習框架
- 深度學習及pytorch基礎深度學習PyTorch
- Pytorch學習(七)---- 儲存提取PyTorch
- 通過例項學習 PyTorchPyTorch
- [PyTorch 學習筆記] 6.2 NormalizationPyTorch筆記ORM
- 深度學習之PyTorch實戰(4)——遷移學習深度學習PyTorch遷移學習
- Pytorch學習筆記|莫凡PythonPyTorch筆記Python
- Pytorch學習筆記之tensorboardPyTorch筆記ORB
- 《白話強化學習與Pytorch》強化學習PyTorch
- Pytorch系列:(八)學習率調整方法PyTorch
- 基於pytorch的深度學習實戰PyTorch深度學習
- 樹莓派學習筆記(三)PyTorch樹莓派筆記PyTorch
- [PyTorch 學習筆記] 3.2 卷積層PyTorch筆記卷積
- Pytorch 目標檢測學習 Day 2PyTorch
- PYTORCH中的學習率怎麼理解PyTorch
- (1) Pytorch深度學習—數值處理PyTorch深度學習
- 零基礎學習人工智慧—Python—Pytorch學習(一)人工智慧PythonPyTorch
- 零基礎學習人工智慧—Python—Pytorch學習(二)人工智慧PythonPyTorch
- 零基礎學習人工智慧—Python—Pytorch學習(三)人工智慧PythonPyTorch
- 零基礎學習人工智慧—Python—Pytorch學習(九)人工智慧PythonPyTorch
- 零基礎學習人工智慧—Python—Pytorch學習(四)人工智慧PythonPyTorch
- 零基礎學習人工智慧—Python—Pytorch學習(五)人工智慧PythonPyTorch
- 零基礎學習人工智慧—Python—Pytorch學習(六)人工智慧PythonPyTorch
- 零基礎學習人工智慧—Python—Pytorch學習(七)人工智慧PythonPyTorch
- 零基礎學習人工智慧—Python—Pytorch學習(八)人工智慧PythonPyTorch
- [PyTorch 學習筆記] 5.1 TensorBoard 介紹PyTorch筆記ORB
- 【深度學習】檢測CUDA、cuDNN、Pytorch是否可用深度學習DNNPyTorch
- Anaconda Pytorch 深度學習入門記錄PyTorch深度學習
- 動手做科研-day04-pytorch學習PyTorch
- PyTorch深度學習入門筆記(一)PyTorch環境配置及安裝PyTorch深度學習筆記
- 【深度學習】PyTorch CUDA環境配置及安裝深度學習PyTorch