0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

最常见的4个神经网络错误是什么?

深度学习自然语言处理 来源:AI公园 作者:Yuval Greenfield 2020-11-27 10:49 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

最常见的神经网络错误:

1)你没有首先尝试过拟合单个batch。

2)你忘了为网络设置train/eval模式。

3)在.backward()之前忘记了.zero_grad()(在pytorch中)。

4)将softmaxed输出传递给了期望原始logits的损失,还有其他吗?

这篇文章将逐点分析这些错误是如何在PyTorch代码示例中体现出来的。

代码:https://github.com/missinglinkai/common-nn-mistakes

常见错误 #1 你没有首先尝试过拟合单个batch

Andrej说我们应该过拟合单个batch。为什么?好吧,当你过拟合了单个batch —— 你实际上是在确保模型在工作。我不想在一个巨大的数据集上浪费了几个小时的训练时间,只是为了发现因为一个小错误,它只有50%的准确性。当你的模型完全记住输入时,你会得到的结果是对其最佳表现的很好的预测。

可能最佳表现为零,因为在执行过程中抛出了一个异常。但这没关系,因为我们很快就能发现问题并解决它。总结一下,为什么你应该从数据集的一个小子集开始过拟合:

发现bug

估计最佳的可能损失和准确率

快速迭代

在PyTorch数据集中,你通常在dataloader上迭代。你的第一个尝试可能是索引train_loader。

#TypeError:'DataLoader'objectdoesnotsupportindexing first_batch=train_loader[0]

你会立即看到一个错误,因为DataLoaders希望支持网络流和其他不需要索引的场景。所以没有__getitem__方法,这导致了[0]操作失败,然后你会尝试将其转换为list,这样就可以支持索引。

#slow,wasteful first_batch=list(train_loader)[0]

但这意味着你要评估整个数据集这会消耗你的时间和内存。那么我们还能尝试什么呢?

Python for循环中,当你输入如下:

foriteminiterable: do_stuff(item)

你有效地得到了这个:

iterator=iter(iterable) try: whileTrue: item=next(iterator) do_stuff(item) exceptStopIteration: pass

调用“iter”函数来创建迭代器,然后在循环中多次调用该函数的“next”来获取下一个条目。直到我们完成时,StopIteration被触发。在这个循环中,我们只需要调用next, next, next… 。为了模拟这种行为但只获取第一项,我们可以使用这个:

first=next(iter(iterable))

我们调用“iter”来获得迭代器,但我们只调用“next”函数一次。注意,为了清楚起见,我将下一个结果分配到一个名为“first”的变量中。我把这叫做“next-iter” trick。在下面的代码中,你可以看到完整的train data loader的例子:

forbatch_idx,(data,target)inenumerate(train_loader): #trainingcodehere

下面是如何修改这个循环来使用 first-iter trick :

first_batch=next(iter(train_loader)) forbatch_idx,(data,target)inenumerate([first_batch]*50): #trainingcodehere

你可以看到我将“first_batch”乘以了50次,以确保我会过拟合。

常见错误 #2: 忘记为网络设置 train/eval 模式

为什么PyTorch关注我们是训练还是评估模型?最大的原因是dropout。这项技术在训练中随机去除神经元。

想象一下,如果右边的红色神经元是唯一促成正确结果的神经元。一旦我们移除红色神经元,它就迫使其他神经元训练和学习如何在没有红色的情况下保持准确。这种drop-out提高了最终测试的性能 —— 但它对训练期间的性能产生了负面影响,因为网络是不全的。在运行脚本并查看MissingLink dashobard的准确性时,请记住这一点。

在这个特定的例子中,似乎每50次迭代就会降低准确度。

如果我们检查一下代码 —— 我们看到确实在train函数中设置了训练模式。

deftrain(model,optimizer,epoch,train_loader,validation_loader): model.train()#???????????? forbatch_idx,(data,target)inexperiment.batch_loop(iterable=train_loader): data,target=Variable(data),Variable(target) #Inference output=model(data) loss_t=F.nll_loss(output,target) #Theiconicgrad-back-steptrio optimizer.zero_grad() loss_t.backward() optimizer.step() ifbatch_idx%args.log_interval==0: train_loss=loss_t.item() train_accuracy=get_correct_count(output,target)*100.0/len(target) experiment.add_metric(LOSS_METRIC,train_loss) experiment.add_metric(ACC_METRIC,train_accuracy) print('TrainEpoch:{}[{}/{}({:.0f}%)] Loss:{:.6f}'.format( epoch,batch_idx,len(train_loader), 100.*batch_idx/len(train_loader),train_loss)) withexperiment.validation(): val_loss,val_accuracy=test(model,validation_loader)#???????????? experiment.add_metric(LOSS_METRIC,val_loss) experiment.add_metric(ACC_METRIC,val_accuracy)

