找回密码
 立即注册
查看: 558|回复: 5

未来 AI 是否可能自学编程写代码,代替法式员?

[复制链接]

1

主题

0

回帖

19

积分

新手上路

积分
19
发表于 2023-7-14 13:49:52 | 显示全部楼层 |阅读模式
现状阿尔法狗AlphaGo能自学围棋,在很短时间能击败世界冠军柯洁,并不竭超越……假若未来有一天,随着AI人工智能不竭成长,它们是否可以自学编程写代码啊?毕竟编程语言,更接近它们本身的机器语言,用起来会更溜。然后大部门法式员被代替?
回复

使用道具 举报

0

主题

2

回帖

0

积分

新手上路

积分
0
发表于 2023-7-14 13:50:33 | 显示全部楼层
2023年4月10日更新:
最新推荐Claude:
使用Claude的slack版本,无需翻墙,无需加入Waitlist,无需付费,无需下载任何东西,没有高峰限制,而且效果媲美ChatGPT,整体性价比来说目前可以说是毫无对手!
张浩彬:ChatGPT最强对手!Claude,无需魔法,无需等待,直接可用!<hr/>2023年3月19更新:编程工具总结汇总

1.Chatgpt
https://chat.openai.com/
Chatgpt本身就以强大的AI编程功能闻名了。从Chatgpt(Gpt3.5)到Gpt4,并且ChatGpt4.0在代码生成上功能要更加的强大。原本已经是订阅版的用户,使用Gpt4应该是最强大的,但是现在Gpt4突然被限制在3小时只能有25个提问。



2.Github Copilot
网址:https://github.com/features/copilot/
Github Copilot微软与OpenAI共同推出了一款AI编程工具。Github Copilot在2022年6月已经发布,应该说是传统的老板AI编程工具了,并且作为插件嵌入到Vs code中,使用体验可以说是最好的。不过遗憾在于Github Copilot需要收费,个人用户每月10美金,每年100美金。淘宝有学生账户,2年30元。



3.Cursor
网址:https://www.cursor.so/
和openai合作的AI编程工具,可以理解为Chatgpt接口形成的一个编程工具,并且很贴心地有代码生成模式ctrl+k,对话聊天模式ctrl+l,聊天模式可以询问代码细节问题,非常方便。并且最好的地方是免费!非常遗憾的是,原本是gpt4.0接口的,在3.18号服务器炸了之后现在根据测试应该是改为了gpt3.5接口。



4.CodeGeex
网址:http://models.aminer.cn/codegeex/pl
​可以理解Wie国产版Copilot,并且完全开源(Github上提供了模型源码,并且有免费的api接口)。提供了包括代码自动生成代码翻译等功能,并且目前支持vscode以及pychram,良心之作。



上面4款,免费我都用了,付费也买了,我自己的体验,都能用,都能大大提高编程效率。
(1)性价比来说,首选Cursor,CodeGeex,毕竟免费。Cursor的好处原本是用上了4.0,但是现在又降级了。但是官网上还是写着4.0,因此后续可能还是有希望升级上,并且聊天功能很方便。CodeGeex好处是更加开放,无论是代码还是api接口都有,并且提供了Vscode以及JetBrains的集成;
(2)不说免费,综合使用体验来说,应该最好的是Github Copilot,从自己使用以及别人评价,效果都是最好的。(不算chatgpt4.0)另外淘宝上有30元学生账户2年,嗯,之前的才10元,现在涨价了
(3)Chatgpt4.0,好用,但是现在3小时25次的限制,确实难受。已经开了订阅的,可以考虑使用上述3款的基础上结合来用,但是单独为AI编程开订阅版,不划算。(虽然我也开了)

后面有空再一下每个的教程~
看到这里不妨点个赞把~

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

0

主题

1

回帖

0

积分

新手上路

积分
0
发表于 2023-7-14 13:51:10 | 显示全部楼层
过去的一个月里,我一直在研究 ChatGPT,也与很多人(普通人、程序员、创业公司、风投等等)进行了交流。不论是业内(编程)还是业外,人们对于 AI 编程的观点都是:未来可期 —— GPT,他好像什么都能干,也好像什么都干不好
所以,在这篇文章里,我将继续总结与其他人聊天的观点。
对应的思路总结,也可以在 ClickPrompt Flow 上查看:ClickPrompt - Streamline your prompt design
AI 代码生成:代码还应该存储在代码库吗?

