“鸡兔同笼”的那些年

“盈亏问题”、“年龄问题”、“植树问题”、“牛吃草问题”、“利润问题”...,小学阶段你是否曾被各种花样的数学应用题折磨过呢?没关系,现在机器学习模型也可以帮助我们去解答应用题了,来看看它可以上几年级了?

本文将给出一个求解小学数学应用题(Math Word Problem)的baseline,基于ape210k数据集训练,直接用Seq2Seq模型生成可执行的数学表达式,最终Large版本的模型能达到75%的准确率,明显高于ape210k论文所报告的结果。所谓“硬刚”,指的是没有对表达式做特别的转换,也没有通过模板处理,就直接生成跟人类做法相近的可读表达式。

数据处理#

这里我们先观察一下ape210k数据集的情况:

可以看到,我们主要关心的是original_text、equation、ans字段,其中original_text就是题目,equation则是运算过程(一般以x=开头),而ans是最终答案。我们希望训练一个模型,由original_text来生成equation,然后经由python的eval函数直接得到ans。

不过,我们需要做一些前处理,因为ape210k给出的equation并不是都可以直接eval的,像上面的例子150*20%/5%-150对python来说就是一个非法表达式。笔者所做的处理如下:1、对于a%这样的百分数,统一替换为(a/100);

2、对于a(b/c)这样的带分数,统一替换为(a+b/c);

3、对于(a/b)这样的真分数,在题目中去掉括号变为a/b;

4、对于比例的冒号:,统一替换为/。

经过这样处理后,大部分equation都可以直接eval了,并且可以与ans进行答案对比,只保留结果一致的题目。不过,还有一点改进的地方,就是这样得到的表达式可能会带有一些冗余的括号(也就是去掉括号后与原来的等价),因此还要加上一步去括号,即遍历每一组括号,如果去掉该组括号结果与原来的等价,那么就去掉该组括号,这样可以得到平均长度更短的表达式,而长度越短越容易生成。

最终,我们得到了如下可用的数据集:

\begin{array}{c|ccc}

\hline

& \text{训练集} & \text{验证集} & \text{测试集} \\

\hline

\text{原有数目} & 200488 & 5000 & 5000\\

\hline

\text{保留数目} & 200390 & 4999 & 4998\\

\hline

\end{array}

剩下的基本上是一些错题、乱题了,暂时忽略。

模型简介#

模型其实是最没什么好讲的,就是以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小时(算上验证集的评测时间)。

对了,说到Large,由于UniLM借用了MLM部分权重,所以我们不能用哈工大开源的RoBERTa-wwm-ext-large,因为这个版本的MLM权重是随机初始化的(但它的Base版本是正常的,可以用)。Large版本推荐用腾讯UER开源的权重,原本是PyTorch版的,笔者将它转换为TF版了,在这里(提取码l0k6)可以下载。

效果如下表:

\begin{array}{c|ccc}

\hline

& \text{beam_size} & \text{验证集} & 测试集 \\

\hline

\text{Base} & 1 & 71.67\% & 71.65\%\\

\text{Base} & 2 & 71.81\% & 72.27\%\\

\text{Base} & 3 & \textbf{71.85}\% & \textbf{72.35}\%\\

\hline

\text{Large} & 1 & 74.51\% & 74.43\%\\

\text{Large} & 2 & 74.97\% & 74.99\%\\

\text{Large} & 3 & \textbf{75.04}\% & \textbf{75.01}\%\\

\hline

\end{array}

Large模型的结果已经比ape210k的论文《Ape210K: A Large-Scale and Template-Rich Dataset of

Math Word Problems》所报告的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,利用SymPy就能达到我们的目的了。具体请看下面的例子:

文章小结#

本文介绍了用Seq2Seq模型做数学应用题的一个baseline,主要思路就是通过“BERT+UniLM”直接将问题转换为可eval的表达式,然后分享了一些结果标准化的经验。通过BERT Large模型的UniLM,我们达到了75%的准确率,超过了原论文开源的结果。

所以,你觉得它能上几年级了呢~

更详细的转载事宜请参考:《科学空间FAQ》

如果您还有什么疑惑或建议,欢迎在下方评论区继续讨论。

如果您觉得本文还不错,欢迎分享/打赏本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!

打赏

微信打赏

支付宝打赏

因为网站后台对打赏并无记录,因此欢迎在打赏时候备注留言。你还可以点击这里或在下方评论区留言来告知你的建议或需求。

如果您需要引用本文,请参考:

苏剑林. (2020, Oct 19). 《BERT可以上几年级了?Seq2Seq“硬刚”小学数学应用题 》[Blog post]. Retrieved from https://kexue.fm/archives/7809

