一、基础数据操作
1. 创建tensor
import torch
x = torch.empty(5, 3) 创建未初始化的5行3列的tensor
torch.tensor(data,) 类似np.array的构造函数
torch.ones(*sizes) 全1Tensor, sizes为tensor的尺寸,例如上面的(5,3)
torch.zeros(*sizes) 全0Tensor
torch.eye(*sizes) 对角线为1,其他为0
torch.arange(s,e,step) 从s到e,左闭右开,步长为step
torch.rand(*sizes) 均匀分布
torch.randn(*sizes) 标准分布
torch.normal(mean,std)/uniform(from,to) 正态分布/均匀分布
torch.randperm(m) 随机排列
例如randperm(5),表示0~4随机排列的1行5列的tensor
2. 索引
【法一】
可以使用类似NumPy的索引操作来访问Tensor的一部分
注意:索引出来的结果与原数据共享内存,也即修改一个,另一个会跟着修改。
y = x[0, :]
y += 1
print(y)
print(x[0, :]) # 源tensor也被改了
【其余方法】
index_select(input, dim, index) 在指定维度dim上选取,比如选取某些行、某些列
nonzero(input) 非0元素的下标
3. 改变形状
x.reshape() 推荐使用
x.view()
【区别】https://blog.csdn.net/Flag_ing/article/details/109129752
x.reshape(n) 形状变为1行n列的tensor
x.reshape(m, n) 形状变为m行n列的tensor
x.reshape(-1, n) 形状变为?行n列的tensor,具体多少行,根据数字n自适应
【补充】.item()函数
可以将一个标量Tensor转换成一个Python number:
x = torch.tensor([2.3466])
print(x) # tensor([2.3466])
print(x.item()) # 2.3466
4. 常用线性代数函数
torch.t(x) 转置
dot/cross 内积/外积
torch.inverse(x) 求逆矩阵
svd 奇异值分解
二、广播机制(broadcasting)
当对两个形状不同的Tensor按元素运算时,可能会触发广播(broadcasting)机制:先适当复制元素使这两个Tensor形状相同后再按元素运算。例如:
x = torch.arange(1, 3).view(1, 2)
print(x)
y = torch.arange(1, 4).view(3, 1)
print(y)
print(x + y)
输出:
tensor([[1, 2]])
tensor([[1],
[2],
[3]])
tensor([[2, 3],
[3, 4],
[4, 5]])
note:x是1行2列,y是3行1列,要运算先统一形状为:3行2列(取每一维度的较大值)然后自我复制成该形状后再运算
x:[1, 2]
————>
[[1, 2],
[1, 2],
[1, 2]]
y:[[1],
[2],
[3]]
————>
[[1, 1],
[2, 2],
[3, 3]]
所以:
[[1, 2], [[1, 1], [[2, 3],
[1, 2], + [2, 2], = [3, 4],
[1, 2]] [3, 3]] [4, 5]]
三、Tensor和NumPy相互转换
三种:
.numpy():tensor转numpy,共享内存
torch.from_numpy():numpy转tensor,共享内存
torch.tensor():numpy转tensor,不共享内存,拷贝新数据
x = torch.ones(5)
y = x.numpy()
print(x) # tensor([1,1,1,1,1])
print(y) # [1,1,1,1,1]
z1 = torch.from_numpy(y)
print("z1:", z1) # tensor([1,1,1,1,1])
z2 = torch.tensor(y)
print("z2:", z2) # tensor([1,1,1,1,1])
x += 1
print("+1后:\n", x) # tensor([2,2,2,2,2])
print(y) # [2,2,2,2,2]
print("+1:z1:", z1) # tensor([2,2,2,2,2])
print("+1:z2:", z2) # tensor([1,1,1,1,1])