使用 RNN 求解基本數學方程 [附編碼示例]

已發表: 2020-12-07

如果生活給了你RNN,做一個計算器

循環神經網絡是經典的人工神經網絡之一,其中節點之間的連接形成順序有向圖。 RNN 因其用於處理可變長度序列的內部狀態存儲器而以語音識別、手寫識別等應用而聞名。

RNN 進一步分為兩種類型。 第一個是有限脈衝,其神經網絡採用有向無環圖的形式,其中一個節點可以與一個或多個在網絡中沒有可見循環的領先節點連接。 另一種是無限脈衝,其神經網絡採用有向循環圖的形式,不能展開為前饋神經網絡。

目錄

我們該怎麼辦?

讓我們建立一個模型來預測算術表達式的輸出。 例如,如果我輸入“11+88”,那麼模型應該將序列中的下一個單詞預測為“99”。 輸入和輸出是一個字符序列,因為 RNN 處理的是順序數據。

與數據集收集相比,現在設計模型的架構看起來像是一項簡單的任務。 生成數據或收集數據集是一項艱鉅的任務,因為數據飢餓 AI 模型需要大量數據才能達到可接受的準確性。

所以這個模型可以通過6個基本步驟來實現:

  1. 生成數據
  2. 建立模型
  3. 向量化和去向量化數據
  4. 製作數據集
  5. 訓練模型
  6. 測試模型

在我們深入實施模型之前,讓我們導入所有必需的庫。

numpy導入np

將張量導入tf

tensorflow.keras.models導入順序

tensorflow.keras.layers導入Dense、Dropout、SimpleRNN、RepeatVector、TimeDistributed

tensorflow.keras.callbacks導入EarlyStopping,LambdaCallback

termcolor導入有色

1. 生成數據

讓我們定義一個 char 字符串,其中包含編寫基本算術方程所需的所有字符。 因此,字符串由 0-9 的所有字符和所有算術運算符組成,例如 /、*、+、-、.(十進制)。

我們不能直接將數值數據輸入到我們的模型中,我們需要以張量的形式傳遞數據。 將數據中的字符串轉換為 one-hot 編碼向量將為我們提供優化的模型性能。 one-hot 編碼向量是一個長度與我們的 char 字符串長度相同的數組,每個 one-hot 向量僅在每個字符串中存在的相應字符索引處具有一個。

例如,假設我們的字符串是 '0123456789',如果我們想編碼一個像 '12' 這樣的字符串,那麼 one-hot 向量將是 [ [0,1,0,0,0,0,0,0 ,0,0],[0,0,1,0,0,0,0,0,0,0] ]。 為此,我們需要創建兩個字典,其中一個索引作為鍵,字符作為值,另一個作為反之亦然。

char_string = ' 0123456789/*+-. '

num_chars = len (char_string)

character_to_index = dict ((c, i) for i, c in enumerate (char_string))

index_to_character = dict ((i, c) for i, c in enumerate (char_string))

現在讓我們編寫一個函數,該函數返回一個隨機算術方程以及該方程的結果。

def除法(n,d):

如果d != 0返回n / d否則0

定義數據生成():

