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

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

3天内不再提示

总结了18个Tips,让你在浏览器里玩转深度学习

电子工程师 来源:未知 作者:李倩 2018-10-21 10:29 次阅读

【导读】TensorFlow.js 的发布可以说是 JS 社区开发者的福音!但是在浏览器中训练一些模型还是会存在一些问题与不同,如何可以让训练效果更好?本文的作者,是一位前端工程师,经过自己不断的经验积累,为大家总结了 18 个 Tips,希望可以帮助大家训练出更好的模型。

TensorFlow.js 发布之后我就把之前训练的目标/人脸检测和人脸识别的模型往 TensorFlow.js 里导,我发现有些模型在浏览器里运行的效果还相当不错。感觉 TensorFlow.js 让我们搞前端的也潮了一把。

虽说浏览器也能跑深度学习模型了,这些模型终归不是为在浏览器里运行设计的,所以很多限制和挑战也就随之而来了。就拿目标检测来说,不说实时检测,就是维持一定的帧率恐怕都很困难。更别提动辄上百兆的模型给用户浏览器和带宽(手机端的话)带来的压力了。

不过只要我们遵循一定的原则,用卷积神经网络 CNN 和 TensorFlow.js 在浏览器里训练个像样的深度学习模型并非痴人说梦。从下面图里可以看到,我训练的这几个模型大小都控制在了 2 MB 以下,最小的才 3 KB。

大家可能心中会有个疑问:你脑残吗?要用浏览器训练模型?对,用自己电脑、服务器、集群或者云来训练深度学习模型肯定是一条正道,但并非人人都有钱用NVIDIA GTX 1080 Ti 或者Titan X(尤其是显卡集体大涨价之后)。这时,在浏览器中训练深度学习模型的优势就体现出来了,有了 WebGL 和 TensorFLow.js 我用电脑上的 AMD GPU 也能很方便地训练深度学习模型。

对目标识别问题,为了稳妥起见通常都会建议大家用一些现成的架构比如YOLO、SSD、残差网络 ResNet 或 MobileNet ,但我个人认为如果完全照搬的话,在浏览器上训练效果肯定是不好的。在浏览器上训练就要求模型要小、要快、要越容易训练越好。下面我们就从模型架构、训练和调试等几个方面来看看如何才能做到这三点。

模型架构

▌1. 控制模型大小

控制模型的规模很重要。如果模型架构太大太复杂,训练和运行的速度都会降低,从浏览器载入模型度速度也会变慢。控制模型的规模说起来简单,难的是取得准确率和模型规模之间的平衡。如果准确率达不到要求,模型再小也是废物。

▌2. 使用深度可分离卷积操作

与标准卷积操作不同,深度可分离卷积先对每个通道进行卷积操作,之后再进行1X1跨通道卷积。这样做的好处是可以大大减小参数个数,所以模型运行速度会有很大提升,资源的消耗和训练速度也会有所提升。深度可分离卷积操作的过程如下图所示:

MobileNet 和 Xception 都使用了深度可分离卷积,TensorFlow.js 版本的 MobileNet 和 PoseNet 中你也能见到深度可分离卷积的身影。虽然深度可分离卷积对模型准确率的影响还有争议,但从我个人的经验来看在浏览器里训练模型用它肯定没错。

第一层我推荐用标准的 conv2d 操作来保持提取完特征的通道之间的关系。因为第一层一般参数不多,所以对性能的影响不大。

其他卷积层就可以都用深度可分离卷积了。比如这里我们就使用了两个过滤器。

这里 tf.separableConv2d 使用的卷积核结构分别是[3,3,32,1]和[1,1,32,64]。

▌3.运用跳跃连接和密集块

随着网络层数的增加,梯度消失问题出现的可能性也会增大。梯度消失会造成损失函数下降太慢训练时间超长或者干脆失败。ResNet 和 DenseNet 中采用的跳跃连接则能避免这一问题。简单说来跳跃连接就是把某些层的输出跳过激活函数直接传给网络深处的隐藏层作为输入,如下图所示:

这样就避免了因为激活函数和链式求导造成的梯度消失问题,我们也能根据需求增加网络的层数了。

显然跳跃连接隐含的一个要求就是连接的两层输出和输入的格式必须能对应得上。我们要用残差网络的话,那最好保证两层的过滤器数目和填充都一致而且步幅为1(不过肯定有其它做法来保证格式对应)。

一开始我模仿残差网络的思路隔一层加一个跳跃连接(如下图)。不过我发现密集块效果更好,模型收敛的速度比加跳跃连接快得多。