python植树问题代码_BERT可以上几年级了?Seq2Seq“硬刚”小学数学应用题相关推荐

  1. bert关键词提取_BERT可以上几年级了?Seq2Seq“硬刚”小学数学应用题

    作者 | 苏剑林 单位 | 追一科技 研究方向 | NLP.神经网络 "鸡兔同笼"的那些年 "盈亏问题"."年龄问题"."植树问题 ...

  2. BERT可以上几年级了?Seq2Seq“硬刚”小学数学应用题

    ©PaperWeekly 原创 · 作者| 苏剑林 单位|追一科技 研究方向|NLP.神经网络 ▲"鸡兔同笼"的那些年 "盈亏问题"."年龄问题&qu ...

  3. 【2023华中杯数学建模】B 题 小学数学应用题相似性度量及难度评估详细建模方案及实现代码

    更新时间:2023-5-1 14:00 1 题目 B 题 小学数学应用题相似性度量及难度评估 某 MOOC 在线教育平台希望能够进行个性化教学,实现用户自主学习.在用户学习时,系统从题库中随机抽取若干 ...

  4. python基础教程--代码集合(上)

    文章目录 1.转义字符与原字符 2.二进制与字符编码 3.二进制编码 4.变量定义 4.数据类型 5.浮点数类型 6.布尔类型 7.字符串类型 8.数据类型转换 9.注释功能 10.标识符和保留字 1 ...

  5. 【Python】编写代码对网络上的ip地址进行端口扫描,收集“ip+开放端口”信息

    题目

  6. python怎么输入代码-教你如何将自己的脚本代码放到服务器上运行

    原标题:教你如何将自己的脚本代码放到服务器上运行 本文授权转自 | 日常学Python 上次弄了个机器人,反响挺不错的,我也挺满意的,因为这个我也初步了解了服务器这个东西,懂得了如何将自己的脚本代码放 ...

  7. python代码编辑器-世界上最好的Python编辑器是什么?

    原标题:世界上最好的Python编辑器是什么? 世界上最好的 Python 编辑器或 IDE 是什么?炫酷的界面.流畅的体验,我们投 PyCharm 一票,那么你呢?本文介绍了 PyCharm.Jup ...

  8. 在线执行代码,线上代码执行,支持 php go woo lua luajit python perl ruby

    在线执行代码,线上代码执行,支持 php go woo lua luajit python perl ruby 在线执行编辑器

  9. Python教学 | Python 中的循环结构(上)【附本文代码和数据】

    查看原文:[数据seminar]Python教学 | Python 中的循环结构(上)[附本文代码和数据] (qq.com) Part1引言 上期文章我们向大家介绍了 Python 程序控制结构中的分 ...

最新文章

  1. java书籍_Java程序员必看的 13 本 Java 书籍!
  2. java和jvm_Java、JVM和操作系统之间的关系,写给新人,
  3. PCB的地与机壳(连接大地)为什么用阻容连接?
  4. 性能提升约 7 倍!Apache Flink 与 Apache Hive 的集成
  5. Python练习 | Python中的strip()函数使用???(求解决方法)
  6. vs2017 cmake android,CMake构建VS2017工程
  7. CCNP精粹系列之四----OSPF(open short path first)
  8. 没有工厂模式(工厂模式2)
  9. 8.Postman中发送请求被拦截(证书问题)
  10. Atitit Atitit 客户常见技术问题的解答.docx
  11. php10充电宝拆解,【变废为宝拆解】拆解一个正品的小米移动电源10400mAh版
  12. 基于最新导则下的生态环境影响评价技术方法及图件制作与案例实践
  13. linux编译安卓源码,Ubuntu下编译Android源码
  14. 前端开发之百度地图使用的API和实例
  15. 打乱mysql数据顺序_打乱数据库表内的数据顺序
  16. 热心肠行为?苹果“偷偷“给应用买广告
  17. 《罗曼蒂克消亡史》影评
  18. 雇佣兵问题(Python解答)
  19. diskgenius合并分区(diskgenius合并分区到c盘)
  20. 用梅森公式求复杂电路系统传递函数

热门文章

  1. 加一度分享:如何降低推广预算,增加KPI
  2. 保存命令行输出信息到log的方法(ubunut下和arm-linux下有效)
  3. Java基础之Http协议的理解与总结
  4. 五种基于RGB色彩空间统计的皮肤检测算法
  5. JavaScript书籍的免费32本-收集分享
  6. mysql 更新并查询结果_数据库_基础知识_MySQL_UpdateSelect(根据查询出来的结果批量更新)...
  7. cjuiautocomplete ajax,Yii CJuiAutoComplete小部件:空响应消息事件
  8. zen of python什么意思_Zen of Python
  9. android javamail获取邮件太多太慢_「Java」 - SpringBoot amp; 邮件发送
  10. xstream-0 使用入门