教你编写一个机器学习代码也能使用的单元测试
摘要: 想不想节省重新训练数据的时间?想不想让你的研究成果有个质的飞跃?来看看这些单元测试,助你一臂之力。
注:这篇文章自从发布出来,就受到读者的好评和关注,因此,我编写了一个机器学习测试库,请点击链接查看!
在过去的一年里,我花了很多时间来研究深度学习,并且也犯过很多错误,这些错误不仅帮助我对机器学习有了更加深入的理解,也让我学会了如何正确合理的设计这些系统。在Google Brain工作期间,我学到了很多设计原则,其中之一就是单元测试可以制定或打破原有的算法,并且能够节省数周的调试和训练时间。
然而,到目前为止,似乎还没有为神经网络代码编码测试单元的比较可靠的教程。即使是在OpenAI上,也只是通过一行行的盯着代码来发现bug,然后再思考导致这一bug的原因到底是什么。显然,大部分人都不愿意这么耗费时间,因此,我希望看完这个教程,你就可以开始着手测试你的系统!
我们从一个简单的例子开始:试试在这段代码中找到bug。
有找到bug吗?实际上,这个神经网络并没有进行堆叠。我在编写代码的时候,只是对slim.conv2d(...)代码行做了简单的复制粘贴,然后对内核大小进行修改,而并没有实际的输入。
略微尴的来说,这其实是我上周编写的代码……这也是个很重要的教训!但是由于某些原因,这些bug很难被发现:
1.这段代码永远不会崩溃,或者引发错误,又或者是运行速度变慢。
2.这个神经网络仍在训练,并且损失函数会越来越小。
3.几个小时后,会收敛到某一数值,结果非常糟糕,但是,你又不知道应该修改哪里。
当唯一的反馈只有最终那个错误验证时,那么,你只有一个办法——就是搜索整个网络架构。不用再多说了,你需要的是一个更好的网络系统。
在我们对数据进行了一整天的训练以后,该如何发现这一bug呢? 我们发现,最容易注意到的是,层的值实际上从未到达函数外的任何其他张量。因此,假设我们有某种类型的损失函数和优化器,这些张量永远都不会得到优化,它们将始终保持为默认值。
通过简单的训练,我们来比较训练之前和训练之后的结果:
在这不到15行的代码中,我们基本上验证了训练过的所有的变量。
这个测试非常简单、实用。现在,假设我们已经修复了上一个问题,现在,添加一些批量优化,看看是否能发现这一bug。
看到了没?这个非常微妙。在tensorflow中,batch_norm实际上将is_training默认为False,所以添加这行代码并不能在训练期间将输入规范化!值得庆幸的是,我们编写的最后一个单元测试将会立刻找到这个问题!
我们来看看另外一个例子,来自于reddit的一个帖子:该作者想创建一个分组器,其输出范围为(0,1),你是否能够找出其中的bug?
这个bug很难发现,并且稍不注意就会导致特别混乱的结果。基本上,这个预测只有一个输出,当你使用softmax交叉熵时,总会导致损失函数为0。
测试这段代码最简单的方法就是——确保损失函数永远不为0。
这个测试类似于我们的第一个测试,唯一不同的就是回退。在这个测试中,你可以确保只训练你想要训练的变量。拿生成对抗网络来(GAN)说,常常出现的bug就是忘记在优化期间训练了哪些变量,类似这种的bug经常会发生。
这其中最大的问题就是:优化器有一个默认设置来优化所有的变量。对于类似于对抗生成网络的架构来说,这是对所有训练时间判了一个死刑。在这里,使用下面的测试代码,你就可以轻松检测到这些bug:
同样,我们也可以为鉴别器或其它强化学习算法编写类似的测试代码。很多演员-评论模型都有自己相对独立的网络,需要通过不同的损失进行优化。
为了你在阅读完本文后,能够更好的进行测试,我认为以下几个建议很重要:
1.保证测试的确定性。如果你真的想要随机输入数据,那么,请确保输入的随机性,以便于轻松的完成测试。
2.保证测试的简短性。一定要有能够训练收敛并检查验证集的单元测试,否则你就是在浪费时间。
3.确保在每次测试前重置图表。
总之,还会有很多测试方法可以测试这些算法。花一个小时的时间来编写一个测试代码,不仅可以帮你节省重新训练的时间,还能够大大改善你的研究成果!
文章原标题《How to unit test machine learning code》
原文链接
教你编写一个机器学习代码也能使用的单元测试相关推荐
- 手把手教你编写一个上位机
关注+星标公众号,不错过精彩内容 转自 | 嵌入式大杂烩 嵌入式开发,基本都会用到有一些上位机工具,比如串口助手就是最常用的工具之一. 那么,今天分享有一篇由ZhengN整理的用Qt写的简单上位机教程 ...
- [转]在C#中像Python一样编写TensorFlow机器学习代码
机器学习是一个令人激动人心的领域,一直有新的技术突破.研究人员不断推动机器智能的提升,教机器如何听说读写--这些曾经是我们人类专属的技能.机器学习的首选语言是Python,最受欢迎的库是Google的 ...
- 人工智能离前端并不远 一步步教你开发一个机器学习APP(附源码)
最近HBO电视网推出的美剧<硅谷Silicon Valley>席卷全球,里面有一个桥段介绍了超级有趣的iOS app- Not Hotdog.你甚至可以在APP Store上下载到它. 受 ...
- 三步教你编写一个Neumorphism风格的小时钟
本文目录 序 Neumorphism 正文开始 一.时钟表盘编写 二.时钟指针编写 三.时钟组件的调用 完整组件代码 序 又到了自己编写组件的时节了 作为一名前端开发者,平时也是阔以没事可以写写自定义 ...
- 【PHP】五分钟教你编写一个实时弹幕网站
由于博主是个忠实的英雄联盟粉丝,所以经常观看一些明星大神的直播.而一谈到直播,肯定会看到满屏幕飘来飘去的弹幕.那么问题来了,这些视频弹幕网站如何做到实时同步的?PHP如何开发一个类似的网站? 首先要搞 ...
- 教你编写一个手势解锁控件
今日科技快讯 5月16日,在联想.华为双方两次公开态度表示,联想对华为主导的5G方案投了赞成票之后,今天柳传志也忍不住联合杨元庆等发了"5G投票事件"的声明,称:有人给联想扣&qu ...
- 手把手教你编写一个音乐播放器
话不多说,直接看效果图: 代码如下: <!doctype html> <html lang="en"><head><meta charse ...
- 写字机上位机c语言,易懂 | 手把手教你编写你的第一个上位机
一.前言 大家好,我是ZhengN,本次来教大家编写一个基于QT的简单的上位机. 学习一个新的东西我们都从最基础地实例开始,比如学习C语言我们会从编写一个hello程序开始.学习嵌入式我们从点灯开始. ...
- Locust使用手册--编写一个locustfile
文章目录 编写一个locustfile 代码分解解读 自动生成locustfile User类 wait_time属性 weight和fixed_count属性 host属性 tasks属性 envi ...
最新文章
- 图的遍历:BFS和DFS
- VTK:绘图之PlotLine3D
- 45分钟,411个中小品牌天猫双11实现新跨越
- 容器编排技术 -- 基于Docker本地运行Kubernetes
- leetcode938.RangeSumofBST
- RobotFramework自动化2-自定义关键字
- Buddy分配器之释放一页
- linux 每日学一点《linux性能测试初步概况》
- Solidworks或CAD怎样输出高质量图片?
- 2017onsite比赛游记帖
- 最新+电脑象棋测试软件,中国象棋2017电脑版
- Python OpenCv 实现实时人脸识别及面部距离测量
- 小码哥教育Vuejs笔记
- 程序员就业大数据报告出炉:平均月薪近2万,90后成主力
- 强化学习:玩转Atari-Pong游戏
- prometheus监控-1
- 英语中什么是开音节,什么是闭音节
- 再次定义手机摄影:华为P40系列国内正式发布
- IDM UEStudio 19中文版
- 百度地图绘制工具类 DrawingManager.js 源码
热门文章
- 家用计算机来源,美计算机专家称BBS才是博客真正起源
- java atd_Java字符串String详解
- 【学习笔记】局域网基本概念和体系结构,以太网、无线局域网与PPP协议、HDLC协议
- yolo极大抑制_pytorch实现yolov3(4) 非极大值抑制nms
- 安装quartus时弹出错误_Win10 安装arcgis10.2 for desktop需要.net framework 解决方案
- php socket keepalive,linux keepalive探测对应用层socket api的影响
- arcgis几何修复有作用吗_修复损坏的 shapefile
- pythonsuper函数_怎么使用python super函数调用父类
- 上线数天获2400星,这个GitHub项目帮你从头开始学习数据科学
- “数学物理反问题”:专门研究“关系”,常跟工程师打交道