编写复杂 TensorFlow 表达式的好工具:TF-Coder

2020 年 8 月 28 日

编写复杂 TensorFlow 表达式的好工具:TF-Coder

当我们操作张量时,必须跟踪多维度、张量形状和 DType 的兼容性,当然还有数学方面的正确性。此外,还有数以百计的 TensorFlow 操作,要找到正确的操作,真不失为一项挑战。


与其直接编写张量操作代码,还不如通过一个说明性例子演示一下,然后就自动获得相应的代码,TensorFlow Coder(TF-Coder)使这成为可能。


TF-coder 是一款程序合成工具,可以帮助你编写 TensorFlow 代码。首先,该工具要求提供所需张量变换的输入输出示例。然后,它运行一个组合搜索来查找执行该转换的 TensorFlow 表达式。TF-Coder 的输出是真正的 TensorFlow 代码,可以将其包含在项目中。


下图介绍了 TF-Coder,这个Colab notebook允许使用 TF-Coder 来解决张量操作问题。



在本文中,我们将举例说明 TF-Coder 可以帮助编写 TensorFlow 代码的各种场景。


TensorFlow 编程示例


假设你想以广播的方式将一个 M-元素向量与一个 N-元素向量“相加”,产生一个包含所有对偶和的 M×N 矩阵。与其在 TensorFlow 文档中挖空心思地找出如何做这件事,不如提供一个输入输出的例子(使用 M=3 和 N=4):


输入张量,作为将输入变量名称映射到示例张量值的 dict。


inputs = {'rows': [10, 20, 30],'cols': [1, 2, 3, 4],}
复制代码


所需的输出张量,对应于所提供的输入张量:


output = [[11, 12, 13, 14],[21, 22, 23, 24],[31, 32, 33, 34]]
复制代码


有了这些信息(默认情况下已输入到 TF-Coder Colab 中),TF-Coder 工具将在几分之一秒内自动找到合适的 TensorFlow 代码:


tf.add(cols, tf.expand_dims(rows, 1))
复制代码


上面的问题很简单,只是为了通过示例来说明编程的思想。TF-Coder 对于较难的问题也很有用,我们将在下面说明。


TF-Coder 帮助找到要使用的正确函数


假设你正在处理一个数字特征,比如,一个物品的价格,在你的数据集中,价格有很大的范围,例如,从 10 美元以下到 1000 美元以上。如果直接将这些价格作为特征来使用,你的模型可能会对训练数据中的特定价格出现过拟合现象,而且在评估过程中也可能难以处理异常价格。


为了处理这些问题,你可能需要使用分桶(bucketing)方法将数字价格转换为分类特征。例如,使用桶(bucket)边界 [10,50,100,1000] 意味着 10 美元以下的价格应该归入 bucket 0,10~50 美元之间的价格归入 bucket 1,以此类推。


选择桶边界之后,要如何使用 TensorFlow 将数字价格映射到桶索引呢?例如,给定以下桶边界和物品价格:


# Input tensorsboundaries = [10, 50, 100, 1000]prices = [15, 3, 50, 90, 100, 1001]
复制代码


你需要计算每个项目的桶号:


# Output tensorbucketed_prices = [1, 0, 2, 2, 3, 4]
复制代码


虽然 TensorFlow 自带了各种各样的分桶操作,但要弄清楚哪些特定操作进行这种分桶处理,可能会很棘手。由于 TF-Coder 可以通过行为识别数百种张量操作,因此可以通过提供输入输出示例来查找正确的操作。


# Input-output exampleinputs = {'boundaries': [10, 50, 100, 1000],'prices': [15, 3, 50, 90, 100, 1001],}output = [1, 0, 2, 2, 3, 4]
复制代码


在几秒钟之内,TF-Coder 输出以下解决方案:


tf.searchsorted(boundaries, prices, side='right')
复制代码


这给了我们一个有用的提示,并且tf.searchorsted的文档也证实这段代码确实按照预期执行了分桶操作。


TF-Coder 帮助你以巧妙的方式组合函数


现在,让我们考虑另一个问题:计算一个 0-1 张量,它标识输入张量每行的最大元素。


# Input tensorscores = [[0.7, 0.2, 0.1],[0.4, 0.5, 0.1],[0.4, 0.4, 0.2],[0.3, 0.4, 0.3],[0.0, 0.0, 1.0]]# Output tensortop_scores = [[1, 0, 0],[0, 1, 0],[1, 0, 0],[0, 1, 0],[0, 0, 1]]
复制代码


