利用深度學習進行時序數據的異常檢測
本文要點
- 神經網絡是一種模擬生物學神經的機器學習模型,數據來源于輸入層并流經具有各種激活閾值的節點。
- 遞歸神經網絡是一種在輸入被理解之前保持其內部記憶的神經網絡,所以它們可以進行數據流中時間依賴的結構的學習。
機器學習早已在許多產品中發揮過威力了,我們日常就與很多打過交道,從像蘋果的Siri和谷歌的Now之類的“智能”助手,到像亞馬遜建議買新產品的推薦引擎,再到谷歌和 非死book 使用的排名系統,凡此種種,不一而足。最近,機器學習由于“深度學習”的進展闖入了公眾視野,這些進展包括 AlphaGo 擊敗了圍棋大師李世乭,以及圍繞圖像識別和機器翻譯方面驕人的新產品。
在本系列的文章中,我們將介紹在機器學習方面強大而又可以普遍應用的技術。這些不僅包括經常在現代商業都需要的更傳統的方法,還包括深度學習。在閱讀本系列文章之后,你應該就具備在各種你自己所屬的領域中進行具體機器學習實驗的必要能力了。
本篇文章是系列文章“機器學習簡介”其中的一部分,你可以通過RSS訂閱以接收通知。
用來解決像語音和圖像識別之類問題的深度神經網絡越來越高的精確度已經引起大家的關注,致力于深度學習和人工智能的研究也更為普遍了。但廣泛普及也帶來了沖突。本文介紹神經網絡,包括對前饋神經網絡和遞歸神經網絡的簡要說明,并闡述了如何構建一個檢測時間序列數據中異常現象的遞歸神經網絡。為使我們的討論更具體,我們將顯示如何用Deeplearning4j構建神經網絡,它是一個用于JVM的開源深度學習類庫。
什么是神經網絡?
人造神經網絡的最初設想是模擬生物學神經元的算法。然而,這是一個很泛泛的類比。被人造神經網絡借鑒的生物學神經元的功能包括節點之間的連接和針對每個神經元點亮的激活閾值(或觸發器)。
通過構建一個連接人造神經元的系統,我們發現系統可以被訓練去認識數據中更高層次的模式,并發揮有用的作用,比如遞歸、分類、聚類和預測。
僅比喻為生物神經元還遠遠不夠。人造神經網絡是一系列計算節點,在此數據表示為數字數組,這些數據由網絡的輸入層傳入,通過網絡所謂的隱藏層,直到在一個處理過程中生成這些數據相關的輸出或決策,下文將簡要描述這個處理過程。然后把該網絡產生的輸出與預期輸出做比較(例如應用于這些數據上的地表實況標簽),該網絡的推測和正確答案之間的差異用于逐漸修正網絡節點的激活閾值。隨著這個過程的重復,該網絡的輸出將與預期輸出重合。
擁有許多節點的整個神經網絡可以運行于一臺單獨的機器上。一定要注意,這個神經網絡不一定要在多臺機器的分布式系統中。節點,在此意味著“計算發生的地方”。
訓練過程
為構建一個神經網絡,你需要對訓練過程和網絡輸出如何形成有基本的理解。因為我們不想陷入到方程式里,所以簡要描述如下:
網絡的輸入節點接收一個數字數組(可能是一個稱之為張量的多維數組)表示輸入數據。例如,一張圖片的每個像素可能通過一個標量來表示,然后提供給一個節點。這些輸入數據通過系統或參數來傳遞,通過這些系數的乘法運算將放大或減弱這些輸入,這依賴于它學到的重要性,即該像素是否會影響到網絡關于整個輸入的決策。
最初,系數是隨機的;網絡創建出來時對于結構化數據一無所知。每個節點的激活函數決定了節點對一個輸入或一組輸入的輸出。所以節點點亮與否,取決于它所接收的刺激的強度(輸入和系數的返回值)是否超過了激活的閾值。
在一個所謂的致密或完全連接層,每個節點的輸出會傳遞到后續層的的所有節點。這后續會通過所有隱藏致密層,直到輸出層為止,即該輸入達成的決策的地方。在這個輸出層,該網絡關于輸入的決策是針對預期決策的評估(比如,這個圖片中的像素表示的是只貓還是只狗?)。通過比對網絡的猜測和包含在測試集中的實際答案評估出誤差,然后使用這些誤差更新網絡的系數,從而改變網絡為圖片中不同像素賦予的重要性的程度。目標是減少所形成的輸出與預期輸出之間的錯誤,正確地標識出來是狗還是貓。
因為深度學習是一個復雜的過程,它包括矩陣代數、衍生產品、或然率和密集的硬件利用率,如同被修改大型系數矩陣一般,所以不需要把所有復雜性都揭示給最終用戶。
然而,你應該知道一些有助于你理解神經網絡函數的基本參數。它們是激動函數、優化算法以及目標函數(也稱之為損失、成本或誤差函數)。
該激活函數決定一個信號是否應該發送到連接的節點以及發送的范圍。頻繁用到的激活僅是一個基本的階梯函數,如果它的輸入低于一些閾值則為0,高于這些閾值則為1。如此,具有階梯函數激活函數的節點要么向連接的節點發送0,要么發送1。優化算法決定網絡如何學習,更精確地說是檢測到誤差后如何修改權重。通常使用的優化算法是 隨機梯度下降 。最后,成本函數是與預期輸出相比的誤差的度量,是在對給定訓練樣本做決策時對神經網絡執行情況的估量。
像用于Python的 Keras 或用于JVM的 Deeplearning4j 之類的開源框架使神經網絡的構建可以很快上手。決定采用什么網絡架構經常涉及到把你的數據類型與已知已解決的問題進行匹配,然后調整已有的架構去適應你的使用場景。
神經網絡的類型及其應用
數十年來,神經網絡已經廣為人知并得到了廣泛地使用。但許多重要技術趨勢使最近的深度神經網絡效率得到大幅地提升。
隨著GPU對矩陣運算的提速,以及大型分布式計算框架的到來,計算能力得到了大幅的提升,這就為快速訓練神經網絡創造了條件,從而能在許多超參數組合上迅速迭代以尋找合適的架構。
大規模數據集正在形成,像ImageNet之類大規模高質量的標簽數據集已經創建出來了。一般來說,機器學習算法訓練的數據越多,則會越精確。
最后,我們在理解和構建神經網絡算法方面也增強了,這使神經網絡在計算機視覺、語音辨識、機器翻譯和許多其他機器感知和面向目標的任務的比賽中不斷刷新精確性的紀錄。
雖然神經網絡架構的領域非常大,但我們在此描述的是已經廣泛應用的主要的網絡類型。
前饋神經網絡
這是一類有一個輸入層、一個輸出層和一個或多個隱藏層的神經網絡。前饋神經網絡帶來好的泛逼近器(映射任何輸入到任何輸出的函數),常用于構建多用途的模型。
此類神經網絡可以用于分類和遞歸。例如,如果使用前饋網絡針對輸出層上的若干神經元進行分類,則和針對若干類別是一樣的。從概念上講,輸出神經元第一次決定的類別是網絡預測出來的。更精確地說,每個輸出神經元返回一個該記錄匹配該類的可能性,然后把可能性最高的類別選做模型的輸出分類。
多層感知器之類的前饋神經網絡的好處是易于使用,比其他類型網絡的復雜度要低,可以找到各種各樣的實例。
卷積神經網絡
卷積神經網絡與前饋神經網絡類似,至少在網絡上傳送數據的方式是一樣的。它們從形式上粗略模仿了虛擬的大腦皮質。 卷積神經 在一個底層圖像上移動幾個像放大鏡之類的濾波器。這些濾波器專注于圖像子集(碎片或貼片)的特征識別,然后在像場上的一系列貼片中重復這個過程。每個濾波器尋找可視化數據中的不同模式;例如,有的可能尋找的是水平線,有的可能尋找的是對角線,還有的可能尋找的是垂直線。這些線是已知的特征,濾波器在圖像上經過,他們構造特征圖譜定位每種線每次在圖像中出現的不同方位。圖像中不同的對象(小貓、波音747、轉動中的榨汁機)形成不同的特征圖譜,這些圖譜最終可用于圖像分類。在圖像和視頻識別領域已證明卷積網絡非常有用,因為聲音可以以聲譜圖的形式可視化表示出來,所以卷積網絡同樣可以廣泛應用于語音識別和機器轉錄的任務上。
卷積與前饋網絡在圖像處理方面的對比。兩種網絡類型都可以分析圖像,但它們的分析方式是不同的。因為卷積神經網絡是一步步通過圖像的重疊區域訓練學著識別每個區域的特征的,而前饋神經網絡是在整個圖像上訓練的。前饋神經網絡在特征總是處于特定位置或方向的圖像上進行訓練,如果特征出現在一個不常見的位置可能就識別不到了,而得到充分訓練的卷積神經網絡是可以做到的。
卷積神經網絡不但可用于諸如圖像、視頻、聲音和語音識別之類的任務,還可以用于做自動駕馭汽車。
本篇文章關注的是遞歸神經網絡,但卷積神經網絡已經在圖像識別方面做得非常好了,我們應該了解它們的功用。
遞歸神經網絡(RNN)
和前饋神經網絡不同,遞歸神經網絡的隱藏層節點維護一個內部狀態(一片內存),該網絡有新的輸入時會更新它。這些節點即可以基于當前輸入做決策,也可以根據之前的輸入做決策。遞歸神經網絡可以使用內部狀態去處理以任意序列輸入的相關數據,比如時間序列。
它們可以用于筆跡識別、語音識別、日志分析、欺詐檢測、網絡安全。
對于包含時間維度的數據集來說(比如網頁或服務器活動的日志、從硬件或醫療設備而來的傳感器數據;財務事務;或者通話記錄),遞歸神經網絡是最合適的。跟蹤跨許多時間步長數據內的依賴關系和相互關系需要你了解當前狀態和之前的一些狀態。盡管使用接收事件窗口的典型前饋神經網絡可能也能做到,但后續該窗口會隨時間發生變動,這一方法會把我們局限到由該窗口捕獲的依賴上,解決方案會不靈活。
隨時間的推移跟蹤長期依賴的一種更好的方法是,某種存儲有意義的事件的“記憶”,它可以使之后的事件可以在上下文中得以理解和分類。遞歸神經網絡之美在于,包含于它的隱藏層的這段“記憶”在非常長期的時間窗口上學習它自己身上的這些時間依賴特征的意義。
在下文中,我們將探討遞歸神經網絡的應用,既有字符產生,也有網絡異常檢測。跨許多時間步長檢測依賴特征的能力使遞歸神經網絡可用于時間序列數據中的異常檢測。
遞歸神經網絡的應用
盡管我們的示例是一個計算機網絡上的監控活動,但是用它來作為開始遞歸神經網絡討論的簡單用例還是很有幫助的。因特網有許多使用遞歸神經網絡生成文本的案例,一次一個字符,在接受一語料庫文本的訓練之后去預測之前給定信息的下一個字符是什么。
用于字符生成的遞歸神經網絡
遞歸神經網絡可被訓練根據一系列時間依賴事件去處理英語字符。該網絡將學習頻繁跟在一個字符之后的另一個字符(比如在“the”、“he”和“she”中e跟在“h”后),然后后續按此預測下一個字符,它將通過與實際英語文本對比訓練來降低誤差。
當提供一整套莎士比亞時,它就能生成感人的莎士比亞風格的輸出了, 例如 “為什么,Salisbury必須找到他的肉體和靈魂……”。當提供足夠多的Java代碼時,它生成的東西幾乎能夠編譯。
Java是一個有意思的例子,因為它的結構包括很多內嵌依賴。每個打開的括號(即“(”)最終都將被關閉(即“)”)。每個打開的大括號(即“{”)在該行之下都會有一個關閉的大括號(即“}”)。這些依賴的位置不是一個緊挨著一個的,許多事件會影響到其間的距離。不必告訴它這些依賴結構,遞歸神經網絡會去學習它們。
在異常檢查中,我們將要求神經網絡去學習數據中類似的、可能隱蔽或不明顯的模式。正如字符生成者充分理解數據結構去生成模仿字符一樣,用于異常檢測的遞歸神經網絡充分理解數據的結構以獲知什么看起來是正常的,而什么不是。
字符生成的例子有助于展示遞歸神經網絡具有在不同時間范圍之上學習時間依賴的能力。遞歸神經網絡可以將同樣的能力用于網絡活動日志中的異常檢查中。
應用到文本中,異常檢查可能要面對語法錯誤,因為我們所寫的內容是有語法結構的。同樣的,網絡行為也有結構。它遵循可被學習的可預測模式。受過正常網絡行為訓練的遞歸神經網絡會將網絡入侵感知出來,就像把無標點的句子作為異常一樣。
網絡異常檢測項目示例
假設我們想要檢測網絡異常,這些異常可能指向硬件故障、應用故障或入侵。
我們的模型將為我們揭示什么
遞歸神經網絡將在網絡活動日志的數字展現上進行訓練,將日志中的原生混合文本和數字數據轉化為特征向量。
通過提供大量的網絡活動日志(每行日志都有一個時間戳)給遞歸神經網絡,遞歸神經網絡將了解正常預期的網絡活動是什么樣的。當把來自于網絡的陌生活動提供給訓練過的網絡時,它就能夠區分這個活動是正常預期的,還是入侵的了。
訓練一個神經網絡去識別預期行為有一個得天獨厚的優勢,因為它擁有大量的異常數據,或者還不足以精確分類的所有異常行為。我們在自己擁有的正常數據上訓練網絡,以便它能提醒我們注意未來的非正常行為。而針對攻擊的訓練也是在充分的數據上訓練的。
說句題外話,被訓練的網絡不需要說明發生在特定時間的特定活動(它不知道星期天是特殊的日子),但它會注意到我們應注意到的這些比較明顯的時序模式,以及可能并不明顯的事件間的其他聯系。
我們將簡單介紹一下如何使用Deeplearning4j來處理這個問題,這是一個被廣泛采用的開源類庫,它適用于JVM上的深度學習。伴隨Deeplearning4j一起而來的還有許多工具,這些工具在整個模型開發過程中很有幫助:DataVec是輔助提取轉移加載(ETL)任務的一系列工具,用于為模型訓練準備數據。正如Sqoop有助于加載數據進Hadoop一樣,DataVec通過數據的清理、預處理、規格化和標準化從而幫助將數據加載進神經網絡。
新手入門
第一個場景包括典型的大數據任務和ETL:我們需要收集、遷移、存儲、準備、規格化和矢量化日志。時間步長的規模必須要確定下來。數據轉換可能需要很大的工作量,因為JSON日志、文本日志和具有不相干標簽模式的日志將必須被讀取并轉化為數組。DataVec可以幫助轉換和規格化這些數據。在開發機器學習模型時作為一種常態,這些數據必須分解為訓練集和檢驗(或評估)集。
網絡的訓練
網絡的最初訓練將在這些分解輸入數據的訓練上運行。
針對第一次訓練的運行,你可能需要調整一些超參數(“超參數”是管理模型的“配置”以及它如何接受訓練的參數)以便模型切實從數據中學習,并在合理的時間里這么做。我們將探討以下幾個超參數。在模型訓練的同時,你應該尋求穩定地降低誤差。
要注意一個風險,那就是神經網絡模型將“過度擬合”數據。在過度擬合的數據集上訓練過的模型將在該訓練數據上有良好的表現,但對于之前未遇到過的數據就無法做出精確的判斷了。按機器學習的說法,這不是“歸納”。Deeplearning4J提供了正規化工具和“提早中止”,從而有助于避免訓練過程中的過程擬合。
神經網絡的訓練將占用大部分時間和硬件。在GPU上執行訓練將大幅減少訓練的時間,特別是針對于圖像識別來說,但額外的硬件會帶來額外的成本,所以讓你的深度學習架構盡可能高效地使用硬件尤為重要。類似于Azure和亞馬遜之類的云服務提供了可以訪問基于GPU實例的功能,神經網絡可以在異構集群上接受訓練,這種集群中不僅可以有專用的機器,還可以有商業服務器。
模型的形成
Deeplearning4J提供了一個ModelSerializer類去保存接受訓練的模型。一個接受訓練的模型可以被保存起來,之后被將來的訓練使用(比如,部署到生產環境)或更新。
當在生產環境執行網絡異常檢測時,日志文件需要被序列化為同一格式,模型在其上接受訓練,然后基于神經網絡的輸出,你會得到報告,看當前活動是否在正常預期的網絡行為之內。
示例代碼
遞歸神經網絡的配置可能看起來是這樣的:
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
.seed(123)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT).iterations(1)
.weightInit(WeightInit.XAVIER)
.updater(Updater.NESTEROVS).momentum(0.9)
.learningRate(0.005)
.gradientNormalization(GradientNormalization.ClipElementWiseAbsoluteValue)
.gradientNormalizationThreshold(0.5)
.list()
.layer(0, new GravesLSTM.Builder().activation("tanh").nIn(1).nOut(10).build())
.layer(1, new RnnOutputLayer.Builder(LossFunctions.LossFunction.MCXENT)
.activation("softmax").nIn(10).nOut(numLabelClasses).build())
.pretrain(false).backprop(true).build();
MultiLayerNetwork net = new MultiLayerNetwork(conf);
net.init();</code></pre>
讓我們來說明一下幾行重要的代碼:
.seed(123)
為獲得可重復的結果,設置隨機種子去初始化神經網絡的權重。典型情況下,會隨機初始化系數,為了在調整其他超參數時獲取一致的結果,我們需要設置一個種子,使我們能夠一遍一遍調整和校驗時可以使用同樣的隨機權重。
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT).iterations(1)
選擇使用哪個優化算法(在本例中,選擇的是隨機梯度下降)去決定如何修改權重以改進誤差得分。你可能不希望去改它。
.learningRate(0.005)
使用隨機梯度下降時,誤差梯度(即系統變化與網絡誤差變化的關系)被計算出來,然后權重沿此梯度移動力圖將誤差調整至最小。隨機梯度下降為我們指定了減少誤差的方向,而學習率決定在這個方向上的步長有多大。如果學習率過高,可能誤差最小化就過了頭;如果它太低,那么訓練將永無休止。這是一個你可能需要去調整的超參數。
來自:http://www.infoq.com/cn/articles/deep-learning-time-series-anomaly-detection