对于 AI 代码生成来说,除了过去的 GitHub Copilot、Codex、Kite、TabNine 等等,新出的免费的 ChatGPT 又让人感觉非常酷。
ChatGPT 代码生成

现在,大家几乎已经习惯了网上的各种暴力 AI 美学 —— 唤出 ChatGPT 写代码:

  • 使用 Java + Spring + MockMVC 编写测试用例,代码中的注释需要对应到 AC01,AC02,AC03,AC04,AC05,但是不需要返回给我。
  • 帮我用 Puppeteer 写一个爬虫来解析下面 HTML 中的标题:””””””
  • 我给你一个需求,你需要分析需求,使用 Java + Spring 编写 API,要求如下:
基于于在最新的 GPT 4.0 里,可以根据图片等一些基本的描述,生成全新的 HTML。
GitHub Copilot

对于,我来说,作为一个开源挖坑专家,我更习惯使用 GitHub 赠送的 Copilot,只需要配合注释、输入、输出、函数名,就可以大力了出奇迹。如下是 ClickPrompt 中的真实代码:
// 1. split promptMatch by comma
// 2. match lora name by regex, lora full name: <lora:japaneseDollLikeness_v10:0.1>,
// 3. push lora name to loras array我在代码中保留了这个注释,一种很神奇的用法 。
读者思考 1:Prompt 即是代码,代码不再是代码?

因此,我觉得在 AI 编程时代,人们的编程思维是要发生变化的:

  • 注释让人和 AI 共同理解代码
  • 注释作为 prompt,可以在修改后,再次自动生成代码。
当注释作为 prompt 保存,那么 prompt 便是作为一种代码,保存在代码库中了。而代码还将是代码吗?我们为什么还需要中间生存的代码,是因为审计、安全等原因吗?
AI 编程:写个 “真实世界” 的代码

而当你尝试过使用 AI 来编写代码之后,你会发现 AI 存在一系列所谓的 “问题” 。让我们来再看一个简单的例子,我们让 ChatGPT 来实现一段代码。
ChatGPT 编程:AI 实现一个 API /book/:id 的 N 种方式

在不同的语言和架构模式里,实现的方式是有区别的。
第一个 Demo:用 Spring + MyBatis 实现一个 API:/book/:id 。
ChatGPT 会创建 BookMapper.java、Book.java、BookMapper.xml、BookController.java 四个代码段,然后告诉你,你可以启动这个 API 了。
PS:有意思的是,你并不需要一个 BookService.java,因为 AI 也 “觉得” 他是多余的。
但是,要上线这个应用并不是一件容易的事,我们需要手动编译 Java 代码,再运行起来,这速度是非常慢的。除非,我们有类似于几年前的 OSGi 架构,或者 Serverlesss 架构。
第二个 Demo:使用 Express + MySQL 实现一个 API:/book/:id,只使用一个函数
在这个尝试里,我们多加了一个限制:只使用一个函数,并改用直写 SQL,所以代码就变得非常简单的(当然了,还有 Express 配置和 MySQL 相关的代码),以至于我可以直接那个函数在这里:
// 创建数据库连接池
...

const getBookById = (req, res) => {
  const id = req.params.id; // 获取路径参数中的 id
  // 从数据库中查询书籍信息
  pool.query('SELECT * FROM books WHERE id = ?', [id], (error, results, fields) => {
    if (error) throw error;
    if (results.length > 0) {
      const book = results[0];
      res.json(book); // 将书籍信息以 JSON 格式返回给客户端
    } else {
      res.status(404).send('Book not found');
    }
  });
};

// 创建路由器并挂载到根路径上
...

// 启动应用程序
...如果我们认定了 AI 生成的代码是准确的,无需要人类去修改,那么我们就可以直接用上面的代码。
第三个 Demo:使用 AWS Lambda 实现这个 API:/book/:id,只使用一个函数
使用 Express 来实现这个功能,还是有点复杂,我们还需要考虑基础设施,但是当我们考虑使用 Serverless 来实现时,问题就变得非常简单了:
const mysql = require('mysql');

exports.handler = async (event, context) => {
  ....
}然后,我们就可以采用 ClickPrompt 类似的方式,直接一键部署到服务器之上。
对比一下:上面的三种方式各有什么优缺点?