请注意,如果同一个最大的元素在一行内多次出现,比如在scores的第三行中,那么应该只标记第一个这样的最大元素,这样每一行的top_scores都有一个条目1


与上一个问题不同的是,没有单一的 TensorFlow 函数可以执行此计算。如果在文档中搜索“max”,你可能会发现tf.reduce_maxtf.argmaxtf.maximum相关,但是应该用哪一个呢?tf.reduce_max产生[0.7, 0.5, 0.4, 0.4, 1.0]tf.argmax产生[0, 1, 0, 1, 2]tf.maximum是不正确的,因为它需要两个参数。这些看起来距我们想要的输出相差甚远。


TF-Coder 可以帮助解决这类棘手的问题。你可以用输入输出示例的形式来编写问题:


# Input-output exampleinputs = {'scores': [[0.7, 0.2, 0.1],[0.4, 0.5, 0.1],[0.4, 0.4, 0.2],[0.3, 0.4, 0.3],[0.0, 0.0, 1.0]],}output = [[1, 0, 0],[0, 1, 0],[1, 0, 0],[0, 1, 0],[0, 0, 1]]
复制代码


TF-Coder 在一个简短的解决方案中使用了tf.one_hottf.argmax的组合:


tf.cast(tf.one_hot(tf.argmax(scores, axis=1), 3), tf.int32)
复制代码


通过对 TensorFlow 操作组合进行详细搜索,TF-Coder 经常会找到类似这样的优雅解决方案,这可能会简化并加快你的 TensorFlow 程序。


TF-Coder 可以帮助你编写调试更少的正确代码


考虑将整数列表归一化为概率分布,方法是将每一行除以该行之和。例如:


# Input tensorcounts = [[0, 1, 0, 0],[0, 1, 1, 0],[1, 1, 1, 1]]# Output tensornormalized = [[0.0, 1.0, 0.0, 0.0],[0.0, 0.5, 0.5, 0.0],[0.25, 0.25, 0.25, 0.25]]
复制代码


即使你知道要使用的相关函数(tf.reduce_sum后跟tf.divide),编写正确的代码仍然是非常重要的。第一次尝试可能是这样的:


# First attemptnormalized = tf.divide(counts, tf.reduce_sum(counts, axis=1))
复制代码


这是正确的吗?有许多潜在的陷阱需要加以考虑:


  • 求和轴是否正确?还是应该是axis=0

  • counts的形状和tf.reduce_sum(counts, axis=1)是否兼容除法,还是需要重塑或转置这两者中的任何一个?

  • countstf.reduce_sum(counts, axis=1)都是tf.int32张量。tf.int32可以用除法吗?还是需要首先将它们转换为 float DType?

  • 这两个参数的顺序是否正确,还是应该互换一下?

  • 输出类型是tf.int32tf.float32,还是别的什么?

  • 有没有尚未考虑的更简单或更好的方法?


你可以通过以下输入输出示例将此任务交给 TF-Coder:


# Input-output exampleinputs = {'counts': [[0, 1, 0, 0],[0, 1, 1, 0],[1, 1, 1, 1]],}output = [[0.0, 1.0, 0.0, 0.0],[0.0, 0.5, 0.5, 0.0],[0.25, 0.25, 0.25, 0.25]]
复制代码


TF-Coder 的解决方案是:


tf.cast(tf.divide(counts, tf.expand_dims(tf.reduce_sum(counts, axis=1), axis=1)), tf.float32)
复制代码


通过使用 TF-Coder 来解决这一问题,减轻了开发人员的心理负担。当 TF-Coder 生成上面的解决方案是,可以保证代码在示例输入上运行时正确地生成示例输出。TF-Coder 的解决方案还将避免任何不必要的步骤。隐私,你可以快速地推导出上述大部分问题的答案:为使形状与除法兼容,需要额外的tf.expand_dims步骤,并且tf.Divide的结果必须强制转换为tf.float32(实际上,tf.divide在除以两个tf.int32张量时返回tf.float64张量)。通过这种方式,TF-Coder 可以帮助你编写简单而正确的代码,而无需经历通过的调试周期。


注意事项


TF-Coder 有一些限制。它目前可以在一分钟内找到涉及 3~4 个操作的解决方案,但涉及 6 个或更多操作的解决方案对 TF-Coder 来说太过复杂,无法在合理的时间内找到。此外,TF-Coder 目前尚不支持复张量、字符串张量或不规则张量。支持的操作的完整列表可以在Colab notebook中找到。


