前言
- 本文主要介绍pytorch中tensor的基本知识
- tensor与numpy中的ndarray类似,只是前者可以使用GPU进行加速
tensor初始化
从data中
data = [[1, 2],[3, 4]]
x_data = torch.tensor(data)
ndarray -> tensor
np_array = np.array(data)
x_np = torch.from_numpy(np_array)
tensor -> tensor
新的tensor会保持原有tensor的属性(大小,数据类型),除非刻意覆盖
x_ones = torch.ones_like(x_data)
print(x_ones.type())
print(x_ones)
>>torch.LongTensor
>>tensor([[1, 1],
[1, 1]])
x_rand = torch.rand_like(x_data, dtype=torch.float)# 覆盖了属性
print(x_rand.type())
print(x_rand)
>>torch.FloatTensor
>>tensor([[0.7219, 0.7205],
[0.8041, 0.1188]])
value ->tensor
shape是tensor维度的tuple
shape = (2, 2)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)
print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")
>>Random Tensor:
>>tensor([[0.4355, 0.3028],
[0.3358, 0.3817]])
>>Ones Tensor:
>>tensor([[1., 1.],
[1., 1.]])
>>Zeros Tensor:
>>tensor([[0., 0.],
[0., 0.]])
-
rand与randn的区别
#rand()取值从0,1之间的均匀分布中抽样。 #randn()取值从以0为均值,1为方差的标准正态分布中抽样。
tensor属性
tensor属性描述了数据的shape,datatype,device信息
tensor = torch.rand(3,4)
print(f"Shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}")
>>Shape of tensor: torch.Size([3, 4])
>>Datatype of tensor: torch.float32
>>Device tensor is stored on: cpu
tensor操作
tensor移动
tensor是在CPU上被创建的,我们需要利用 .to() 函数将其移动到GPU上。在设备之间copy large tensor是非常耗时,耗内存的
-
语法
# We move our tensor to the GPU if available if torch.cuda.is_available(): tensor = tensor.to('cuda')
-
例子
shape = (2, 2) rand_tensor = torch.randn(shape) print(rand_tensor.device) >>cpu t = time.time() if torch.cuda.is_available(): rand_tensor = rand_tensor.to('cuda') print(time.time() - t) print(rand_tensor.device) >>2.7548062801361084 >>cuda:0 rand_tensor = rand_tensor.to('cpu') print(rand_tensor.device) >>cpu
tensor拼接
使用torch.cat函数
-
语法
t = torch.cat([tensor1, tensor2, tensor3 ...], dim)
- dim = 0 代表按行拼接(使行增加)
- 这时列的维度要相同才能完成拼接(对齐)
- dim = 1 代表按列拼接(使列增加)
- 这时行的维度要相同才能完成拼接(对齐)
- dim = 0 代表按行拼接(使行增加)
-
例子
t1 = torch.cat([tensor, tensor, tensor], dim=1) #增加列 print(t1) >>tensor([[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.]])
tensor乘法
-
矩阵乘法
y1 = tensor @ tensor.T y2 = tensor.matmul(tensor.T) y3 = torch.rand_like(tensor) torch.matmul(tensor, tensor.T, out=y3)
-
对应位置点乘
z1 = tensor * tensor z2 = tensor.mul(tensor) z3 = torch.rand_like(tensor) torch.mul(tensor, tensor, out=z3)
单元素tensor
可以使用 .item() 来将其转化成 python 的数值型数据
tensor = torch.ones(4, 4)
agg = tensor.sum()
print(agg.dtype)
>>torch.float32
agg_item = agg.item()
print(type(agg_item))
>><class 'float'>
in-place操作
将结果存储到操作数中的操作被称为 in-place 操作
tensor.add_(5)
tensor与numpy
前面已经介绍过 numpy -> tensor
tensor -> numpy
在CPU上的tensor和numpy array是共享内存的,改变其中的一个,另一个也会改变
data = [[1, 2], [3, 4]]
tensor_data = torch.tensor(data)
np_data = tensor_data.numpy() #将tensor转换成ndarray
tensor_data.add_(1) #加_是改变自身,否则自身不发生改变
print(tensor_data)
>>tensor([[2, 3],
[4, 5]])
print(np_data)
>>[[2 3]
[4 5]]