我們擅長商業(yè)策略與用戶體驗的完美結合。
歡迎瀏覽我們的案例。
我認為 Yann LeCun 等人于 1989 年發(fā)表的論文「反向傳播應用于手寫郵政編碼識別」(Backpropagation Applied to Handwritten Zip Code Recognition),具有相當重要的歷史意義,因為據我所知,這是最早用反向傳播機制端到端訓練的神經網絡在現實生活中的應用。
除了其使用的微型數據集(7291 個 16x16 的灰度數字圖像)和微型神經網絡(僅 1000 個神經元)顯得落伍之外,在 33 年后的今天,這篇論文讀來仍然十分新穎——它展示了一個數據集,描述了神經網絡結構、損失函數、優(yōu)化器,并報告了在訓練集和測試集上實驗得到的錯誤率。
除了時光已流逝 33 年,這篇文章仍是一篇標準的深度學習論文。因此,我此次復現這篇論文,一是為了好玩,二是將這次練習作為一個案例來研究深度學習進展的本質。
實施細節(jié)
我試著盡可能與這篇論文保持一致,并用 PyTorch 復現了 GitHub repo 上 karpathy/lecun1989-repro 中的所有內容。
最初的網絡部署在 Lisp 上,使用 Bottou 和 LeCun 1988 年發(fā)表的「backpropagation simulator SN(后來命名為 Lush)」。
這篇論文是用法語寫的,所以我沒有更好地理解它,但從結構上來看,你可以使用更高級的 API 來構造神經網絡,就像你今天在 PyTorch 上搭建各式各樣的項目那樣。
作為軟件設計的簡要說明,現代程序庫采用了一種分為 3 部分的設計:
1)一個高速(C/CUDA)通用張量庫,能在多維張量上實現基本的數學運算;
2)一個自動求導引擎,能跟蹤正向計算特征,并能提供反向傳播操作;
3)可編程(Python)的深度學習編碼器,高級的 API,需要包含常見的深度學習操作,比如構建層、架構、提供優(yōu)化器、損失函數等。
訓練細節(jié)
在訓練過程中,我們必須在有 7291 個示例的訓練集上訓練 23 個周期,總共向神經網絡傳送了 167693 次數據(包含樣本和標簽)。最初的網絡在 SUN-4/260 工作站上訓練了 3 天。
我在我的 MacBook Air(M1)CPU 上運行了我的實現,并在大約 90 秒的時間內完成了運行(約 3000 倍的顯著提速)。
我的 conda 設置為使用本機 AMD64 版本,而不是 Rosetta 仿真。如果 Pytorch 支持 M 1(包括 GPU 和 NPU)的全部功能,加速可能會更顯著,但這似乎仍在開發(fā)中。
我還天真地嘗試在一張 A100 GPU 上運行代碼,但實際上訓練速度更慢了,很可能是因為網絡太小了(4 個卷積層,最多 12 個通道,總共 9760 個參數,64 K 位址量,1 K 激活值),SGD 每次只能使用一個樣本。
這就是說,如果真的想用現代硬件(A100)和軟件基礎設施(CUDA、PyTorch)解決這個問題,我們需要用每個樣本的 SGD 過程來交換完整的批量訓練,以最大限度地提高 GPU 利用率,并很可能實現另一個約 100 倍的訓練耗時提速。
復現 1989 年的表現
原論文展示的結果如下:
eval: split train. loss 2.5e-3. error 0.14%. misses: 10
eval: split test . loss 1.8e-2. error 5.00%. misses: 102
而我的復現代碼在同時期的表現如下:
eval: split train. loss 4.073383e-03. error 0.62%. misses: 45
eval: split test . loss 2.838382e-02. error 4.09%. misses: 82
由此可見,我只能粗略地再現這些結果,卻不能做到完全一樣??杀氖?,很可能永遠無法進行精確復現了,因為我認為原始數據集已經被遺棄在了時間的長河中。
相反,我不得不使用更大的 MNIST 數據集(哈哈,我從沒想過我會用「大」來形容它)來模擬它,取其 28x28 位,通過雙線性插值將其縮小到 16x16 像素,并隨機地從中提取合理數量的訓練集和測試集樣本。
但我相信還有其他罪魁禍首。例如,這篇論文對權重初始化方案的描述有點過于抽象,我懷疑 PDF 文件中存在一些格式錯誤,例如,刪除點「.」讓「2.5」看起來像「2 5」,并且有可能(我想是吧?)刪除了平方根。
例如,我們被告知權重初始值是從均勻的「2 4/F」中提取的,其中 F 是扇入,但我猜這肯定是(我猜的)指「2.4/sqrt(F)」,其中 sqrt 有助于保持輸出的標準偏差。
網絡的 H1 層和 H2 層之間的特定稀疏連接結構也被忽略了,論文只是說它是“根據一個在這里不會被討論的方案選擇的”,所以我不得不在這里做出一些合理的猜測,比如使用重疊塊稀疏結構。
論文還聲稱使用了 tanh 非線性,但我想這實際上可能是映射 ntanh(1)=1 的「標準化 tanh」,并可能添加了一個按比例縮小的跳躍連接,這是在當時很流行的操作,以確保 tanh 平滑的尾部至少有一點梯度。
最后,本文使用了「牛頓算法的一個特殊版本,它使用了 Hessian 的正對角近似值」,但我只使用了 SGD,因為它非常簡單,更何況根據本文,「人們認為該算法不會帶來學習速度的巨大提高」。
坐上時光車「作弊」
這是我最喜歡的部分。
想一下,相比于 1989,我們已經在未來生活了 33 年,這時的深度學習是一個非?;鸨难芯款I域。 利用我們的現代理解和 33 年來的研發(fā)技術積累,我們能在原有成果的基礎上提高多少?
我最初的結果是:
eval: split train. loss 4.073383e-03. error 0.62%. misses: 45 eval: split test . loss 2.838382e-02. error 4.09%. misses: 82
歸到目標 -1(負類)或 +1(正類)的任務,輸出神經元同樣也具有 tanh 非線性。 所以我刪除了輸出層上的 tanh 以獲得類別 logit,并在標準(多類)交叉熵損失函數中交換。 這一變化極大地改善了訓練錯誤,在訓練集上直接過擬合了,結果如下:
eval: split train. loss 9.536698e-06. error 0.00%. misses: 0 eval: split test . loss 9.536698e-06. error 4.38%. misses: 87
其次,根據我的經驗,一個經過微調的 SGD 可以很好地工作,但現代的 Adam 優(yōu)化器(當然,學習率為 3e-4)幾乎總是作為一個強大的 baseline,幾乎不需要任何調整。 因此,為了提高我對優(yōu)化不會影響性能的信心,我選擇了使用學習率為 3e-4 的 AdamW,并在訓練過程中逐步將其降至 1e-4,結果如下:
eval: split train. loss 0.000000e+00. error 0.00%. misses: 0 eval: split test . loss 0.000000e+00. error 3.59%. misses: 72
由于仍然出現了嚴重的過度擬合,我隨后介紹了一種簡單的數據增強策略,將輸入圖像水平或垂直移動最多 1 個像素。 然而,由于這模擬了數據集大小的增加,我還必須將訓練周期數數從 23 次增加到 60 次(我已經驗證過在原始設置中單純地增加通過次數并不能顯著改善結果):
eval: split train. loss 8.780676e-04. error 1.70%. misses: 123 eval: split test . loss 8.780676e-04. error 2.19%. misses: 43
數據增強是一個相當簡單且非常標準的概念,用于克服過度擬合,但我在 1989 年的論文中沒有找到它,也許它是一個 1989 年后才有的創(chuàng)新(我猜的)。
由于我們仍然有點過擬合,我在工具箱中找到了另一個現代工具,Dropout。 我在參數最多的層(H 3)前加了一個 0.25 的弱衰減。
因為 dropout 將激活設置為零,所以將其與激活范圍為 [-1, 1] 的 tanh 一起使用沒有多大意義,所以我也將所有非線性替換為更簡單的 ReLU 激活函數。 因為 dropout 在訓練中會帶來更多的噪音,我們還必須訓練更長的時間,增加至最多 80 個訓練周期,但結果卻變得十分喜人:
eval: split train. loss 2.601336e-03. error 1.47%. misses: 106 eval: split test . loss 2.601336e-03. error 1.59%. misses: 32
我驗證了在原來的網絡中僅僅交換 tanh->relu 并沒有帶來實質性的收益,所以這里的大部分改進都來自于增加了 dropout。
總之,如果我能時光旅行到 1989 年,我將能夠減少大約 60% 的錯誤率,使我們從約 80 個錯誤減少到約 30 個錯誤,測試集的總體錯誤率約為 1.5%。
這并不是完全沒有代價的,因為我們還將訓練時間增加了近 4 倍,這將使 1989 年的訓練時間從 3 天增加到近 12 天。但推理速度不會受到影響。
剩下的測試失敗樣本如下所示:
更進一步
然而,在替換 MSE->Softmax,SGD->AdamW,添加數據增強,dropout,交換 tanh→relu 之后,我開始逐漸減少依賴觸手可得的技巧。
我嘗試了更多的方法(例如權重標準化),但沒有得到更好的結果。 我還嘗試將 Visual Transformer(ViT)小型化為「 micro-ViT」,大致在參數量和計算量上與之前相符,但無法仿真 convnet 的性能。
當然,在過去的 33 年里,我們還研究出了許多其他創(chuàng)新,但其中許多創(chuàng)新(例如,殘差連接,層/批次標準化)只適用于更大的模型,并且大多有助于穩(wěn)定大規(guī)模優(yōu)化。
在這一點上,進一步的收益可能來自網絡規(guī)模的擴大,但這會增加測試的推斷時間。
用數據「作弊」
另一種提高性能的方法是擴大數據集的規(guī)模,盡管完成數據標注需要一些成本。
我們在最初的 baseline(再次作為消融參考)上測試結果是:
eval: split train. loss 4.073383e-03. error 0.62%. misses: 45 eval: split test . loss 2.838382e-02. error 4.09%. misses: 82
讓 baseline 訓練 100 個周期,這已經表明僅僅增加數據就能提高性能:
eval: split train. loss 1.305315e-02. error 2.03%. misses: 60 eval: split test . loss 1.943992e-02. error 2.74%. misses: 54
但進一步將其與當代知識的創(chuàng)新(如前一節(jié)所述)結合在一起,將帶來迄今為止最好的表現:
eval: split train. loss 3.238392e-04. error 1.07%. misses: 31 eval: split test . loss 3.238392e-04. error 1.25%. misses: 24
總而言之,在 1989 年簡單地擴展數據集將是提高系統(tǒng)性能的有效方法,且不需要犧牲推理時間。
反思
讓我們總結一下我們在 2022 年時,作為一名時間旅行者考察 1989 年最先進的深度學習技術時所學到的:
首先,33 年來宏觀層面上沒有太大變化。我們仍在建立由神經元層組成的可微神經網絡結構,并通過反向傳播和隨機梯度下降對其進行端到端優(yōu)化。所有的東西讀起來都非常熟悉,只是 1989 時它們的體量比較小。
按照今天的標準,1989 年的數據集就是一個「嬰兒」:訓練集只有 7291 個 16x16 的灰度圖像。今天的視覺數據集通常包含數億張來自網絡的高分辨率彩色圖像(例如,谷歌有 JFT-300M,OpenAI CLIP 是在 400M 的數據集上訓練的),但仍會增長到幾十億。這大約是此前每幅圖像約一千倍的像素信息(384*384*3/(16*16))乘以十萬倍的圖像數(1e9/1e4),輸入的像素數據的差距約為一億倍。
那時的神經網絡也是一個「嬰兒」:這個 1989 年的網絡有大約 9760 個參數、64 K 個位址和 1 K 個激活值。現代(視覺)神經網絡的規(guī)模通常有幾十億個小參數(1000000X)和 O(~1e12)個位址數(~1000000X),而自然語言模型甚至可以達到數萬億級別的參數量。
最先進的分類器花了 3 天時間在工作站上訓練,而現在在我的無風扇筆記本電腦上訓練只需 90 秒(3000 倍原始提速),通過切換到全批量優(yōu)化并使用 GPU,很可能能進一步獲得 100 倍的提升。
事實上,我能夠根據現代的技術創(chuàng)新調整模型,比如使用數據增強,更好的損失函數和優(yōu)化器,以將錯誤率降低 60%,同時保持數據集和模型的測試時間不變。
僅通過增大數據集就可以獲得適度的收益。
進一步的顯著收益可能來自更大的模型,這將需要更多的計算成本和額外的研發(fā),以幫助在不斷擴大的規(guī)模上穩(wěn)定訓練。值得一提的是,如果我被傳送到 1989 年,我最終會在沒有更強大計算機的情況下,使模型達到改進能力的上限。
假設這個練習的收獲在時間維度上保持不變。2022 年的深度學習意味著什么?2055 年的時間旅行者會如何看待當前網絡的性能?
2055 年的神經網絡在宏觀層面上與 2022 年的神經網絡基本相同,只是更大。
我們今天的數據集和模型看起來像個笑話。兩者都在大約上千億倍大于當前數據集和模型。
我們可以在個人電腦設備上用大約一分鐘的時間來訓練 2022 年最先進的模型,這將成為一個有趣的周末項目。
今天的模型并不是最優(yōu)的,只要改變模型的一些細節(jié),損失函數,數據增強或優(yōu)化器,我們就可以將誤差減半。
我們的數據集太小,僅通過擴大數據集的規(guī)模就可以獲得適度的收益。
如果不升級運算設備,并投資一些研發(fā),以有效地訓練如此規(guī)模的模型,就不可能取得進一步的收益。
但我想說的最重要的趨勢是, 在某些目標任務(如數字識別)上從頭開始訓練一個神經網絡的整個過程由于過于精細化而很快變得過時,特別是隨著 GPT 等基礎模型的出現。
這些基礎模型只由少數具有大量計算資源的機構來訓練,并且大多數應用是通過輕量級的微調網絡,快速部署工程,數據清洗,模型蒸餾,用專用的推理網絡來實現的。
我認為,我們應該期待這一趨勢愈發(fā)蓬勃,而且也已經確實如此。 在最極端的推斷中,你根本不會想訓練任何神經網絡。
在 2055 年,你將要求一個千億大小的神經網絡超強大腦通過用英語說話(或思考)來執(zhí)行一些任務。
如果你的要求足夠清晰,它會很樂意執(zhí)行的。當然,你也可以自己訓練神經網絡……但你還有什么訓練的必要呢?
?。?a href="http://www.weiseditor.com/wechat/">邯鄲小程序開發(fā))