实操教程 | Pytorch Debug指南:15条重要建议

共 4386字,需浏览 9分钟

 ·

2021-08-15 17:20

↑ 点击蓝字 关注极市平台

作者 | Coggle

来源 | Coggle数据科学

编辑 | 极市平台

极市导读

 

在使用Pytorch时你或多或少会遇到各种bug,为了缓解你的痛苦😢,本文将对常见的错误进行解释,并说清楚来龙去脉 >>加入极市CV技术交流群,走在计算机视觉的最前沿


在使用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:填充符号的索引

嵌入特征向量从随机初始化,不要用 Kaiming、Xavier初始化方法。因为标准差为1,初始化、激活函数等被设计为输入标准差为 1。nn.Embedding模块的示例用法:

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,或者遍历模块列表。

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模块应用一个小型神经网络,并将输出添加回输入。最好在单独的类中实现这种动态,以保持主模型类小而清晰。

输入相同的维度

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

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

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损失函数,则当模型预测不正确的非常高或非常低的值时,您可能会遇到问题。

如果觉得有用,就请分享到朋友圈吧!

△点击卡片关注极市平台,获取最新CV干货

公众号后台回复“CVPR21检测”获取CVPR2021目标检测论文下载~


极市干货
深度学习环境搭建:如何配置一台深度学习工作站?
实操教程:OpenVINO2021.4+YOLOX目标检测模型测试部署为什么你的显卡利用率总是0%?
算法技巧(trick):图像分类算法优化技巧21个深度学习调参的实用技巧


CV技术社群邀请函 #

△长按添加极市小助手
添加极市小助手微信(ID : cvmart4)

备注:姓名-学校/公司-研究方向-城市(如:小极-北大-目标检测-深圳)


即可申请加入极市目标检测/图像分割/工业检测/人脸/医学影像/3D/SLAM/自动驾驶/超分辨率/姿态估计/ReID/GAN/图像增强/OCR/视频理解等技术交流群


每月大咖直播分享、真实项目需求对接、求职内推、算法竞赛、干货资讯汇总、与 10000+来自港科大、北大、清华、中科院、CMU、腾讯、百度等名校名企视觉开发者互动交流~



觉得有用麻烦给个在看啦~  
浏览 26
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报