这个问题不太容易注意到,在循环中我们调用了test函数。

deftest(model,test_loader): model.eval() #...

在test函数内部,我们将模式设置为eval!这意味着,如果我们在训练过程中调用了test函数,我们就会进eval模式,直到下一次train函数被调用。这就导致了每一个epoch中只有一个batch使用了drop-out ,这就导致了我们看到的性能下降。

修复很简单 —— 我们将model.train()向下移动一行,让如训练循环中。理想的模式设置是尽可能接近推理步骤,以避免忘记设置它。修正后,我们的训练过程看起来更合理,没有中间的峰值出现。请注意,由于使用了drop-out ,训练准确性会低于验证准确性。

常用的错误 #3: 忘记在.backward()之前进行.zero_grad()

当在 “loss”张量上调用 “backward” 时,你是在告诉PyTorch从loss往回走,并计算每个权重对损失的影响有多少,也就是这是计算图中每个节点的梯度。使用这个梯度,我们可以最优地更新权值。

这是它在PyTorch代码中的样子。最后的“step”方法将根据“backward”步骤的结果更新权重。从这段代码中可能不明显的是,如果我们一直在很多个batch上这么做,梯度会爆炸,我们使用的step将不断变大。

output=model(input)#forward-pass loss_fn.backward()#backward-pass optimizer.step()#updateweightsbyanevergrowinggradient????????????

为了避免step变得太大,我们使用zero_grad方法。

output=model(input)#forward-pass optimizer.zero_grad()#resetgradient???? loss_fn.backward()#backward-pass optimizer.step()#updateweightsusingareasonablysizedgradient????

这可能感觉有点过于明显,但它确实赋予了对梯度的精确控制。有一种方法可以确保你没有搞混,那就是把这三个函数放在一起:

zero_grad

backward

step

在我们的代码例子中,在完全不使用zero_grad的情况下。神经网络开始变得更好,因为它在改进,但梯度最终会爆炸,所有的更新变得越来越垃圾,直到网络最终变得无用。

调用backward之后再做zero_grad。什么也没有发生,因为我们擦掉了梯度,所以权重没有更新。剩下的唯一有变化的是dropout。

我认为在每次step方法被调用时自动重置梯度是有意义的。

在backward的时候不使用zero_grad的一个原因是,如果你每次调用step()时都要多次调用backward,例如,如果你每个batch只能将一个样本放入内存中,那么一个梯度会噪声太大,你想要在每个step中聚合几个batch的梯度。另一个原因可能是在计算图的不同部分调用backward—— 但在这种情况下,你也可以把损失加起来,然后在总和上调用backward。

常见错误 #4: 你把做完softmax的结果送到了需要原始logits的损失函数中

logits是最后一个全连接层的激活值。softmax也是同样的激活值,但是经过了标准化。logits值,你可以看到有些是正的,一些是负的。而log_softmax之后的值,全是负值。如果看柱状图的话,可以看到分布式一样的,唯一的差别就是尺度,但就是这个细微的差别,导致最后的数学计算完全不一样了。但是为什么这是一个常见的错误呢?在PyTorch的官方MNIST例子中,查看forward方法,在最后你可以看到最后一个全连接层self.fc2,然后就是log_softmax。

但是当你查看官方的PyTorch resnet或者AlexNet模型的时候,你会发现这些模型在最后并没有softmax层,最后得到就是全连接的输出,就是logits。

这两个的差别在文档中没有说的很清楚。如果你查看nll_loss函数,并没有提得输入是logits还是softmax,你的唯一希望是在示例代码中发现nll_loss使用了log_softmax作为输入。

原文标题:收藏 | 使用PyTorch时,最常见的4个错误

文章出处:【微信公众号:深度学习自然语言处理】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 神经网络
    +关注

    关注

    42

    文章

    4842

    浏览量

    108155
  • pytorch
    +关注

    关注

    2

    文章

    813

    浏览量

    14921

原文标题:收藏 | 使用PyTorch时,最常见的4个错误

