前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Pytorch Debug指南:15条重要建议

Pytorch Debug指南:15条重要建议

作者头像
AI算法与图像处理
发布2021-09-06 11:06:52
1.3K0
发布2021-09-06 11:06:52
举报

在使用Pytorch时你或多或少会遇到各种bug,为了缓解你的痛苦😢,本文将对常见的错误进行解释,并说清楚来龙去脉。

细节就是魔鬼,虽然代码不报错但还是可能会对精度带来影响。如果本文对你有帮助,请收藏&转发!

CrossEntropyLoss和NLLLoss

最常见的错误是损失函数和输出激活函数之间的不匹配。nn.CrossEntropyLossPyTorch中的损失模块执行两个操作:nn.LogSoftmaxnn.NLLLoss

因此nn.CrossEntropyLossPyTorch的输入应该是最后一个线性层的输出。不要在nn.CrossEntropyLossPyTorch之前应用Softmax。 否则将对Softmax输出计算log-softmax,将会降低模型精度。

如果使用nn.NLLLoss模块,则需要自己应用log-softmax。nn.NLLLoss需要对数概率,而不是普通概率。因此确保应用nn.LogSoftmaxor nn.functional.log_softmax,而不是nn.Softmax

Softmax的计算维度

注意Softmax的计算维度。通常是输出张量的最后一个维度,例如nn.Softmax(dim=-1)。如果混淆了维度,模型最终会得到随机预测。

类别数据与嵌入操作

对于类别数据,常见的做法是进行数值编码。但对于深度学习而言,这并不是一个很好的操作,数值会带来大小关系,且会丢失很多信息。

因此对于类别数据建议使用one-hotEmbedding操作,对于nn.Embedding模块,你需要设置的参数包括:

  • num_embeddings:数据类别的数量
  • embedding_dim:每个类别的嵌入维度
  • padding_idx:填充符号的索引

嵌入特征向量从随机初始化

N(0,1)

,不要用 Kaiming、Xavier初始化方法。因为标准差为1,初始化、激活函数等被设计为输入标准差为 1。

nn.Embedding模块的示例用法:

代码语言:javascript
复制
import torch
import torch.nn as nn
# Create 5 embedding vectors each with 32 features
embedding = nn.Embedding(num_embeddings=5,
                         embedding_dim=32)

# Example integer input
input_tensor = torch.LongTensor([[0, 4], [2, 3], [0, 1]])

# Get embeddings
embed_vectors = embedding(input_tensor)

print("Input shape:", input_tensor.shape)
print("Output shape:", embed_vectors.shape)
print("Example features:\n", embed_vectors[:,:,:2])

nn.LSTM 中 数据维度

默认情况下,PyTorch的nn.LSTM模块假定输入维度为[seq_len, batch_size, input_size],所以确保不要混淆序列长度和批大小的次数。如果混淆LSTM仍然可以正常运行,但会给出错误的结果。

维度不匹配

如果Pytorch执行矩阵乘法,并两个矩阵出现维度不匹配,PyTorch会报错并抛出错误。但是也存在PyTorch不会抛出错误的情况,此时未对齐的维度具有相同的大小。建议使用多个不同的批量大小测试您的代码,以防止维度不对齐。

训练和评估模式

在PyTorch中,神经网络有两种模式:traintrain。您可以使用model.eval()model.train()对模型时进行切换。

不同的模式决定是否使用dropout,以及如何处理Batch Normalization。常见的错误是在eval后忘记将模型设置回train模式,确定模型在预测阶段为eval模式。

参数继承

PyTorch支持nn.Modules,一个模块可以包含另一个模块,另一个模块又可以包含一个模块,依此类推。

当调用.parameters()时,PyTorch会查找该模块内的所有模块,并将它们的参数添加到最高级别模块的参数中。

但是PyTorch不会检测列表、字典或类似结构中模块的参数。如果有一个模块列表,请确保将它们放入一个nn.ModuleListnn.Sequential对象中。

