驚為天人,NumPy手寫全部主流機器學習模型,代碼超3萬行

2021-01-12 機器之心Pro

機器之心報導

參與:思源、一鳴、張倩

用 NumPy 手寫所有主流 ML 模型,普林斯頓博士後 David Bourgin 最近開源了一個非常剽悍的項目。超過 3 萬行代碼、30 多個模型,這也許能打造「最強」的機器學習基石?

NumPy 作為 Python 生態中最受歡迎的科學計算包,很多讀者已經非常熟悉它了。它為 Python 提供高效率的多維數組計算,並提供了一系列高等數學函數,我們可以快速搭建模型的整個計算流程。毫不負責任地說,NumPy 就是現代深度學習框架的「爸爸」。

儘管目前使用 NumPy寫模型已經不是主流,但這種方式依然不失為是理解底層架構和深度學習原理的好方法。最近,來自普林斯頓的一位博士後將 NumPy 實現的所有機器學習模型全部開源,並提供了相應的論文和一些實現的測試效果。

項目地址:https://github.com/ddbourgin/numpy-ml根據機器之心的粗略估計,該項目大約有 30 個主要機器學習模型,此外還有 15 個用於預處理和計算的小工具,全部.py 文件數量有 62 個之多。平均每個模型的代碼行數在 500 行以上,在神經網絡模型的 layer.py 文件中,代碼行數接近 4000。

這,應該是目前用 NumPy 手寫機器學習模型的「最高境界」吧。

誰用 NumPy 手推了一大波 ML 模型

通過項目的代碼目錄,我們能發現,作者基本上把主流模型都實現了一遍,這個工作量簡直驚為天人。我們發現作者 David Bourgin 也是一位大神,他於 2018 年獲得加州大學伯克利分校計算認知科學博士學位,隨後在普林斯頓大學從事博士後研究。

儘管畢業不久,David 在頂級期刊與計算機會議上都發表了一些優秀論文。在最近結束的 ICML 2019 中,其關於認知模型先驗的研究就被接收為少有的 Oral 論文。

David Bourgin 小哥哥就是用 NumPy 手寫 ML 模型、手推反向傳播的大神。這麼多的工作量,當然還是需要很多參考資源的,David 會理解這些資源或實現,並以一種更易讀的方式寫出來。

正如 reddit 讀者所質疑的:在 autograd repo 中已經有很多這樣的例子,為什麼你還要做這個項目?

作者表示,他的確從 autograd repo 學到了很多,但二者的不同之處在於,他顯式地進行了所有梯度計算,以突出概念/數學的清晰性。當然,這麼做的缺點也很明顯,在每次需要微分一個新函數時,你都要寫出它的公式……

估計 David Bourgin 小哥哥在寫完這個項目後,機器學習基礎已經極其牢固了。最後,David 表示下一步會添加文檔和示例,以方便大家使用。

項目總體介紹

這個項目最大的特點是作者把機器學習模型都用 NumPy 手寫了一遍,包括更顯式的梯度計算和反向傳播過程。可以說它就是一個機器學習框架了,只不過代碼可讀性會強很多。

David Bourgin 表示他一直在慢慢寫或收集不同模型與模塊的純 NumPy 實現,它們跑起來可能沒那麼快,但是模型的具體過程一定足夠直觀。每當我們想了解模型 API 背後的實現,卻又不想看複雜的框架代碼,那麼它可以作為快速的參考。

文章後面會具體介紹整個項目都有什麼模型,這裡先簡要介紹它的整體結構。如下所示為項目文件,不同的文件夾即不同種類的代碼集。

在每一個代碼集下,作者都會提供不同實現的參考資料,例如模型的效果示例圖、參考論文和參考連結等。如下所示,David 在實現神經網絡層級的過程中,還提供了參考論文。

當然如此龐大的代碼總會存在一些 Bug,作者也非常希望我們能一起完善這些實現。如果我們以前用純 NumPy 實現過某些好玩的模型,那也可以直接提交 PR 請求。因為實現基本上都只依賴於 NumPy,那麼環境配置就簡單很多了,大家差不多都能跑得動。

手寫 NumPy 全家福

作者在 GitHub 中提供了模型/模塊的實現列表,列表結構基本就是代碼文件的結構了。整體上,模型主要分為兩部分,即傳統機器學習模型與主流的深度學習模型。

其中淺層模型既有隱馬爾可夫模型和提升方法這樣的複雜模型,也包含了線性回歸或最近鄰等經典方法。而深度模型則主要從各種模塊、層級、損失函數、最優化器等角度搭建代碼架構,從而能快速構建各種神經網絡。

