百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 博客教程 > 正文

CNN手把手维修攻略:你的网络不好好训练,需要全面体检

connygpt 2024-08-28 14:14 9 浏览

作者 Zeyad Emam

方栗子 郭一璞 编译

量子位 出品 | 公众号 QbitAI

你的CNN还健在么?

Github用户Zeyad Emam贡献了一篇CNN故障排除攻略,详细介绍了CNN的常见故障和调教方法,量子位编译了中文版。

欢迎收藏并食用~

介绍

本文是一篇给卷积神经网络排查故障的攻略,主要来自于作者此前的经验和包括斯坦福CS231n课程笔记在内的线上资源。

本文主要针对使用深度神经网络进行的监督学习。虽然本攻略假设你用的是TensorFlow和Python3.6,不过本文内容编程语言无关,你可以当成是一篇通用的指南。

首先,假设我们现在有一个CNN,测试后发现它的表现比我们预想的差很多。于是,你就可以按照本攻略的步骤,一步一步来完成故障排除,之后你的神经网络可能就更合你心意了。

第一部分是故障排除开始之前的必备事项,后面的则是针对具体问题的解决办法,问题主要集中在相对更为常见的方面,每个部分会优先给出针对该问题最容易实现的解决方法。

前菜:故障排除前

首先,给大家列一下完成深度学习算法时要遵循的最佳实践。

1.使用适当的日志和有意义的变量名。在TensorFlow中,你可以通过名称来跟踪不同的变量,并在TensorBoard中可视化图形。最重要的是,在每个训练步骤中,你都能记录相关的值,比如:step_number、accuracy、loss、learning_rate,甚至有时候还包括一些更具体的值,比如mean_intersection_over_union。之后,就可以画出每一步的损失曲线。

2.确保您的网络连接正确。使用TensorBoard或其他debug技术确保图中的每个操作的输入和输出都准确无误,还要确保在将数据和标签送入网络之前对其进行适当的预处理和配对。

3.实施数据增强技术。虽然这一点并不是对所有情况都适用,不过如果你在搞图像相关的神经网络,用简单的数据增强技术处理一下图像,例如镜像、旋转、随机裁剪和重新缩放、添加噪声、弹性变形等,大部分时候出来的效果都有巨大提升。

而且,TensorFlow内置了大多数基本的图像处理功能,十分良心了。

4.对所有层使用权重初始化和正则化。不要把权重初始化为相同的值,当然你要是把它们都初始化成0……那就更糟了,这可能会引入对称性,并且导致梯度消失,大多数时候都会导致糟糕的结果。

一般情况下,如果你在权重初始化时遇到问题,你可以考虑在神经网络中添加批量标准化层(Batch Normalization Layer)。关于批量标准化层,可以看这篇名为《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》的论文,链接:arxiv.org/abs/1502.03167

5.确保正则化条款不会压倒损失函数中的其他项。关闭正则化,找出损失的数量级,然后适当调整正则化权重。确保在增加正则化强度时,损失也在增加。

6.尝试过拟合一个小数据集。关闭正则化/丢失/数据增强,拿出训练集的一小部分,让神经网络练它几个世纪,确保可以实现零损失,不然就很可能是错误的。

在某些情况下,将损失驱动为零非常具有挑战性,例如,如果您的损失涉及每个像素的softmax-ed logits和ground truth labels之间的交叉熵,那么在语义分割中可能真的难以将其降低到0。相反,你应该争取达到接近100%的准确度。

可以在tf.metrics.accuracy这里了解如何通过获取softmax-ed logits的argmax并将其与ground truth labels进行比较来计算。

7.在过拟合上述小数据集的同时,找到合理的学习率。Yoshua Bengio的论文中给到了结论:最佳学习率通常接近最大学习率的一半,不会引起训练标准的差异,这个观察结果是设置学习率的启发。例如,从较大的学习率开始,如果训练标准发散,就用最大学习率除以3再试试,直到观察不到发散为止。

8.执行梯度检查。如果您在图表中使用自定义操作,则梯度检查尤其重要。斯坦福CS231n中介绍了梯度检查的方法。

故障排除前的步骤主要来自于下面三篇资料,需要的朋友可复制链接查看:

· 斯坦福CS231n中数据预处理部分

