0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

總結(jié)了18個(gè)Tips,讓你在瀏覽器里玩轉(zhuǎn)深度學(xué)習(xí)

電子工程師 ? 來源:未知 ? 作者:李倩 ? 2018-10-21 10:29 ? 次閱讀

【導(dǎo)讀】TensorFlow.js 的發(fā)布可以說是 JS 社區(qū)開發(fā)者的福音!但是在瀏覽器中訓(xùn)練一些模型還是會(huì)存在一些問題與不同,如何可以讓訓(xùn)練效果更好?本文的作者,是一位前端工程師,經(jīng)過自己不斷的經(jīng)驗(yàn)積累,為大家總結(jié)了 18 個(gè) Tips,希望可以幫助大家訓(xùn)練出更好的模型。

TensorFlow.js 發(fā)布之后我就把之前訓(xùn)練的目標(biāo)/人臉檢測(cè)和人臉識(shí)別的模型往 TensorFlow.js 里導(dǎo),我發(fā)現(xiàn)有些模型在瀏覽器里運(yùn)行的效果還相當(dāng)不錯(cuò)。感覺 TensorFlow.js 讓我們搞前端的也潮了一把。

雖說瀏覽器也能跑深度學(xué)習(xí)模型了,這些模型終歸不是為在瀏覽器里運(yùn)行設(shè)計(jì)的,所以很多限制和挑戰(zhàn)也就隨之而來了。就拿目標(biāo)檢測(cè)來說,不說實(shí)時(shí)檢測(cè),就是維持一定的幀率恐怕都很困難。更別提動(dòng)輒上百兆的模型給用戶瀏覽器和帶寬(手機(jī)端的話)帶來的壓力了。

不過只要我們遵循一定的原則,用卷積神經(jīng)網(wǎng)絡(luò) CNN 和 TensorFlow.js 在瀏覽器里訓(xùn)練個(gè)像樣的深度學(xué)習(xí)模型并非癡人說夢(mèng)。從下面圖里可以看到,我訓(xùn)練的這幾個(gè)模型大小都控制在了 2 MB 以下,最小的才 3 KB。

大家可能心中會(huì)有個(gè)疑問:你腦殘嗎?要用瀏覽器訓(xùn)練模型?對(duì),用自己電腦、服務(wù)器、集群或者云來訓(xùn)練深度學(xué)習(xí)模型肯定是一條正道,但并非人人都有錢用NVIDIA GTX 1080 Ti 或者Titan X(尤其是顯卡集體大漲價(jià)之后)。這時(shí),在瀏覽器中訓(xùn)練深度學(xué)習(xí)模型的優(yōu)勢(shì)就體現(xiàn)出來了,有了 WebGL 和 TensorFLow.js 我用電腦上的 AMD GPU 也能很方便地訓(xùn)練深度學(xué)習(xí)模型。

對(duì)目標(biāo)識(shí)別問題,為了穩(wěn)妥起見通常都會(huì)建議大家用一些現(xiàn)成的架構(gòu)比如YOLO、SSD、殘差網(wǎng)絡(luò) ResNet 或 MobileNet ,但我個(gè)人認(rèn)為如果完全照搬的話,在瀏覽器上訓(xùn)練效果肯定是不好的。在瀏覽器上訓(xùn)練就要求模型要小、要快、要越容易訓(xùn)練越好。下面我們就從模型架構(gòu)、訓(xùn)練和調(diào)試等幾個(gè)方面來看看如何才能做到這三點(diǎn)。

模型架構(gòu)

▌1. 控制模型大小

控制模型的規(guī)模很重要。如果模型架構(gòu)太大太復(fù)雜,訓(xùn)練和運(yùn)行的速度都會(huì)降低,從瀏覽器載入模型度速度也會(huì)變慢。控制模型的規(guī)模說起來簡(jiǎn)單,難的是取得準(zhǔn)確率和模型規(guī)模之間的平衡。如果準(zhǔn)確率達(dá)不到要求,模型再小也是廢物。

▌2. 使用深度可分離卷積操作