random1 = np.random.randint(低= 0 ,高= 100

random2 = np.random.randint(low = 0 ,high = 100 )

op = np.random.randint(低= 0 ,高= 4

如果op == 1

arith = str (random1) + ' + ' + str (random2)

res = str (random1 + random2)

elif op == 1

arith = str (random1) + ' ' + str (random2)

res = str (random1 random2)

elif op == 2

arith = str (random1) + ' * ' + str (random2)

res = str (random1 * random2)

否則

arith = str (random1) + ' / ' + str (random2)

res = str ( round (division(random1, random2), 2 ))

返回arith, res

另請閱讀:有趣的神經網絡項目想法

2. 建立模型

該模型將有一個編碼器和一個解碼器。 編碼器是一個簡單的 RNN 模型,輸入形狀為 (None,num_chars) 和 128 個隱藏單元,我們選擇隱藏單元為 32,64,128 等的原因是因為 CPU 或 GPU 以隱藏單元為冪的性能更好2.

我們的編碼器將是一個完全連接的網絡,這些網絡的輸出將反饋到網絡中,這就是 RNN 的工作方式。 RNN 層默認使用“tanh”激活,我們不會更改,因為它最適合編碼器。 該層的輸出將是單個向量,為了獲得整個輸出的單個向量,我們將使用帶有所需次數的 RepeatVector() 層作為參數。

現在輸出向量將具有給定輸入的本質,並且該向量將被饋送到解碼器。

解碼器由一個簡單的 RNN 層組成,這將生成輸出序列,因為我們需要 RNN 層返回預測序列,我們將把“return_sequences”標記為 True。 通過將“return_sequences”指定為 True,RNN 層將返回每個時間步的預測序列(多對多 RNN)。

該 RNN 層的輸出被饋送到具有“num_chars”個隱藏單元的 Dense 層,我們將使用 softmax 激活,因為我們需要每個字符的概率。 在我們部署一個 Dense 層之前,我們需要將該層縮減為一個 TimeDistributed 層,因為我們需要部署 Dense 層用於每個時間步的輸出。

hidden_​​units = 128

max_time_steps = 5 #我們將輸出硬編碼為 5 個字符

定義模型():

模型=順序()

model.add(SimpleRNN(hidden_​​units, input_shape = ( None , num_chars)))

model.add(RepeatVector(max_time_steps))

model.add(SimpleRNN(hidden_​​units, return_sequences = True ))

model.add(TimeDistributed(Dense(num_chars,activation = ' softmax ' )))

返回模型

模型=模型()

模型.summary()

model.compile(損失= '分類交叉熵' ,優化器= '亞當' ,指標= [ '準確性' ])

模型的架構將如上圖所示

必讀:神經網絡教程

3. 向量化和去向量化數據

讓我們定義用於向量化和去向量化數據的函數。

這是將算術表達式和結果一起向量化的函數。

def向量化(arith, res):

x = np.zeros((max_time_steps, num_chars))

y = np.zeros((max_time_steps, num_chars))

x_remaining = max_time_steps len (arith)

y_remaining = max_time_steps len (res)

對於i, c in enumerate (arith):

x[x_remaining + i, character_to_index[c]] = 1

對於範圍內i (x_remaining):

x[i, character_to_index[ ' 0 ' ]] = 1

對於i, c in enumerate (res):

y[y_remaining + i, character_to_index[c]] = 1

對於範圍內(y_remaining):

y[i, character_to_index[ ' 0 ' ]] = 1

返回x, y

同樣,這裡是對字符串進行去矢量化的函數。 由於我們收到的輸出是一個概率向量,我們將使用 np.argmax() 來選擇概率最高的字符。 現在 index_to_character 字典用於追溯該索引處的字符。

def去矢量化(輸入):

res = [index_to_character[np.argmax(vec)] for i, vec in enumerate ( input )]

返回'​​ ' .join(res)

現在我們對“去向量化”函數的約束是,它將用零填充尾隨字符。 例如,如果輸入向量是 ('1-20', '-19'),那麼去向量化的輸出將是 ('01-20', '00-19')。 我們需要處理這些額外的填充零。 讓我們編寫一個用於剝離字符串的函數。

def剝離(輸入):

標誌=

輸出= ' '

對於c輸入 _

如果不是標誌c == ' 0 '

繼續

如果c == ' + 'c == ' 'c == ' * 'c == ' / 'c == ' ' :

標誌=

否則

標誌=

輸出+= c

返回輸出

4. 製作數據集

現在我們已經完成了定義一個生成數據的函數,讓我們使用該函數並創建一個包含許多這樣的(算術表達式,結果)對的數據集。

def create_dataset (num_equations):

x_train = np.zeros((num_equations, max_time_steps, num_chars))

y_train = np.zeros((num_equations, max_time_steps, num_chars))

對於範圍內i (num_equations):

e, l =數據生成()

x, y =矢量化(e, l)

x_train[i] = x

y_train[i] = y

返回x_train, y_train

5. 訓練模型

讓我們創建一個包含 50,000 個樣本的數據集,這是訓練我們的數據飢餓模型的一個公平數字,我們將使用 25% 的數據進行驗證。 另外,如果準確率在 8 個 epoch 內保持不變,我們為智能訓練中斷創建回調。 這可以通過將耐心參數設置為 8 來實現。

x_train, y_train = create_dataset( 50000 )

simple_logger = LambdaCallback(

on_epoch_end = lambda e, l: print ( ' {:.2f} ' .format(l[ ' val_accuracy ' ]), end = ' _ ' )

)

early_stopping = EarlyStopping(monitor = ' val_loss ' , 耐心= 8 )

model.fit(x_train,y_train,epochs = 100 ,validation_split = 0.25 ,verbose = 0

回調= [simple_logger, early_stopping])

6. 測試模型

現在讓我們通過創建一個大小為 30 的數據集來測試我們的模型。

x_test, y_test = create_dataset(num_equations = 20 )

preds = model.predict(x_test)

full_seq_acc = 0

對於i, pred in enumerate (preds):

pred_str =剝離(去矢量化(pred))

y_test_str =剝離(去向量化(y_test[i]))

x_test_str =剝離(去向量化(x_test[i]))

col = ' green ' if pred_str == y_test_str else ' red '

full_seq_acc += 1 / len (preds) * int (pred_str == y_test_str)

outstring = '輸入:{},輸出:{},預測:{} ' .format(x_test_str, y_test_str, pred_str)

打印(彩色(outstring,col))

print ( ' \n全序列精度:{:.3f} % ' .format( 100 * full_seq_acc))

輸出將如下所示

我們可以看到這裡的準確性有點差,無論如何我們可以通過調整一些超參數來優化它,比如隱藏單元的數量、驗證拆分、epoch 的數量等。

結論

我們了解了 RNN 的基本工作流程,了解 RNN 最適合序列數據,生成隨機算術方程的數據集,開發了用於預測基本算術表達式輸出的序列模型,使用數據集訓練了該模型我們已經創建並最終使用模型從未見過的小數據集測試了該模型。

如果您有興趣了解有關 RNN、機器學習的更多信息,請查看 IIIT-B 和 upGrad 的機器學習和人工智能 PG 文憑,該文憑專為在職專業人士設計,提供 450 多個小時的嚴格培訓、30 多個案例研究和作業, IIIT-B 校友身份、5 個以上實用的實踐頂點項目和頂級公司的工作協助。

機器學習中有哪些不同類型的神經網絡?

在機器學習中,人工神經網絡基本上是被設計成類似於人腦的計算模型。 機器學習根據需要實現的數學計算採用不同類型的人工神經網絡。 這些神經網絡是不同機器學習技術的子集,它們以不同的方式從數據中學習。 一些最廣泛使用的神經網絡類型是 - 循環神經網絡 - 長期短期記憶,前饋神經網絡 - 人工神經元,徑向基函數神經網絡,Kohonen 自組織神經網絡,卷積神經網絡和模塊化神經網絡,其中。

遞歸神經網絡有什麼優勢?

循環神經網絡是深度學習和機器學習中最常用的人工神經網絡之一。 在這種類型的神經網絡模型中,從上一步獲得的結果作為輸入饋送到後續步驟。 遞歸神經網絡具有幾個優點,例如 - 它可以隨著時間的推移保留所有信息,包括其先前的輸入,這使其成為時間序列預測的理想選擇。 這種類型是長短記憶的最佳實例。 此外,循環神經網絡通過使用卷積層提供建設性的像素鄰域。

神經網絡在實際應用中是如何使用的?

人工神經網絡是深度學習的一個組成部分,深度學習又是機器學習和人工智能的一個超級專業分支。 神經網絡用於不同行業以實現各種關鍵目標。 人工神經網絡的一些最有趣的實際應用包括股票市場預測、面部識別、航空航天工業中的高性能自動駕駛和故障診斷、國防領域的武裝攻擊和目標定位分析、圖像處理、醫療保健領域的藥物發現和疾病檢測、簽名驗證、筆跡分析、天氣預報和社交媒體趨勢預測等。