人工智慧開講 用 Seq2Seq 模型做數學應用題

2021-10-25 06:15:56 字數 4026 閱讀 1660

▲「雞兔同籠」的那些年

「盈虧問題」、「年齡問題」、「植樹問題」、「牛吃草問題」、「利潤問題」...,小學階段你是否曾被各種花樣的數學應用題折磨過呢?沒關係,現在機器學習模型也可以幫助我們去解答應用題了,來看看它可以上幾年級了?

本文將給出乙個求解小學數學應用題(math word problem)的 baseline,基於ape210k 資料集 [1] 訓練,直接用 seq2seq 模型生成可執行的數學表示式,最終 large 版本的模型能達到73%+的準確率,高於 ape210k **所報告的結果。

所謂「硬剛」,指的是沒有對表示式做特別的轉換,也沒有通過模板處理,就直接生成跟人類做法相近的可讀表示式。

資料處理

這裡我們先觀察一下 ape210k 資料集的情況:

可以看到,我們主要關心的是original_textequationans字段,其中original_text就是題目,equation則是運算過程(一般以 x= 開頭),而ans是最終答案。我們希望訓練乙個模型,由original_text來生成equation,然後經由 python 的 eval 函式直接得到ans

不過,我們需要做一些前處理,因為 ape210k 給出的equation並不是都可以直接 eval 的,像上面的例子 150*20%/5%-150 對 python 來說就是乙個非法表示式。筆者所做的處理如下:

對於a%這樣的百分數,統一替換為(a/100);

對於a(b/c)這樣的帶分數,統一替換為(a+b/c);

對於(a/b)這樣的真分數,在題目中去掉括號變為a/b;

對於比例的冒號:,統一替換為/。

經過這樣處理後,大部分equation都可以直接 eval 了,並且可以與ans進行答案對比,只保留結果一致的題目。

不過,還有一點改進的地方,就是這樣得到的表示式可能會帶有一些冗餘的括號(也就是去掉括號後與原來的等價),因此還要加上一步去括號,即遍歷每一組括號,如果去掉該組括號結果與原來的等價,那麼就去掉該組括號,這樣可以得到平均長度更短的表示式,而長度越短越容易生成。

最終,我們得到了如下可用的資料集:

剩下的基本上是一些錯題、亂題了,暫時忽略。

模型簡介

模型其實是最沒什麼好講的,就是以original_text為輸入、equation為輸出,以「bert+unilm」為基礎架構,訓練乙個 seq2seq 模型。如果對模型還有什麼疑惑的地方,請閱讀從語言模型到seq2seq:transformer如戲,全靠mask。

筆者的訓練是用 22g 的單卡 titan rtx 跑的,優化器是 adam,學習率是 2e-5。base 版本的用了 batch_size=32,大概需要訓練 25 個 epoch,每個 epoch 約 50 分鐘(算上驗證集的評測時間);而 large 版本則是 batch_size=16,大概需要訓練 15 個 epoch,每個 epoch 約 2 小時(算上驗證集的評測時間)。

提取碼:l0k6

效果如下表:

large 模型的結果已經比 ape210k 的**ape210k: a large-scale and template-rich dataset of math word problems[4] 所報告的 70.20% 要明顯高了,因此說明我們這裡的模型是乙個不算太差的 baseline。

感覺如果用一些 seq2seq 的技巧來緩解一下 exposure bias 問題(參考seq2seq中exposure bias現象的**與對策),模型還能有進一步提公升;還有或許可以引入 copy 機制,增強輸出與輸入數字的一致性;還有可以想辦法進一步縮短序列長度(比如四個字元的 3.14 替換為兩個字母 pi)。這些就留給大家嘗試了。

標準輸出

如果純粹從建模的角度來看,其實我們的任務已經完成了,即模型只需要輸出式子就行了,評測的時候則只需要判斷式子 eval 後的結果跟參***是否一致就好。

但是從實際實用的角度,我們還需要對輸出做進一步的標準化,即根據不同的題目決定輸出的是小數、整數、分數還是百分數等,這就需要我們:1)決定什麼時候該輸出什麼格式;2)根據指定格式對結果進行轉換。

第一步比較簡單,一般來說根據題目或方程的一些關鍵字就可以判斷了。比如表示式裡邊如果有小數的,那麼輸出結果一般也是小數;如果題目是問「多少輛」、「多少個」、「多少人」之類的,那麼輸出的都是整數;如果直接問「幾分之幾」或「百分之幾」的,那麼相應地就是分數或百分數了。

比較困難是應該是取整類題目,比如「每盒蛋糕 7.90 元,50 元最多可以買多少盒蛋糕?」要求我們對 50/7.90 進行下取整,但有時候則是上取整。不過讓筆者很意外的是,ape210k 裡邊並沒有取整類題目,所以也就不存在這個問題。如果遇到有取整的資料集,如果規則判斷起來比較困難,那麼最直接的方法就是把取整符號也加入到 equation 中讓模型去**。

第二步看起來有點複雜,主要是分數的場景,一般讀者可能不知道如何讓式子保留分數運算結果,如果直接 eval('(1+2)/4'),那麼得到的是 0.75(python3),但有時我們希望得到的是分數結果 3/4。

事實上,保持分數的運算屬於 cas 的範疇(computer algebra system,計算機代數系統),說白了就是符號運算而不是數值運算,而 python 中剛好也有這樣的工具,那就是 sympy [5] ,利用 sympy 就能達到我們的目的了。具體請看下面的例子:

from sympy import integer

import re

r = (integer(1) + integer(2)) / integer(4)

print(r)  # 輸出是 3/4 而不是 0.75

equation = '(1+2)/4'

print(eval(equation))  # 輸出是 0.75

new_equation = re.sub('(\d+)', 'integer(\\1)', equation)

print(new_equation)  # 輸出是 (integer(1)+integer(2))/integer(4)

print(eval(new_equation))  # 輸出是 3/4

文章小結本文介紹了用 seq2seq 模型做數學應用題的乙個 baseline,主要思路就是通過「bert+unilm」直接將問題轉換為可 eval 的表示式,然後分享了一些結果標準化的經驗。通過 bert large 模型的 unilm,我們達到了73%+的準確率,超過了原**開源的結果。

所以,你覺得它能上幾年級了呢?

人工智慧 2 智慧型體

理性智慧型體 任務環境 智慧型體的結構 智慧型體的類別 亞符號ai 反邏輯 聯結主義ai 機器智慧型體 機械人 軟體智慧型體 軟體機械人 抽象智慧型體 各種定義 正確的行為 理性的動作 理性的 探索 學習 自主 理性的動作,對給定的感知序列,能使期待的效能指標最大化 理性的概念 example pe...

人工智慧開發神器是什麼 為何多人用Python入門

人工智慧開發神器是什麼?為何多人用python入門?人工智慧 artificialintelligence 英文縮寫為ai。它是研究 開發用於模擬 延伸和擴充套件人的智慧型的理論 方法 技術及應用系統的一門新的技術科學。人工智慧不是人的智慧型,但能像人那樣思考 也可能超過人的智慧型。資料顯示,國內人...

人工智慧開發培訓工資高嗎

可能大家都知道,在未來的幾十年裡,人工智慧會逐漸滲透到社會的每乙個方面,在醫療 工作 教育和科技等眾多領域為我們提供支援和建議。如果現在學習人工智慧,那麼人工智慧開發培訓出來後工資高嗎?其實這個問題很難回答,主要還在於大家。如果你對人工智慧是真的感興趣,而且也真正用心在為成為人工智慧工程師做準備,相...