5.張量索引操作
(1)索引操作
- 行列索引
- 列表索引
print(data[[0, 2], [1, 2]]) #返回(0, 1),(2, 2)兩個位置的元素print(data[[[0], [1]], [1, 2]]) # 返回0,1行的1,2列共4個元素
- 范圍索引
print(data[:3, :2]) # 前3行前2列數據print(data[2:, :2]) # 第2行到最后的前2列數據
- 布爾索引
tensor([[0, 7, 6, 5, 9],[6, 8, 3, 1, 0],[6, 3, 8, 7, 3],[4, 9, 5, 3, 1]])
print(data[data[:, 2] > 5])
print(data[:, data[1] > 5])
輸出結果:
tensor([[0, 7, 6, 5, 9],[6, 3, 8, 7, 3]])tensor([[0, 7],[6, 8],[6, 3],[4, 9]])
- 多維索引
data = torch.randint(0, 10, [3, 4, 5])
print(data)
#獲取0軸上的第一個數據
print(data[0, :, :])# 獲取1軸上的第一個數據
print(data[:, 0, :])# 獲取2軸上的第一個數據
print(data[:, :, 0])
6.張量形狀操作
(1)reshape函數
import torchdata = torch.tensor([[10, 20, 30], [40, 50, 60]])# 1.使用shape屬性或者size方法都可以獲得張量的形狀
print(data.shape, data.shape[0], data.shape[1])
print(data.size(), data.size(0), data.size(1))# 2.使用reshape函數修改張量形狀
new_data = data.reshape(1, 6)
print(new_data.shape)
(2)squeeze()
和unsqueeze()
函數
- squeeze函數刪除形狀為1的維度(降維),unsqueeze函數添加形狀為1的維度(升維)
import torchtorch.random.manual_seed(22)
data = torch.randint(0, 10, [3, 4, 5])# 添加維度
data1 = data.unsqueeze(dim = 1).unsqueeze(dim = -1)
print(data1.shape)# 降低維度
print(data1.squeeze().shape)
輸出結果:
torch.Size([3, 1, 4, 5, 1])
torch.Size([3, 4, 5])
(3)transpose()
和permute()
函數
- transpose函數可以實現交換張量形狀的指定維度;permute函數可以一次交換更多的維度
import torchtorch.random.manual_seed(22)
data = torch.randint(0, 10, [4, 2, 3, 5])
print(data.shape)# 轉換成[3, 4, 5, 2]
data1 = torch.transpose(data, 0, 2)
data2 = torch.transpose(data1, 1, 2)
data3 = torch.transpose(data2, 2, 3)
print(data3.shape)data4 = torch.permute(data, [2, 0, 3, 1])
print(data4.shape)print(data.permute([2, 0, 3, 1]).shape)
輸出結果:
torch.Size([4, 2, 3, 5])
torch.Size([3, 4, 5, 2])
torch.Size([3, 4, 5, 2])
torch.Size([3, 4, 5, 2])
(4)view()和contiguous()函數
-
view函數也可以用于修改張量的形狀,只能用于存儲在整塊內存中的張量
-
一個張量經過了transpose或者permute函數的處理之后,就無法使用view函數進行形狀操作,如果要使用view函數,需要使用contiguous()變得連續以后再使用view函數
import torchtorch.random.manual_seed(22)
data = torch.randint(0, 10, [2, 3])
print(data.shape)# 判斷內存是否連續
print(data.is_contiguous())print(data.view(-1).shape)data1 = torch.transpose(data, 0, 1)
print(data1.is_contiguous()) # 內存不連續data2 = data1.contiguous()
print(data2.view(-1).shape)if data.is_contiguous():data.view(-1)
else:data.contiguous().view(-1)
輸出結果:
torch.Size([2, 3])
True
torch.Size([6])
False
torch.Size([6])
7.張量拼接操作
- torch.cat():可以將兩個張量根據指定的維度拼接起來,不改變維度數
import torch
data1 = torch.randint(0, 10, [1, 2, 3])
data2 = torch.randint(0, 10, [1, 2, 3])
print(data1)
print(data2)# 1.按0維度拼接
new_data1 = torch.cat([data1, data2], dim = 0)
# print(new_data1)
print(new_data1.shape)# 2.按1維度拼接
new_data2 = torch.cat([data1, data2], dim = 1)
# print(new_data2)
print(new_data2.shape)# 3.按2維度拼接
new_data3 = torch.cat([data1, data2], dim = 2)
# print(new_data3)
print(new_data3.shape)
輸出結果:
tensor([[[5, 1, 8],[8, 9, 5]]])
tensor([[[5, 2, 9],[0, 5, 6]]])
torch.Size([2, 2, 3])
torch.Size([1, 4, 3])
torch.Size([1, 2, 6])
8.自動微分模塊
- 訓練神經網絡時,最常用的算法就是反向傳播。在該算法中,參數(模型權重)會根據損失函數關于對應參數的梯度進行調整。為了計算這些梯度,pytorch內置了名為torch.autograd的微分引擎,它支持任意計算圖的自動梯度計算
"""w = w - L(w.grad)"""
import torch# 數據 特征+目標
x = torch.tensor(5)
y = torch.tensor(0.)# 權重 偏置
w = torch.tensor(1, requires_grad=True,dtype = torch.float32)
b = torch.tensor(3, requires_grad=True, dtype = torch.float32)# 預測
z = w*x + b# 損失
loss = torch.nn.MSELoss()
loss = loss(z, y)# 微分
loss.backward()#梯度
print(w.grad)
print(b.grad)
輸出結果:
tensor(80.)
tensor(16.)
import torchx = torch.ones(2, 5)
y = torch.zeros(2, 3)w = torch.randn(5, 3, requires_grad=True)
b = torch.randn(3, requires_grad=True)z = torch.matmul(x, w) + bloss = torch.nn.MSELoss()
loss = loss(z, y)loss.backward()print(w.grad)
print(b.grad)
輸出結果:
tensor([[0.2782, 1.4126, 0.4037],[0.2782, 1.4126, 0.4037],[0.2782, 1.4126, 0.4037],[0.2782, 1.4126, 0.4037],[0.2782, 1.4126, 0.4037]])
tensor([0.2782, 1.4126, 0.4037])