PyTorch + NumPy这么做会降低模型准确率,这是bug还是预期功能?
作者|維度
?來(lái)源|機(jī)器之心
近日,有用戶在自己的項(xiàng)目中發(fā)現(xiàn)了一個(gè)微小的 bug,在 PyTorch 同時(shí)使用 NumPy 的隨機(jī)數(shù)生成器和多進(jìn)程數(shù)據(jù)加載會(huì)導(dǎo)致相同的擴(kuò)充數(shù)據(jù),只有專門設(shè)置 seed 才可以解決這個(gè) bug,否則會(huì)降低模型的準(zhǔn)確率。不過(guò),有人認(rèn)為這并不是一個(gè) bug,而是預(yù)期功能,是「按預(yù)期工作的」。
行內(nèi)人都知道,機(jī)器學(xué)習(xí)(ML)代碼中的 bug 很難修復(fù),并且它們不會(huì)造成編譯錯(cuò)誤,而是悄悄地降低準(zhǔn)確率。這些 bug 簡(jiǎn)直防不勝防。最近,一位專注于機(jī)器學(xué)習(xí)的用戶遇到了一個(gè)非常熟悉的 bug,修復(fù)了之后性能有了大幅度提升。這是一個(gè)什么樣的 bug 呢?
根據(jù)用戶的描述,bug 是這樣的:除非你在 DataLoader 中使用 worker_init_fn 選項(xiàng)專門設(shè)置 seed,否則在 PyTorch 同時(shí)使用 NumPy 的隨機(jī)數(shù)生成器和多進(jìn)程數(shù)據(jù)加載會(huì)導(dǎo)致相同的擴(kuò)充數(shù)據(jù)。用戶沒有這樣做,因而這個(gè) bug 悄悄地降低了模型的準(zhǔn)確率。
該 bug 非常小并且很容易出現(xiàn)。所以,這位用戶很好奇會(huì)不會(huì)也對(duì)其他項(xiàng)目造成損害呢?ta 從 GitHub 上下載了 10 萬(wàn)個(gè)導(dǎo)入 PyTorch 的庫(kù),并分析了這些庫(kù)的源代碼。之后,ta 保留了那些具有自定義數(shù)據(jù)集、同時(shí)使用 NumPy 的隨機(jī)數(shù)生成器和多進(jìn)程數(shù)據(jù)加載以及或多或少使用抽象語(yǔ)法樹進(jìn)行分析的項(xiàng)目。
結(jié)果顯示,95% 以上的庫(kù)存在著這個(gè) bug,如 PyTorch 的官方教程、OpenAI 的代碼以及 NVIDIA 的項(xiàng)目。甚至特斯拉 AI 負(fù)責(zé)人 Andrej Karpathy 也曾遭受過(guò)該 bug 的困擾。
OpenAI 的 ebm_code_release 項(xiàng)目。
這個(gè) bug 究竟怎樣影響模型的準(zhǔn)確率?這位用戶從以下兩個(gè)示例中進(jìn)行了簡(jiǎn)要描述。
bug 描述
在 PyTorch 中加載、預(yù)處理和擴(kuò)充數(shù)據(jù)的標(biāo)準(zhǔn)方法是子類化 torch.utils.data.Dataset 并重寫 __getitem__方法。要應(yīng)用擴(kuò)充方法(如隨機(jī)裁剪、圖像翻轉(zhuǎn)),__getitem__方法經(jīng)常使用 NumPy 來(lái)生成隨機(jī)數(shù),然后將 map-styled 數(shù)據(jù)集傳遞給 DataLoader 來(lái)創(chuàng)建 batch。這種訓(xùn)練 pipeline 可能會(huì)受到數(shù)據(jù)預(yù)處理的阻礙,因此并行加載數(shù)據(jù)是有意義的。可以通過(guò)增加 DataLoader 對(duì)象中的 num_workers 參數(shù)來(lái)實(shí)現(xiàn)。
問(wèn)題是,這個(gè)工作流導(dǎo)致了相同的數(shù)據(jù)擴(kuò)充。
PyTorch 使用多進(jìn)程并行加載數(shù)據(jù),worker 進(jìn)程是使用 fork start 方法創(chuàng)建的。這意味著每個(gè)工作進(jìn)程繼承父進(jìn)程的所有資源,包括 NumPy 的隨機(jī)數(shù)生成器的狀態(tài)。
示例 1
為了更加形象地描述問(wèn)題,用戶從以下兩個(gè)示例中進(jìn)行了簡(jiǎn)要概述。
示例 1 為一個(gè)示例數(shù)據(jù)集,它返回三個(gè)元素的隨機(jī)向量。示例使用兩個(gè)和四個(gè)工作進(jìn)程的 batch 大小。
代碼返回如下結(jié)果:每個(gè)進(jìn)程返回的隨機(jī)數(shù)都是相同的。
示例 2
示例 2 演示了如何在 face-landmarks 數(shù)據(jù)集上使用 Dataset 和 DataLoader 類。此外,還提到了數(shù)據(jù)擴(kuò)充的重要性,并提供了一個(gè)隨機(jī)裁剪擴(kuò)充的例子。這是使用 NumPy 的隨機(jī)數(shù)生成器實(shí)現(xiàn)的。
通過(guò)增加 num_workers 來(lái)加速數(shù)據(jù)加載,可以得到相同的裁剪結(jié)果:
batch 大小為 8, num_workers 為 2,random crop augmentation(隨機(jī)裁剪擴(kuò)充)
這個(gè) bug 很容易產(chǎn)生。在某些情況下,它對(duì)最終性能的影響很小。在另一些情況下,相同的擴(kuò)充會(huì)導(dǎo)致嚴(yán)重的退化。
基于對(duì)開放源碼 PyTorch 項(xiàng)目的分析,發(fā)現(xiàn) bug 的這位用戶擔(dān)心這個(gè)問(wèn)題在許多支持真實(shí)產(chǎn)品的代碼庫(kù)中都存在。
究竟是 bug,還是預(yù)期功能或特征?
這位用戶描述的 bug 也引起了眾多網(wǎng)友的熱議,其中一些人并不認(rèn)為這是 bug。
用戶「amasterblaster」認(rèn)為,這不是一個(gè) bug,而是所有種子隨機(jī)函數(shù)的預(yù)期功能。這是因?yàn)榧词乖陔S機(jī)實(shí)驗(yàn)中,有時(shí)你想要對(duì)比靜態(tài)參數(shù)的變化,并得到相同的隨機(jī)數(shù)。只有當(dāng)你被讀為真隨機(jī)(true random)時(shí),才會(huì)根據(jù) OS time 設(shè)置 seed。
用戶「xicor7017」表示自己也遇到了相同的問(wèn)題,也認(rèn)為它并不是一個(gè) bug,而是一個(gè)可能不為人所知的特征。如果忽略它的話,調(diào)試問(wèn)題時(shí)會(huì)很麻煩。
與此同時(shí),另一些人表達(dá)出了不同的觀點(diǎn),認(rèn)為既然「如果事情朝著人們不希望的方向發(fā)展,那么它就不應(yīng)該這樣,也就構(gòu)成了 bug。」
用戶「IntelArtiGen」稱自己意識(shí)到了這個(gè) bug,認(rèn)為它是不正常的,并且對(duì)自己的項(xiàng)目造成了一些小問(wèn)題。用戶「gwern」贊同這種觀點(diǎn),認(rèn)為如果 95% 以上的用戶使用時(shí)出現(xiàn)錯(cuò)誤,則代碼就是錯(cuò)的。
用戶「synonymous1964」進(jìn)一步解讀了這個(gè) bug。ta 認(rèn)為,人們可能誤解了這個(gè)問(wèn)題,問(wèn)題不在于設(shè)置特定的隨機(jī)種子會(huì)導(dǎo)致每次訓(xùn)練過(guò)程中生成相同序列的隨機(jī)數(shù),這顯然是按預(yù)期工作的。相反,問(wèn)題在于多個(gè)數(shù)據(jù)下載進(jìn)程中(由 PyTorch 中的 num_workers 設(shè)置)的每個(gè)進(jìn)程都會(huì)在某個(gè)特定的訓(xùn)練過(guò)程中輸出相同序列的隨機(jī)數(shù)。毫無(wú)疑問(wèn),這當(dāng)然會(huì)對(duì)項(xiàng)目造成影響,具體取決于你如何進(jìn)行數(shù)據(jù)加載和擴(kuò)充。所以,即使這個(gè) bug 是「按預(yù)期工作的」,但向更多其他用戶指出來(lái)也挺好的。
不知道機(jī)器之心的讀者,有沒有遇到過(guò)類似的 bug 呢?如果有,可以在評(píng)論中發(fā)表自己對(duì)該 bug 的觀點(diǎn)。
參考鏈接:
https://tanelp.github.io/posts/a-bug-that-plagues-thousands-of-open-source-ml-projects/
https://www.reddit.com/r/MachineLearning/comments/mocpgj/p_using_pytorch_numpy_a_bug_that_plagues/
????
現(xiàn)在,在「知乎」也能找到我們了
進(jìn)入知乎首頁(yè)搜索「PaperWeekly」
點(diǎn)擊「關(guān)注」訂閱我們的專欄吧
關(guān)于PaperWeekly
PaperWeekly 是一個(gè)推薦、解讀、討論、報(bào)道人工智能前沿論文成果的學(xué)術(shù)平臺(tái)。如果你研究或從事 AI 領(lǐng)域,歡迎在公眾號(hào)后臺(tái)點(diǎn)擊「交流群」,小助手將把你帶入 PaperWeekly 的交流群里。
總結(jié)
以上是生活随笔為你收集整理的PyTorch + NumPy这么做会降低模型准确率,这是bug还是预期功能?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: AAAI 2021 | 学习截断信息检索
- 下一篇: 各门店电费挂2000店下月冲回怎么做?