劇透警告:其實 Morse 電碼並不須要破解。它頗有用,由於能夠用最少的設備來發送消息。我之因此說它不須要破解,是由於這種代碼是衆所周知的,點和破折號的組合並非什麼祕密。可是從理論上講,它是一種替代密碼(substitution cipher):每一個字母和每一個數字都是使用點和破折號來表示,以下圖所示:python
AI 前線:Morse 電碼是一種時通時斷的信號代碼,經過不一樣的排列順序來表達不一樣的英文字母、數字和標點符號。它發明於 1837 年。Morse 電碼是一種早期的數字化通訊形式,可是它不一樣於現代只使用零和一兩種狀態的二進制代碼,它的代碼包括五種: 點、劃、點和劃之間的停頓、每一個詞之間中等的停頓以及句子之間長的停頓。git
讓咱們先不要懷疑,假設咱們收到了 Morse 電碼的消息,但咱們不知道如何解讀。假設咱們還有一些代碼示例和它們對應的單詞。如今,咱們能夠推測它是一種替代密碼,而後咱們能夠最終計算出每一個字母的代碼,從而解碼消息。github
或者,咱們能夠構建一個 encoder-decoder 模型 來猜想(幾乎)全部的單詞!做爲受虐狂,咱們固然會選擇後者。照這樣說,讓咱們猛拍一下堂·吉訶德的戰馬 Rocinante,開始大戰風車的征程。算法
AI 前線:Rocinante,西班牙語,駑騂可貴 [音譯],《堂·吉訶德》中堂·吉訶德所騎的馬的名字。數組
這裏有個手頭問題: 咱們有幾個編碼序列及對應的可理解的例子。使用這些例子,咱們必須學習一些模式,並使用這些信息來預測新的編碼標記(單詞)可能會是什麼。與咱們預測數值結果的常見迴歸問題不一樣,咱們手頭有一些序列到序列(sequence-to-sequence)的學習問題,在數據中有時間結構。這是遞歸神經網絡(RNN)可能有用的一個即時提示(它用於語音和語音數據的 RNN,以及用於圖像數據的 CNN 和用於圖像字母的 RNN 組合)。粗略地說,這屬於一類問題:也包含了機器翻譯的問題;這個模型的結構在這裏起到了啓發的做用。有關此主題的更多信息請參閱 [1]。限於篇幅咱們不會贅述 RNN 的理論,但對於這個主題的簡要介紹請參考文獻 [2] 的一系列文章。安全
若是你想知道這個問題是否能夠用不一樣的方法來解決,答案是:YES。馬爾可夫鏈蒙特卡羅方法(Markov Chain Monte Carlo)會獲得相似的結果。在這種狀況下,咱們將會遵循優秀論文 [3] 中第一個例子所提到的過程。微信
AI 前線:馬爾可夫鏈蒙特卡羅算法(簡寫爲 MCMC)的核心思想是找到某個狀態空間的馬爾可夫鏈,使得該馬爾可夫鏈的穩定分佈就是咱們的目標分佈 p(x)。這樣咱們在該狀態空間進行隨機遊走的時候,每一個狀態 x 的停留時間正比於目標機率 p(x)。在用 MCMC 進行抽樣的時候,咱們首先引進一個容易抽樣的參考分佈 q(x),在每步抽樣的過程當中從 q(x) 裏面獲得一個候選樣本 y,而後按照必定的原則決定是否接受該樣本,該原則的肯定就是要保證咱們獲得的本來剛好服從 p(x) 分佈。網絡
馬爾可夫鏈,因安德烈·馬爾可夫(A.A.Markov,1856-1922)得名,是指數學中具備馬爾可夫性質的離散事件隨機過程。該過程當中,在給定當前知識或信息的狀況下,過去(即當前之前的歷史狀態)對於預測未來(即當前之後的將來狀態)是無關的。函數
在馬爾可夫鏈的每一步,系統根據機率分佈,能夠從一個狀態變到另外一個狀態,也能夠保持當前狀態。狀態的改變叫作轉移,與不一樣的狀態改變相關的機率叫作轉移機率。隨機漫步就是馬爾可夫鏈的例子。隨機漫步中每一步的狀態是在圖形中的點,每一步能夠移動到任何一個相鄰的點,在這裏移動到每個點的機率都是相同的(不管以前漫步路徑是如何的)。post
粗略地說,咱們想從 (x_1,...,x_n) 輸入序列預測輸出序列 (y_1,...,y_m),這就涉及了條件機率(conditional probability)的學習。
AI 前線:條件機率是指事件 A 在另一個事件 B 已經發生條件下的發生機率。條件機率表示爲:P(A|B),讀做「在 B 條件下 A 的機率」。條件機率能夠用決策樹進行計算。條件機率的謬論是假設 P(A|B) 大體等於 P(B|A)。
這裏的主要障礙是,從可變尺寸的輸入來預測可變尺寸的輸出。在元級這一層次上,是經過將兩個 RNN 組合在一塊兒來解決的,其中,第一個 RNN 將可變尺寸的輸入映射到固定尺寸的輸出,另外一個 RNN 接受固定尺寸輸入並返回可變尺寸的輸出。固定尺寸的中間向量,成爲上下文矢量(context vector),它將信息從輸入序列中封裝起來,每次輸入一個字符。產生上下文矢量的機制是使 RNN 對於捕獲時間結構有用:上下文矢量是最終的 timestep 或它的某些函數以後的隱藏狀態。上述條件機率使用鏈式法則(chain rule) 計算的。
AI 前線:鏈式法則是微積分中的求導法則,用於求一個複合函數的導數,是在微積分的求導運算中一種經常使用的方法。複合函數的導數將是構成複合這有限個函數在相應點的 導數的乘積,就像鎖鏈同樣一環套一環,故稱鏈式法則。可見搞人工智能,學好數學很是重要。
其中,h 是上下文矢量。最後,可使用 softmax 函數來計算上述方程右邊的條件機率,該函數將字符 y_{i-1},...,y_1 的獨熱編碼(one-hot encoded)矢量做爲輸入,在第二 RNN 中的遞歸層(recurrent layer)的輸出和上下文矢量。這裏使用的特定類型的 RNN 是 LSTM,有效克服了 Simple-RNN 的侷限性,Simple-RNN 受到漸變問題的影響,並可以更好地捕獲遠程依賴關係。
AI 前線:Simple-RNN 是最簡單的循環神經網絡,它是 LSTM 的基礎。Simple-RNN 與 BP 同樣都有前饋層與反饋層。可是 Simple-RNN 引入了基於時間 (狀態) 的循環機制。
咱們將引入一個特殊的字符(11)來表示每一個字母的代碼之間的空格。例如,SOS 的代碼將表示爲:...11---*...(替換...---...)。咱們這樣作是爲了確保與給定代碼相對應的單詞是惟一的。接下來,咱們將使用已編譯數據集(words_alpha)中的英文單詞,而不是用隨機生成的字母集做爲咱們的數據。爲了得到數據的感受,參看下圖所示的單詞長度的直方圖。從直方圖上能夠看出,長度超過 5 個字母的單詞要比短的單詞多。
對包含編碼單詞的數據進行訓練的網絡,通常會預測長的單詞。請記住,網絡並不會計算出生成數據的「公式」,也就是說,它並不會學習圖 1 中的圖表。
咱們開始數據準備工做,構建一個函數,將所輸入的英文單詞編碼爲它的 Morse 電碼並輸出。
爲了說明的目的,咱們將從給定的固定長度的單詞生成訓練和驗證數據。在這裏,咱們將這個長度固定爲 9,由於長度爲 9 的字數足夠大(參見上述直方圖)。注意,此舉將意味着來自網絡的輸出單詞的長度將是固定的,可是輸入的 Morse 電碼並不必定都是相同的長度。假定咱們知道每一個字母的編碼長度最長是 4(其實咱們不用這個特定的假設,能夠選擇的長度最長的 Morse 電碼 max_length_x 來訓練數據。)所以,若是單詞的長度爲 n ,那麼與其對應的 Morse 電碼的長度最多爲 4n+(n-1),其中 n-1 對應的是 11s 的數量。咱們用左邊的空格填充代碼,使它們的長度相同,這意味着咱們輸入字符的詞彙表是 {‘.’, ‘—’, ‘*’, ‘ ’}。通常而言,咱們讓輸出的字符詞彙表是全部字母和空格的特殊字符。回到關於網絡猜想長單詞的評論,咱們的意思是,因爲長單詞的數量會形成不平衡,所以網絡將會傾向於猜想更少的空格。在下面的代碼片斷中,output_list 將包含英文單詞,input_list 將包含填充的 Morse 電碼。
如今,咱們構建輸入中字符的一個獨熱編碼矢量,使輸入數據適合神經網絡。爲此,咱們構建了一個類對象(相似於 Keras 文檔中的例子),它將有助於編碼和解碼,並將 Morse 電碼和英語單詞解碼。咱們將類分配給具備適當字符集的對象。
AI 前線:獨熱編碼即 One-Hot 編碼,又稱一位有效編碼,其方法是使用 N 位狀態寄存器來對 N 個狀態進行編碼,每一個狀態都有它獨立的寄存器位,而且在任意時候,其中只有一位有效。
將數據拆分,生成一個訓練集 x_train,從整個數據集 x,y 的四分之一中提取出 y_train,咱們將保留剩下的四分之三做爲驗證集 x_val、y_val。注意,咱們最好將訓練集的一部分做爲驗證集,其他的做爲測試集,但考慮咱們是隨便弄的設置,咱們對模型構建更感興趣,而非參數調優。如今,咱們已經準備好了訓練和測試(驗證)數據,而且能夠繼續對網絡進行修改。
構建神經網絡的最簡單方法是使用 Keras 模型和順序 API。因爲咱們不須要 TensorFlow 的所有功能和靈活性,因此咱們選擇了 Keras。
咱們所選的模型拓撲結合了簡單的 RNN 的強大變體,稱爲長短時間記憶(Long Short Term Memory,LSTM)網絡。
AI 前線:長短時間記憶網絡是一種時間遞歸神經網絡,適合於處理和預測時間序列中間隔和延遲相對較長的重要事件。基於長短時間記憶網絡的系統能夠實現機器翻譯、視頻分析、文檔摘要、語音識別、圖像識別、手寫識別、控制聊天機器人、合成音樂等任務。
第一個 LSTM 用做編碼器,接受一個可變長度的輸入序列,每次一個字符,並將其轉換爲固定長度的內部潛在表示。另外一個 LSTM 則做爲解碼器,將潛在的表示做爲輸入,並將其輸出傳遞到一個密集層,該層使用 softmax 函數,每次預測一個字符。
該模型的編碼器和解碼器組件可能具備多層 LSTM,一般並不清楚哪一種拓撲最適合使用。通常來講,對機器翻譯而言,深層網絡工做得更好。根據經驗法則,咱們指望多層可以學習更高層次的時間表示,所以當數據具有了一些層次結構時,咱們就會使用它。對咱們來講,每層有一層就足矣。
該模型使用 Sequential() 構建,而且每次只添加一個層。第一個 LSTM 層將 3D 張量做爲輸入,並要求用戶指定輸入維度。這能夠用代碼中指定的 input_shape 簡單地完成,其中第一個組件表示時間步驟的數量,第二個組件表示特徵的數量。對咱們來講,特徵的數量就是輸入序列的詞彙表中元素的數量,也就是 4,由於咱們有「.」、「-」、「*」和空白字符「」。因爲咱們每次只提供一個獨熱編碼矢量,所以時間步驟的數量就是 max_len_x。咱們還將指定層中的內存單元(或塊)的數量(此處用 latent_dim 參數表示,咱們使用 256),這是潛在表示的維度。請注意,咱們但願將 LSTM 的最終隱藏狀態做爲潛在表示返回,這包含了來自全部時間步驟的信息,即所有輸入序列。若是咱們使用 return_sequences = true 選項,那麼將獲得每一個時間步驟的隱藏狀態的輸出,但這隻包含到該步驟的序列信息。
這就獲得了簡單的編碼器模型。咱們將構建一個相似的層做爲解碼器。但上面的代碼片斷的輸出是個 2D 數組。咱們經過使用方便的 RepeatVector 層重複輸出時間數量 max_len_y,將其轉換爲 3D 張量,並做爲下一個 LSTM 層(解碼器)。如今,咱們在這個 LSTM 中使用 return_sequences = True 選項來輸出隱藏狀態序列,咱們須要使用這些信息進行預測。爲此,咱們使用一個 TimeDistibuted 密集層,它輸出一個長度爲 max_len_y 的矢量,咱們使用 softmax 激活函數來選擇最有可能的字母。爲了快速瞭解 TimeDistributed 層的目的,請參閱 Jason Brownlee 撰寫的博文:How to Use the TimeDistributed Layer for Long Short-Term Memory Networks in Python。
https://machinelearningmastery.com/timedistributed-layer-for-long-short-term-memory-networks-in-python/
如下是對網絡和各類輸入、輸出維度的快速摘要。
咱們將模型擬合到數據中,在集合 x_train、y_train 上進行訓練,並使用 x_val 和 y_val 來查看咱們的工做狀況。須要設置的最後一組參數是輪數(epochs)的數量和批大小。批大小是在梯度降低算法中經過網絡傳遞的訓練集的大小,而後對網絡中的權重進行更新。一般批大小就是計算機內存可處理的最大值。一個輪數是經過這些批次的訓練數據的全面訓練一次。此處,咱們設置了 1024 的批大小,使用了 120 個輪數,在下圖便可看到,在大約 100 個輪數以後,精度並無明顯的增長。通常來講,看哪一個參數起做用須要反覆試驗才知道。如今咱們用 fit() 方法來擬合模型。
最後,從上面的圖表能夠看出,在驗證集上咱們能夠獲得大約 93% 的準確率,結果彷佛並不壞。固然,若是咱們增大訓練數據的規模,還能夠作得更好。下面是對一組隨機選擇的單詞的預測。
在左邊輸入代碼,中間輸入相應的單詞,右邊輸入預測。若是預測正確,那麼該單詞爲綠色,不然爲紅色。
正如你所看到的,錯誤的預測也不算太壞。咱們必須提醒本身,破譯密碼並無破解代碼,也就是說,弄清楚每一個字母表明什麼。事實上,咱們能夠輸入字母的代碼,並查看網絡預測的單個字母的代碼,以下所示,咱們離目標還很遠!
做爲 encoder-decoder 模型的另外一個例子,你能夠嘗試使用凱撒加密(Caesar cipher)或者其餘代碼來查看這種方法的有效性如何。
AI 前線:凱撒加密,或稱愷撒加密、愷撒變換、變換加密,是一種最簡單且最廣爲人知的加密技術。它是一種替換加密的技術,明文中的全部字母都在字母表上向後(或向前)按照一個固定數目進行偏移後被替換成密文。例,當偏移量是 3 的時候,全部的字母 A 將被替換成 D,B 變成 E,以此類推。這個加密方法是以凱撒的名字命名的,當年凱撒曾用此方法與其將軍們進行聯繫。凱撒密碼一般被做爲其餘更復雜的加密方法中的一個步驟。凱撒密碼還在現代的 ROT13 系統中被應用。可是和全部的利用字母表進行替換的加密技術同樣,凱撒密碼很是容易被破解,並且在實際應用中也沒法保證通訊安全。
References:
[1] Sequence to Sequence Learningwith Neural Networks
http://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf
[2] Understanding LSTM Networks
http://colah.github.io/posts/2015-08-Understanding-LSTMs/
[3] THE MARKOV CHAIN MONTE CARLO REVOLUTION
http://www.ams.org/journals/bull/2009-46-02/S0273-0979-08-01238-X/S0273-0979-08-01238-X.pdf
更多幹貨內容,可關注AI前線,ID:ai-front,後臺回覆「AI」、「TF」、「大數據」可得到《AI前線》系列PDF迷你書和技能圖譜。