cs231n.github.io/neural-networks-2

· 斯坦福CS231n中训练神经网络部分

cs231n.github.io/neural-networks-3

· Practical Recommendations for Gradient-Based Training of Deep Architectures

Yoshua Bengio

arxiv.org/pdf/1206.5533v2.pdf

现在,开始进食主菜:

损失没有改善怎么办?

如果,训练了好几个Epoch,损失还是没有变小,甚至还越来越大,就要:

1.确认你用的损失函数是合适的,你优化的张量也是对的。常用损失函数列表传送门:t.cn/RkZXji1。

2.用个好点的优化器。这里也有常见优化器的列表:t.cn/RDKwbNA。

3.确认变量真的在训练。要检查这个,就得看张量板的直方图。

或者写个脚本,在几个不同的训练实例 (training instances) 中,算出每个张量的范数

如果变量没在训练,请看下节,“变量没在训练怎么办?”。

4.调整初始学习率,实施适当的学习率计划。

如果损失越来越大,可能是初始学习率太大;如果损失几乎不变,可能是初始学习率太小

不管怎样,一旦找到好用的初始学习率,就要进行学习率衰减计划。

像AMA这样的优化器,内部就有学习率衰减机制。但它可能衰减得不够激烈,还是自己做一个比较好。

5.确认没有过拟合。做个学习率 vs 训练步数的曲线,如果像是抛物线,可能就过拟合了。解决方法参见下文“过拟合怎么办?”章节

变量没在训练怎么办?

像上文说的,看了张量板直方图,或者写了脚本来算每个张量的范数之后,把范数是常数的那些张量拎出来。

如果有个变量不训练:

1.确认TF把它看做可训练 (trainable) 的变量。详情可以查看TF GraphKeys:t.cn/R18Do6Y。

2.确认没发生梯度消失

如果下游变量 (更靠近output的变量) 训练正常,而上游变量不训练,大概就是梯度消失了。

解决方案见下文,“梯度消失/梯度爆炸”章节。

3.确认ReLU (线性整流函数) 还在放电

如果大部分神经元电压都保持在了,可能就要改变一下权重初始化策略了:尝试用一个不那么激烈的学习率衰减,并且减少权重衰减正则化

梯度消失/梯度爆炸

1.考虑用个好点的权重初始化策略。尤其是在,训练之初梯度就不怎么更新的情况下,这一步尤为重要。

2.考虑换一下激活函数。比如ReLU,就可以拿Leaky ReLU或者MaxOut激活函数来代替。

3.如果是RNN (递归神经网络) 的话,就可以用LSTM block。详情可参照此文:t.cn/RI6Qe7t

过拟合怎么办?

过拟合,就是神经网络记住训练数据了。如果网络在训练集验证集上,准确度差别很大,可能它就过拟合了。详情可见 (Train/Val accuracy) :t.cn/RAkUzJP。

1.做个数据扩增。可上翻至本文第一节。

2.做个Dropout。在训练的每一步,都抛弃一些神经元。详情请见:t.cn/RkZodZo。

3.增加正则化。

4.做个批量归一化。详情请见:t.cn/RNunyfR。

5.做个早停止 (early stopping) 。因为,过拟合可能是训练了太多Epoch造成的。详情可见:t.cn/RkZKjEQ。

6.还不行的话,就用个小一点的网络吧。不过,没到万不得已,还是别这样。

还能调些什么?

1.考虑用个带权重的损失函数。

比如,在图像的语义分割中,神经网络要给每一个像素归类。其中一些类别,可能很少有像素属于它。

如果,给这些不常被光顾的类别,加个权重,mean_iou这项指标就会好一些。

2.改变网络架构。之前的网络,可能太深,可能太浅了。

3.考虑把几个模型集成起来用。

4.用跨步卷积 (strided convolution) 来代替最大池化/平均池化。

5.做个完整的超参数搜索。

6.改变随机种子 (random seeds) 。

7.上面的步骤全都不管用的话,还是再去多找点数据吧。

最后,祝大家的CNN都能吃喝不愁,健康成长。

原作者传送门:

https://gist.github.com/zeyademam/0f60821a0d36ea44eef496633b4430fc

诚挚招聘