與標(biāo)準(zhǔn)卷積操作不同,深度可分離卷積先對(duì)每個(gè)通道進(jìn)行卷積操作,之后再進(jìn)行1X1跨通道卷積。這樣做的好處是可以大大減小參數(shù)個(gè)數(shù),所以模型運(yùn)行速度會(huì)有很大提升,資源的消耗和訓(xùn)練速度也會(huì)有所提升。深度可分離卷積操作的過程如下圖所示:

MobileNet 和 Xception 都使用了深度可分離卷積,TensorFlow.js 版本的 MobileNet 和 PoseNet 中你也能見到深度可分離卷積的身影。雖然深度可分離卷積對(duì)模型準(zhǔn)確率的影響還有爭(zhēng)議,但從我個(gè)人的經(jīng)驗(yàn)來看在瀏覽器里訓(xùn)練模型用它肯定沒錯(cuò)。

第一層我推薦用標(biāo)準(zhǔn)的 conv2d 操作來保持提取完特征的通道之間的關(guān)系。因?yàn)榈谝粚右话?a target="_blank">參數(shù)不多,所以對(duì)性能的影響不大。

其他卷積層就可以都用深度可分離卷積了。比如這里我們就使用了兩個(gè)過濾器。

這里 tf.separableConv2d 使用的卷積核結(jié)構(gòu)分別是[3,3,32,1]和[1,1,32,64]。

▌3.運(yùn)用跳躍連接和密集塊

隨著網(wǎng)絡(luò)層數(shù)的增加,梯度消失問題出現(xiàn)的可能性也會(huì)增大。梯度消失會(huì)造成損失函數(shù)下降太慢訓(xùn)練時(shí)間超長(zhǎng)或者干脆失敗。ResNet 和 DenseNet 中采用的跳躍連接則能避免這一問題。簡(jiǎn)單說來跳躍連接就是把某些層的輸出跳過激活函數(shù)直接傳給網(wǎng)絡(luò)深處的隱藏層作為輸入,如下圖所示:

這樣就避免了因?yàn)榧せ詈瘮?shù)和鏈?zhǔn)角髮?dǎo)造成的梯度消失問題,我們也能根據(jù)需求增加網(wǎng)絡(luò)的層數(shù)了。

顯然跳躍連接隱含的一個(gè)要求就是連接的兩層輸出和輸入的格式必須能對(duì)應(yīng)得上。我們要用殘差網(wǎng)絡(luò)的話,那最好保證兩層的過濾器數(shù)目和填充都一致而且步幅為1(不過肯定有其它做法來保證格式對(duì)應(yīng))。

一開始我模仿殘差網(wǎng)絡(luò)的思路隔一層加一個(gè)跳躍連接(如下圖)。不過我發(fā)現(xiàn)密集塊效果更好,模型收斂的速度比加跳躍連接快得多。

下面我們就來看看具體的代碼,這里的密集塊有四個(gè)深度可分離卷積層,其中第一層我把步幅設(shè)為 2 來改變輸入的大小。

▌4.激活函數(shù)選ReLU

在瀏覽器里訓(xùn)練深度網(wǎng)絡(luò)的話激活函數(shù)不用看直接選 ReLU 就行了,主要原因還是梯度消失。不過大家可以試試 ReLU 的不同變種,比如

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

訓(xùn)練過程

▌5.優(yōu)化器選Adam

這也是我個(gè)人的經(jīng)驗(yàn)只談。之前用 SGD 經(jīng)常會(huì)卡在局部極小值或者出現(xiàn)梯度爆炸。我推薦大家一開始把學(xué)習(xí)速率設(shè)為 0.001 然后其他參數(shù)都用默認(rèn):

▌6.動(dòng)態(tài)調(diào)整學(xué)習(xí)速率

一般來說當(dāng)損失函數(shù)不再下降的時(shí)候我們就該停止訓(xùn)練了,因?yàn)樵儆?xùn)練就過擬合了。不過如果我們發(fā)現(xiàn)損失函數(shù)出現(xiàn)上下震蕩的情況,則可能通過減小學(xué)習(xí)速率讓損失函數(shù)變得更小。