下面我们就来看看具体的代码,这里的密集块有四个深度可分离卷积层,其中第一层我把步幅设为 2 来改变输入的大小。

▌4.激活函数选ReLU

在浏览器里训练深度网络的话激活函数不用看直接选 ReLU 就行了,主要原因还是梯度消失。不过大家可以试试 ReLU 的不同变种,比如

和 MobileNet 用的 ReLU-6 (y = min(max(x, 0), 6)):

训练过程

▌5.优化器选Adam

这也是我个人的经验只谈。之前用 SGD 经常会卡在局部极小值或者出现梯度爆炸。我推荐大家一开始把学习速率设为 0.001 然后其他参数都用默认:

▌6.动态调整学习速率

一般来说当损失函数不再下降的时候我们就该停止训练了,因为再训练就过拟合了。不过如果我们发现损失函数出现上下震荡的情况,则可能通过减小学习速率让损失函数变得更小。

下面这个例子中我们可以看到学习速率一开始设的是 0.01,然后从 32 期开始出现震荡(黄线)。这里通过将学习速率改为 0.001(蓝线)使损失函数又减小了大概 0.3。

▌7.权重初始化原则

我个人喜欢把偏置量设为 0,权重则用传统的正态分布。我一般用的是 Glorot 正态分布初始化法:

▌8.把数据集顺序打乱

老生常谈了。TensorFlow.js 中我们可以用 tf.utils.shuffle 来实现。

▌9. 保存模型

js 可以通过 FileSaver.js 来实现模型的存储(或者叫下载)。比如下面的代码就可以把模型所有的权重保存起来:

保存成什么格式是自己定的,但 FileSaver.js 只管存,所以这里要用JSON.strinfify 把 Blob 转成字符串:

调试

▌10.保证预处理和后处理的正确性

虽然是句废话但“垃圾数据垃圾结果”实在是至理名言。标记要标对,每层的输入输出也要前后一致。尤其是对图片做过一些预处理和后处理的话更要仔细,有时候这些小问题还比较难发现。所以虽然费些功夫但磨刀不误砍柴工。

▌11.自定义损失函数

TensorFlow.js 提供了很多现成的损失函数给大家用,而且一般说来也够用了,所以我不太建议大家自己写。如果实在要自己写的话,请一定注意先测试测试。

▌12.在数据子集试试过拟合

我建议大家模型定义好之后先挑个十几二十张图试试看损失函数有没有收敛。最好能把结果可视化一下,这样就能很明显地看出这个模型有没有成功的潜质。

这样做我们也能早早地发现模型和预处理时的一些低级错误。这其实也就是 11 条里说的测试测试损失函数。

性能

▌13.内存泄漏

不知道大家知不知道 TensorFlow.js 不会自动帮你进行垃圾回收。张量所占的内存必须自己手动调用 tensor.dispose() 来释放。如果忘记回收的话内存泄漏是早晚的事。

判断有没有内存泄漏很容易。大家把 tf.memory() 每次迭代都输出来看看张量的个数。如果没有一直增加那说明没泄漏。

▌14.调整画布大小,而不是张量大小

在调用 TF . from pixels 之前,要将画布转换成张量,请调整画布的大小,否则你会很快耗尽 GPU 内存。

如果你的训练图像大小都一样,这将不会是一个问题,但是如果你必须明确地调整它们的大小,你可以参考下面的代码。(注意,以下语句仅在 tfjs - core 的当前状态下有效,我当前正在使用 tfjs - core 版本 0.12.14)

▌15.慎选批大小

每一批的样本数选多少,也就是批大小显然取决于我们用的什么 GPU 和网络结构,所以大家最好试试不同的批大小看看怎么最快。我一般从 1 开始试,而且有时候我发现增加批大小对训练的效率也没啥帮助。

▌16.善用IndexedDB

我们训练的数据集因为都是图片所以有时候还是挺大的。如果每次都下载的话肯定效率低,最好是用 IndexedDB 来存储。IndexedDB 其实就是浏览器里嵌入的一个本地数据库,任何数据都能以键值对的形式进行存储。读取和保存数据也只要几行代码就能搞定。

▌17.异步返回损失函数值

要实时监测损失函数值的话可以用下面的代码这来自己算然后异步返回:

需要注意的是如果每期训练完要把损失函数值存到文件里的话这样的代码就有点问题了。因为现在损失函数的值是异步返回了所以我们得等最后一个 promise 返回才能存。不过我一般都暴力地在一期结束之后直接等个 10 秒再存:

▌18.权重的量化

