pytorch常用函数

这里记录了一些在使用pytorch进行构建神经网络的时候会用到的函数以及用法。

transpose函数

在 PyTorch 中,transpose() 函数用于交换张量(Tensor)的两个维度。这是对多维数据进行操作时非常有用的功能,特别是在处理来自不同数据源的形状各异的数据时。

transpose() 允许你指定两个维度的索引,然后将这两个维度进行交换。这对于调整数据的布局以符合特定操作的需求(如卷积层输入、矩阵乘法等)非常有用。

用法

torch.transpose(input, dim0, dim1) 接收三个参数:

  • input:要操作的张量。
  • dim0:要交换的第一个维度。
  • dim1:要交换的第二个维度。

示例代码

假设你有一个三维张量,形状为 (2, 3, 4),你想要交换第一维(dim0,索引为0)和第三维(dim1,索引为2):

1
2
3
4
5
6
7
8
9
import torch

# 创建一个形状为 (2, 3, 4) 的三维张量
x = torch.randn(2, 3, 4)
print("Original shape:", x.shape)

# 交换第一维和第三维
x_transposed = torch.transpose(x, 0, 2)
print("Transposed shape:", x_transposed.shape)

这将输出:

1
2
Original shape: torch.Size([2, 3, 4])
Transposed shape: torch.Size([4, 3, 2])

在这个例子中,原始张量的形状从 (2, 3, 4) 变成了 (4, 3, 2)。

注意事项

  • transpose() 不会在内存中重新排列数据,而是返回一个新的视图,其中的数据按照新的维度顺序访问。这意味着它的操作效率很高。
  • 如果你需要交换多于两个维度的数据,可以使用 permute() 方法,它允许一次重新排序多个维度。
  • 对于常见的将最后一维和前一维交换的操作,可以使用 .T 属性(只适用于2D张量)或更具体的 torch.t() 函数来实现。

unsqueeze函数

在 PyTorch 中,unsqueeze() 函数的作用是向张量中添加一个大小为1的新维度。这种操作在深度学习中经常使用,特别是当需要对数据形状进行调整以满足特定操作或网络层要求时。

unsqueeze() 函数通过在指定的位置插入一个大小为1的新维度来扩展张量的形状。这对于将一维数组转换为二维的列向量或行向量,或者为数据添加一个批量维度(batch dimension)非常有用。

用法

torch.unsqueeze(input, dim) 接收两个参数:

  • input:要操作的张量。
  • dim:在哪个维度前添加新的大小为1的维度。

新维度的位置是基于现有维度的索引来确定的,且支持负索引。负索引从末尾向前数。

示例代码

假设你有一个形状为 (3,) 的一维张量,并希望将其变为形状为 (1, 3) 的二维张量,以及形状为 (3, 1) 的二维张量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import torch

# 创建一个一维张量
x = torch.tensor([1, 2, 3])
print("Original tensor:", x)
print("Original shape:", x.shape)

# 添加一个新的维度,使其成为二维张量 (1, 3)
x_unsqueezed = torch.unsqueeze(x, 0)
print("Unsqueezed tensor (dim=0):", x_unsqueezed)
print("Unsqueezed shape (dim=0):", x_unsqueezed.shape)

# 添加一个新的维度,使其成为二维张量 (3, 1)
x_unsqueezed = torch.unsqueeze(x, 1)
print("Unsqueezed tensor (dim=1):", x_unsqueezed)
print("Unsqueezed shape (dim=1):", x_unsqueezed.shape)

输出结果:

1
2
3
4
5
6
Original tensor: tensor([1, 2, 3])
Original shape: torch.Size([3])
Unsqueezed tensor (dim=0): tensor([[1, 2, 3]])
Unsqueezed shape (dim=0): torch.Size([1, 3])
Unsqueezed tensor (dim=1): tensor([[1], [2], [3]])
Unsqueezed shape (dim=1): torch.Size([3, 1])

