兩次深度debug經(jīng)歷,希望大家不要踩坑
深度學(xué)習(xí)模型debug目前來看,還是一個難點問題。pytorch能夠有這樣的發(fā)展勢頭,容易debug應(yīng)該是一個突出優(yōu)點。本篇文章記錄一下筆者使用tensorflow時兩次debug的經(jīng)歷,希望能給大家?guī)硪稽c啟發(fā)。
預(yù)測為Nan
訓(xùn)練好的一個文本分類模型,本地測試一切正常,部署到tfserving后,預(yù)測一直為Nan。
這個模型是另一個小伙伴訓(xùn)練的,我負責(zé)工程部署。當時疫情,大家都窩在家里。
當時我的第一反應(yīng)是,是不是tfserving有問題?可是查看log,打印出來的值也都正常,就是最后返回的時候沒有l(wèi)og,傳到后端那里就是Nan了。筆者當時剛接觸tfserving,從log查找問題這條重要的線索就中斷了。
沒辦法,面向搜索引擎debug吧,查了一圈,也沒發(fā)現(xiàn)任何有效的信息。
這下真有點狗咬刺猬不知道從哪下嘴了。
沒辦法,使出最笨的debug辦法,我從輸出開始,逆序依次將每層輸出作為模型輸出,在tfserving上部署,查看是否為Nan,這項工作就比較耗時,我讓小伙伴在家里,修改一次模型,就訓(xùn)練兩個step,保存的checkpoint發(fā)給我,我部署在tfserving上,我就要看看,到底是哪一層造成的Nan。
經(jīng)過一個下午的修改、訓(xùn)練、部署、測試,終于終于發(fā)現(xiàn)了問題的原因所在:
模型中使用了dynamic_rnn,tfserving并不支持這個算子!
坑爹啊!
loss為Nan
復(fù)現(xiàn)某個語義相似度論文。非常奇怪,有時loss會變成Nan,有時又沒問題,可以成功復(fù)現(xiàn)論文的結(jié)果。
于是,先開始在網(wǎng)上查了一堆loss為Nan的資料,softmax時發(fā)生了除0,或者計算loss時數(shù)據(jù)溢出,這時比較常見的,我在這兩個地方也做了加固,確保不會除0,當時也把代碼走讀了一遍,感覺到可能除0的地方,都加了episilon,事實證明,我還是有點大意了,暫且按下不表。
然后就是網(wǎng)上說的各種各樣的解決方案,試,一個又一個的試,試到海枯石爛!
結(jié)果就是,木有用!
這時候,時間已經(jīng)過去2天。我強迫自己冷靜下來,想到了自己debug以來總結(jié)的最厲害的一條經(jīng)驗:
看似最詭異的bug,很可能來自最naive的錯誤!
那么,總結(jié)我查到的所有資料,除0是最常見的操作,那么,會不會某個地方還是可能會除0,只是我沒發(fā)現(xiàn)?
于是,我又一行一行代碼查看,突然,發(fā)現(xiàn)有個地方很詭異:兩個矩陣相除,element_wise的矩陣相除,也就是說,只要底下矩陣中任意一個元素為0,就會發(fā)生除0錯誤!
我迅速在這個地方做了加固,代碼終于可以順暢正常的運行了!
總結(jié)
遇到困難的bug,一定不要放棄,在解決bug的過程中,往往能學(xué)到很多之前不熟悉的知識!

E?N?D

各位伙伴們好,詹帥本帥假期搭建了一個個人博客和小程序,匯集各種干貨和資源,也方便大家閱讀,感興趣的小伙伴請移步小程序體驗一下哦!(歡迎提建議)
推薦閱讀
牛逼!Python常用數(shù)據(jù)類型的基本操作(長文系列第①篇)
牛逼!Python的判斷、循環(huán)和各種表達式(長文系列第②篇)
推薦閱讀
牛逼!Python常用數(shù)據(jù)類型的基本操作(長文系列第①篇)
牛逼!Python的判斷、循環(huán)和各種表達式(長文系列第②篇)