此外,TF-Coder 只保证其解决方案对给定的输入输出示例有效。该工具会搜索与提供的输入输出示例匹配的简单 TensorFlow 表达式,但有时候这个解决方案过于简单,不能以语气的方式进行泛化。使示例尽可能清晰可能会有所帮助,这通常可以通过向输入和输出张良添加更多的数字来实现。请查看 TF-Coder 的解决方案,以确保它们正确地实施了预期的行为。


亲自尝试 TF-Coder


一定要亲自尝试 TF-Coder!哪怕是 Google 有经验的 TensorFlow 用户,也可以在 TF-Coder 的帮助下学习新事物。


你可以使用这个Colab notebookd访问该工具,无需下载或者安装。按照本教程进行详细的演练。你也可以看看我们托管在 GitHub上的代码和文档,以及我们的研究论文


注意:在 Colab 工具中,我们希望记录 TF-Coder 的问题和由此产生的解决方案,这样我们就可以改进工具,并构建一个数据集来加速程序的综合研究,但是,这种数据收集是完全可选的。


原文链接


https://blog.tensorflow.org/2020/08/introducing-tensorflow-coder-tool.html


2020 年 8 月 28 日 15:381077
用户头像
赵钰莹 InfoQ高级编辑

发布了 648 篇内容, 共 383.7 次阅读, 收获喜欢 2082 次。

关注

评论 1 条评论

发布
用户头像
有这么厉害?我下载试试去,要是真这么好用,可真就是帮了大忙了!谢谢小编!
2020 年 08 月 28 日 16:37
回复
没有更多评论了
发现更多内容

iOS 动画 - 窗景篇(三·完结)

柯烂

ios swift 动画 移动互联网 动效

海阅优品致力打造新零售蓝海

Geek_116789

计算机操作系统基础(五)---Linux的进程管理

书旅

php 线程 多线程 操作系统 进程

实现简单的"纤程"

Near

软件架构语录

hiqian

MySQL系列 - SQL查询与修改执行过程

俊俊哥

MySQL 性能优化 关系型数据库 存储

如何学 Java,我说点不太一样的学习方式

四猿外

学习 程序员 个人成长 程序员成长

架构师训练营第四周课后作业

竹森先生

极客时间 极客大学架构师训练营

对直播带货的一点思考

Neco.W

直播 直播带货

MySQL实战45讲笔记(1)

王传义

msyql

告别静默式看房 融云音视频助力上海中原 App 上线 VR 带看服务

Geek_116789

【写作群星榜】6.20~6.26 写作平台优秀作者 & 文章排名

InfoQ写作平台

写作平台 排行榜

创新管理体系标准ISO56002介绍

涛哥

数字化转型 创新

科学计算软件被禁,阿里达摩院能研发Matlab?

飞哥

阿里巴巴 matlab

那些会阻碍程序员成长的细节[3]

码闻强

程序员 职业规划 职业成长

深入浅出kubernetes之WorkQueue详解

博文视点Broadview

Kubernetes 源码分析 k8s 队列 延迟队列

架构师训练营第四周作业

张明森

架构师训练营第四周学习总结

张明森

玩转Java8中的 Stream 之从零认识 Stream

Java小咖秀

学习 stream java8 Java 面试 经验

为什么建议你使用枚举?

王磊

Java 枚举

了不起的 TypeScript 入门教程 [1.2 w字]

阿宝哥

Java typescript 前端 Web

聊一聊程序员如何增加收入

张小方

程序员 互联网 面试 副业赚钱 薪资

一群龙舟划手 “拍了拍” 你:端午节安康~

BonreeAPM

来了!8M/S+速度,Pdown复活!

程序员生活志

一二线城市知名 IT 互联网公司名单(新版)

程序员生活志

互联网 IT 大厂

融云年中大促钜惠来袭 IM+RTC 超值套餐最低6折起

Geek_116789

Dart vs Swift

柠檬水

swift dart

势能造就下的互联网大厂程序员为什么去开滴滴了?

非著名程序员

程序员 程序人生 提升认知 程序员成长

IM聊天教程:发送图片/视频/语音/表情

GoEasy消息推送

websocket 即时通讯 聊天室 聊天

从0开始设计Flutter独立APP | 第二篇: 完整的国际化语言支持

渔子长

flutter 前端

重学 Java 设计模式:实战中介者模式「按照Mybatis原理手写ORM框架,给JDBC方式操作数据库增加中介者场景」

小傅哥

设计模式 小傅哥 代码优化 代码规范 中介者模式

编写复杂 TensorFlow 表达式的好工具:TF-Coder-InfoQ