为了实现又小又快的目标,在模型训练完成之后我们应该对权重进行量化来压缩模型。权重量化不光能减小模型的体积,对提高模型的速度也很有帮助,而且几乎全是好处没坏处。这一步就让模型又能小又能快,非常适合我们在浏览器里训练深度学习模型。

在浏览器里训练深度学习模型的十八招(实际十七招)就总结到这里,希望大家读了这篇文章能够有所收获。

如果有问题也欢迎在后台给我们留言,大家一起讨论!

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

    关注

    42

    文章

    4562

    浏览量

    98631
  • 深度学习
    +关注

    关注

    73

    文章

    5219

    浏览量

    119863

原文标题:前端工程师掌握这18招,就能在浏览器里玩转深度学习

文章出处:【微信号:rgznai100,微信公众号:rgznai100】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    怎么卸载ie浏览器 #电脑小技巧

    浏览器电脑/办公
    学习硬声知识
    发布于 :2022年11月01日 23:50:37

    11你应当使用FIREFOX浏览器的理由

    安全。与IE不同的是,火狐不允许浏览器安装ActiveX控件 。 ActiveX其实是一可以在线更新Internet Explorer和Windows 的程序。但是它也一非常大的危险,那就是为
    发表于 11-26 16:31

    IE浏览器出错故障分析

    使用 ie 浏览器浏览网页时,出现“该程序执行了非法操作,即将关闭……”的错误提示对话框。此时单击“确定”按钮后会弹出一提示“发生内部错误……”的对话框,再单击“确定”后所有打开的 ie
    发表于 01-06 14:46

    腾讯X5内核Android浏览器 - Q立方浏览器

    传闻中的腾讯X5内核Android浏览器——Q立方浏览器可以下载了哦,超强Html5性能,全新交互模式,无需下载APP即可体验数十应用......总之很好很强大。附件回复可见,解压得出apk文件.[hide][/hide]
    发表于 01-06 14:17

    有使用此浏览器时偶有疑问

    有使用此浏览器时偶有疑问:此浏览器如果浏览AI蒙版后的图,用此浏览器打开后蒙版会失效
    发表于 02-25 15:56

    Labview递归做出的文件浏览器

    本帖最后由 yelei1254 于 2013-12-12 14:04 编辑 自己学习递归时,做的文件浏览器的程序,界面没有优化,程序框图给大家参考。
    发表于 12-10 14:32

    labview怎么调用谷歌浏览器或者火狐浏览器,(非IE浏览器

    `在虚拟仪器中需要显示本地嵌入式网页,自带的active控件的IEweb浏览器不支持,需要火狐或者谷歌浏览器。那么怎么调用其他的浏览器呢实现谷歌地球呢?不用IE,用火狐或谷歌怎么做到!`
    发表于 05-18 10:26

    PADS layout项目浏览器没有东西

    PADS layout项目浏览器没有东(元器件,PCB封装,网络)点开都没有,请问有人遇到过吗?怎么解决的
    发表于 04-07 10:58

    Web浏览器,Web浏览器是什么意思

    Web浏览器,Web浏览器是什么意思 看起来给Web浏览器下定义似乎有点荒谬,因为它像电视或收音机一样为大家所熟悉。互联网用户通过使
    发表于 03-22 11:01 2.1w次阅读

    使用WebBrower制作浏览器_Delphi教程

    Delphi教程使用WebBrower制作浏览器,很好的Delphi学习资料。
    发表于 03-16 14:59 6次下载

    JAVA教程之HTML浏览器

    JAVA教程之HTML浏览器,很好的学习资料。
    发表于 03-31 11:13 10次下载

    Delphi教程之SQL浏览器

    Delphi教程之SQL浏览器学习Delphi的必备资料。
    发表于 03-31 11:29 5次下载

    四大浏览器续航对决,结果Chrome浏览器完胜

    近日,YouTube频道UP主Linus Tech Tips进行了一次四大浏览器续航对决,结果Chrome浏览器完胜。
    发表于 06-27 10:16 1289次阅读

    魅族18系列重磅上线新版魅族浏览器

    3月5日消息,博主@布鲁卡晒出了魅族18系列上的新版魅族浏览器,主界面没有任何推广和广告。
    的头像 发表于 03-05 10:18 2348次阅读

    IE浏览器正式退役,由Edge浏览器来接任它的工作

    昨天,全球最著名的IE浏览器正式退出了历史舞台。 1995年8月16日,IE浏览器首次亮相在大家的视野中,其简洁的界面迅速吸引了大批用户的注意,在当时,IE浏览器就是大家公认最好用的浏览器
    的头像 发表于 06-16 16:42 2095次阅读