下面這個(gè)例子中我們可以看到學(xué)習(xí)速率一開始設(shè)的是 0.01,然后從 32 期開始出現(xiàn)震蕩(黃線)。這里通過將學(xué)習(xí)速率改為 0.001(藍(lán)線)使損失函數(shù)又減小了大概 0.3。

▌7.權(quán)重初始化原則

我個(gè)人喜歡把偏置量設(shè)為 0,權(quán)重則用傳統(tǒng)的正態(tài)分布。我一般用的是 Glorot 正態(tài)分布初始化法:

▌8.把數(shù)據(jù)集順序打亂

老生常談了。TensorFlow.js 中我們可以用 tf.utils.shuffle 來實(shí)現(xiàn)。

▌9. 保存模型

js 可以通過 FileSaver.js 來實(shí)現(xiàn)模型的存儲(chǔ)(或者叫下載)。比如下面的代碼就可以把模型所有的權(quán)重保存起來:

保存成什么格式是自己定的,但 FileSaver.js 只管存,所以這里要用JSON.strinfify 把 Blob 轉(zhuǎn)成字符串:

調(diào)試

▌10.保證預(yù)處理和后處理的正確性

雖然是句廢話但“垃圾數(shù)據(jù)垃圾結(jié)果”實(shí)在是至理名言。標(biāo)記要標(biāo)對(duì),每層的輸入輸出也要前后一致。尤其是對(duì)圖片做過一些預(yù)處理和后處理的話更要仔細(xì),有時(shí)候這些小問題還比較難發(fā)現(xiàn)。所以雖然費(fèi)些功夫但磨刀不誤砍柴工。

▌11.自定義損失函數(shù)

TensorFlow.js 提供了很多現(xiàn)成的損失函數(shù)給大家用,而且一般說來也夠用了,所以我不太建議大家自己寫。如果實(shí)在要自己寫的話,請(qǐng)一定注意先測(cè)試測(cè)試。

▌12.在數(shù)據(jù)子集試試過擬合

我建議大家模型定義好之后先挑個(gè)十幾二十張圖試試看損失函數(shù)有沒有收斂。最好能把結(jié)果可視化一下,這樣就能很明顯地看出這個(gè)模型有沒有成功的潛質(zhì)。

這樣做我們也能早早地發(fā)現(xiàn)模型和預(yù)處理時(shí)的一些低級(jí)錯(cuò)誤。這其實(shí)也就是 11 條里說的測(cè)試測(cè)試損失函數(shù)。

性能

▌13.內(nèi)存泄漏

不知道大家知不知道 TensorFlow.js 不會(huì)自動(dòng)幫你進(jìn)行垃圾回收。張量所占的內(nèi)存必須自己手動(dòng)調(diào)用 tensor.dispose() 來釋放。如果忘記回收的話內(nèi)存泄漏是早晚的事。

判斷有沒有內(nèi)存泄漏很容易。大家把 tf.memory() 每次迭代都輸出來看看張量的個(gè)數(shù)。如果沒有一直增加那說明沒泄漏。

▌14.調(diào)整畫布大小,而不是張量大小

在調(diào)用 TF . from pixels 之前,要將畫布轉(zhuǎn)換成張量,請(qǐng)調(diào)整畫布的大小,否則你會(huì)很快耗盡 GPU 內(nèi)存。

如果你的訓(xùn)練圖像大小都一樣,這將不會(huì)是一個(gè)問題,但是如果你必須明確地調(diào)整它們的大小,你可以參考下面的代碼。(注意,以下語句僅在 tfjs - core 的當(dāng)前狀態(tài)下有效,我當(dāng)前正在使用 tfjs - core 版本 0.12.14)

▌15.慎選批大小

每一批的樣本數(shù)選多少,也就是批大小顯然取決于我們用的什么 GPU 和網(wǎng)絡(luò)結(jié)構(gòu),所以大家最好試試不同的批大小看看怎么最快。我一般從 1 開始試,而且有時(shí)候我發(fā)現(xiàn)增加批大小對(duì)訓(xùn)練的效率也沒啥幫助。

▌16.善用IndexedDB

