PyTorch张量
在本PyTorch教程中,我们将讨论PyTorch Tensor,这是此深度学习框架的组成部分。
PyTorch张量
您以前使用过Python numpy吗?如果是,那么本节对您来说将非常简单!即使您没有使用numpy的经验,也可以在PyTorch和NumPy之间无缝切换!
PyTorch中的Tensor类似于numpy数组,具有使用GPU进行计算的另外灵活性。
1. 2D Pytorch张量
想象一个张量为一个数字数组,其维数可能是任意的。
在C/C++/Java中,张量和多维数组之间的唯一区别是,维中所有列的大小都相同。
例如,以下内容可以是二维张量的有效表示。
[[1 2 3 4], [5 6 7 8]]
但是请注意,以下示例不是有效示例,因为张量不是锯齿状数组。
[[1 2 3 4], [5 6 7]]
PyTorch张量对于程序员来说真的很方便,因为它们几乎与numpy数组相同。
但是,与numpy方法有一些区别,因此建议您也参考官方文档以获取更多信息。
2.初始化一个空的PyTorch张量
让我们考虑以下示例,该示例初始化一个空的Tensor。
import torch # Creates a 3 x 2 matrix which is empty a = torch.empty(3, 2)
张量为空并不意味着它不包含任何东西。
只是分配了内存而已。
import torch # Creates a 3 x 2 matrix which is empty a = torch.empty(3, 2) print(a) # Create a zero initialized float tensor b = torch.zeros(3, 2, dtype=torch.float32) print(b)
输出
tensor([[3.4655e-37, 0.0000e+00], [4.4842e-44, 0.0000e+00], [ nan, 6.1657e-44]]) tensor([[0., 0.], [0., 0.], [0., 0.]])
第一个张量是PyTorch只需为张量分配内存的结果。
存储器中的所有先前内容均不会被擦除。
由于PyTorch会分配内存并将张量元素零初始化,因此第二张量将填充零。
注意与numpy.empty()和numpy.zeros()的相似性。
这是因为PyTorch旨在替代" numpy",因为GPU可用。
3.查找PyTorch张量大小
让我们创建一个基本张量并确定其大小。
import torch # Create a tensor from data c = torch.tensor([[3.2 , 1.6, 2], [1.3, 2.5 , 6.9]]) print(c)
输出
tensor([[3.2000, 1.6000, 2.0000], [1.3000, 2.5000, 6.9000]])
要获取张量的大小,我们可以使用tensor.size()
print(c.size())
输出
torch.Size([2, 3])
PyTorch张量操作
像numpy一样,PyTorch支持类似的张量操作。
摘要在下面的代码块中给出。
1.关于张量的基本数学运算
import torch # Tensor Operations x = torch.tensor([[2, 3, 4], [5, 6, 7]]) y = torch.tensor([[2, 3, 4], [1.3, 2.6, 3.9]]) # Addition print(x + y) # We can also use torch.add() print(x + y == torch.add(x, y)) # Subtraction print(x - y) # We can also use torch.sub() print(x-y == torch.sub(x, y))
输出
tensor([[ 4.0000, 6.0000, 8.0000], [ 6.3000, 8.6000, 10.9000]]) tensor([[True, True, True], [True, True, True]]) tensor([[0.0000, 0.0000, 0.0000], [3.7000, 3.4000, 3.1000]]) tensor([[True, True, True], [True, True, True]])
我们还可以将结果分配给张量。
将以下代码片段添加到上面的代码中。
# We can assign the output to a tensor z = torch.zeros(x.shape) torch.add(x, y, out=z) print(z)
输出
tensor([[ 4.0000, 6.0000, 8.0000], [ 6.3000, 8.6000, 10.9000]])
2.使用PyTorch张量进行内联加减法
当带有下划线(_)后缀时,PyTorch还支持就地操作,例如加法和减法。
让我们继续上面操作摘要代码中的相同变量。
# In-place addition print('Before In-Place Addition:', y) y.add_(x) print('After addition:', y)
输出
Before In-Place Addition: tensor([[2.0000, 3.0000, 4.0000], [1.3000, 2.6000, 3.9000]]) After addition: tensor([[ 4.0000, 6.0000, 8.0000], [ 6.3000, 8.6000, 10.9000]])
3.访问张量索引
我们也可以在PyTorch中使用基于numpy的索引
# Use numpy slices for indexing print(y[:, 1]
输出
tensor([6.0000, 8.6000])
重塑PyTorch张量
类似于numpy,我们可以使用torch.reshape()来重塑张量。
我们也可以使用tensor.view()
实现相同的功能。
import torch x = torch.randn(5, 3) # Return a view of the x, but only having # one dimension y = x.view(5 * 3) print('Size of x:', x.size()) print('Size of y:', y.size()) print(x) print(y) # Get back the original tensor with reshape() z = y.reshape(5, 3) print(z)
输出
Size of x: torch.Size([5, 3]) Size of y: torch.Size([15]) tensor([[ 0.3224, 0.1021, -1.4290], [-0.3559, 0.2912, -0.1044], [ 0.3652, 2.3112, 1.4784], [-0.9630, -0.2499, -1.3288], [-0.0667, -0.2910, -0.6420]]) tensor([ 0.3224, 0.1021, -1.4290, -0.3559, 0.2912, -0.1044, 0.3652, 2.3112, 1.4784, -0.9630, -0.2499, -1.3288, -0.0667, -0.2910, -0.6420]) tensor([[ 0.3224, 0.1021, -1.4290], [-0.3559, 0.2912, -0.1044], [ 0.3652, 2.3112, 1.4784], [-0.9630, -0.2499, -1.3288], [-0.0667, -0.2910, -0.6420]])
所有Tensor操作的列表均可在PyTorch的文档中找到。
PyTorch – NumPy桥
我们可以很容易地将PyTorch张量转换为numpy数组,反之亦然。
PyTorch的设计方式是,CPU上的Torch张量和相应的" numpy"数组将具有相同的内存位置。
因此,如果您更改其中一个,则另一个将自动更改。
为了证明这一点,让我们使用" torch.numpy()"和" torch.from_numpy()"方法进行测试。
torch.numpy()用于将Tensor转换为numpy数组,而torch.from_numpy()将执行相反的操作。
import torch # We also need to import numpy to declare numpy arrays import numpy as np a = torch.tensor([[1, 2, 3], [4, 5, 6]]) print('Original Tensor:', a) b = a.numpy() print('Tensor to a numpy array:', b) # In-Place addition (add 2 to every element) a.add_(2) print('Tensor after addition:', a) print('Numpy Array after addition:', b)
输出
Original Tensor: tensor([[1, 2, 3], [4, 5, 6]]) Tensor to a numpy array: [[1 2 3] [4 5 6]] Tensor after addition: tensor([[3, 4, 5], [6, 7, 8]]) Numpy Array after addition: [[3 4 5] [6 7 8]]
实际上,numpy数组也改变了它的价值!
让我们做相反的事情
import torch import numpy as np c = np.array([[4, 5, 6], [7, 8, 9]]) print('Numpy array:', c) # Convert to a tensor d = torch.from_numpy(c) print('Tensor from the array:', d) # Add 3 to each element in the numpy array np.add(c, 3, out=c) print('Numpy array after addition:', c) print('Tensor after addition:', d)
输出
Numpy array: [[4 5 6] [7 8 9]] Tensor from the array: tensor([[4, 5, 6], [7, 8, 9]]) Numpy array after addition: [[ 7 8 9] [10 11 12]] Tensor after addition: tensor([[ 7, 8, 9], [10, 11, 12]])
注意:如果您不通过a + = 3
或者np.add(out = a)
使用numpy`就地加法,那么Tensor将不会反映numpy数组中的更改。
例如,如果您尝试这样做:
c = np.add(c, 3)
由于您使用的是=
,这意味着Python将创建一个新对象并将该新对象分配给名为c
的名称。
因此,原始内存位置仍保持不变。
将CUDA GPU与PyTorch张量配合使用
通过将张量移动到GPU,我们可以使NVIDIA CUDA GPU执行计算并提高速度。
注意:仅当您启用了CUDA的NVIDIA GPU时才适用。
如果您不确定这些术语是什么,我建议您在线搜索。
我们可以使用" torch.cuda.is_available()"检查是否有可用于PyTorch的GPU。
import torch if torch.cuda.is_available(): print('Your device is supported. We can use the GPU for PyTorch!') else: print('Your GPU is either 不支持 by PyTorch or you haven't installed the GPU version')
对我来说,它是可用的,因此只要您的笔记本电脑支持,请确保先安装CUDA,然后再继续进行。
我们可以使用" tensor.to(device)"将张量从CPU移至GPU,其中" device"是设备对象。
可以是" torch.device(" cuda")",也可以只是" cpu"。
import torch x = torch.tensor([1, 2, 3], dtype=torch.long) if torch.cuda.is_available(): print('CUDA is available') # Create a CUDA Device object device = torch.device("cuda") # Create a tensor from x and store on the GPU y = torch.ones_like(x, device=device) # Move the tensor from CPU to GPU x = x.to(device) # This is done on the GPU z = x + y print(z) # Move back to CPU and also change dtype print(z.to("cpu", torch.double)) print(z) else: print('CUDA is not available')
输出
CUDA is available tensor([2, 3, 4], device='cuda:0') tensor([2., 3., 4.], dtype=torch.float64) tensor([2, 3, 4], device='cuda:0')