除了模型外,整個項目還有一些輔助模塊,包括一堆預處理相關的組件和有用的小工具。

該 repo 的模型或代碼結構如下所示:

1. 高斯混合模型

EM 訓練2. 隱馬爾可夫模型

維特比解碼似然計算通過 Baum-Welch/forward-backward 算法進行 MLE 參數估計3. 隱狄利克雷分配模型(主題模型)

用變分 EM 進行 MLE 參數估計的標準模型用 MCMC 進行 MAP 參數估計的平滑模型4. 神經網絡

4.1 層/層級運算

AddFlattenMultiplySoftmax全連接/Dense稀疏進化連接LSTMElman 風格的 RNN最大+平均池化點積注意力受限玻爾茲曼機 (w. CD-n training)2D 轉置卷積 (w. padding 和 stride)2D 卷積 (w. padding、dilation 和 stride)1D 卷積 (w. padding、dilation、stride 和 causality)4.2 模塊

雙向 LSTMResNet 風格的殘差塊(恆等變換和卷積)WaveNet 風格的殘差塊(帶有擴張因果卷積)Transformer 風格的多頭縮放點積注意力4.3 正則化項

Dropout歸一化批歸一化(時間上和空間上)層歸一化(時間上和空間上)4.4 優化器

SGD w/ 動量AdaGradRMSPropAdam4.5 學習率調度器

常數指數Noam/TransformerDlib 調度器4.6 權重初始化器

Glorot/Xavier uniform 和 normalHe/Kaiming uniform 和 normal標準和截斷正態分布初始化4.7 損失

交叉熵平方差Bernoulli VAE 損失帶有梯度懲罰的 Wasserstein 損失4.8 激活函數

ReLUTanhAffineSigmoidLeaky ReLU4.9 模型

Bernoulli 變分自編碼器帶有梯度懲罰的 Wasserstein GAN4.10 神經網絡工具

col2im (MATLAB 埠)im2col (MATLAB 埠)conv1Dconv2Ddeconv2Dminibatch5. 基於樹的模型

決策樹 (CART)[Bagging] 隨機森林[Boosting] 梯度提升決策樹6. 線性模型

嶺回歸Logistic 回歸最小二乘法貝葉斯線性回歸 w/共軛先驗7.n 元序列模型

最大似然得分Additive/Lidstone 平滑簡單 Good-Turing 平滑8. 強化學習模型

使用交叉熵方法的智能體首次訪問 on-policy 蒙特卡羅智能體加權增量重要採樣蒙特卡羅智能體Expected SARSA 智能體TD-0 Q-learning 智能體Dyna-Q / Dyna-Q+ 優先掃描9. 非參數模型

Nadaraya-Watson 核回歸k 最近鄰分類與回歸10. 預處理

離散傅立葉變換 (1D 信號)雙線性插值 (2D 信號)最近鄰插值 (1D 和 2D 信號)自相關 (1D 信號)信號窗口文本分詞特徵哈希特徵標準化One-hot 編碼/解碼Huffman 編碼/解碼詞頻逆文檔頻率編碼11. 工具

相似度核距離度量優先級隊列Ball tree 數據結構項目示例

由於代碼量龐大,機器之心在這裡整理了一些示例。

例如,實現點積注意力機制:

class DotProductAttention(LayerBase):def __init__(self, scale=True, dropout_p=0, init="glorot_uniform", optimizer=None): super().__init__(optimizer) self.init = init self.scale = scale self.dropout_p = dropout_p self.optimizer = self.optimizer self._init_params() def _fwd(self, Q, K, V): scale = 1 / np.sqrt(Q.shape[-1]) if self.scale else 1 scores = Q @ K.swapaxes(-2, -1) * scale # attention scores weights = self.softmax.forward(scores) # attention weights Y = weights @ V return Y, weights def _bwd(self, dy, q, k, v, weights): d_k = k.shape[-1] scale = 1 / np.sqrt(d_k) if self.scale else 1 dV = weights.swapaxes(-2, -1) @ dy dWeights = dy @ v.swapaxes(-2, -1) dScores = self.softmax.backward(dWeights) dQ = dScores @ k * scale dK = dScores.swapaxes(-2, -1) @ q * scale return dQ, dK, dV

在以上代碼中,Q、K、V 三個向量輸入到「_fwd」函數中,用於計算每個向量的注意力分數,並通過 softmax 的方式得到權重。而「_bwd」函數則計算 V、注意力權重、注意力分數、Q 和 K 的梯度,用於更新網絡權重。

在一些實現中,作者也進行了測試,並給出了測試結果。如圖為隱狄利克雷(Latent Dirichlet allocation,LDA)實現進行文本聚類的結果。左圖為詞語在特定主題中的分布熱力圖。右圖則為文檔在特定主題中的分布熱力圖。