注意事项

  • 使用 unsqueeze() 后,虽然张量的数据未改变,但形状的改变可能会影响之后的操作,如矩阵乘法或广播。
  • unsqueeze() 仅添加大小为1的维度,这通常在准备数据供神经网络使用时非常有用,例如在时间序列或图像数据的单个样本前添加批量大小维度。

nn.Embedding

nn.Embedding 是 PyTorch 中的一个模块,用于将输入的整数索引映射到对应的高维稠密向量表示。它通常用于处理自然语言处理(NLP)任务中的词嵌入(word embeddings)。

nn.Embedding 的作用是将每个整数(通常是单词的索引)转换为一个定长的稠密向量(即嵌入向量)。这些向量可以在训练过程中学习,以捕捉词汇中每个单词的语义特征。嵌入向量通常比原始词汇索引更有用,因为它们可以表示词汇的语义关系。

用法

1
2
3
4
5
6
7
8
9
10
11
12
13
import torch
import torch.nn as nn

# 创建一个 nn.Embedding 实例
embedding = nn.Embedding(num_embeddings=10, embedding_dim=3)

# 输入是一个索引序列,通常是一个批次的词汇索引
input_indices = torch.tensor([1, 2, 3, 4])

# 获取嵌入向量
embedded_vectors = embedding(input_indices)

print(embedded_vectors)

参数说明

  • num_embeddings: 词汇表的大小,即总共要嵌入的词的数量(通常是最大的索引值+1)。
  • embedding_dim: 每个嵌入向量的维度(通常是几十到几百)。

示例解释

在上面的代码中:

  1. 我们创建了一个 nn.Embedding 层,指定了 10 个词汇(索引为 0 到 9)和每个词汇对应的嵌入向量维度为 3。
  2. 输入的 input_indices 是一个包含词汇索引的张量 [1, 2, 3, 4]
  3. 通过嵌入层后,输出是一个形状为 (4, 3) 的张量,每个输入索引对应一个 3 维的嵌入向量。

典型应用场景

  1. 词嵌入: 在 NLP 模型中,将文本序列转换为词嵌入表示。
  2. 分类任务: 用于将离散的类别(如商品ID、用户ID等)转换为嵌入向量。
  3. 序列建模: 在处理序列数据时,使用 nn.Embedding 将每个序列中的元素转换为嵌入向量。

nn.Embedding 是处理稀疏表示(如单词索引)的有效方式,并且通常与其他模型组件(如 RNN、Transformer 等)结合使用,以完成复杂的序列任务。

nn.Linear

nn.Linear 是 PyTorch 中用于创建全连接层(也称为线性层或仿射层)的模块。在深度学习模型中,nn.Linear 用于对输入数据进行线性变换,即对输入进行加权求和,并加上一个偏置项。

作用
nn.Linear 的主要作用是对输入张量进行线性变换。它实现了如下的数学运算:

$$ y = xW^T + b $$

其中:

  • $x$ 是输入张量,
  • $W$ 是权重矩阵,
  • $b $是偏置向量,
  • $y $是输出张量。

在这一步中,输入的数据将与权重矩阵相乘,然后加上偏置项,得到输出数据。

用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import torch
import torch.nn as nn

# 创建一个 nn.Linear 实例
# 设定输入特征维度为 5,输出特征维度为 3
linear = nn.Linear(in_features=5, out_features=3)

# 创建一个输入张量(形状为 (batch_size, in_features))
input_tensor = torch.randn(2, 5) # 2是批次大小,5是输入特征的维度

# 通过线性层进行前向传播
output_tensor = linear(input_tensor)

print(output_tensor)

参数说明

  • in_features: 输入数据的特征数(即每个输入向量的长度)。
  • out_features: 输出数据的特征数(即每个输出向量的长度)。
  • bias: 是否使用偏置项。默认值为 True,即使用偏置项。

输出

  • output_tensor 是一个形状为 (batch_size, out_features) 的张量,它是输入张量通过线性层后的结果。