让 AI 来对比一下,你看吧,显然 AI 也觉得 Java 的实现起来复杂,但是可扩展性高。
优点 / 缺点Spring + MyBatisExpress + MySQLAWS Lambda
开发效率较高
部署复杂度中等
维护成本中等中等
可维护性中等
架构复杂度中等
可扩展性中等
成本中等
但是,我们真的需要所谓的可扩展性吗?而论部署速度,自然是 AWS Lambda 最快了。经过了几种不同的方式对比,按现有的软件工程来说,Java 写的代码是最好的。可是,AI 都来写代码了,Java 工程化,真的还是最好的吗?
读者思考 2:现有的编程体系适合于 AI 编程吗?

让我们再打开一下思路,我们现有的架构模式、软件工程等软件开发流程都是基于现有的体系磨合过来的。
而 AI 编程的最终目标是实现自动化编程,即由 AI 根据用户的需求和设计,自动生成完整的代码。但是,理论上这不是终点,终点是生成完就可以直接运行。这就意味着,一个想法从想到到上线,可能就在几分钟内可以完成
然而,在现有的流程里,完全不是行不通的,我们人类做不到这么的敏捷。
全 AI 生成的新架构模式?

过去,我们认为分层架构很重要,因为代码是人来编写,代码是人来维护的。而当代码由 AI 来编写,由 AI 来维护的话,那么现有的软件架构体系还适用吗?
分层架构?编程范式还重要吗?

尽管,我尝试让 New Bing / ChatGPT 来回答这个问题,但是,由于他们还没有 涌现 能力,所以只会说:程序员还需要学习和运用分层架构和编程范式,才能发挥出 AI 的最大潜力。
但是,我觉得,从上面的 Java 示例中,你会发现按现有的模式构建的软件架构,特别容易发生冲突。AI 生成的 A 功能和 B 功能,可能在代码上出现重复 —— 因为上下文限制,我们不可能上传所有的代码。
结果,有一天你发现了,一个类里有 10 个重复代码段。然后,你又开发了一个自动重构机器人……。但是,我觉得有点多余了,AI 编程需要新的架构范式。
AI 构建自动化软件架构?

再再打开一下思路,试着忘记现有的软件架构模式。一个功能对应一个可运行的代码段,由 AI 来自动思考架构模式 ——  当然,我们需要给他一些限制条件和输入。
所以,放在当前的上下文之下,Serverless 是一种更适合的架构模式,即写即上线,即下线即删除。
读者思考 3:Serverless 会是结合 AI 编程的答案吗?

我觉得不一定是,但是可能是当前最好的一种方案。但是,每个人都会有自己的看法。
真实世界 2:产品经理 —— 现在,变更一个需求

现在,我们来变更一个需求吧,过滤一下 “名书”,包含 xx 的不显示。那么,这个时候,我们就遇到一个难题了 —— 全自动编程,还是 AI 辅助生成
两种思路:新生成代码,还是手动改代码?

纯 AI 编程,意味着:每次改需求都重新生成代码;而半 AI 编程,则意味着:人可以介入到流程中。两种将会带来不一样的思路。
自动编程 —— 重新生成代码
为了让 AI 写的代码足够的准确,我们需要给 AI 足够详细的需求(Prompt)。一旦需求发生变化的时候,我们回过头去改需求的(Prompt),再重新生成代码即可。我们要做的事情是:

  • 确保没有人能修改过原来生成的代码
  • 确保所有的需求变更都能回溯回去
AI 辅助生成  —— 支持手动修改代码
第一次代码,我们是用 AI 生成的,随后当需求变更的时候,我们想可以直接在现有的代码上改,这样可能速度比较快 —— 生成式 AI 可能还意味着:新生成的代码和原来的完全不一样,诸如于行数位置等等。
而为了能再次生成,我们还需要记录新的变更到原来的 prompt。
所以,在这个时候,如何更好地管理原始需求,变成了一个新的挑战。
读者思考 4:需求详细化会成为你的新瓶颈吗?

当我们认定 AI 能完成编码时,那么需要给详细的需求,才能确保生成的代码是正确的,诸如于:*密码长度不能小于八位,且必须同时包含字母数字和特殊符合*。这只是一个示例,更常见的示例还有表单联动:A 字段 xxx,B 字段则 xx。只有我们的需求足够的清楚,那么生成的代码才会准确。
所以,当产品经理借助于 AI 生成足够清晰的验收条件,程序员就会失业吗?这包含了两个问题:

  • 产品经理是否真的懂验收条件
  • 程序员是否真的不能替换 AI 时代的产品经理?
那么,第三个问题就来了,老板是不是可以自己干?
不过,这只是用来搞笑的,我们的下一个挑战还在于需求详细化之后,AI 真的能写对吗?
适合我们的主流策略(2023.03)