文章出处:【微信号:zenRRan,微信公众号:深度学习自然语言处理】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    为什么 VisionFive V1 板上的 JH7100 中并存 NVDLA 引擎和神经网络引擎?

    我想知道为什么 VisionFive V1 板上的 JH7100 中并存 NVDLA 引擎和神经网络引擎,请问?您能否举一些关于他们的用例的例子?
    发表于 03-25 06:01

    神经网络的初步认识

    日常生活中的智能应用都离不开深度学习,而深度学习则依赖于神经网络的实现。什么是神经网络神经网络的核心思想是模仿生物神经系统的结构,特别是大脑中神经
    的头像 发表于 12-17 15:05 458次阅读
    <b class='flag-5'>神经网络</b>的初步认识

    自动驾驶中常提的卷积神经网络啥?

    在自动驾驶领域,经常会听到卷积神经网络技术。卷积神经网络,简称为CNN,是一种专门用来处理网格状数据(比如图像)的深度学习模型。CNN在图像处理中尤其常见,因为图像本身就可以看作是由像素排列成的二维网格。
    的头像 发表于 11-19 18:15 2243次阅读
    自动驾驶中常提的卷积<b class='flag-5'>神经网络</b>是<b class='flag-5'>个</b>啥?

    CNN卷积神经网络设计原理及在MCU200T上仿真测试

    数的提出很大程度的解决了BP算法在优化深层神经网络时的梯度耗散问题。当x&gt;0 时,梯度恒为1,无梯度耗散问题,收敛快;当x&lt;0 时,该层的输出为0。 CNN
    发表于 10-29 07:49

    NMSIS神经网络库使用介绍

    (q7_t) 和 16 位整数 (q15_t)。 卷积神经网络示例: 本示例中使用的 CNN 基于来自 Caffe 的 CIFAR-10 示例。神经网络由 3 卷积层组成,中间散布着 ReLU
    发表于 10-29 06:08

    构建CNN网络模型并优化的一般化建议

    通过实践,本文总结了构建CNN网络模型并优化的一般化建议,这些建议将会在构建高准确率轻量级CNN神经网络模型方面提供帮助。 1)避免单层神经网络:我们清楚神经网络本身是需要不断抽象出
    发表于 10-28 08:02

    在Ubuntu20.04系统中训练神经网络模型的一些经验

    本帖欲分享在Ubuntu20.04系统中训练神经网络模型的一些经验。我们采用jupyter notebook作为开发IDE,以TensorFlow2为训练框架,目标是训练一手写数字识别的神经网络
    发表于 10-22 07:03

    CICC2033神经网络部署相关操作

    在完成神经网络量化后,需要将神经网络部署到硬件加速器上。首先需要将所有权重数据以及输入数据导入到存储器内。 在仿真环境下,可将其存于一文件,并在 Verilog 代码中通过 readmemh 函数
    发表于 10-20 08:00

    液态神经网络(LNN):时间连续性与动态适应性的神经网络

    1.算法简介液态神经网络(LiquidNeuralNetworks,LNN)是一种新型的神经网络架构,其设计理念借鉴自生物神经系统,特别是秀丽隐杆线虫的神经结构,尽管这种微生物的
    的头像 发表于 09-28 10:03 1551次阅读
    液态<b class='flag-5'>神经网络</b>(LNN):时间连续性与动态适应性的<b class='flag-5'>神经网络</b>

    神经网络的并行计算与加速技术

    随着人工智能技术的飞速发展,神经网络在众多领域展现出了巨大的潜力和广泛的应用前景。然而,神经网络模型的复杂度和规模也在不断增加,这使得传统的串行计算方式面临着巨大的挑战,如计算速度慢、训练时间长等
    的头像 发表于 09-17 13:31 1291次阅读
    <b class='flag-5'>神经网络</b>的并行计算与加速技术

    基于神经网络的数字预失真模型解决方案

    在基于神经网络的数字预失真(DPD)模型中,使用不同的激活函数对整个系统性能和能效有何影响?
    的头像 发表于 08-29 14:01 3664次阅读

    无刷电机小波神经网络转子位置检测方法的研究

    摘要:论文通过对无刷电机数学模型的推导,得出转角:与三相相电压之间存在映射关系,因此构建了一以三相相电压为输人,转角为输出的小波神经网络来实现转角预测,并采用改进遗传算法来训练网络结构与参数,借助
    发表于 06-25 13:06

    神经网络专家系统在电机故障诊断中的应用

    摘要:针对传统专家系统不能进行自学习、自适应的问题,本文提出了基于种经网络专家系统的并步电机故障诊断方法。本文将小波神经网络和专家系统相结合,充分发挥了二者故障诊断的优点,很大程度上降低了对电机
    发表于 06-16 22:09

    神经网络RAS在异步电机转速估计中的仿真研究

    众多方法中,由于其结构简单,稳定性好广泛受到人们的重视,且已被用于产品开发。但是MRAS仍存在在低速区速度估计精度下降和对电动机参数变化非常敏感的问题。本文利用神经网络的特点,使估计更为简单、快速
    发表于 06-16 21:54

    基于FPGA搭建神经网络的步骤解析

    本文的目的是在一神经网络已经通过python或者MATLAB训练好的神经网络模型,将训练好的模型的权重和偏置文件以TXT文件格式导出,然后通过python程序将txt文件转化为coe文件,(coe
    的头像 发表于 06-03 15:51 1499次阅读
    基于FPGA搭建<b class='flag-5'>神经网络</b>的步骤解析