量子位正在招募编辑/记者,工作地点在北京中关村。期待有才气、有热情的同学加入我们!相关细节,请在量子位公众号(QbitAI)对话界面,回复“招聘”两个字。

量子位 QbitAI · 头条号签约作者

?'?' ? 追踪AI技术和产品新动态

相关推荐

3分钟让你的项目支持AI问答模块,完全开源!

hello,大家好,我是徐小夕。之前和大家分享了很多可视化,零代码和前端工程化的最佳实践,今天继续分享一下最近开源的Next-Admin的最新更新。最近对这个项目做了一些优化,并集成了大家比较关注...

干货|程序员的副业挂,12个平台分享

1、D2adminD2Admin是一个完全开源免费的企业中后台产品前端集成方案,使用最新的前端技术栈,小于60kb的本地首屏js加载,已经做好大部分项目前期准备工作,并且带有大量示例代码,助...

Github标星超200K,这10个可视化面板你知道几个

在Github上有很多开源免费的后台控制面板可以选择,但是哪些才是最好、最受欢迎的可视化控制面板呢?今天就和大家推荐Github上10个好看又流行的可视化面板:1.AdminLTEAdminLTE是...

开箱即用的炫酷中后台前端开源框架第二篇

#头条创作挑战赛#1、SoybeanAdmin(1)介绍:SoybeanAdmin是一个基于Vue3、Vite3、TypeScript、NaiveUI、Pinia和UnoCSS的清新优...

搭建React+AntDeign的开发环境和框架

搭建React+AntDeign的开发环境和框架随着前端技术的不断发展,React和AntDesign已经成为越来越多Web应用程序的首选开发框架。React是一个用于构建用户界面的JavaScrip...

基于.NET 5实现的开源通用权限管理平台

??大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加班不熬夜不掉头发,是我的目标!??今天小编推荐一款基于.NE...

StreamPark - 大数据流计算引擎

使用Docker完成StreamPark的部署??1.基于h2和docker-compose进行StreamPark部署wgethttps://raw.githubusercontent.com/a...

教你使用UmiJS框架开发React

1、什么是Umi.js?umi,中文可发音为乌米,是一个可插拔的企业级react应用框架。你可以将它简单地理解为一个专注性能的类next.js前端框架,并通过约定、自动生成和解析代码等方式来辅助...

简单在线流程图工具在用例设计中的运用

敏捷模式下,测试团队的用例逐渐简化以适应快速的发版节奏,大家很早就开始运用思维导图工具比如xmind来编写测试方法、测试点。如今不少已经不少利用开源的思维导图组件(如百度脑图...)来构建测试测试...

【开源分享】神奇的大数据实时平台框架,让Flink&Spark开发更简单

这是一个神奇的框架,让Flink|Spark开发更简单,一站式大数据实时平台!他就是StreamX!什么是StreamX大数据技术如今发展的如火如荼,已经呈现百花齐放欣欣向荣的景象,实时处理流域...

聊聊规则引擎的调研及实现全过程

摘要本期主要以规则引擎业务实现为例,陈述在陌生业务前如何进行业务深入、调研、技术选型、设计及实现全过程分析,如果你对规则引擎不感冒、也可以从中了解一些抽象实现过程。诉求从硬件采集到的数据提供的形式多种...

【开源推荐】Diboot 2.0.5 发布,自动化开发助理

一、前言Diboot2.0.5版本已于近日发布,在此次发布中,我们新增了file-starter组件,完善了iam-starter组件,对core核心进行了相关优化,让devtools也支持对IAM...

微软推出Copilot Actions,使用人工智能自动执行重复性任务

IT之家11月19日消息,微软在今天举办的Ignite大会上宣布了一系列新功能,旨在进一步提升Microsoft365Copilot的智能化水平。其中最引人注目的是Copilot...

Electron 使用Selenium和WebDriver

本节我们来学习如何在Electron下使用Selenium和WebDriver。SeleniumSelenium是ThoughtWorks提供的一个强大的基于浏览器的开源自动化测试工具...

Quick 'n Easy Web Builder 11.1.0设计和构建功能齐全的网页的工具

一个实用而有效的应用程序,能够让您轻松构建、创建和设计个人的HTML网站。Quick'nEasyWebBuilder是一款全面且轻巧的软件,为用户提供了一种简单的方式来创建、编辑...