示例

在上面的代码中:

  1. 我们创建了一个 nn.Linear 层,输入的特征数为 5,输出的特征数为 3。
  2. 输入的 input_tensor 是一个形状为 (2, 5) 的张量,即有两个输入样本,每个样本有 5 个特征。
  3. 通过线性层后,得到的 output_tensor 是一个形状为 (2, 3) 的张量,每个输入样本被映射到了一个 3 维的输出向量。

典型应用场景

  1. 神经网络中的全连接层: nn.Linear 通常用于构建神经网络中的全连接层,特别是在多层感知机(MLP)中。
  2. 分类任务: 在分类问题中,nn.Linear 层经常作为输出层,输入为前一层的输出特征,输出为类别的概率分布。
  3. 回归任务: 在回归问题中,nn.Linear 层可以作为模型的输出层,用于预测连续值。

训练权重和偏置
在训练过程中,nn.Linear 层的权重矩阵 ( W ) 和偏置向量 ( b ) 会通过反向传播算法进行更新,以最小化损失函数。

nn.Linear 是构建神经网络的基础模块之一,广泛应用于各种深度学习模型中。

optim.Adam

optim.Adam 是 PyTorch 中的一个优化器,用于训练神经网络模型。Adam 代表的是 “Adaptive Moment Estimation”,是一种自适应学习率优化算法。它结合了 AdaGrad 和 RMSProp 的优点,能够在处理稀疏梯度和非平稳目标时表现良好。

Adam 优化器的作用是在训练过程中更新模型的参数,以最小化损失函数。它通过使用一阶和二阶矩估计来动态调整每个参数的学习率,从而加速训练并提高收敛效果。

主要特点

  • 自适应学习率:Adam 根据每个参数的梯度的一阶和二阶矩动态调整学习率,适应性强。
  • 动量机制:Adam 结合了动量的方法,考虑了梯度的历史信息,有效减少了振荡并加快了收敛。
  • 默认参数设置:通常情况下,Adam 的默认参数已经表现得非常好,适用于大多数任务。

用法

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
import torch
import torch.nn as nn
import torch.optim as optim

# 假设我们有一个简单的神经网络模型
model = nn.Linear(10, 1)

# 创建 Adam 优化器
# lr 是学习率,通常使用 1e-3 作为默认值
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 定义一个简单的损失函数
criterion = nn.MSELoss()

# 创建一个示例输入和目标
input_data = torch.randn(10)
target = torch.randn(1)

# 前向传播计算输出
output = model(input_data)

# 计算损失
loss = criterion(output, target)

# 反向传播计算梯度
loss.backward()

# 使用 Adam 优化器更新模型参数
optimizer.step()

# 在下一次优化步骤前清零梯度
optimizer.zero_grad()
  1. 模型定义:首先定义了一个简单的线性模型。
  2. 创建优化器:使用 optim.Adam 创建一个 Adam 优化器,传入模型的参数和学习率。
  3. 计算损失:使用均方误差损失(MSE)作为损失函数。
  4. 反向传播:计算梯度,通过 loss.backward() 来执行。
  5. 参数更新:通过 optimizer.step() 更新模型的参数。
  6. 清零梯度:使用 optimizer.zero_grad() 来清除梯度,否则在下一次 backward() 时,梯度会累积。

参数

  • lr(学习率): 控制每一步的参数更新的幅度,默认值为 0.001
  • betas: 控制一阶和二阶矩估计的指数衰减率,默认值为 (0.9, 0.999)
  • eps: 一个很小的数值,防止除零操作,默认值为 1e-08
  • weight_decay: 权重衰减(L2 正则化),用于防止过拟合,默认值为 0
  • amsgrad: 是否使用 AMSGrad 变种(一种改进版本),默认值为 False
文章作者: Dar1in9
文章链接: http://dar1in9s.github.io/2024/05/12/机器学习/pytorch常用方法/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Dar1in9's Blog