创建tensor
几何代数中定义的张量是基于向量和矩阵的推广,比如可以将标量视为零阶张量,矢量可以视为一阶张量,矩阵就是二阶张量
使用torch.rand构造一个随机初始化的矩阵
import torch
x = torch.rand(4, 3)
print(x)
tensor([[0.9090, 0.0717, 0.6515],
[0.5202, 0.4521, 0.5968],
[0.2457, 0.9790, 0.5771],
[0.3811, 0.2427, 0.6869]])
构造全零矩阵
x = torch.zeros(4, 3, dtype=torch.long)
print(x)
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
将list转化为tensor
x = torch.tensor([5.5, 3])
print(x)
print(x.shape, x.size())
tensor([5.5000, 3.0000])
torch.Size([2]) torch.Size([2])
构造形状相同的矩阵
y = torch.ones_like(x)
y
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
张量的操作
加法操作
y = torch.rand(4, 3)
x = torch.ones_like(y)
# 方法一
print(x + y)
# 方法二
print(torch.add(x, y))
# 方法三, out-place
result = torch.empty_like(x)
print(torch.add(x, y, out=result))
# 方法四, in-place
y.add_(x)
print(y)
tensor([[1.7305, 1.0857, 1.2853],
[1.8159, 1.0455, 1.8792],
[1.8721, 1.7205, 1.7788],
[1.5893, 1.9778, 1.6206]])
tensor([[1.7305, 1.0857, 1.2853],
[1.8159, 1.0455, 1.8792],
[1.8721, 1.7205, 1.7788],
[1.5893, 1.9778, 1.6206]])
tensor([[1.7305, 1.0857, 1.2853],
[1.8159, 1.0455, 1.8792],
[1.8721, 1.7205, 1.7788],
[1.5893, 1.9778, 1.6206]])
tensor([[1.7305, 1.0857, 1.2853],
[1.8159, 1.0455, 1.8792],
[1.8721, 1.7205, 1.7788],
[1.5893, 1.9778, 1.6206]])
索引操作
需要注意的是:索引出来的结果与原数据共享内存,修改一个,另一个也会接着修改,如果不想修改,可以使用copy()等方法
x = torch.rand(3, 4)
x
tensor([[0.4065, 0.7128, 0.6444, 0.0308],
[0.4295, 0.9147, 0.7969, 0.4274],
[0.5885, 0.1450, 0.0452, 0.6621]])
取第二列
print(x[:, 1])
tensor([0.7128, 0.9147, 0.1450])
修改切片数据源数据也会被改
y = x[0, :]
y += 1
print(y)
print(x)
tensor([2.4065, 2.7128, 2.6444, 2.0308])
tensor([[2.4065, 2.7128, 2.6444, 2.0308],
[0.4295, 0.9147, 0.7969, 0.4274],
[0.5885, 0.1450, 0.0452, 0.6621]])
如果想改变一个tensor的大小或者形状,可以使用torch.view
x = torch.rand(4, 4)
y = x.view(16)
z = x.view(-1, 8)
print(x.shape, y.shape, z.shape)
torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])
注意view()返回的新tensor和源tensor是共享内存的,即改变了其中的一个,另外一个也会发生变化
x += 1 # 对x的所有数据都加1,观察y发现y的所有数据也都增加了一
print(x)
print(y)
tensor([[2.6332, 2.9636, 2.7696, 2.0887],
[2.2007, 2.0402, 2.2890, 2.3280],
[2.8369, 2.8077, 2.2749, 2.1647],
[2.5960, 2.1254, 2.9193, 2.0021]])
tensor([2.6332, 2.9636, 2.7696, 2.0887, 2.2007, 2.0402, 2.2890, 2.3280, 2.8369,
2.8077, 2.2749, 2.1647, 2.5960, 2.1254, 2.9193, 2.0021])
如果想直接返回一个真正的副本(即不共享内存),可以先使用clone()创造一个副本然后再使用view改变形状
使用clone的时候还有一个好处是会被记录在计算图中,即梯度回传到副本的时候也会被回传到源tensor
x = torch.rand(3, 3)
y = x.clone().view(-1)
y += 1
print(x, y)
tensor([[0.9508, 0.8564, 0.1388],
[0.1186, 0.9064, 0.5860],
[0.6449, 0.1584, 0.1335]]) tensor([1.9508, 1.8564, 1.1388, 1.1186, 1.9064, 1.5860, 1.6449, 1.1584, 1.1335])
# 对于只有一个值的tensor来说还可以使用.item()方法来获得tensor的value
x = torch.rand(1)
print(type(x))
print(type(x.item()))
# 对于有多个值的tensor来说可以使用.tolist()方法来获得tensor的value
x = torch.rand(3, 3)
print(type(x))
print(type(x.tolist()))
<class 'torch.Tensor'>
<class 'float'>
<class 'torch.Tensor'>
<class 'list'>
广播机制
当两个形状不同的Tensor按元素运算时,可能会触发广播(broadcasting)机制:先适当复制元素使得两个Tensor有相同的形状之后再按元素运算
x = torch.arange(1, 3).view(1, 2)
y = torch.arange(1, 4).view(3, 1)
print(x)
print(y)
print(x + y)
tensor([[1, 2]])
tensor([[1],
[2],
[3]])
tensor([[2, 3],
[3, 4],
[4, 5]])
版权声明:本文为qq_46311811原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。