本篇文章仅作为个人记录用途,不提供任何知识内容正确性的保障。若文章有问题,请联系我并告知,感激不尽。


由于是第一次写学习笔记相关文章,有几点想要事先说明:

  1. 本博客所有学习笔记文章的目的都非教学,而是学习记录,方便我日后查看
  2. 如果能帮助到您,那当然最好
  3. 本人是初学者,因此恐怕不能解决您看本文遇到的问题,但会尽力

本文主要内容:PyTorch最基础的一些知识。

本篇学习笔记的所有内容都基于https://learnpytorch.io/

BTW:learnpytorch.io有配套的YouTube视频资源:


1. 创建张量(tensor)

关于张量的一些概念

  1. dimension:维度,scalar-0, vector-1, matrix-2, 方括号的层数
  2. shape:每个维度上的元素个数

标量

scalar = torch.tensor(a)

1.标量:单个数字,注意没有[]
2.将标量转换为整数:

scalar.item()
# output: a

3.查看标量的维度(dimension):

print(scalar.ndim)
# output: 0

scalar的维度为0,有0个方括号

向量

vector = torch.tensor([a, b])
  1. 向量: 一组数字,可以大于等于1个
  2. 注意:a为向量,b为标量

    a = torch.tensor([1])
    b = torch.tensor(1)
  3. 查看向量的维度:

    print(vector.ndim)
    #output: 1

    向量的维度为1,共有一个方括号

  4. 查看向量的形状:

    vector.shape
    # output: torch.Size([2])

    向量有一个维度,这个维度中的元素个数为2。

矩阵

MATRIX = torch.tensor([[7, 8], [9, 10], [11, 12]])
  1. 矩阵:多组向量。注意需要嵌套两层括号!
  2. 查看矩阵的维度:

    print(MATRIX.ndim)
    # output: 2

    矩阵有两层方括号,维度为2

  3. 查看矩阵的形状:

    MATRIX.shape
    # output: torch.Size([3, 2])

    这个矩阵共有两个维度:
    第0维:3个元素(第一个括号内有三个方括号)
    第1维:2个元素(第二层括号内有两个数字)

张量

TENSOR = torch.tensor([[[1, 2, 3], [3, 6, 9], [2, 4, 5]]])
  1. 张量:多组矩阵。注意需要嵌套三层括号。这是一个包含一个3x3矩阵的张量
  2. 查看张量维度:

    print(TENSOR.ndim)
    # output: 3

    张量有三层方括号,维度为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填满整个张量。

  1. 将张量填满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。

  2. 将张量填满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. 张量数据类型

  1. 张量有很多种数据类型,有些是为CPU设计的,也有些是为GPU设计的。
  2. 如果看到torch.cuda,说明这个tensor是在使用GPU(Nvidia的GPU使用的计算工具名为CUDA)。
  3. 最常见、默认的数据类型为torch.float32torch.float
  4. 计算精度越高,越准确。这在深度学习中很重要,因为这个过程中涉及到很多计算操作,精度/细节越多,计算量就越大。因此低精度数据所需的计算时间更短。
  5. 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. 遇到的问题
    (1) shape issue: 张量的形状不匹配
    (2) datatype issue: 张量的数据类型不匹配:例如一个是torch.float32,另一个是torch.float16
    (3) device issue: 张量的运行设备不匹配:一个在CPU中,另一个在GPU中。PyTorch中计算张量需要两个在同一个设备中!
  2. dtype参数创建张量

    float_16_tensor = torch.tensor([3.0, 6.0, 9.0], dtype=torch.float16)
    float_16_tensor.dtype
    # output: torch.type16

    dtype参数传递,就能指定数据类型。

6. 从张量中获取信息

张量的三个常见属性:

  1. shape: 张量的形状
  2. dtype: 数据类型
  3. 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为需要转置的矩阵,dim0dim1为需要交换的维度。
dim0dim1较难理解,接下来我们拆开分析:
在二维矩阵(matrix)中,dim0dim1不需要说明因为对于矩阵,永远是行(第0维)与列(第一维)进行交换,因此dim0dim1分别为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的dtypetorch.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,使其dtypetorch.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

  1. Google Colab, 这也是我的方案。完全免费,不需要任何配置,也可以很好的分享合作。但缺点是不能保存output,计算资源有限,且会受到超时的限制。
  2. 用自己的GPU,可以在本地运行程序,但GPU需要花钱,配置难度中等。
  3. 云计算,如AWS, GCP, Azure,前期投入成本低,就可以获得几乎无限的计算资源。但是如果持续运转就会非常昂贵,且需要大量时间进行配置。
    在学习中,我所使用的是Google Colab,用MacBook进行小规模的程序运行。

可以用!nvidia-smi指令来看Nvidia GPU的配置:

!nvidia-smi
Wed 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中的最大/最小值等等。