上一篇我們提到了用來處理智能合約漏洞可以靠能夠發掘文章脈絡的RNN來進行訓練,有興趣的人可以先去看看,而此篇文章我們將介紹機器學習經典的CNN分類模型,以及如何讓文章順利轉化為數據以訓練模型。
CNN卷積神經網路(Convolutional neural network)一直都是深度學習最主流的一種類神經網路。它被用來作為影像辨識的模型已經行之有年。最初,影像辨識的方法因為將影像作為向量輸入而缺少了「影像數據的相對位置」這個重要的資訊,
而科學家們在研究貓的大腦皮層得到了靈感,在視覺化的資訊感受上能夠更有效的進行反饋,這造就CNN的「卷積」,它能夠更有效地處理影像這種初始資料格式形如矩陣一般的輸入方式。
CNN是甚麼
那CNN到底是甚麼呢? 卷積神經網路(CNN)是一種用於影像處理和分類的神經網路。它包含卷積層、池化層和全連接層。卷積層可以將影像分成多個小區塊,每個小區塊都是一個filter或卷積核,將這些filter應用於影像上,標記出哪些區域與filter相似。通常使用池化層來縮小卷積層輸出的數據量,接著使用激活函數(如ReLU)來加入非線性性質,最後使用全連接層進行分類。
卷積層(convolution layer):
卷積層是上一段提到能夠處理影像形如矩陣輸入的地方,輸入之後他想瞭解在這個分類case裡有甚麼是重要特徵(feature),所以他將影像分成了數個小區塊(通常是3x3 pixels),每一個小區塊都是一種filter(或稱為卷積核,kernel),藉由很多個filter有序地掃過影像的每一個地方,標記出哪一個地方跟掃過的這個filter很像,並在隨後權重更新的過程中,加重對分類比較重要的filter的權重當作特徵,然後就能夠知道這些特徵出現在影像的哪裡。
一個卷積層的範例: 神經網路會先行產生許多個filter,它是來自局部的影像資料。卷積層幫助神經網路評價影像資料的每一個地方跟該filter的相似度。在經過後續全連階層的權重更新後,可以幫助我們回推重要的filter(特徵)出現在影像資料的哪裡?
這個過程類似玩拼圖的時候,會把拼圖塊在整個拼圖面上一個一個有序地去找剛好能塞進去的地方,只不過在卷積層不同的是,他一個一個對照的區域會有部分重疊,然後他會對每一個對照的區域進行評分,通常和filter完全一樣的會給1,完全相反的會給-1,完全看不出關係的會給0,是不是很有趣呢?
就像玩拼圖一樣,卷積神經網路檢查不同的filter在影像資料上的相似程度。並透過滾動方式有序地游移在影像資料的每個角落。
池化層(pooling layer):
想想我們剛用了數個小區塊來對影像進行評分,有幾個filter就要評分幾次,所以在經過了卷積層之後就會產生很大量的數據,所以接下來通常會使用池化層來縮小數據量,以避免超出硬體設備的運算能力,不過如果你的硬體設備可以的話,其實也不必用到池化XDD
池化的方法是選取一個小範圍,就像卷積時我們也選的一個小範圍,這次不重複的依序將各個範圍裏代表的數字挑出來,例如2x2的範圍裡如果最大的數字是1就選1出來,以此類推。也可以設定選最小的,或是選平均的。這是一個不用學習的機械化過程,目的只是縮小數據量而已。
通過池化層,影像資料會被"縮小",留下比較重要的資訊。
激活函數(activation function):
接著不管你有沒有經過池化,接下來需要經過激活函數,他可以使神經網路得到非線性的性質,在CNN,通常使用ReLU(rectified linear unit)。
全連接層(fully connected layer):
最後進入全連接層,這裡將原本矩陣型的影像,變成向量型的,這個過程叫做flattening,向量型的目的是為了讓傳統的分類器能夠銜接上來進行特徵權重的更新,而最後常利用softmax函數進行化整為機率分布來進一步分類。
CNN整體架構的一個範例: 影像原始資料透過適當地轉換後送入卷積層,爾後經過數次的卷積-池化-激活,最後連接全連接層並進行分類決策。
為什麼要用CNN來檢視合約
卷積神經網路最獨特的地方就是它因為有卷積層,因此輸入的資料可以比別人多一個維度,也就是說初始資料比較不會因為資料處理而失真。另外,卷積搭配池化和激活函數可以有效的降低訓練運算上的困難,使用者也可以依造自己的硬體設備去彈性的調整神經網路的架構。最後,卷積神經網路是許多人正在研究的主題,有許多應用在不同情境下的變體,因此可以在網路上找到豐富的資源來進行資料訓練。
該怎麼結合CNN跟自然語言處理
現在問題來了,上次我們講到
把智能合約當作文章來輸入RNN,那到底智能合約要怎麼被輸入CNN跟RNN呢?這裡就要用到word embedding的方法。
word embedding是甚麼呢?它是用來將文章轉化為數據的方法,實際上就是將文章內的文字、單詞、片語乃自一段完整句子的語法、語義,轉化成數學向量的方式,其中方法有很多種,Birunda跟Devi(註1)將word embedding分成三大類: traditional word embedding、static word embedding 和 contextualized word embedding。
三大word embedding類型,並舉出幾種常見的embedding方法。值得一提的是三種類型由簡單的traditional word embedding到較複雜的static 、contextualized word embedding循序演進而成的。
traditional word embedding
講到traditional word embedding,就不得不說獨熱編碼(On-Hot Encoding)的概念,traditional word embedding 常使用獨熱編碼的方式來表示單詞。獨熱編碼是一個有幾個單詞就有幾個維度的向量,而每個單詞都映射到特定維度,而這個單詞的表示就會是在該特定維度的有值(1),其它維度沒有值(0),舉個例子,如果有一個分類變量“顏色”,它有三個取值:“紅色”、“綠色”和“藍色”。將“顏色”變量轉換為one-hot編碼時,可以創建一個長度為3的二進制向量。對於每個顏色,向量的對應位置都是1,其它位置都是0。例如,“紅色”的one-hot編碼是[1, 0, 0],“綠色”的one-hot編碼是[0, 1, 0],“藍色”的one-hot編碼是[0, 0, 1]。但這種表示法很沒有效率,在有大量單詞的情況下維度也會很大,且數據中沒有值的(0)的地方就會很多,當一個個詞向量排在一起成為一個句子的時候,也就是成為一個矩陣的時候會很稀疏。
獨熱編碼出現之後有一些延伸的模型,當我們考慮單詞出現在所有資料集(data set)中的次數時就會得到詞袋模型(bag-of-words model),它跟one-hot一樣不考慮單詞之間的順序,只關注每個單詞的出現次數(或存在/不存在)。當你考慮不同篇文章中每篇文章的單詞出現的頻率又不一樣的時候就可以用count vector matrix表示。TF-IDF是count vector matrix的進階版,它發現有些單詞在整個資料集中出現頻率較低但在某篇文章中出現頻率很高,所以以一種加權方式來表示這個問題。而共現矩陣(co-occurrence matrix)則使用該單詞前後出現的單詞出現的次數來給出詞向量。
count vector matrix的一個範例,row描述了不同的單詞,而column是資料集中不同的文件。表格內的數字指的就是該單詞在該文件出現的次數。
static word embedding
static word embedding是在traditional word embedding的基礎上推廣,最著名的是由Google團隊研究出來的word2Vec,word2Vec會使用單詞的上下文句子作為輸入,從而輸出該單詞的向量表示,它是由兩個小的神經網路構成: continuous bag-of-words (CBOW) 、skip-gram。這兩個神經網路分別有它們的作用,CBOW用輸入的上下文來預測單詞向量,而skip-gram則利用預測的詞向量反推可能的上下文,這樣子一來一往就可以利用反推出來的上下文對照原本的上下文進行修正,從而給出更加精確的詞向量。
word2Vec的單詞向量由詞袋模型給定;而FB團隊改進了word2Vec得到Fast-text,其單詞向量由n-gram給定,n-gram是由n個相連的字符所組成的序列(n>1),所以它會多考慮了字符結構對詞義的影響。
那Fast test相較於word2Vec能夠更體現單詞內字符之間的相對位置關係,並能處理未知詞彙(out-of-vocabulary, OOV),不過相對而言訓練速度就比word2Vec慢。
而GloVe( global vectors for word representation)則是使用共現矩陣再進行降維,在表現上跟word2Vec差不多,會生成與word2Vec 相似的詞向量。
contextualized word embedding
contextualized word embedding較經典的方法有ELMo跟BERT,它們跟static word embedding不同的地方是多考慮了目標單詞向量與上下文之間的關係。舉例來說: “小明明天要去泡湯”跟”小明明天的旅遊計畫泡湯了”中的泡湯是具有不同意思的雙關語,而static word embedding會將兩種泡湯當作同一個東西,它會整理資料集中所有有包括泡湯的句子來產生同一個泡湯詞向量,而contextualized word embedding則能夠依據上下文區分出“泡溫泉的泡湯”跟“計劃失敗的泡湯”,並給它們各自不同的詞向量。
為了理解上下文的脈絡,ELMo模型引入了一個雙向的 LSTM模型,利用這種RNN架構去從上下文推敲單詞所想表達出來的語意。而BERT則是基於Transformer模型的雙向編碼器,能夠更好的捕捉較遠文句之間的關係。所以ELMo透過上下文的語意變化較能認知雙關語的問題,而BERT透過"先掩蔽部分語言再來進行預測"的過程,來學習上下文相對位置的依賴關係,能更好地理解語句層次的關聯性。
contextualized word embedding需要預先去學習大量的資料(文本),這也是它和先前的word embedding方法不同的一個地方。透過大量學習,產生更能反映真實語義的詞向量。
當CNN導入word embedding
Word embedding讓我們有能力將文句、文章、程式碼這種初始資料,對其中的單詞轉化成一個一個詞向量,那單詞聚集起來之後就變成一個文章矩陣,那這樣不就可以用CNN進行漏洞辨識了嗎?當然這樣類似的方法CNN也用於語音分析、情感分析上面。簡而言之,我們將文章初始資料經過word embedding的資料處理方法後,能夠符合CNN的資料輸入格式,以利分析。
接下來呢?
我們都會感到好奇,AI是怎麼認識我們人類所說的語言,科學家想方設法盡可能地將文句所想表達的意思轉換成數據。最初從簡單的單詞開始下手,接下來思考單詞的變體、單詞的出現的頻率、單詞對應上下文之間的脈絡,語法與語義的表達,乃自整個文章的脈絡、框架。我們將這些表達輸入分類模型或是生成模型,分類模型告訴我們這些表達所含有的問題或是漏洞,或是告訴我們這些表達所含有的情感;生成模型進一步描述這些表達如何描述得更圓滿、或是去得到這些表達的深層訴求。這些都是當今機器學習所想要完成的任務,期待它能夠更好的運用在智能合約的漏洞檢測上。而如何有效偵測資料量很少的漏洞案例或是尚未發現的漏洞案例正是我們接下來要挑戰的,這些需要你我的幫助與反饋。希望未來區塊鏈有你有我、和AI會更好~
-----------------------------------------------------------------------------
作者阿原目前從事區塊鏈資料分析工作,對區塊鏈的經濟架構、事件發展有很大的興趣,並希望能將相關的區塊鏈知識分析並且統整給大家。如果喜歡我的文章,或是想獲得更多區塊鏈大小事,歡迎關注
我的vocus帳號!
另外,我已經加入由
趨勢科技防詐達人所成立的方格子專題-《區塊鏈生存守則》,在那裡我會跟其他優質的創作者一起帶大家深入瞭解區塊鏈,並隨時向大家更新區塊鏈資安事件。
參考資料:
A Review on Word Embedding Techniques for Text Classification: DOI:10.1007/978-981-15-9651-3_23(註1)