
我們熟知的SQL是一種數據庫查詢語句,它方便了開發者在大型數據中執行高效的操作。但本文從另一角度嵌套SQL查詢語句而構建了一個簡單的三層全連接網絡,雖然由于語句的嵌套過深而不能高效計算,但仍然是一個非常有意思的實驗。
在這篇文章中,我們將純粹用SQL實現含有一個隱藏層(以及帶
ReLU 和 softmax 激活函數)的神經網絡。這些神經網絡訓練的步驟包含前向傳播和反向傳播,將在 BigQuery
的單個SQL查詢語句中實現。當它在 BigQuery 中運行時,實際上我們正在成百上千臺服務器上進行分布式神經網絡訓練。聽上去很贊,對吧?
也就是說,這個有趣的項目用于測試 SQL 和 BigQuery 的限制,同時從聲明性數據的角度看待神經網絡訓練。這個項目沒有考慮任何的實際應用,不過最后我將討論一些實際的研究意義。
我們先從一個基于神經網絡的簡單分類器開始。它的輸入尺寸為 2,輸出為二分類。我們將有一個維度為 2 的單隱層和 ReLU 激活函數。輸出層的二分類將使用 softmax 函數。我們在實現網絡時遵循的步驟將是在 Karpathy’s CS231n 指南(https://cs231n.github.io/neural-networks-case-study/)中展示的基于 SQL 版本的 Python 示例。
模型
該模型含有以下參數:
輸入到隱藏層
W: 2×2 的權重矩陣(元素: w_00, w_01, w_10, w_11)
B: 2×1 的偏置向量(元素:b_0, b_1)
隱藏到輸出層
W2: 2×2 的權重矩陣(元素: w2_00, w2_01, w2_10, w2_11)
B2: 2×1 的偏置向量(元素:b2_0, b2_1)
訓練數據存儲在 BigQuery 表格當中,列 x1 和 x2 的輸入和輸出如下所示(表格名稱:example_project.example_dataset.example_table)
如前所述,我們將整個訓練作為單個 SQL 查詢語句來實現。在訓練完成后,通過 SQL 查詢語句將會返回參數的值。正如你可能猜到的,這將是一個層層嵌套的查詢,我們將逐步構建以準備這個查詢語句。我們將會從最內層的子查詢開始,然后逐個增加嵌套的外層。
前向傳播
首先,我們將權重參數 W 和 W2 設為服從正態分布的隨機值,將權重參數 B 和 B2 設置為 0。 W 和 W2 的隨機值可以通過 SQL 本身產生。為了簡單起見,我們將從外部生成這些值并在 SQL 查詢中使用。用于初始化參數的內部子查詢如下:
SELECT *,
-0.00569693 AS w_00,
0.00186517 AS w_01,
0.00414431 AS w_10,
0.0105101 AS w_11,
0.0 AS b_0,
0.0 AS b_1,
-0.01312284 AS w2_00,
-0.01269512 AS w2_01,
0.00379152 AS w2_10,
-0.01218354 AS w2_11,
0.0 AS b2_0,
0.0 AS b2_1
FROM `example_project.example_dataset.example_table`
請注意,表格 example_project.example_dataset.example_table 已經包含了列 x1、 x2 和 y。模型參數將會被作為上述查詢結果的附加列添加。
接下來,我們將計算隱藏層的激活值。我們將使用含有元素 d0 和 d1 的向量 D 表示隱藏層。我們需要執行矩陣操作 D = np.maximum(0, np.dot(X, W) + B),其中 X 表示輸入向量(元素 x1 和 x2)。這個矩陣運算包括將權重 W 和輸入 X 相乘,再加上偏置向量 B。然后,結果將被傳遞給非線性 ReLU 激活函數,該函數將會把負值設置為 0。SQL 中的等效查詢為:
SELECT *,
(CASE
WHEN ((x1*w_00 + x2*w_10) + b_0) >0.0THEN ((x1*w_00 + x2*w_10) + b_0)
ELSE0.0
END) AS d0,
(CASE
WHEN ((x1*w_01 + x2*w_11) + b_0) >0.0THEN ((x1*w_01 + x2*w_11) + b_1)
ELSE0.0
END) AS d1
FROM {inner subquery}
上面的查詢將兩個新列 d0 和 d1 添加到之前內部子查詢的結果當中。 上述查詢的輸出如下所示。
這完成了從輸入層到隱藏層的一次轉換?,F在,我們可以執行從隱藏層到輸出層的轉換了。
首先,我們將計算輸出層的值。公式是:scores = np.dot(D, W2) + B2。然后,我們將對計算出來的值用 softmax 函數來獲得每個類的預測概率。SQL 內部的等價子查詢如下:
SELECT *,
EXP(scores_0)/(EXP(scores_0) + EXP(scores_1)) AS probs_0,
EXP(scores_1)/(EXP(scores_0) + EXP(scores_1)) AS probs_1
FROM
( SELECT *,
((d0*w2_00 + d1*w2_10) + b2_0) AS scores_0,
((d0*w2_01 + d1*w2_11) + b2_1) AS scores_1
FROM {INNER sub-query})
首先,我們將使用交叉熵損失函數來計算當前預測的總損失。首先,計算每個樣本中正確類預測概率對數的負值。交叉熵損失只是這些 X 和 Y 實例中數值的平均值。自然對數是一個遞增函數,因此,將損失函數定義為負的正確類預測概率對數很直觀。如果正確類的預測概率很高,損失函數將會很低。相反,如果正確類的預測概率很低,則損失函數值將很高。
為了減少過擬合的風險,我們也將同樣增加 L2 正則化。在整體損失函數中,我們將包含 0.5*reg*np.sum(W*W) + 0.5*reg*np.sum(W2*W2),其中 reg 是超參數。在損失函數中包括這一函數將會懲罰那些權重向量中較大的值。
在查詢當中,我們同樣會計算訓練樣本的數量(num_examples)。這對于后續我們計算平均值來說很有用。SQL 查詢中計算整體損失函數的語句如下:
SELECT *,
(sum_correct_logprobs/num_examples) +1e-3*(0.5*(w_00*w_00 + w_01*w_01 + w_10*w_10 + w_11*w_11) +0.5*(w2_00*w2_00 + w2_01*w2_01 + w2_10*w2_10 + w2_11*w2_11)) AS loss
FROM
(SELECT *,
SUM(correct_logprobs) OVER () sum_correct_logprobs,
COUNT(1) OVER () num_examples
FROM
(SELECT *,
(CASE
WHEN y =0THEN -1*LOG(probs_0)
ELSE -1*LOG(probs_1)
END) AS correct_logprobs
FROM {inner subquery}))
反向傳播
接下來,對于反向傳播,我們將計算每個參數對于損失函數的偏導數。我們使用鏈式法則從最后一層開始逐層計算。首先,我們將通過使用交叉熵和 softmax 函數的導數來計算 score 的梯度。與此相對的查詢是:
SELECT *,
(CASE
WHEN y =0THEN (probs_0–1)/num_examples
ELSE probs_0/num_examples
END) AS dscores_0,
(CASE
WHEN y =1THEN (probs_1–1)/num_examples
ELSE probs_1/num_examples
END) AS dscores_1
FROM {inner subquery}
在上文中,我們用 scores = np.dot(D, W2) + B2 算出了分數。因此,基于分數的偏導數,我們可以計算隱藏層 D 和參數 W2,B2 的梯度。對應的查詢語句是:
SELECT *,
SUM(d0*dscores_0) OVER () AS dw2_00,
SUM(d0*dscores_1) OVER () AS dw2_01,
SUM(d1*dscores_0) OVER () AS dw2_10,
SUM(d1*dscores_1) OVER () AS dw2_11,
SUM(dscores_0) OVER () AS db2_0,
SUM(dscores_1) OVER () AS db2_1,
CASE
WHEN (d0) <=0.0THEN0.0
ELSE (dscores_0*w2_00 + dscores_1*w2_01)
END AS dhidden_0,
CASE
WHEN (d1) <=0.0THEN0.0
ELSE (dscores_0*w2_10 + dscores_1*w2_11)
END AS dhidden_1
FROM {inner subquery}
同理,我們知道 D = np.maximum(0, np.dot(X, W) + B)。因此,通過 D 的偏導,我們可以計算出 W 和 B 的導數。我們無須計算 X 的偏導,因為它不是模型的參數,且也不必通過其它模型參數進行計算。計算 W 和 B 的偏導的查詢語句如下:
SELECT *,
SUM(x1*dhidden_0) OVER () AS dw_00,
SUM(x1*dhidden_1) OVER () AS dw_01,
SUM(x2*dhidden_0) OVER () AS dw_10,
SUM(x2*dhidden_1) OVER () AS dw_11,
SUM(dhidden_0) OVER () AS db_0,
SUM(dhidden_1) OVER () AS db_1
FROM {inner subquery}
最后,我們使用 W、B、W2 及 B2 各自的導數進行更新操作。計算公式是 param = learning_rate * d_param ,其中learning_rate 是參數。為了體現 L2 正則化,我們會在計算 dW 和 dW2 時加入一個正則項 reg*weight。我們也去掉如 dw_00, correct_logprobs 等緩存的列,它們曾在子查詢時被創建,用于保存訓練數據(x1, x2 及 y 列) 和模型參數(權重和偏置項)。對應的查詢語句如下:
SELECT x1,
x2,
y,
w_00 — (2.0)*(dw_00+(1e-3)*w_00) AS w_00,
w_01 — (2.0)*(dw_01+(1e-3)*w_01) AS w_01,
w_10 — (2.0)*(dw_10+(1e-3)*w_10) AS w_10,
w_11 — (2.0)*(dw_11+(1e-3)*w_11) AS w_11,
b_0 — (2.0)*db_0 AS b_0,
b_1 — (2.0)*db_1 AS b_1,
w2_00 — (2.0)*(dw2_00+(1e-3)*w2_00) AS w2_00,
w2_01 — (2.0)*(dw2_01+(1e-3)*w2_01) AS w2_01,
w2_10 — (2.0)*(dw2_10+(1e-3)*w2_10) AS w2_10,
w2_11 — (2.0)*(dw2_11+(1e-3)*w2_11) AS w2_11,
b2_0 — (2.0)*db2_0 AS b2_0,
b2_1 — (2.0)*db2_1 AS b2_1
FROM {inner subquery}
這包含了正向和反向傳播的一整個迭代過程。以上查詢語句將返回更新后的權重和偏置項。部分結果如下所示:
為了進行多次訓練迭代,我們將反復執行上述過程。用一個簡單 Python 函數足以搞定,代碼鏈接如下:https://github.com/harisankarh/nn-sql-bq/blob/master/training.py。
因為迭代次數太多,查詢語句嵌套嚴重。執行 10 次訓練迭代的查詢語句地址如下:
https://github.com/harisankarh/nn-sql-bq/blob/master/out.txt
因為查詢語句的多重嵌套和復雜度,在 BigQuery 中執行查詢時多項系統資源告急。BigQuery 的標準 SQL 擴展的縮放性比傳統 SQL 語言要好。即使是標準 SQL 查詢,對于有 100k 個實例的數據集,也很難執行超過 10 個迭代。因為資源的限制,我們將會使用一個簡單的決策邊界來評估模型,如此一來,我們就可以在少量迭代后得到較好的準確率。
我們將使用一個簡單的數據集,其輸入 X1、X2 服從標準正態分布。二進制輸出 y 簡單判斷 x1 + x2 是否大于 0。為了更快的訓練完 10 個迭代,我們使用一個較大的學習率 2.0(注意:這么大的學習率并不推薦實際使用,可能會導致發散)。將上述語句執行 10 個迭代得出的模型參數如下:
我們將使用 Bigquery 的函數 save to table 把結果保存到一個新表。我們現在可以在訓練集上執行一次推理來比較預測值和預期值的差距。查詢語句片段在以下鏈接中:
https://github.com/harisankarh/nn-sql-bq/blob/master/query_for_prediction.sql。
僅通過十個迭代,我們的準確率就可達 93%(測試集上也差不多)。
如果我們把迭代次數加到 100 次,準確率高達 99%。
優化
下面是對本項目的總結。我們由此獲得了哪些啟發?如你所見,資源瓶頸決定了數據集的大小以及迭代執行的次數。除了祈求谷歌開放資源上限,我們還有如下優化手段來解決這個問題。
創建中間表和多個 SQL 語句有助于增加迭代數。例如,前 10 次迭代的結果可以存儲在一個中間表中。同一查詢語句在執行下 10 次迭代時可以基于這個中間表。如此,我們就執行了 20 個迭代。這個方法可以反復使用,以應對更大的查詢迭代。
相比于在每一步增加外查詢,我們應該盡可能的使用函數的嵌套。例如,在一個子查詢中,我們可以同時計算 scores 和 probs,而不應使用 2 層嵌套查詢。
在上例中,所有的中間項都被保留直到最后一個外查詢執行。其中有些項如 correct_logprobs 可以早些刪除(盡管 SQL 引擎可能會自動的執行這類優化)。
多嘗試應用用戶自定義的函數。如果感興趣,你可以看看這個 BigQuery 的用戶自定義函數的服務模型的項目(但是,無法使用 SQL 或者 UDFs 進行訓練)。
意義
現在,讓我們來看看基于深度學習的分布式 SQL 引擎的深層含義。 BigQuery、Presto 這類 SQL 倉庫引擎的一個局限性在于,查詢操作是在 CPU 而不是 GPU 上執行的。研究 blazingdb 和 mapd 等基于 GPU 加速的數據庫查詢結果想必十分有趣。一個簡單的研究方法就是使用分布式 SQL 引擎執行查詢和數據分布,并用 GPU 加速數據庫執行本地計算。
退一步來看,我們已經知道執行分布式深度學習很難。分布式 SQL 引擎在數十年內已經有了大量的研究工作,并產出如今的查詢規劃、數據分區、操作歸置、檢查點設置、多查詢調度等技術。其中有些可以與分布式深度學習相結合。如果你對這些感興趣,請看看這篇論文(https://sigmodrecord.org/publications/sigmodRecord/1606/pdfs/04_vision_Wang.pdf),該論文對分布式數據庫和分布式深度學習展開了廣泛的研究討論。
數據分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
CDA數據分析師證書考試體系(更新于2025年05月22日)
2025-05-26解碼數據基因:從數字敏感度到邏輯思維 每當看到超市貨架上商品的排列變化,你是否會聯想到背后的銷售數據波動?三年前在零售行 ...
2025-05-23在本文中,我們將探討 AI 為何能夠加速數據分析、如何在每個步驟中實現數據分析自動化以及使用哪些工具。 數據分析中的AI是什么 ...
2025-05-20當數據遇見人生:我的第一個分析項目 記得三年前接手第一個數據分析項目時,我面對Excel里密密麻麻的銷售數據手足無措。那些跳動 ...
2025-05-20在數字化運營的時代,企業每天都在產生海量數據:用戶點擊行為、商品銷售記錄、廣告投放反饋…… 這些數據就像散落的拼圖,而相 ...
2025-05-19在當今數字化營銷時代,小紅書作為國內領先的社交電商平臺,其銷售數據蘊含著巨大的商業價值。通過對小紅書銷售數據的深入分析, ...
2025-05-16Excel作為最常用的數據分析工具,有沒有什么工具可以幫助我們快速地使用excel表格,只要輕松幾步甚至輸入幾項指令就能搞定呢? ...
2025-05-15數據,如同無形的燃料,驅動著現代社會的運轉。從全球互聯網用戶每天產生的2.5億TB數據,到制造業的傳感器、金融交易 ...
2025-05-15大數據是什么_數據分析師培訓 其實,現在的大數據指的并不僅僅是海量數據,更準確而言是對大數據分析的方法。傳統的數 ...
2025-05-14CDA持證人簡介: 萬木,CDA L1持證人,某電商中廠BI工程師 ,5年數據經驗1年BI內訓師,高級數據分析師,擁有豐富的行業經驗。 ...
2025-05-13CDA持證人簡介: 王明月 ,CDA 數據分析師二級持證人,2年數據產品工作經驗,管理學博士在讀。 學習入口:https://edu.cda.cn/g ...
2025-05-12CDA持證人簡介: 楊貞璽 ,CDA一級持證人,鄭州大學情報學碩士研究生,某上市公司數據分析師。 學習入口:https://edu.cda.cn/g ...
2025-05-09CDA持證人簡介 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度、美團、阿里等 ...
2025-05-07相信很多做數據分析的小伙伴,都接到過一些高階的數據分析需求,實現的過程需要用到一些數據獲取,數據清洗轉換,建模方法等,這 ...
2025-05-06以下的文章內容來源于劉靜老師的專欄,如果您想閱讀專欄《10大業務分析模型突破業務瓶頸》,點擊下方鏈接 https://edu.cda.cn/g ...
2025-04-30CDA持證人簡介: 邱立峰 CDA 數據分析師二級持證人,數字化轉型專家,數據治理專家,高級數據分析師,擁有豐富的行業經驗。 ...
2025-04-29CDA持證人簡介: 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度,美團,阿里等 ...
2025-04-28CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-27數據分析在當今信息時代發揮著重要作用。單因素方差分析(One-Way ANOVA)是一種關鍵的統計方法,用于比較三個或更多獨立樣本組 ...
2025-04-25CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-25