我們訓(xùn)練的數(shù)據(jù)集因?yàn)槎际菆D片所以有時(shí)候還是挺大的。如果每次都下載的話肯定效率低,最好是用 IndexedDB 來存儲(chǔ)。IndexedDB 其實(shí)就是瀏覽器里嵌入的一個(gè)本地?cái)?shù)據(jù)庫,任何數(shù)據(jù)都能以鍵值對(duì)的形式進(jìn)行存儲(chǔ)。讀取和保存數(shù)據(jù)也只要幾行代碼就能搞定。

▌17.異步返回?fù)p失函數(shù)值

要實(shí)時(shí)監(jiān)測(cè)損失函數(shù)值的話可以用下面的代碼這來自己算然后異步返回:

需要注意的是如果每期訓(xùn)練完要把損失函數(shù)值存到文件里的話這樣的代碼就有點(diǎn)問題了。因?yàn)楝F(xiàn)在損失函數(shù)的值是異步返回了所以我們得等最后一個(gè) promise 返回才能存。不過我一般都暴力地在一期結(jié)束之后直接等個(gè) 10 秒再存:

▌18.權(quán)重的量化

為了實(shí)現(xiàn)又小又快的目標(biāo),在模型訓(xùn)練完成之后我們應(yīng)該對(duì)權(quán)重進(jìn)行量化來壓縮模型。權(quán)重量化不光能減小模型的體積,對(duì)提高模型的速度也很有幫助,而且?guī)缀跞呛锰帥]壞處。這一步就讓模型又能小又能快,非常適合我們?cè)跒g覽器里訓(xùn)練深度學(xué)習(xí)模型。

在瀏覽器里訓(xùn)練深度學(xué)習(xí)模型的十八招(實(shí)際十七招)就總結(jié)到這里,希望大家讀了這篇文章能夠有所收獲。

如果有問題也歡迎在后臺(tái)給我們留言,大家一起討論!

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴

原文標(biāo)題:前端工程師掌握這18招,就能在瀏覽器里玩轉(zhuǎn)深度學(xué)習(xí)

