本篇文章仅作为个人记录用途,不提供任何知识内容正确性的保障。若文章有问题,请联系我并告知,感激不尽。
由于是第一次写学习笔记相关文章,有几点想要事先说明:
- 本博客所有学习笔记文章的目的都非教学,而是学习记录,方便我日后查看
- 如果能帮助到您,那当然最好
- 本人是初学者,因此恐怕不能解决您看本文遇到的问题,但会尽力
本文主要内容:PyTorch最基础的一些知识。
本篇学习笔记的所有内容都基于https://learnpytorch.io/。
BTW:learnpytorch.io有配套的YouTube视频资源:
1. 创建张量(tensor)
关于张量的一些概念
- dimension:维度,scalar-0, vector-1, matrix-2, 方括号的层数
- shape:每个维度上的元素个数
标量
scalar = torch.tensor(a)1.标量:单个数字,注意没有[]
2.将标量转换为整数:
scalar.item()
# output: a3.查看标量的维度(dimension):
print(scalar.ndim)
# output: 0scalar的维度为0,有0个方括号
向量
vector = torch.tensor([a, b])- 向量: 一组数字,可以大于等于1个
注意:a为向量,b为标量
a = torch.tensor([1]) b = torch.tensor(1)查看向量的维度:
print(vector.ndim) #output: 1向量的维度为1,共有一个方括号
查看向量的形状:
vector.shape # output: torch.Size([2])向量有一个维度,这个维度中的元素个数为2。
矩阵
MATRIX = torch.tensor([[7, 8], [9, 10], [11, 12]])- 矩阵:多组向量。注意需要嵌套两层括号!
查看矩阵的维度:
print(MATRIX.ndim) # output: 2矩阵有两层方括号,维度为2
查看矩阵的形状:
MATRIX.shape # output: torch.Size([3, 2])这个矩阵共有两个维度:
第0维:3个元素(第一个括号内有三个方括号)
第1维:2个元素(第二层括号内有两个数字)
张量
TENSOR = torch.tensor([[[1, 2, 3], [3, 6, 9], [2, 4, 5]]])- 张量:多组矩阵。注意需要嵌套三层括号。这是一个包含一个3x3矩阵的张量
查看张量维度:
print(TENSOR.ndim) # output: 3张量有三层方括号,维度为3
查看张量的形状:
TENSOR.shape # output: torch.Size([1, 3, 3])这个张量共有三个维度:
第0维:1个元素(第一层括号内有一个方括号)
第1维:3个元素(第二层括号内有三个方括号)
第2维:3个元素(第三层括号内有三个元素)
为MATRIX和TENSOR命名使用大写字母,为scalar和vector命名使用小写字母。
2. 随机张量(random tensors)
在机器学习的过程中,往往不需要自己用手创建张量,而是随机生成,然后不断调整优化。torch.rand()用来创建随机张量,需要传递size作为参数(也即是shape),注意传入的size参数需要在()内包裹。
random_tensor = torch.rand(size=(3, 4))
random_tensor, random_tensor.dtype
# output:
# (tensor([[0.5180, 0.2474, 0.2446, 0.7396],
# [0.7613, 0.3348, 0.5451, 0.8527],
# [0.5921, 0.9142, 0.7648, 0.0040]]),
# torch.float32)随机生成一个3行、4列的矩阵,.dtype可以输出张量中的元素的数据类型,为float。torch.rand()可以生成任意形状(size)的张量。
例如:随机生成一个图像,形状为[224, 224, 3]
random_image_size_tensor = torch.rand(size=(224, 224, 3))
random_image_size_tensor.shape, random_image_size_tensor.ndim
#output: (torch.Size([224, 224, 3]), 3)3. 0和1
有时候我们会想将1/0填满整个张量。
将张量填满0
用到torch.zeros(size=()),同样需要传入参数size,用()包裹。zeros = torch.zeros(size=(3, 4)) zeros, zeros.dtype # output: # (tensor([[0., 0., 0., 0.], # [0., 0., 0., 0.], # [0., 0., 0., 0.]]), # torch.float32)生成了一个3行、4列的矩阵,其中元素都是0,且数据类型为float。
将张量填满1
ones = torch.ones(size=(3, 4)) ones, ones.dtype # output: # (tensor([[1., 1., 1., 1.], # [1., 1., 1., 1.], # [1., 1., 1., 1.]]), # torch.float32)
4. 创建一个range张量
有时候想要一系列数字,例如从1到100,或从0到10。
这里的方法与Python相似:使用torch.arange(start, end, step)
注意,这里与Python不同的是函数名为arange而非range!! 在PyTorch中,torch.range()已不推荐使用!start: 起始值end: 终止值(不包含)step: 步长
range_tensor = torch.arange(0, 11, 1)
range_tensor
# output: tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])如果想要创建一个全0/1的张量,其形状与某个已知张量相同,可以用:torch.zeros_like(input=...)和torch.ones_like(input=...)
注意zeros和ones的后面都有s!
range_tensor = torch.arange(0, 11, 1)
zeros = torch.zeros_like(input=range_tensor)
print(zeros)
ones = torch.ones_like(input=range_tensor)
print(ones)
# output:
# tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
# tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])5. 张量数据类型
- 张量有很多种数据类型,有些是为CPU设计的,也有些是为GPU设计的。
- 如果看到
torch.cuda,说明这个tensor是在使用GPU(Nvidia的GPU使用的计算工具名为CUDA)。 - 最常见、默认的数据类型为
torch.float32或torch.float - 计算精度越高,越准确。这在深度学习中很重要,因为这个过程中涉及到很多计算操作,精度/细节越多,计算量就越大。因此低精度数据所需的计算时间更短。
dtype参数:float_32_tensor = torch.tensor([3.0, 6.0, 9.0], dtype=None, device = None, requires_grad=False) float_32_tensor.shape, float_32_tensor.dtype, float_32_tensor.device # output: # (torch.Size([3]), torch.float32, device(type='cpu'))
解释:dtype=None: 不指定数据类型device=None:不指定运行设备requires_grad=False:如果为True,则对于Tensor的操作将被记录。
- 遇到的问题
(1) shape issue: 张量的形状不匹配
(2) datatype issue: 张量的数据类型不匹配:例如一个是torch.float32,另一个是torch.float16。
(3) device issue: 张量的运行设备不匹配:一个在CPU中,另一个在GPU中。PyTorch中计算张量需要两个在同一个设备中! 用
dtype参数创建张量float_16_tensor = torch.tensor([3.0, 6.0, 9.0], dtype=torch.float16) float_16_tensor.dtype # output: torch.type16将
dtype参数传递,就能指定数据类型。
6. 从张量中获取信息
张量的三个常见属性:
shape: 张量的形状dtype: 数据类型device: 存储设备(CPU/GPU)
rand_tensor = torch.rand(3, 4)
print(rand_tensor)
print(f"Shape of tensor: {rand_tensor.shape}")
print(f"Datatype of tensor: {rand_tensor.dtype}")
print(f"Device tensor is stored on: {rand_tensor.device}")
# output:
# tensor([[0.8502, 0.5263, 0.6175, 0.0186],
# [0.2349, 0.3131, 0.1066, 0.8167],
# [0.5754, 0.0819, 0.9750, 0.6324]])
# Shape of tensor: torch.Size([3, 4])
# Datatype of tensor: torch.float32
# Device tensor is stored on: cpu当出现错误时,很有可能是这三个属性有问题:what (shape), what (dtype), where (device)
7. 张量操作
操作类型
张量操作包括:
- 加法
- 减法
- 元素间乘法
- 除法
- 矩阵乘法
基础操作
张量的基础操作(fundamental operations)包括:加法(+)、减法(-)、乘法(*)
tensor = torch.tensor([1, 2, 3])
tensor + 10
# output: tensor([11, 12, 13])每个元素加10
tensor * 10
# output: tensor([10, 20, 30])每个元素乘10
以上所有操作没有对张量本身改变!
tensor = tensor - 10
tensor
# output: tensor([-9, -8, -7])
tensor = tensor + 10
tensor
# output: tensor([1, 2, 3])PyTorch也有一系列内置函数,如torch.mul(), torch.add()进行基础操作,但平常使用*, +更多。
torch.multiply(tensor, 10)
# output: tensor([10, 20, 30])tensor
# output: tensor([1, 2, 3]), original tensor unchanged这样的函数不改变张量本身。
矩阵乘法
矩阵乘法是深度学习与机器学习中最常见的操作。
PyTorch通过torch.matmul()函数实现矩阵乘法
矩阵乘法的具体规则这里就不具体说明了。
tensor = torch.tensor([1, 2, 3])
tensor.shape
# output: torch.Size([3])tensor * tensor
torch.matmul(tensor, tensor)
# output:
# tensor([1, 4, 9])
# tensor(14)*代表元素相乘,因此结果为[1*1, 2*2, 3*3]。torch.matmul()为矩阵乘法,对于向量来说,就是内积(点乘),因此结果为1*1+2*2+3*3
@可以代替torch.matmul(),但不推荐。
tensor @ tensor
# output: tensor(14)8. 最常见的错误:shape errors
shape errors
深度学习过程中涉及到大量的矩阵乘法,而矩阵对于其形状、大小有很严格的规则,因此最常见的错误就是形状不匹配。
Example:
tensor_A = torch.tensor([[1, 2], [3, 4], [5, 6]], dtype=torch.float32)
tensor_B = torch.tensor([[7, 10], [8, 11], [9, 12]], dtype=torch.float32)
torch.matmul(tensor_A, tensor_B) # This will cause error
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
[/tmp/ipython-input-1828183431.py](https://localhost:8080/#) in <cell line: 0>()
1 tensor_A = torch.tensor([[1, 2], [3, 4], [5, 6]], dtype=torch.float32)
2 tensor_B = torch.tensor([[7, 10], [8, 11], [9, 12]], dtype=torch.float32)
----> 3 torch.matmul(tensor_A, tensor_B) # This will cause error
RuntimeError: mat1 and mat2 shapes cannot be multiplied (3x2 and 3x2)需要让AB两个张量的inner dimension相匹配,才能进行矩阵乘法!
因此可以用矩阵的转置(transpose)
$$ (\mathbf{A}^T)_{ij} = a_{ji} $$
使用torch.transpose(input, dim0, dim1)进行操作,会返回转置后的矩阵。
其中input为需要转置的矩阵,dim0和dim1为需要交换的维度。dim0和dim1较难理解,接下来我们拆开分析:
在二维矩阵(matrix)中,dim0和dim1不需要说明因为对于矩阵,永远是行(第0维)与列(第一维)进行交换,因此dim0和dim1分别为0和1。
但对于高维的张量来说,其维度>2,因此需要挑选两个维度进行交换。
因此,对于矩阵,我们可以使用tensor.T方法进行转置。这种方法会返回转置后的矩阵,而不会改变原矩阵!
print(tensor_A)
print(tensor_B.T)
output = tensor_A @ tensor_B.T
print(output)
# output:
# tensor([[1., 2.], [3., 4.], [5., 6.]])
# tensor([[ 7., 8., 9.], [10., 11., 12.]])
# tensor([[ 27., 30., 33.], [ 61., 68., 75.], [ 95., 106., 117.]])最小值、最大值、平均值、和……
现在,我们开始关注聚合(aggregate)张量的方式。
创建一个tensor,然后找到这个tensor的最大值、最小值、平均值、和:
x = torch.arange(0, 100, 10)
x
# output: tensor([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])Perform aggregation:
print(f'minimum: {x.min()}')
print(f'maximum: {x.max()}')
print(f'mean: {x.type(torch.float32).mean()}')
print(f'sum: {x.sum()}')
# output:
# minimum: 0
# maximum: 90
# mean: 45.0
# sum: 450我们可以看到,以下方法是用来进行aggregation的:tensor.min(): 返回最小值tensor.max(): 返回最大值tensor.mean(): 返回平均值tensor.sum(): 返回和
上面那个程序注意到,求平均值的方法似乎与其他方法不一样。这是因为上面的x这个tensor的dtype为torch.int64,为整型,而torch.mean()这个方法要求张量数据类型为torch.float32。因此需要先对其类型进行转换才能使用,否则会报错。
PyTorch中也有相对应的函数,效果与上面的方法相同。
torch.max(x)
torch.min(x)
torch.mean(x.type(torch.float32))
torch.sum(x)找到最小值/最大值所对应的索引
如果想要找到张量中最大值/最小值所对应的位置/索引,可以使用torch.argmax(), torch.argmin()方法。
这个可以找到最大值/最小值的位置,却不返回其值,这在softmax方法中很实用。
x = torch.arange(0, 100, 10)
print(f"the maximum is {x.argmax()}th number")
print(f"the minimum is {x.argmin()}th number")
# output:
# the maximum is 9th number
# the minimum is 0th number当张量中出现多个最大/小值的时候,这个方法返回索引小的位置。
这个在softmax中非常有用:
$$ \mathrm{Softmax}(x_i) = \frac{e^{x_i}}{\sum_{j} e^{x_j}} $$
改变张量的数据类型
当两个张量数据类型不同,例如一个为torch.float64, 另一个为torch.float32时,就会出现错误,因此改变数据类型可以解决这个错误。
使用tensor.type(...)方法,...为想要修改为的数据类型。返回一个修改后的张量,而不修改原tensor。
tensor = torch.arange(10., 100., 10.)
tensor.dtype
#output: torch.float32现在我们创建一个新的tensor,使其dtype为torch.float16
tensor_float16 = tensor.type(torch.float16)
tensor_float16
# output: tensor([10., 20., 30., 40., 50., 60., 70., 80., 90.], dtype=torch.float16)tensor_int8 = tensor.type(torch.int8)
tensor_int8
# output: tensor([10, 20, 30, 40, 50, 60, 70, 80, 90], dtype=torch.int8)需要注意的是dtype在写的时候需要添加torch.,不要忘记!
数字后缀越小,精度越低,计算越快。
还有更多的tensor methods可以在https://docs.pytorch.org/docs/stable/tensors.html找到。
8. 改变形状
这些操作是改变tensor的维度、形状,却不改变其中的值。
| 函数 | 方法 | 功能 |
|---|---|---|
torch.reshape(input, shape) | tensor.reshape(shape) | 返回改变形状的新tensor |
| 无 | tensor.view(shape) | 返回原始tensor的视图,改变形状 |
torch.stack(tensors, dim=0) | 将多个形状相同的tensor,沿新维度(dim)堆叠 | |
torch.squeeze(input) | 移除所有元素个数为1的维度 | |
torch.unsqueeze(input, dim) | 返回一个新张量,在dim处插入一个新维度,大于或等于dim的维度向后移1 | |
torch.permute(input, dims) | 返回原始tensor的视图,各个维度按照dims的指定顺序排列 |
这些函数/方法能够帮助我们确保张量的形状正确,以进行操作。
# Create a tensor
x = torch.arange(1., 8.)
x, x.shape
# output: (tensor([1., 2., 3., 4., 5., 6., 7.]), torch.Size([7]))用tensor.reshape(shape)添加新的维度:
# Add an extra dimension
x_reshaped = x.reshape(1, 7)
x_reshaped, x_reshaped.shape
# output: (tensor([[1., 2., 3., 4., 5., 6., 7.]]), torch.Size([1, 7]))用tensor.view(shape)返回新的视图:
# Change view
z = x.view(1, 7)
z, z.shape
# output: (tensor([[1., 2., 3., 4., 5., 6., 7.]]), torch.Size([1, 7]))注意:tensor.view(shape)本身并不会改变原张量的任何形状/值。但是如果修改新视图中的值,原张量中的值也会改变。
# Changing z changes x
z[:, 0] = 5
z, x
# output: (tensor([[5., 2., 3., 4., 5., 6., 7.]]), tensor([5., 2., 3., 4., 5., 6., 7.]))用torch.stack(tensors dim=0)进行堆叠:
x_stacked = torch.stack([x, x, x, x], dim=0)
x_stacked
# output: tensor([[5., 2., 3., 4., 5., 6., 7.],
# [5., 2., 3., 4., 5., 6., 7.],
# [5., 2., 3., 4., 5., 6., 7.],
# [5., 2., 3., 4., 5., 6., 7.]])用torch.squeeze()对tensor进行压缩:
print(f'Previous tensor: {x_reshaped}')
print(f'Previous shape: {x_reshaped.shape}')
x_squeezed = x_reshaped.squeeze()
print(f'\nNew tensor: {x_squeezed}')
print(f'New shape: {x_squeezed.shape}')
# output:
# Previous tensor: tensor([[5., 2., 3., 4., 5., 6., 7.]])
# Previous shape: torch.Size([1, 7])
# New tensor: tensor([5., 2., 3., 4., 5., 6., 7.])
# New shape: torch.Size([7])用torch.unsqueeze()在特定维度增加一个维度,元素个数为1:
print(f"Previous tensor: {x_squeezed}")
print(f"Previous shape: {x_squeezed.shape}")
## Add an extra dimension with unsqueeze
x_unsqueezed = x_squeezed.unsqueeze(dim=0)
print(f"\nNew tensor: {x_unsqueezed}")
print(f"New shape: {x_unsqueezed.shape}")
# output:
# Previous tensor: tensor([5., 2., 3., 4., 5., 6., 7.])
# Previous shape: torch.Size([7])
# New tensor: tensor([[5., 2., 3., 4., 5., 6., 7.]])
# New shape: torch.Size([1, 7])用torch.permute(input, dims)将input的维度重新排序:
# Create tensor with specific shape
x_original = torch.rand(size=(224, 224, 3))
# Permute the original tensor to rearrange the axis order
x_permuted = x_original.permute(2, 0, 1) # shifts axis 0->1, 1->2, 2->0
print(f"Previous shape: {x_original.shape}")
print(f"New shape: {x_permuted.shape}")
# output:
# Previous shape: torch.Size([224, 224, 3])
# New shape: torch.Size([3, 224, 224])与tensor.view()相似,torch.permute()返回的也是视图,因此修改视图也会修改原tensor。
9. 索引(indexing)
有时候需要从张量中选择特定的数据,如第一行或第二列,这时候就需要用到索引(indexing)。
PyTorch的索引与Python中列表的索引非常相似。
x = torch.arange(0, 10).reshape(1, 3, 3)
print(f"First square bracket:\n{x[0]}")
print(f"Second square bracket: {x[0][0]}")
print(f"Third square bracket: {x[0][0][0]}")
# output:
# First square bracket:
# tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# Second square bracket: tensor([1, 2, 3])
# Third square bracket: 1你可以用:来表示在这个维度的所有元素,然后用一个,来增加另外的维度。
示例分析:
对于刚才的三维张量,x[:, 0]::对应0维;0对应1维,第二维没写。因此就是0维的所有元素,一维的第0个元素。
x[:, 0] #all value of 0 dimension and 0 index of 1 dimension
# output: tensor([1, 2, 3])对于x[:, :, 1],就是:0维的所有元素,1维的所有元素,2维的第1个索引。
x[:, :, 1]
# output: tensor([2, 5, 8])对于x[:, 1, 1]就是:0维的所有元素,1维的第一个元素,2维的第一个。
x[:, 1, 1]
# output: tensor([5])对于x[0, 0, :]就是:0维的第0个元素,1维的第0个元素,2维的所有元素,也就是[1, 2, 3]
x[0, 0, :]
# output: tensor([1, 2, 3])10. PyTorch与NumPy
这部分由于我还没学习过NumPy,所以暂时跳过。
11. 可复现性(Reproducibility)
计算机是假随机(pseudorandomness),每一步都可以预测。神经网络从随机数开始,然后再通过tensor operating进行优化。从随机数开始 -> tensor operations -> 重复优化
虽然随机性很好,但有时我们需要少一些随机,才可以进行可重复的实验,因此我们需要可复现性。
首先我们创建两个随机的tensor,由于他们是随机的,因此他们也会不同。
random_tensor_A = torch.rand(3, 4)
random_tensor_B = torch.rand(3, 4)
print(f"Tensor A:\n{random_tensor_A}\n")
print(f"Tensor B:\n{random_tensor_B}\n")
print(f"Does Tensor A equal Tensor B? (anywhere)")
random_tensor_A == random_tensor_B
'''
output:
Tensor A:
tensor([[0.6957, 0.0544, 0.9308, 0.7216],
[0.5228, 0.0609, 0.0955, 0.0569],
[0.2501, 0.6331, 0.3514, 0.7632]])
Tensor B:
tensor([[0.4979, 0.7928, 0.0497, 0.2677],
[0.9419, 0.6545, 0.6710, 0.6050],
[0.4906, 0.1517, 0.1015, 0.5361]])
Does Tensor A equal Tensor B? (anywhere)
tensor([[False, False, False, False],
[False, False, False, False],
[False, False, False, False]])
'''这两个tensor是不同的。但如果你想要创建两个完全相同的随机tensor,就需要torch.manual_seed(seed)。seed是一个整数,可以是任何数字。
import torch
import random
RANDOM_SEED=42
torch.manual_seed(seed=RANDOM_SEED)
random_tensor_C = torch.rand(3, 4)
# Have to reset the seed every time a new rand() is called
# Without this, tensor_D would be different to tensor_C
torch.random.manual_seed(seed=RANDOM_SEED)
# try commenting this line out and seeing what happens
random_tensor_D = torch.rand(3, 4)
print(f"Tensor C:\n{random_tensor_C}\n")
print(f"Tensor D:\n{random_tensor_D}\n")
print(f"Does Tensor C equal Tensor D? (anywhere)")
random_tensor_C == random_tensor_D
'''
output:
Tensor C:
tensor([[0.8823, 0.9150, 0.3829, 0.9593],
[0.3904, 0.6009, 0.2566, 0.7936],
[0.9408, 0.1332, 0.9346, 0.5936]])
Tensor D:
tensor([[0.8823, 0.9150, 0.3829, 0.9593],
[0.3904, 0.6009, 0.2566, 0.7936],
[0.9408, 0.1332, 0.9346, 0.5936]])
Does Tensor C equal Tensor D? (anywhere)
tensor([[True, True, True, True],
[True, True, True, True],
[True, True, True, True]])
'''注意到,如果想生成相同的随机tensor,那么在每次生成前,都需要用torch.manual_seed(seed)对种子进行初始化。
12. 使用GPU运行tensor
获得一个GPU
- Google Colab, 这也是我的方案。完全免费,不需要任何配置,也可以很好的分享合作。但缺点是不能保存output,计算资源有限,且会受到超时的限制。
- 用自己的GPU,可以在本地运行程序,但GPU需要花钱,配置难度中等。
- 云计算,如AWS, GCP, Azure,前期投入成本低,就可以获得几乎无限的计算资源。但是如果持续运转就会非常昂贵,且需要大量时间进行配置。
在学习中,我所使用的是Google Colab,用MacBook进行小规模的程序运行。
可以用!nvidia-smi指令来看Nvidia GPU的配置:
!nvidia-smiWed Oct 29 17:07:34 2025 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 550.54.15 Driver Version: 550.54.15 CUDA Version: 12.4 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 Tesla T4 Off | 00000000:00:04.0 Off | 0 | | N/A 38C P8 9W / 70W | 0MiB / 15360MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | No running processes found | +-----------------------------------------------------------------------------------------+上面的结果看起来很混乱,是由于没有换行,但也能看到完全免费的Google Colab提供的是什么GPU。
将Tensor放入GPU
尝试创建一个张量并将其放进GPU中:
使用some_tensor = some_tensor.to(device)
tensor = torch.tensor([1, 2, 3])
print(tensor, tensor.device) # not in GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
tensor_GPU = tensor.to(device)
tensor_GPU
# output:
# tensor([1, 2, 3]) cpu
# tensor([1, 2, 3], device='cuda:0')将tensor放回CPU
不能使用tensor.numpy()方法:
tensor_GPU.numpy()
# cause a error这会造成一个错误!
若想将其放回CPU,应该使用tensor.cpu(),将此tensor复制到CPU的存储中。
tensor_back_to_cpu = tensor_GPU.cpu().numpy()
tensor_back_to_cpu
# output: array([1, 2, 3])总结
PyTorch Fundamentals的内容就到这里了!内容还是很多的,从tensor的定义,以及其shape, dimension,到tensor操作,包括加减乘除、向量乘法,与调整其形状的reshape, squeeze, unsqueeze,新建随机tensor、找到tensor中的最大/最小值等等。