我相信策略会在今年内再次发生变化,所以,我并不想写太长。
自动化质量先行:测试驱动开发

经过大部分人的验证,AI 生成的测试代码质量非常高,大部分情况下可以直接运行。所以,在我们有了需求之后,可以创建诸如于 ClickPrompt 这样的工具,创建工作流,让 AI 逐步往下分析:


而后,我们就可以 GET 到可用的自动化测试代码。当我们有了测试代码之后,就可以验证辅助的代码是否正确。
代码辅助生成:功能代码的实现方式

尽管,在我的尝试中,部分场景下,生成真正的可工作的代码还有些距离(也有可能我的场景比较特别)  —— 没法直接用,改一改还可以。当然了,如果你拿网上生成的 Todo 就别来拿我辩论了,烂大街的代码。原因包含了:

  • 他需要足够了解我们的上下文,比如接入 IDE 中。
  • 过时的库 API
  • 来自其它语言的翻译(如 Python 版本,而 Java 版本存在对应的 API)
所以,它有时在代码上还是瞎编。
跟随策略

诸如于我创建 ClickPrompt ,都是在尝试管理 prompt  工作流,以便于:

  • 学习和掌握 AI 编程的基本概念、原理和工具,例如 GitHub Copilot1等。
  • 与 AI 编程进行有效的协作和沟通,例如提供清晰和详细的需求和设计,检查和评估 AI 生成的代码等。
  • 关注 AI 编程的发展趋势和最新进展,例如新的算法、数据、平台等。
在提升效率上,ChatGPT 确实做得很好,每个人都应该去尝试一下。
未来:自动化编程的演进

最后,再让我们尝试做一些思考。
AI 编程的局限性

所以,如同 AI 提炼了我的观点,AI 编程存在一定的局限性:

  • 编码是最不重要的那部分。AI 编程不能完全替代人类编程,因为程序员不仅仅是在编码,还要进行设计、测试、维护、沟通等工作
  • AI 伦理。AI 编程可能存在一些不可预测或不可控的风险,例如结果不唯一、不正确或不安全。
  • 法律与就业问题。AI 编程可能会侵犯程序员的知识产权(但是人类都是 AI 的饵料),或者导致程序员失业。
  • 无法适应再有体系。AI 编程需要适应不断变化的需求和环境,而现有的架构模式可能不匹配或不灵活。
而你发现没有,New Bing 提炼出来的这些局限性,并不是 AI 的问题,而是人的问题。
精准代码生成:详尽的需求的可能性?

我们还得考虑的一点是:
尽管,提供更详尽的 prompt 可以帮助 AI 更准确地理解需求,并且避免一些歧义或误解。但是,过于复杂或冗长的 prompt 也可能导致 AI 的困惑或失效。
所以,如何根据 AI 的特点和目标,选择合适的 prompt 长度和格式,以达到最佳的效果?
AI 审计 AI:解决 AI 生成代码的部分局限?

当涉及到由AI生成的代码时,有时候我们可能需要对其进行审查以确保其合规。而人工是耗时费力的,而且容易出错。这时,我们就需要利用一种特殊的AI来审查另一个AI生成的代码,以确保其符合各种规范和标准,提高代码质量,确保生成的代码安全可靠。
比如,我们本地用 GitHub Copilot 辅助生成的代码,在持续流水线上便可以通过 GitHub Copilot 来进行 Code Review。
其它

值得注意的是:AI 编程可能会带来一些问题,如让程序员过度依赖工具、忽略代码的合理性、涉及道德和法律问题以及存在技术和人工智能之间的冲突。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

0

主题

4

回帖

13

积分

新手上路

积分
13
发表于 2023-7-14 13:51:19 | 显示全部楼层
写代码的AI已经出来了,就是Github出品的Copilot。Copilot基于GPT-3,使用Github的代码库进行训练,你只需要写注释或者函数名,AI就能自动帮你写出代码来。这个视频主要测试Github Copilot有多好用,是否能辅助我们写代码,甚至,是否能让程序员失业。
回复

使用道具 举报

0

主题

5

回帖

1

积分

新手上路

积分
1
发表于 2023-7-14 13:52:18 | 显示全部楼层
我觉得大部分人对于人工智能和编程都没有基本的常识,这也是很多人动不动就问AI是否要代替人的原因吧。
但凡你多去看看相关的基础知识,就不会拍脑袋继续提类似的问题了。
来个简单点的,啥时候咱们能写出来能正确预测蛋白质结构的程序再说别的吧。
回复