文章出處:【微信號(hào):rgznai100,微信公眾號(hào):rgznai100】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    AI語音識(shí)別-我給瀏覽器加了個(gè)語音搜索功能

    本篇文章就采用華為云提供的在線語音識(shí)別服務(wù)給瀏覽器設(shè)計(jì)一個(gè)語音自動(dòng)搜索的功能,編程語言采用C++,軟件框架采用QT設(shè)計(jì),瀏覽器內(nèi)核采用QWebEngineView,在QT5.7以后,QT
    的頭像 發(fā)表于 07-10 09:18 ?1794次閱讀
    AI語音識(shí)別-我給<b class='flag-5'>瀏覽器</b>加了<b class='flag-5'>個(gè)</b>語音搜索功能

    11個(gè)你應(yīng)當(dāng)使用FIREFOX瀏覽器的理由

    安全。與IE不同的是,火狐不允許瀏覽器安裝ActiveX控件 。 ActiveX其實(shí)是一個(gè)可以在線更新Internet Explorer和Windows 的程序。但是它也一個(gè)非常大的危險(xiǎn),那就是為
    發(fā)表于 11-26 16:31

    Web瀏覽器,Web瀏覽器是什么意思

    Web瀏覽器,Web瀏覽器是什么意思 看起來給Web瀏覽器下定義似乎有點(diǎn)荒謬,因?yàn)樗耠娨暬蚴找魴C(jī)一樣為大家所熟悉?;ヂ?lián)網(wǎng)用戶通過使
    發(fā)表于 03-22 11:01 ?2.1w次閱讀

    使用WebBrower制作瀏覽器_Delphi教程

    Delphi教程使用WebBrower制作瀏覽器,很好的Delphi學(xué)習(xí)資料。
    發(fā)表于 03-16 14:59 ?6次下載

    JAVA教程之HTML瀏覽器

    JAVA教程之HTML瀏覽器,很好的學(xué)習(xí)資料。
    發(fā)表于 03-31 11:13 ?10次下載

    Delphi教程之SQL瀏覽器

    Delphi教程之SQL瀏覽器,學(xué)習(xí)Delphi的必備資料。
    發(fā)表于 03-31 11:29 ?5次下載

    liebao瀏覽器

    瀏覽器
    發(fā)表于 03-20 08:00 ?0次下載

    四大瀏覽器續(xù)航對(duì)決,結(jié)果Chrome瀏覽器完勝

    近日,YouTube頻道UP主Linus Tech Tips進(jìn)行了一次四大瀏覽器續(xù)航對(duì)決,結(jié)果Chrome瀏覽器完勝。
    發(fā)表于 06-27 10:16 ?1401次閱讀

    基于JavaScript瀏覽器兼容性測(cè)試方法

    針對(duì)JavaScript瀏覽器兼容性問題缺乏有效的測(cè)試方法的問題,基于變異測(cè)試技術(shù),對(duì)Web應(yīng)用程序中的JavaScript語言在主流瀏覽器中的兼容性進(jìn)行了分析,設(shè)計(jì)了18個(gè)針對(duì)
    發(fā)表于 12-04 09:36 ?0次下載
    基于JavaScript<b class='flag-5'>瀏覽器</b>兼容性測(cè)試方法

    瀏覽器怎么了 核心功能被弱化

    在PC端,客戶端的價(jià)值被弱化,用戶更習(xí)慣直接通過瀏覽各類網(wǎng)站,而瀏覽網(wǎng)站的主要工具便是瀏覽器,瀏覽器曾一度是用戶電腦必備的軟件之一。正是因?yàn)?b class='flag-5'>瀏覽器
    的頭像 發(fā)表于 04-29 10:20 ?4686次閱讀

    區(qū)塊鏈瀏覽器可以查詢哪些信息

    淘寶網(wǎng)站的數(shù)據(jù)儲(chǔ)存在阿里巴巴公司的服務(wù),京東網(wǎng)站的數(shù)據(jù)存儲(chǔ)在京東公司的服務(wù),如果我們?cè)陔娔X上要查看淘寶網(wǎng)、京東網(wǎng)站上的信息,就需要借助瀏覽器
    發(fā)表于 06-11 11:52 ?8896次閱讀
    區(qū)塊鏈<b class='flag-5'>瀏覽器</b>可以查詢哪些信息

    IE瀏覽器正式退役,由Edge瀏覽器來接任它的工作

    昨天,全球最著名的IE瀏覽器正式退出了歷史舞臺(tái)。 1995年8月16日,IE瀏覽器首次亮相在大家的視野中,其簡(jiǎn)潔的界面迅速吸引了大批用戶的注意,在當(dāng)時(shí),IE瀏覽器就是大家公認(rèn)最好用的瀏覽器
    的頭像 發(fā)表于 06-16 16:42 ?2779次閱讀

    瀏覽器支持javascript怎么設(shè)置

    和JavaScript之間的關(guān)系。瀏覽器是一個(gè)軟件應(yīng)用程序,用于解析和渲染網(wǎng)頁。它可以是桌面應(yīng)用程序(例如Chrome,F(xiàn)irefox和Safari)或移動(dòng)應(yīng)用程序(例如Safari和Chrome
    的頭像 發(fā)表于 11-26 11:22 ?1458次閱讀

    瀏覽器需要支持javascript怎么解決

    JavaScript是一種流行的腳本語言,用于對(duì)網(wǎng)頁進(jìn)行動(dòng)態(tài)交互和功能增強(qiáng)。幾乎所有現(xiàn)代瀏覽器都支持JavaScript,但在某些情況下,用戶可能需要采取措施來確保瀏覽器支持JavaScript
    的頭像 發(fā)表于 11-26 11:23 ?5017次閱讀

    寫一個(gè)Chrome瀏覽器插件

    一、什么是瀏覽器插件 瀏覽器插件是依附于瀏覽器,用來拓展網(wǎng)頁能力的程序。插件具有監(jiān)聽瀏覽器事件、獲取和修改網(wǎng)頁元素、攔截網(wǎng)絡(luò)請(qǐng)求、添加快捷菜單等功能。使用
    的頭像 發(fā)表于 11-18 17:12 ?419次閱讀
    寫一<b class='flag-5'>個(gè)</b>Chrome<b class='flag-5'>瀏覽器</b>插件