圖註:隱狄利克雷分布實現的效果。

相關焦點

  • 實戰|手把手入門神經網絡,74行代碼實現手寫數字識別
    以我們學習「機器學習」的經驗來看,很多高大上的概念剛開始不懂也沒關係,先寫個東西來跑跑,有個感覺了之後再學習那些概念和理論就快多了。如果別人已經做好了輪子,直接拿過來用則更快。因此,本文直接用Michael Nielsen先生的代碼作為例子,給大家展現神經網絡分析的普遍過程:導入數據,訓練模型,優化模型,啟發式理解等。
  • 比Keras更好用的機器學習「模型包」:無需預處理,0代碼上手做模型
    巔峰贅婿原標題:比Keras更好用的機器學習「模型包」:無需預處理,0代碼上手做模型蕭簫發自凹非寺量子位報導|公眾號QbitAI做機器學習模型時,只是融合各種算法,就已經用光了腦細胞?又或者覺得,數據預處理就是在「浪費時間」?
  • 幾行代碼搞定ML模型,低代碼機器學習Python庫正式開源
    機器之心機器之心報導機器之心編輯部PyCaret 庫支持在「低代碼」環境中訓練和部署有監督以及無監督的機器學習模型,提升機器學習實驗的效率。想提高機器學習實驗的效率,把更多精力放在解決業務問題而不是寫代碼上?低代碼平臺或許是個不錯的選擇。最近,機器之心發現了一個開源低代碼機器學習 Python 庫 PyCaret,它支持在「低代碼」環境中訓練和部署有監督以及無監督的機器學習模型。
  • 機器學習模型的超參數優化
    引言模型優化是機器學習算法實現中最困難的挑戰之一。機器學習和深度學習理論的所有分支都致力於模型的優化。機器學習中的超參數優化旨在尋找使得機器學習算法在驗證數據集上表現性能最佳的超參數。超參數與一般模型參數不同,超參數是在訓練前提前設置的。
  • Python機器學習的迷你課程(14天教學)
    __version__))# numpyimport numpyprint('numpy: {}'.format(numpy.import numpyimport pandasmyarray = numpy.array([[1, 2, 3], [4, 5, 6]])rownames = ['a', 'b']colnames =
  • Python學習第117課——numpy中dot的運用舉例
    閒話少敘,我們對numpy中的矩陣相乘做一些舉例說明。我們還是使用上節的兩個矩陣為例。上節我們用手寫推導矩陣相乘過程如下:我們現在用代碼演示一下numpy中的矩陣相乘。我們知道如果兩個數組都是2維以上才能用矩陣相乘。用代碼生成兩個2行2列的數組x和y(跟我們手寫推導時的矩陣x和y結構一樣,都是2行2列),然後進行矩陣相乘。
  • 手把手:用Python搭建機器學習模型預測黃金價格
    新年第一天,讓我們嘗試用python搭建一個機器學習線性回歸模型,預測金價!自古以來,黃金一直作為貨幣而存在,就是在今天,黃金也具有非常高的儲藏價值,那麼有沒有可能預測出黃金價格的變化趨勢呢?答案是肯定的,讓我們使用機器學習中的回歸算法來預測世界上貴重金屬之一,黃金的價格吧。
  • 微軟推出Lobe桌面應用程式 助你輕鬆創建機器學習模型
    需要指出的是,Lobe 無需聯網或登錄,且目前僅可輸出機器學習模型。微軟團隊正在研究一系列的應用程式和工具,以便用戶在幾乎不需要編程的情況下,即可運行相關模型。Lobe 項目經理 Bill Barnes 表示,其使用了複雜的技術,來讓事情變得更加有趣。
  • 機器學習之多元線性回歸模型梯度下降公式與代碼實現(篇二)
    上一篇我們介紹了線性回歸的概述和最小二乘的介紹,對簡單的一元線性方程模型手推了公式和python代碼的實現。機器學習之線性回歸模型詳細手推公式與代碼實現(篇一)今天這一篇來介紹多元線性回歸模型多元線性回歸模型介紹在回歸分析中,如果有兩個或兩個以上的自變量,就稱為多元回歸
  • 機器學習之分類算法K-Means介紹與代碼分析(篇四)
    隨著競爭越來愈激烈,機器學習在這個領域也扮演著至關重要的角色。如果你想創建一個優秀的隊伍並且喜歡根據球員狀態來識別類似的球員,那麼K-means算法是一個很好的選擇。K-Means代碼實現1.centroids=[]): 7self.n_clusters = n_clusters 8self.max_iter = max_iter 9self.centroids = np.array( centroids, dtype=np.float )1011# 訓練模型方法
  • 使用Flask部署機器學習模型
    我所學的一切都集中在模型構建組件上。沒有多少人會談論如何部署你的機器學習模型。把你的模型投入生產意味著什麼?它需要什麼?這些都是每個數據科學家需要回答的關鍵的職業定義問題。這就是為什麼我決定寫下這個教程來演示如何使用Flask來部署機器學習模型。
  • 在python中使用SageMaker Debugger進行機器學習模型的開發調試
    在這篇博客文章中,將討論調試機器學習代碼與傳統軟體的不同之處,以及為什麼調試機器學習代碼要困難得多。然後,將展示如何使用更好的機制來捕獲調試信息、在訓練期間實時監控常見問題、發現問題後及時幹預以防止發生進一步的錯誤及浪費計算機資源。
  • Numpy學習打卡task02
    2019年10月,有學者指出,與經典的偽隨機數發生器(PRNGs)方法相比,將量子隨機數發生器(QRNGs)引入到包括神經網絡和卷積神經網絡在內的機器學習模型中,用於隨機初始權重分布和隨機森林的拆分過程,對其能力產生了深遠的影響。均勻分布在0和1之間的隨機數可以通過所需分布的逆累積分布函數(CDF)來產生任何所需分布的隨機數(見逆變換抽樣)。逆CDF也被稱為分位函數。
  • 交叉驗證和超參數調整:如何優化你的機器學習模型
    現在我們知道了交叉驗證是什麼以及它為什麼重要,讓我們看看是否可以通過調優超參數從我們的模型中獲得更多。超參數調優模型參數是在模型訓練時學習的,不能任意設置。與模型參數不同,超參數是用戶在訓練機器學習模型前可以設置的參數。
  • 一鍵獲取新技能,玩轉NumPy數據操作
    除了數據切片和數據切塊的功能之外,掌握numpy也使得開發者在使用各數據處理庫調試和處理複雜用例時更具優勢。在本文中,將介紹NumPy的主要用法,以及它如何呈現不同類型的數據(表格,圖像,文本等),這些經Numpy處理後的數據將成為機器學習模型的輸入。
  • 手把手教您Python機器學習項目
    創建6個機器學習模型,選擇最好的,建立準確性可靠的信心。如果您是一個機器學習初學者,並希望最終開始使用Python,那麼本教程就是為您設計的。2019年11月/ 11月更新:為每個部分添加了完整的代碼示例。2019年12月/ 12月更新:更新示例以刪除v0.22中API變化引起的警告。2020年1月更新:更新到刪除測試工具的代碼片段。如何用Python開始機器學習?
  • 數據科學中100個Numpy代碼技巧
    機器學習涉及到對數組的大量轉換和操作,這使得NumPy成為必不可少的工具之一。下面的100個練習都是從numpy郵件列表、stack overflow和numpy文檔中收集的。1.以np的名稱導入numpy包(★☆☆)import numpy as np2.列印numpy版本和配置(★☆☆)print(np.
  • 揭開機器學習模型的「黑箱」
    本文介紹六種機器學習模型解釋方法的原理,並以華泰XGBoost選股模型為例,嘗試揭開機器學習模型的「黑箱」。如果不將機器學習模型的黑箱打開,不弄清機器學習模型的「思考」過程,直接使用機器學習的判斷結果,可能帶來較大的風險。  近年來研究者提出諸多機器學習模型解釋方法,核心思想各有不同  近年來研究者提出諸多機器學習模型解釋方法,除了傳統的特徵重要性外,ICE、PDP、SDT、LIME、SHAP都是揭開機器學習模型黑箱的有力工具。
  • 機器學習模型太大難部署?這裡有 3 個解決方案
    2018 年夏天,就在 GPT-2 首次發布的前幾個月,Google 發布了 NASNet,這是一個創紀錄的圖像分類模型,它擁有 8890 萬個參數,比其他任何能夠識別圖像中物體的主流圖像分類模型都要大:資料來源:Sik-Ho Tsang趨勢很明顯。為了實現機器學習驅動未來的美好願景,這些「超級模型」將越來越大。
  • ...首個自動圖機器學習工具包AutoGL,開源易用可擴展,支持自定義模型
    圖結構豐富且具有與生俱來的導向能力,因此非常適合機器學習模型。同時,它又無比複雜,難以進行大規模擴展應用。而且不同的圖數據在結構、內容和任務上千差萬別,所需要的圖機器學習模型也可能相差甚遠,這就導致不同任務的模型自動化面臨巨大挑戰。如何設計最優的圖自動機器學習模型,是一個尚未解決的難題。圖 + AutoML = ?