Pytorch入门3-Pytorch基本使用

Pytorch入门3-Pytorch基本使用

第一节:张量基本使用

一、什么是张量

PyTorch中的几乎所有计算,都是基于一个新的数据结构:张量(Tensor)。PyTorch提供的张量的用法与Numpy中的多维数组高度相似,但是于Numpy中的数组相比,张量存在以下优势:
●GPU加速:张量可以通过.cuda()或传递参数device=”cuda”即可使用GPU来运行。
●自动微分:张量可以实现自动微分的功能,来实现梯度下降,从而更新参数。
●深度学习集成:张量内置深度学习常见的操作,比如卷积、池化等。
总而言之,张量是一个专为深度学习定制开发的数据结构,使用张量可以快速开发深度学习项目,但是对外提供的方法与Numpy的ndarray非常类似,学习成本非常低。

二、创建张量

创建张量有两种方式,分别是torch.tensor和torch.Tensor,下面分别来说明。

1使用torch.tensor创建张量

使用torch.tensor创建张量,张量的类型由给定的值来确定,如果都是整数,那么就是torch.int64类型,如果其中有浮点数,那么就是``torch.float32类型,如果都是True或False,那么就是torch.bool类型,或者可以通过指定dtype`参数来手动指定其类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 创建标量张量  
tensor1 = torch.tensor(20)
print(tensor1)
# 提取张量中的标量
print(tensor1.item())

# 用列表创建张量
tensor2 = torch.tensor([[1,2], [3,4],[5,6]])
print(tensor2)

# 用numpy数组创建张量
tensor3 = torch.tensor(np.array([[1.0,2], [3,4],[5,6]]))
print(tensor3)

# 指定类型
tensor2 = torch.tensor([1, 2], dtype=torch.float)
print(tensor2.dtype)

2使用torch.Tensor创建张量

使用torch.Tensor创建的张量,默认类型是torch.float32类型。如果想要创建其他类型,那么可以使用具体类型的类来创建:
●torch.IntTensor():torch.int32类型。
●torch.ShortTensor():torch.int16类型。
●torch.LongTensor():torch.int64类型。
●torch.FloatTensor():torch.float32类型。
●torch.DoubleTensor():torch.float64类型。
●torch.BoolTensor():torch.bool类型。
示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 指定张量形状,值是随机的  
tensor4 = torch.Tensor(2,3)

# 指定张量初始值
tensor5 = torch.Tensor([[1,2], [3,4],[5,6]])

# 创建int类型的张量
tensor6 = torch.IntTensor([[1,2], [3,4],[5,6]])

# 创建short类型张量
tensor7 = torch.ShortTensor([1,11])

# 创建long类型张量
tensor8 = torch.LongTensor([11,22])

# 创建float类型张量
tensor9 = torch.FloatTensor([1,2])

# 创建Double类型的张量
tensor10 = torch.DoubleTensor([1,2])

# 创建bool类型的张量
tensor11 = torch.BoolTensor([1,0])

3张量数据类型转换

有时候需要对张量的类型进行转换,我们可以使用Tensor.type(dtype)或Tensor.int/float等方法进行转换,类型转换。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
# 1. 使用Tensor.type  
tensor1 = torch.tensor([[1,2],[3,4]])
print(tensor1.dtype)
tensor1 = tensor1.type(torch.float32)
print(tensor1.dtype)

# 2. 使用Tensor.类型
tensor1 = torch.tensor([[1,2],[3,4]])
print(tensor1.dtype)
tensor1 = tensor1.float()
print(tensor1.dtype)

4指定区间创建张量

我们也可以使用指定区间的方法,让torch自动生成张量。指定区间的常用方法有:torch.arange、torch.linspace以及torch.logspace。

4.1 torch.arange(start, end, step)

torch.arange方法取值范围是[start, end)。示例代码如下:

1
2
3
tensor7 = torch.arange(1,10, 2)  
print(tensor7)

4.2 torch.linspace(start, end, steps)

这个方法是在[start, end]范围内,平均切分steps个值,并把这些值取出来。示例代码如下:

1
2
3
tensor8 = torch.linspace(1,10, 3)  
print(tensor8)

4.3 torch.logspace(start, end, steps, base)

在[start, end]范围内,使用base作为底(默认是10),区间内的数作为指数,取steps个值。示例代码如下:

1
2
3
tensor9 = torch.logspace(1, 4, 4, 2)  
print(tensor9)

5按形状填充张量

5.1 torch.zeros(size)

创建size形状的全0的张量,默认是torch.float32类型。示例代码如下:

1
2
torch.zeros(2,3)  

5.2 torch.ones(size)

创建size形状的全1张量。示例代码如下:

1
2
torch.ones(2,3)  

5.3 torch.full(size, value)

创建size形状,按指定值填充的张量,比如创建一个全是5的张量:

1
2
torch.full((2,3), 5)  

5.4 torch.empty(size)

创建size形状的未初始化的张量,他们的值是随机的。示例代码如下:

1
2
torch.empty((3,4))  

5.5 torch.zeros_like(input)

创建与给定张量形状相同的全0张量。示例代码如下:

1
2
torch.zeros_like(torch.tensor([[1,2], [3,4],[5,6]]))  

5.6 torch.ones_like(input)

创建与给定张量形状相同的全1张量。示例代码如下:

1
2
torch.ones_like(torch.tensor([[1,2], [3,4],[5,6]]))  

5.7 torch.full_like(input, value)

创建与给定张量形状相同,并且为给定值的张量。示例代码如下:

1
2
torch.full_like(torch.Tensor(2,3),5)  

5.8 torch.empty_like(input)

创建与给定张量形状相同,并且未初始化的张量。示例代码如下:

1
2
torch.empty_like(torch.Tensor(2,3))  

6创建随机张量

有时候想要创建一些随机值的张量,那么可以使用以下方法。

6.1 torch.rand(size)

创建在[0,1)上均匀分布的,指定形状的张量。示例代码如下:

1
2
torch.rand(2,3)  

6.2 torch.randint(low, high, size)

创建在[low,high)上均匀分布的,指定形状的torch.int64类型的张量。示例代码如下:

1
2
torch.randint(1, 10, (2,3))  

6.3 torch.randn(size)

从标准正态分布(均值为0,方差为1)中随机取值,创建指定形状的张量。示例代码如下:

1
2
torch.randn((3,4))  

6.4 torch.normal(mean, std, size)

从均值为mean,标准差为std的正态分布中随机取值,创建形状为size的随机张量。示例代码如下:

1
2
torch.normal(0, 1,(3,4))  

6.5 torch.rand_like(input)

创建与input形状相同,值范围在[0,1)的随机张量。示例代码如下:

1
2
torch.rand_like(torch.Tensor(2,3))  

生成浮点类型的随机张量,他的input参数(参考张量)也必须是浮点类型,如果没有指定dtype参数,那么生成的张量的数据类型与input数据类型保持一致。

6.6 torch.randint_like(input, low, high)

创建与input形状相同,值范围在[low, high)上均匀分布的随机张量,如果没有指定dtype参数,生成的张量的类型与input保持一致(bool类型除外)。示例代码如下:

1
2
torch.randint_like(torch.Tensor(2,3), 1, 10)  

6.7 torch.randn_like(input)

创建标准正态分布的,与input形状相同的张量,其中input的类型必须是浮点类型。示例代码如下:

1
2
torch.randn_like(torch.Tensor(2,3))  

6.8 torch.randperm(n)

生成范围[0,n-1]的随机排列。示例代码如下:

1
2
torch.randperm(3)  

6.9 torch.random.initial_seed()

查看随机数种子。

6.10 torch.manual_seed(seed)

设置随机数种子,如果想要每次产生相同的结果,那么可以设置随机数种子。示例代码如下:

1
2
3
torch.manual_seed(100)  
torch.randn(10)

在设置完了随机数种子后,以后每次生成随机数时,都是可复现的。比如:第一次生成的随机数是A、B、C…,那么第二次再重新执行代码,生成的随机数依然是A、B、C…。
更完整的固定随机数种子的写法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def set_global_seed(seed):  
    # 固定Python的哈希行为
    os.environ['PYTHONHASHSEED'] = str(seed)
    # 设置random库的随机数种子
    random.seed(seed)
    # 设置numpy的随机数种子
    np.random.seed(seed)
    # 设置torch的随机数种子
    torch.manual_seed(seed)
    # 设置GPU的随机数种子
    torch.cuda.manual_seed(seed)
    # 启用cuDNN软件的确定性
    torch.backends.cudnn.deterministic = True
    # 关闭cuDNN的性能优化,否则就会有不确定性
    torch.backends.cudnn.benchmark = False

如果使用DataLoader,且使用了多进程,那么在创建DataLoader对象时,还需要设置随机数种子。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import os  
import random
import numpy as np
import torch
from torch.utils.data import DataLoader, Dataset

def set_global_seed(seed):
    os.environ['PYTHONHASHSEED'] = str(seed)
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    torch.backends.cudnn.deterministic = True
    torch.backends.cudnn.benchmark = False

def seed_worker(worker_id):
    worker_seed = torch.initial_seed() % 2\*\*32
    np.random.seed(worker_seed)
    random.seed(worker_seed)

# ==== 主程序 ====
set_global_seed(42)

dataset = YourDataset()
dataloader = DataLoader(
    dataset,
    batch_size=32,
    num_workers=4,
    worker_init_fn=seed_worker,
    shuffle=True,
    generator=torch.Generator().manual_seed(42)  # 控制 DataLoader shuffle
)

三、张量与数组的转换

pytorch中的张量与numpy中的数组具有高度相似性,因此torch提供了非常方便的函数来实现两者之间的类型转换。

1数组转张量

数组转张量有两种方法。第一种是在创建张量时直接传入数组对象,第二种是使用torch.from_numpy来实现。第一种方式不会共享底层的内存,第二种方式默认会共享内存,如果不想共享内存,那么可以调用数组的copy方法。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
tensor = torch.tensor(np.array([1,2]))  

# 1. 使用torch.from_numpy,默认共享内存
arr = np.array([1,2,3,4,5])
tensor = torch.from_numpy(arr)
print(arr)
tensor[0] = 0
print(arr)

# 2. 使用torch.from_numpy,并且使用数组的copy方法,将不会共享内存
arr = np.array([1,2,3,4,5])
tensor = torch.from_numpy(arr.copy())
print(arr)
tensor[0] = 0
print(arr)

2张量转数组

张量转数组,只需调用Tensor.numpy()方法即可,默认情况下会共享内存,如果不想共享内存,那么可以调用copy()方法。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1. 使用Tensor.numpy()将张量转换为数组,默认会共享底层内存  
tensor = torch.tensor([1,2,3,4,5])
print(tensor)
arr = tensor.numpy()
arr[0] = 0
print(tensor)

# 2. 调用copy方法,不会共享底层内存
tensor = torch.tensor([1,2,3,4,5])
print(tensor)
arr = tensor.numpy().copy()
arr[0] = 0
print(tensor)

四、形状操作

张量创建后,可以修改其形状,主要有以下方法可以实现形状的修改。

1 transpose

使用transpose可以交换张量中某两个维度的元素。可以理解为,改变索引方式。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
tensor = torch.randint(1, 10, (2,3,4))  
print(tensor)
# 交换第1维和第2维的元素,形状变为:(2,4,3)
print(tensor.transpose(1,2))
# 输出
tensor([[[3, 5, 8, 1],
[5, 5, 6, 9],
[2, 2, 9, 4]],

[[7, 7, 5, 5],
[6, 8, 9, 4],
[7, 2, 3, 5]]])
tensor([[[3, 5, 2],
[5, 5, 2],
[8, 6, 9],
[1, 9, 4]],

[[7, 6, 7],
[7, 8, 2],
[5, 9, 3],
[5, 4, 5]]])

2 permute

如果想要重新排列多个维度的元素,可以使用permute实现。示例代码如下:

1
2
3
4
5
tensor = torch.randint(1, 10, (2,3,4))  
print(tensor)
# 形状变为:(3,4,2)
print(tensor.permute(1,2,0))

3 reshape

reshape方法直接将张量重新调整成目标的形状,但前提是调整前和调整后元素的个数必须相同。会先把数据压平,再重组。示例代码如下:

1
2
3
4
5
6
7
8
9
tensor = torch.randint(1,10, (2,2,3))  

# 重新调整形状
tensor.reshape(2,6)

# 或者某个维度指定为-1,那么torch会自动计算剩余数量
# 下面代码,会自动计算第二个维度的元素个数为6
tensor.reshape(2, -1)

4 view

view方法也可以调整形状,但是前提是该张量在内存中存储必须是连续的地址,并且将形状修改后的张量与原张量是共享内存的。示例代码如下:

1
2
3
4
5
6
7
# 先判断内存是否连续  
result = tensor.is_contiguous()
if not result:
    # 强制内存连续
    tensor = tensor.contiguous()
tensor.view(-1, 3, 2)

view方法存在的意义是,他不会在内存中进行拷贝,从而提高性能。

五、张量拼接

可以使用以下两个方法实现张量的拼接。

1 torch.cat

按指定维度进行拼接,除拼接维度外,其余维度尺寸大小必须相同。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
tensor1 = torch.randint(1,10,(2,3,4))  
tensor2 = torch.randint(1,10,(2,2,4))
print(tensor1)
print(tensor2)

# 按第一维度进行拼接得到新的张量
torch.cat([tensor1, tensor2], dim=1)


tensor([[[5, 5, 9, 6],
[6, 1, 3, 4],
[9, 7, 2, 9]],

[[2, 6, 9, 3],
[3, 4, 9, 6],
[8, 7, 1, 4]]])
tensor([[[4, 1, 6, 2],
[7, 3, 7, 5]],

[[1, 1, 3, 7],
[9, 4, 6, 5]]])


tensor([[[5, 5, 9, 6],
[6, 1, 3, 4],
[9, 7, 2, 9],
[4, 1, 6, 2],
[7, 3, 7, 5]],

[[2, 6, 9, 3],
[3, 4, 9, 6],
[8, 7, 1, 4],
[1, 1, 3, 7],
[9, 4, 6, 5]]])

2 torch.stack

张量堆叠,两个张量的形状必须完全一致,堆叠后会按照给定的维度新增一个维度。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
tensor1 = torch.randint(1,10,(3,2))
tensor2 = torch.randint(1,10,(3,2))
print(tensor1)
print(tensor2)
tensor([[6, 2],
[3, 2],
[5, 8]])
tensor([[8, 3],
[5, 7],
[1, 8]])


# 将两个张量按照第0维度堆叠
tensor3 = torch.stack([tensor1, tensor2])
tensor([[[6, 2],
[3, 2],
[5, 8]],

[[8, 3],
[5, 7],
[1, 8]]])

# 将两个张量按照第1维度堆叠
tensor4 = torch.stack([tensor1, tensor2], dim=1)
tensor([[[6, 2],
[8, 3]],

[[3, 2],
[5, 7]],

[[5, 8],
[1, 8]]])

tensor5 = torch.stack([tensor1, tensor2], dim=2)
tensor([[[6, 8],
[2, 3]],

[[3, 5],
[2, 7]],

[[5, 1],
[8, 8]]])

六、增加或删除维度

1 unsqueeze增加维度

使用unsqueeze可以在原有张量的基础上增加一个维度。示例代码如下:

1
2
3
4
5
6
7
8
9
tensor1 = torch.tensor([1, 2, 3, 4, 5])  
print(tensor1)
# 在0维上增加一个维度(变为:(1,5)) tensor([[1, 2, 3, 4, 5]])
print(tensor1.unsqueeze(dim=0))
# 在1维上增加一个维度(变为:(5,1))
print(tensor1.unsqueeze(dim=1))
# 在-1维上增加一个维度(变为:(5,1))
print(tensor1.unsqueeze(dim=-1))

unsqueeze不会拷贝张量到新的内存中,相反会和原张量共享内存。

2 squeeze删除维度

使用sequeeze可以在原有张量上删除size=1的维度,如果没有size=1的维度,那么会保持不变。示例代码如下:

1
2
3
4
5
# (1,4)的张量  
tensor1 = torch.tensor([[1,2,3,4]])
# 删除size=1的张量
print(tensor1.squeeze())

作者

步步为营

发布于

2026-09-28

更新于

2026-09-29

许可协议