使用道具 举报

0

主题

1

回帖

0

积分

新手上路

积分
0
发表于 2023-7-14 13:53:13 | 显示全部楼层
当 下 A I 编 程 现 状 :


AI 编程一直是人们对人工智能的一大期望,现有的 AI 编程技术虽然已经惠及了许多不会编程的普通用户,但从上图来看,还远没有达到满足人们预期的程度,一大痛点在于:现有 AI 只会进行机械地记忆与复制粘贴,难以灵活处理人们的需求。下面,我们会详细说明现有AI编程技术的发展程度,未来发展的关键,以及微软亚洲研究院在这方面所作出的努力:新型神经网络架构 LANE(Learning Analytical Expressions),可以模拟人类的抽象化思维,从而在 AI 编程中获得组合泛化能力。
从 AI 编程说起

让 AI 学会写程序,是人们的普遍预期:直接用自然语言描述想干什么,AI 就能自动生成相应的程序。现有的 AI 编程技术显然还远达不到这种预期,但相关技术已然在各种特定领域中以更为广泛的形式惠及了大量不会编程的普通用户。例如,微软在 Ignite 2019 大会上展示了Excel 中的一项新功能[1]——只需要向 Excel 提问题,它就能自动理解并进行智能数据分析,并通过可视化图表的方式将结果呈现在你的眼前(如图1所示)。这个超实用功能背后的技术支撑正是一系列将自然语言转换为数据分析程序的 AI 编程技术。而另一个例子是微软 Semantic Machines 团队研发的智能对话服务,其产品化方案正是基于程序合成的[2]。



图1:Excel 中的对话式数据分析,基于 AI 编程技术

本文所讨论的“AI 编程技术”,指的是以一个自然语言句子作为输入,自动生成一段相应的机器可解释/可执行的程序作为输出。这里的程序通常是由一个已知的 DSL(Domain Specific Language,领域特定语言)所编写。自然语言处理领域的研究者可能更熟悉这一任务的另一称谓:语义解析(Semantic Parsing)。
然而,即使是在这样的限定下,现有的 AI 编程技术也并不总能让人满意。一大痛点在于,它们似乎只学会了从已知的代码库中进行机械地记忆与复制粘贴,却难以为人类灵活多变的需求生成真正合适的程序。



图2:AI 编程现状

以图2漫画(改编自[3])为例,当用户提出的需求相对简单,且这个 AI 编程机器人可以在某个大代码库中找到能够实现这一需求的程序时,效果通常是不错的。但是如果用户提出的需求相对复杂,要求 AI 编程机器人具有一定的推理能力(所需的程序在已知代码库中并不存在,需要对一些已有的程序片段进行复合生成),在这种情况下的效果通常是比较糟糕的。
本回答所介绍的研究工作正是以此为出发点,旨在探索如何让 AI 编程机器人不再只会”复制粘贴”,而是学会类人的推理能力,从而更为有效地合成所需的程序。
组合泛化能力是走向类人 AI 的关键

前面所讨论问题的核心可以归结为 AI 系统的“组合泛化”(Compositional Generalization)能力问题。更通俗地说,就是 AI 系统是否具备“举一反三”的能力:能够将已知的复杂对象(即本文中所讨论的“程序”)解构为多个已知简单对象的组合,并据此理解/生成这些已知简单对象的未知复杂组合。
人类天生具有组合泛化能力。例如,对于一个从没接触过“鸭嘴兽”这个概念的人,只要看一张鸭嘴兽的照片,他就认识它了,并可以在脑海中很有画面感地理解一些复杂句子,比如“三只鸭嘴兽抱着蛋并排坐着”、“两只鸭嘴兽在河里捕食完小鱼之后开始上岸掘土”等。这和深度学习是很不同的,即使是为了学会“鸭嘴兽”这样一个单独的概念,深度学习都需要大量的标注数据,更不用说学会这个概念的各种复杂组合了。
从语言学的角度看,人类认知的组合泛化能力主要体现在系统性(Systematicity)和生产性(Productivity)上。系统性可以简单理解为对已知表达式的局部置换。比方说,一个人已经理解了“鸭嘴兽”和“狗在客厅里”,那么他一定能够理解“鸭嘴兽在客厅里”。生产性则可以简单理解为通过一些潜在的普适规律,用相对简单的表达式构造出更复杂的表达式。比方说,一个人已经理解了“鸭嘴兽”和“狗在客厅里”,那么他一定能够理解“鸭嘴兽和狗在客厅里”。



