作者:Artur Suilin
下面我們將簡要介紹 Artur Suilin 如何修正 GRU 以完成網站流量時序預測競賽。
預測有兩個主要的信息源:
局部特征。我們看到一個趨勢時,希望它會繼續(xù)(自回歸模型)朝這個趨勢發(fā)展;看到流量峰值時,知道它將逐漸衰減(滑動平均模型);看到假期交通流量增加,就知道以后的假期也會出現(xiàn)流量增加(季節(jié)模型)。全局特征。如果我們查看自相關(autocorrelation)函數(shù)圖,就會注意到年與年之間強大的自相關和季節(jié)間的自相關。我決定使用 RNN seq2seq 模型進行預測,原因如下:
RNN 可以作為 ARIMA 模型的自然擴展,但是比 ARIMA 更靈活,更具表達性。RNN 是非參數(shù)的,大大簡化了學習。想象一下對 145K 時序使用不同的 ARIMA 參數(shù)。任何外源性的特征(數(shù)值或類別、時間依賴或序列依賴)都可以輕松注入該模型。seq2seq 天然適合該任務:我們根據(jù)先前值(包括先前預測)的聯(lián)合概率(joint probability)預測下一個值。使用先前預測可保持模型穩(wěn)定,因為誤差會在每一步累積,如果某一步出現(xiàn)極端預測,則有可能毀了所有后續(xù)步的預測質量?,F(xiàn)在的深度學習出現(xiàn)了太多的炒作。特征工程
RNN 足夠強大來發(fā)現(xiàn)和學習自身特征。模型的特征列表如下:
pageviews:原始值經過 log1p() 的轉換得到幾乎正態(tài)的時序內值分布,而不是偏態(tài)分布。agent, country, site:這些特征從網頁 url 中提取,然后經過 One-Hot 編碼。day of week:捕捉每周的季節(jié)效應。year-to-year autocorrelation, quarter-to-quarter autocorrelation:捕捉各年、各季度的季節(jié)效應。page popularity:高流量和低流量頁面具有不同的流量變化模式,該特征(pageviews 的中間值)幫助捕捉流量規(guī)模。pageviews 特征丟失了規(guī)模信息,因為每個 pageviews 序列被獨立歸一化至零均值和單位方差。lagged pageviews:之后將具體介紹。特征預處理
所有特征(包括 One-Hot 編碼的特征)被歸一化至零均值和單位方差。每個 pageviews 序列被獨立歸一化。
時間依賴特征(自相關性、國家等)被「拉伸」至時序長度,即每天重復使用 tf.tile() 命令。
模型在來自初始時序的隨機固定長度樣本上進行訓練。例如,如果初始時序長度是 600 天,我們使用 200 天的樣本進行訓練,那么我們可以在前 400 天中隨意選擇開始采樣的樣本。
該采樣工作是一種有效的數(shù)據(jù)增強機制:訓練代碼在每一步隨機選擇每次時序的開始點,生成無限量的幾乎不重復的數(shù)據(jù)。
模型的核心技術
模型主要由兩部分組成,即編碼器和解碼器。
編碼器為 cuDNN GRU,cuDNN 要比 TensorFlow 的 RNNCells 快大約 5 到 10 倍,但代價就是使用起來不太方便,且文檔也不夠完善。
解碼器為 TF GRUBlockCell,該 API 封裝在 tf.while_loop() 中。循環(huán)體內的代碼從上一步獲得預測,并加入到當前時間步的輸入特征中。
處理長時間序列
LSTM/GRU 對于相對較短的序列(100-300 項以內)來說是非常好的解決方案。但對于較長的序列來說,LSTM/GRU 仍然有效,只不過會逐漸遺忘較早時間步所包含的信息。Kaggle 競賽的時間序列長達 700 多天,所以我們需要找一些方法來「加強」GRU 的記憶力。
我們第一個方法先是考慮使用一些注意力機制。注意力機制可以將過去較長距離的有用信息保留到當前 RNN 單元中。對于我們的問題,最簡單高效的注意力方法是使用固定權重的滑動窗口注意力機制。它在較長距離的過去時間步上有兩個重要的點(考慮長期的季節(jié)性),即 1 年前和 1 個季度前。
我們可以采用 current_day – 365 和 current_day – 90 這兩個時間點的編碼器輸出,并將它們饋送到全連接層以降低維度,并將結果加入到解碼器的輸入特征中。這個解決方案雖然簡單卻大大降低了預測誤差。
隨后我們將重要的點與它們的近鄰求均值,并借此減少噪聲和補償不均勻的間隔(閏年和不同長度的月份):attn_365 = 0.25 * day_364 + 0.5 * day_365 + 0.25 * day_366。
但隨后我們意識到 0.25、0.5、0.25 是一個一維卷積核(length=3),我們可以自動學習更大的卷積核以檢測過去重要的點。
最后,我們構建了一個非常大的注意力機制,它會查看每一個時間序列的「指紋」(指紋由較小的卷積網絡產生),并決定應該注意哪些點和為較大卷積核生成權重。這個應用于解碼器輸出的較大卷積核會為每一個預測的日期生成一個注意力特征。雖然最后沒有使用這種方法,但這個注意力機制仍然保留在代碼中,讀者可以在模型代碼中找到它。
注意,我們并沒有使用經典的注意力方案(Bahdanau 或 Luong 注意力機制),因為經典的注意力機制應該在每個預測步上使用所有的歷史數(shù)據(jù)點從頭開始計算,因此這種方法對于較長時間序列(約兩年的天數(shù))來說太耗時間了。所以我們的方案將會對所有數(shù)據(jù)點進行一次卷積,對所有預測時間步使用相同的注意力權重(這也是缺點),這樣的方案計算起來要快很多。
因為我們對注意力機制的復雜度感到不太滿意,因此我們試圖完全移除注意力機制,并將一年前、半年前、一季度前重要的數(shù)據(jù)點作為編碼器和解碼器的附加特征。這樣的結果是非常令人驚訝的,甚至在預測質量方面都要比帶注意力機制的模型略勝一籌。因此我們最好的公開分數(shù)都是僅使用滯后(lagged)數(shù)據(jù)點實現(xiàn)的,它們都沒有使用注意力機制。
滯后數(shù)據(jù)點另一個重要的優(yōu)勢是,模型可以使用更短的編碼器而不需要擔心損失過去的信息,因為這些信息現(xiàn)在明確地包含在特征中。在采用這種方法后,即使我們編碼器的長度是 60 到 90 天,結果也是完全可以接受的,而以前需要 300-400 天的長度才能獲得相同的性能。此外,更短的編碼器就等于更快速的訓練和更少的信息損失。
損失和正則化
SMAPE(競賽用的目標損失函數(shù))因其在零值周圍不穩(wěn)定的行為而無法直接使用(當真值為零的時候,損失函數(shù)是階躍函數(shù);預測值也為零的時候,則損失函數(shù)不確定)。
我使用經平滑處理的可微 SMAPE 變體,它在所有實數(shù)上都表現(xiàn)良好:
epsilon = 0.1summ = tf.maximum(tf.abs(true) + tf.abs(predicted) + epsilon, 0.5 + epsilon)smape = tf.abs(predicted – true) / summ * 2.0?
另一個選擇是在 log1p(data) 上的 MAE 損失函數(shù),它很平滑,且訓練目標與 SMAPE 非常接近。
最終預測取最接近的整數(shù),負面預測取零。
我嘗試使用論文《Regularizing RNNs by Stabilizing Activations》中經正則化的 RNN 激活值,因為 cuDNN GRU 的內部權重無法直接正則化(也可能是我沒有找到正確的方法)。穩(wěn)性損失(Stability loss)不起作用,激活損失可以為較小損失權重(1e-06..1e-05)帶來少許改進。
訓練和驗證
我使用 COCOB 優(yōu)化器(詳見論文《Training Deep Networks without Learning Rates Through Coin Betting》)結合梯度截斷進行訓練。COCOB 嘗試預測每個訓練步的最優(yōu)學習率,因此我完全不必調整學習率。它的收斂速度也比傳統(tǒng)的基于動量的優(yōu)化器快得多,尤其是在第一個 epoch 上,可以讓我及早停止不成功的實驗。
有兩種方式可以將時序分割為訓練和驗證數(shù)據(jù)集:
Walk-forward 分割。這實際上不是分割:我們在完整數(shù)據(jù)集上訓練和驗證,但使用不同的時間跨度。驗證用的時間跨度比訓練用時間跨度前移一個預測間隔。Side-by-side 分割。這是主流機器學習傳統(tǒng)的分割模型。數(shù)據(jù)集被分割成兩個獨立的部分,一個用于訓練,另一個用于驗證。兩種方式我都試了,但對于這個任務來說 Walk-forward 更好,因為它與競賽目標直接相關:使用歷史值預測未來值。但是該分割破壞了時序結尾的數(shù)據(jù)點,使得訓練準確預測未來的模型變得困難。
具體來說:比如,我們有 300 天的歷史數(shù)據(jù),想預測接下來 100 天的數(shù)據(jù)。如果我們選擇 walk-forward 分割,我們必須使用前 100 天的數(shù)據(jù)用于真實訓練,后面 100 天的數(shù)據(jù)用于訓練模式的預測(運行解碼器、計算損失),再后面 100 天的數(shù)據(jù)用于驗證,最后 100 天用于對未來值真正進行預測。因此,我們實際上可以使用 1/3 的數(shù)據(jù)點來訓練,最后一個訓練數(shù)據(jù)點和第一個預測數(shù)據(jù)點之間隔了 200 天。間隔太大了,因為一旦我們離開某個訓練數(shù)據(jù),預測質量將出現(xiàn)指數(shù)級下降(不確定性增加)。使用 100 天差距訓練的模型預測質量相對較好。
Side-by-side 分割所需要的計算力更少,因為它在端點時并不會消耗數(shù)據(jù)點。但是對于我們的數(shù)據(jù),模型在驗證集上的性能與在訓練集上的性能是強相關的,并且與將來的實際模型性能幾乎不具有相關性。換而言之,并行分割對于我們的問題基本上是沒有什么作用的,它只是復制了在訓練數(shù)據(jù)集上觀察到的模型損失。
我僅使用驗證集(帶有前向分步分割)進行模型調優(yōu),預測未來數(shù)值的最終模型只是在盲目的模式中進行訓練,沒有使用任何驗證集。
降低模型方差
優(yōu)于強噪音數(shù)據(jù)的輸入,模型不可避免地具有高方差。坦白講,我很驚訝 RNN 居然從噪音數(shù)據(jù)中學習到了東西。
在不同 seed 上訓練的相同模型具有不同的表現(xiàn),有時模型甚至在「不幸」的 seed 上變得發(fā)散。訓練期間,表現(xiàn)也會逐步地發(fā)生很大波動。依靠純粹的運氣很難贏得比賽,因此我決定采取行動降低方差。
我不知道哪個訓練步驟最適合預測未來(但前數(shù)據(jù)的驗證結果與未來數(shù)據(jù)的結果只有弱相關關系),所以我不能使用提前停止。但是我知道近似區(qū)域,其中模型(可能)進行了充分訓練,但(可能)沒有開始過擬合。我決定把這個最佳區(qū)域設置為 10500 到 11500 次迭代區(qū)間內,并且從這個區(qū)域的每第 10000 個步驟保存 10 個檢查點。相似地,我決定在不同的 seed 上訓練 3 個模型,并從每個模型中保存檢查點。因此我一共有 30 個檢查點。降低方差、提升模型性能的一個眾所周知的方法是 ASGD(SGD 平均)。它很簡單,并在 TensorFlow 中得到很好的支持。我們必須在訓練期間保持網絡權重的移動平均值,并在推斷中使用這些平均權重,而不是原來的權重。三個模型的結合表現(xiàn)不錯(在每個檢查點上使用平均模型權重的 30 個檢查點的平均預測)。我在排行榜上(針對未來數(shù)據(jù))獲得了相較于歷史數(shù)據(jù)上的驗證大致相同的 SMAPE 誤差。
理論上講,你也可以把前兩種方法用作集成學習,但我主要用其降低方差。
超參數(shù)調節(jié)
很多模型參數(shù)(層的數(shù)量、深度,激活函數(shù),dropout 系數(shù)等)能夠(并且應該)被調節(jié)從而獲得更優(yōu)的模型表現(xiàn)。手動調節(jié)乏味且費時,所以我決定自動化該過程,并使用 SMAC3 搜索超參數(shù)。下面是 SMAC3 的一些優(yōu)勢:
支持條件參數(shù)(例如,為每層聯(lián)合調節(jié)層數(shù)和 dropout;如果 n_layers > 1,第二層上的 dropout 將被調節(jié))明確處理模型方差。SMAC 在不同種子上訓練每個模型的若干個實例,如果實例在相同種子上訓練還要對比模型。如果它在所有相同種子上優(yōu)于另一個模型,則該模型獲勝。與我的期望相反,超參數(shù)搜索并沒有建立定義明確的全局最小。所有的最佳模型大致具有相同的性能,但參數(shù)不同。可能 RNN 模型對于這個任務來說太具有表現(xiàn)力了,并且最好的模型得分更多依賴于模型架構上的數(shù)據(jù)信噪比。不管怎樣,最好的參數(shù)設置依然可以在 hparams.py 文件中找到。
- 消息稱去年全球IT支出超過5萬億美元 數(shù)據(jù)中心系統(tǒng)支出大幅增加
- 2025年全球數(shù)據(jù)中心:數(shù)字基礎設施的演變
- 谷歌押注多模態(tài)AI,BigQuery湖倉一體是核心支柱
- 數(shù)字化轉型支出將飆升:到2027年將達到4萬億美元
- 量子與人工智能:數(shù)字化轉型的力量倍增器
- 華為OceanStor Dorado全閃存存儲榮獲CC認證存儲設備最高認證級別證書
- 2024年終盤點 | 華為攜手伙伴共筑鯤鵬生態(tài),openEuler與openGauss雙星閃耀
- 特朗普宣布200億美元投資計劃,在美國多地建設數(shù)據(jù)中心
- 工信部:“點、鏈、網、面”體系化推進算力網絡工作 持續(xù)提升算網綜合供給能力
- 2025年超融合基礎設施的4大趨勢
免責聲明:本網站內容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網站出現(xiàn)的信息,均僅供參考。本網站將盡力確保所提供信息的準確性及可靠性,但不保證有關資料的準確性及可靠性,讀者在使用前請進一步核實,并對任何自主決定的行為負責。本網站對有關資料所引致的錯誤、不確或遺漏,概不負任何法律責任。任何單位或個人認為本網站中的網頁或鏈接內容可能涉嫌侵犯其知識產權或存在不實內容時,應及時向本網站提出書面權利通知或不實情況說明,并提供身份證明、權屬證明及詳細侵權或不實情況證明。本網站在收到上述法律文件后,將會依法盡快聯(lián)系相關文章源頭核實,溝通刪除相關內容或斷開相關鏈接。