参数初始化

正确初始化模型的参数非常重要。用标准正态分布初始化参数不是好的选择,推荐的方法有KaimingXavier

zero_grad()

请记住在执行loss.backward()之前调用optimizer.zero_grad()。如果在执行反向传播之前没有重置所有参数的梯度,梯度将被添加到上一批的梯度中。

指标计算逻辑

在怀疑自己或模型之前,请经常检查您的指标计算逻辑计算两次或更多次。像准确性这样的指标很容易计算,但在代码中添加错误也很容易。例如,检查您是否对批次维度进行了平均,而不是意外对类维度或任何其他维度进行平均。

设备不匹配

如果使用GPU可能会看到一个错误,例如:

Runtime Error: Input type (torch.FloatTensor) dand weigh type (torch.cuda.FloatTensor) should be on the same device.

此错误表示输入数据在CPU上,而权重在GPU上。确保所有数据都在同一设备上。这通常是GPU,因为它支持训练和测试加速。

nn.Sequential和nn.ModuleList

如果模型有很多层,推荐将它们汇总为一个nn.Sequentialnn.ModuleList对象。在前向传递中,只需要调用sequential,或者遍历模块列表。

代码语言:javascript
复制
class MLP(nn.Module):

    def __init__(self, input_dims=64, hidden_dims=[128,256], output_dims=10):
        super().__init__()
        hidden_dims = [input_dims] + hidden_dims
        layers = []
        for idx in range(len(hidden_dims)-1):
            layers += [
                nn.Linear(hidden_dims[i], hidden_dims[i+1]),
                nn.ReLU(inplace=True)
            ]
        self.layers = nn.Sequential(*layers)

    def forward(self, x):
        return self.layers(x)

参数重复计算

在深度神经网络中,通常会有重复添加到模型中的块。如果这些块需要比更复杂的前向函数,建议在单独的模块中实现它们。

例如,一个 ResNet 由多个具有残差连接的ResNet块组成。ResNet模块应用一个小型神经网络,并将输出添加回输入。最好在单独的类中实现这种动态,以保持主模型类小而清晰。

输入相同的维度

如果您有多个具有相同输入的线性层或卷积,则可以将它们堆叠在一起以提高效率。假设我们有:

y_1=W_1x+b_1
y_2=W_2x+b_2

虽然可以通过两个线性层来实现它,但您可以通过将两层堆叠为一层来获得完全相同的神经网络。单层效率更高,因为这代表单个矩阵运算,而不是GPU的两个矩阵运算,因此我们可以并行化计算。

代码语言:javascript
复制
x = torch.randn(2, 10)

# Implementation of separate layers:
y1_layer = nn.Linear(10, 20)
y2_layer = nn.Linear(10, 30)
y1 = y1_layer(x)
y2 = y2_layer(x)

# Implementation of a stacked layer:
y_layer = nn.Linear(10, 50)
y = y_layer(x)
y1, y2 = y[:,:20], y[:,20:50]

使用带logits的损失函数

分类损失函数(例如二元交叉熵)在PyTorch中有两个版本:nn.BCELossnn.BCEWithLogitsLoss,建议和推荐的做法是使用后者。

这因为它在数值上更稳定,并在您的模型预测非常错误时防止出现任何不稳定性。如果您不使用logit损失函数,则当模型预测不正确的非常高或非常低的值时,您可能会遇到问题。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-08-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI算法与图像处理 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • CrossEntropyLoss和NLLLoss
  • Softmax的计算维度
  • 类别数据与嵌入操作
  • nn.LSTM 中 数据维度
  • 维度不匹配
  • 训练和评估模式
  • 参数继承
  • 参数初始化
  • zero_grad()
  • 指标计算逻辑
  • 设备不匹配
  • nn.Sequential和nn.ModuleList
  • 参数重复计算
  • 输入相同的维度
  • 使用带logits的损失函数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档