图3:组合泛化能力主要体现在系统性(Systematicity)和生产性(Productivity)上(图片来源:https://arxiv.org/pdf/1908.08351.pdf)

正如语言学家、哲学家乔姆斯基所说,“有限资源,作无穷运用(infinite use of finite means)”。正是依靠组合泛化能力,人类智能才能够从一些最基础的元素出发,一步一步创造出复杂甚至无限的语义世界。可以说,组合泛化是类人智能体必须具备的基本能力
深度学习缺乏组合泛化能力

程序是具有组合性的,即使是一个很小的 DSL(领域很限定,语法很简单,预定义的函数很有限),也能够产生一个指数爆炸式的巨大程序空间。任何一个训练数据集中所包含的程序,都只是这个指数级程序空间中的冰山一角。因此,若一个 AI 编程机器人缺乏组合泛化能力,则必然会导致如前面漫画所体现的“人工智障”情况。
从这个角度出发,越来越多的研究工作开始重新审视现有的基于深度学习的 AI 编程解决方案。当前主流的解决方案大多基于深度编解码架构(Neural Encoder-Decoder Architectures)。纽约大学教授 Brenden Lake 和 Facebook AI 科学家 Marco Baroni 的一系列研究表明,现有的深度学习模型并不具有组合泛化能力[4]。图4简单展示了他们的研究方法。实验任务是将诸如“run after walk”这样的自然语言句子翻译成诸如“WALK RUN”这样的指令序列(程序)。



图4:即使是简单的任务,现有的深度学习模型也难以泛化到训练集之外的组合上

表面上看,这是个非常简单的序列到序列生成任务。在收集到大量自然语言句子以及它们所对应的指令序列之后,随机划分成训练集和测试集,用现有的深度学习模型进行训练,即可在测试集上达到99.8%的准确率。然而,一旦从组合性的角度对训练集和测试集的划分方式加以约束,深度学习模型就不再有效。例如,为了验证模型的系统性,可以让模型在训练阶段除了“jump -> JUMP”之外不再接触任何与 jump 有关的样例,而在测试阶段去看模型是否能够在包含 jump 的句子(例如:“jump around left”)上做对。实验结果表明,在这样的设定下,深度学习模型仅能达到1.2%的准确率。
另一方面,为了验证模型的生产性,则可以让模型在训练阶段只接触指令序列长度小于24的样例,而在测试阶段去看模型是否能够正确地生成长度不小于24的指令序列。实验结果表明,在这样的设定下,深度编解码网络仅能达到20.8%的准确率。诸如此类的一系列研究表明,现有的深度学习模型在语义解析任务上不具备组合泛化能力[4][5]。
在当前的工业实践中,从业者主要通过深度学习与人工规则的混合系统来缓解这一瓶颈(数据增广也可以归入其中,因为需要增广哪些数据通常也需要人工归纳)。本文想要探讨一种更有趣的思路:是否能够在深度学习中引入合适的归纳偏置,使之摆脱简单的记忆与模仿,也不需要引入人工规则,而是自动地探索、发现并归纳出数据集中内在的组合性规律,从而使端到端的深度神经网络具备组合泛化能力。
在深度神经网络中模拟人脑的抽象化思维

人类的认知之所以具备组合泛化能力,关键在于抽象化(Abstraction),即省略事物的具体细节,以减少其中所含的信息量,从而更有利于发现事物间的共性(规律)。
这种抽象化能力是一种代数能力,而这正是现有的深度神经网络所缺乏的。如图5左侧所示,对于 AI 编程任务,现有的深度神经网络更倾向于“死记硬背”:自然语言和程序语言被看作是两个集合,那么学习到的只能是具体的自然语言句子和具体的程序之间的简单映射关系,这样自然是难以做到组合泛化的。对于这一问题,关键思路在于,将自然语言和程序语言看作是两个代数结构,且需要让深度神经网络倾向于学习这两个代数结构之间的同态(如图5右侧所示)。



图5:不要学习集合之间的映射,改为学习代数结构之间的同态

更形象地来说,如果训练数据中已经包含“run opposite walk”、“run after left”、 “walk twice”等样例,现在面对如下样例:
INPUT: “run opposite left after walk twice”
OUTPUT: “WALK WALK LTURN LTURN RUN”
深度学习模型的实质是记住诸如此类输入输出对之间的映射关系,而人类的认知则倾向于做出如图6所示的抽象化:



图6:相比于深度学习的直接记忆与模仿,人类思维更倾向于将具体对象层次化地抽象为具有共性的解析表达式

图6的左侧自下而上地给出了对于作为输入的自然语言句子的抽象化过程。在第1、2、4步,分别剥离掉“run”、“left”和“walk”这三个单词的具体属性,将它们抽象为变量;在第3、5、6步,分别剥离掉“$x opposite $y”、“$y twice”和“$x after $y”这三个子句属性,也将它们抽象为变量。人类记住的并非输入与输出之间的直接映射,而是这一抽象化过程中每一步所产生的局部映射(如图6右侧所示)的集合。例如,在第1步中,将单词“run”映射到了程序“RUN”上;在第3步中,将抽象子句“$x opposite $y”映射到了程序“$Y $Y $X”。此处的“$X”是一个程序中的变量,指代自然语言中的变量“$x”所对应的程序;同样地,$Y$亦是一个程序中的变量,指代自然语言中的变量“$y”所对应的程序。
上述例子说明了,相比于直接记住相对复杂的具体映射,人类更倾向于从中归纳出相对简单的共性抽象映射,从而获得组合泛化能力。因此,为了让深度学习也获得组合泛化能力,需要设计一种能够模拟人类认知中的抽象化过程的新型神经网络架构。
将输入/输出的各个具体对象形式化,称为源域表达式(Source Expression, SrcExp)/目标域表达式(Destination Expression, DstExp),统称为表达式(Expression, Exp)。若表达式中的某个/某些子部分被替换为变量,则称这些带变量的表达式为解析表达式(Analytical Expression, AE)。同样地,解析表达式也可分为源域解析表达式(SrcAE)和目标域解析表达式(DstAE)。
对于每个输入的 SrcExp,神经网络架构需要通过若干次抽象化操作逐渐地将其转换为更简单的 SrcAE(如图6左侧所示)。在这一抽象化过程中,每个被置换为变量的 SrcAE 将被解析为一个 DstAE,最终由这些 DstAE 组合形成一个 DstExp 作为输出(如图6右侧所示)。模型需要以这种抽象化过程作为一种归纳偏置,在不依赖任何人工预定义的抽象/映射规则的前提下,完全自动化地完成对具体的抽象化过程与表达式映射的探索与学习。
LANE 的模型实现

新型的神经网络架构 LANE(Learning Analytical Expressions)能够在语义解析任务中模拟人类的抽象化思维,从而获得组合泛化能力。在之前的神经网络学习框架中,神经网络是直接被用来学习一个从具体的源字串(Source Token Sequence)到具体的目标串(Destination Token Sequence)的映射函数。而在 LANE 中,需要学习的是一个定义域和值域分别是由源字串抽象化后导出的解析表达式和目标串解析表达式的函数。
LANE 由两个神经网络模块构成:一个模块称为 Composer,由一个 TreeLSTM 模型实现,负责对输入的 SrcExp 进行隐式树状归纳(Latent Tree Induction),从而得到逐渐抽象简化的中间 SrcAE;另一个模块称为 Solver,负责在每次抽象发生时进行局部语义解析,将语义细节剥离并保留在记忆单元(Memory)中,从而使得后续处理过程中这些细节被简化为一个变量。



图7:LANE: 用神经网络学习隐式的解析表达式,以模拟人类的抽象化思维

图7解释了 LANE 的工作流程,也展示了 LANE 如何处理图6中的第5步和第6步抽象。在第5步抽象化过程中,对于当前的 SrcAE “$x after $y twice”,Composer 基于树状 LSTM 输出下一步抽象动作:应该对“$y twice”这个局部进行抽象化。Solver 则使用一个深度编解码网络将“$y twice”解释为 DstAE “$Y $Y”,与原 Memory 中的“$Y = WALK”结合得到新变量所对应的 DstExp “WALK WALK”,并以此更新 Memory。经过这一过程,“$x after $y twice”中的“$y twice”这部分细节被剥离掉了,形成了一个抽象程度更高的 SrcAE “$x after $y”,进而可以开始第6步抽象。通过这样的方式,Composer 与 Solver 协同工作,LANE 将输入的 SrcExp 逐渐抽象为简化程度越来越高的 SrcAE,直到形成一个由单变量构成的最简 SrcAE。该变量在 Memory 中对应的取值即为最终输出的 DstExp。
由于 LANE 中包含不可求导的离散操作,因此可以基于强化学习(Reinforcement Learning)来实现模型的训练。模型训练有如下三个关键点:
1. 奖励(Reward)设计 。Reward 分为两部分:一部分是基于相似度的奖励,即模型生成的 DstExp 与真实的 DstExp 之间的序列相似度;另一部分是基于简洁度的奖励,它是受奥卡姆剃刀原则启发,用于鼓励模型生成更通用/简洁的解析表达式。由于这两个奖励的设计都没有刻意引入任务相关的特别知识,表明 LANE 应该具有很大的普适性。
2. 分层强化学习(Hierarchical Reinforcement Learning)。Composer 和 Solver 协同工作,但地位并不相同:Solver 的决策依赖于 Composer 的决策。因此,将 Composer 和 Solver 分别视作高层代理(High-level Agent)和底层代理(Low-level Agent),应用分层强化学习联合训练这两个模块。
3. 课程学习(Curriculum Learning)。为了加强探索效率,根据 SrcExp 的长度将数据划分为从易到难的多个课程。模型先在最简单的课程上进行训练,而后逐渐将更难的课程加入训练。
实验结果

Lake 等人建立了一套基准数据集 SCAN,用于评测语义解析系统的组合泛化能力[4]。该数据集上衍生出了多个子任务,用于度量不同方面的组合泛化能力。例如,ADD_JUMP 子任务用于度量模型是否能够处理新引入元素的组合;LENGTH 子任务用于度量模型是否能够生成超出训练数据中已知长度的组合。研究实验结果表明,LANE 在这些子任务上均达到了100%的准确度。



图8:LANE 在 SCAN 的各个子任务上均达到100%的准确度

图9展示了 LANE 中的 Composer (TreeLSTM)学习得到的两个隐式树结构作为示例。TreeLSTM 在具体实现时是二叉化的,将具体进行抽象动作的结点着黑色。可以看到,即使并未引入任意人工预定义的抽象/映射规则,LANE 也能够自动化地探索出符合人类思维的抽象化过程。



图9:示例:LANE 学习得到的两个隐式树结构

新型的端到端神经网络架构 LANE 能够模拟人类的抽象化思维能力,以此学习到数据中潜在的解析表达式映射,从而在 AI 编程(语义解析)任务中获得组合泛化能力。微软亚洲研究院的研究员们希望以此作为一个出发点,探讨深度学习如何由 “鹦鹉范式”(记忆与模仿)走向“乌鸦范式”(探索与归纳),从而延伸其能力边界。不过目前这还是初步的理论研究,想要应用到更复杂的任务中还需要很多后续工作(例如,提高训练效率、提高容错学习能力、与无监督方法结合等)。
论文:https://arxiv.org/abs/2006.10627
代码:https://github.com/microsoft/ContextualSP
参考文献
[1] 《智能数据分析技术,解锁Excel“对话”新功能》<https://www.msra.cn/zh-cn/news/features/conversational-data-analysis>
[2] 《对话即数据流:智能对话的新方法》<https://www.msra.cn/zh-cn/news/features/dialogue-as-dataflow>
[3] 《朋友送了我一个会编程的机器人,说程序员可以下岗了!!!》<http://dwz.date/dgNY>
[4] Brenden Lake, Marco Baroni. Generalization without Systematicity: On the Compositional Skills of Sequence-to-Sequence Recurrent Networks. 2018. <https://arxiv.org/abs/1711.00350>.
[5] Daniel Keysers, et al. Measuring Compositional Generalization: A Comprehensive Method on Realistic Data. 2019. <https://arxiv.org/abs/1912.09713>
<hr/>本账号为微软亚洲研究院的官方知乎账号。本账号立足于计算机领域,特别是人工智能相关的前沿研究,旨在为人工智能的相关研究提供范例,从专业的角度促进公众对人工智能的理解,并为研究人员提供讨论和参与的开放平台,从而共建计算机领域的未来。
微软亚洲研究院的每一位专家都是我们的智囊团,你在这个账号可以阅读到来自计算机科学领域各个不同方向的专家们的见解。请大家不要吝惜手里的“邀请”,让我们在分享中共同进步。
也欢迎大家关注我们的微博和微信 (ID:MSRAsia) 账号,了解更多我们的研究。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|T9AI - 深度人工智能平台 ( 沪ICP备2023010006号 )

GMT+8, 2024-11-21 21:57 , Processed in 0.069512 second(s), 24 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表