来源|机器之心
怎样使编程愈发方便?近来,微软TensorFlow开源了一个帮助开发者写TensorFlow代码的程序合成工具TF-Coder。
用过TensorFlow框架的应当都晓得,在操纵张量时,须要跟踪多个维度、张量形状和数据类型兼容性,其实还须要考虑物理正确性。据悉,TensorFlow有数百种操作,找到要使用的正确操作也是一项挑战。
这么,不仅直接对张量操纵进行编码以外,倘若仅通过一个说明性示例进行演示,能够手动获取相应的代码呢?这个看法听上去很迷人,而TensorFlowCoder(TF-Coder)使这成为可能!
TF-Coder的原理是:给出期望张量变换的输入-输出示例,TF-Coder运行组合搜索,找出还能执行此变换的TensorFlow表达式,并最终输出对应的TensorFlow代码。
给出输入-输出示例,TF-Coder在1.3秒内找出解决方案。
TF-Coder的合成算法如下所示:
下边的动图展示了使用TF-Coder解决张量操纵问题的过程:
这么,TF-Coder工具可以在什么场景中起到作用呢?
TF-Coder:通过示例进行TensorFlow编程
如果你想将包含M个元素的向量(下例手指‘rows’)和包含N个元素的向量(下例手指‘cols’)依次进行相减,生成一个包含所有成对和的MxN矩阵。
使用TF-Coder,你只需提供一个输入-输出示例(M=3,N=4)即可完成该操作,无需逐行进行编程。
比如输入张量为:
inputs = {
'rows': [10, 20, 30],
'cols': [1, 2, 3, 4],
}
对应的输出张量为:
output = [[11, 12, 13, 14],
[21, 22, 23, 24],
[31, 32, 33, 34]]
基于以上输入-输出信息(默认情况下早已输入到TF-CoderColab中),TF-Coder工具将在1秒内手动找到合适的TensorFlow代码:
tf.add(cols, tf.expand_dims(rows, 1))
这个简单的事例借以说明TF-Coder借助示例进行编程的思想。而TF-Coder的功能不止于此,它还可用于更难的编程问题中。
TF-Coder帮你找到正确的函数
假定你正在处理数值特点,如某个物品的价位。数据集中的价钱范围很广,比如从高于10欧元到超出1000美金不等。若果这种价位被直接用作特点,则模型可能出现过拟合,在模型评估阶段可能无法处理异常价位。
为了解决上述问题,你可能须要使用bucketing,来将数字价钱转换为类别特点。比如,使用bucket边界[10,50,100,1000]意味着高于10英镑的价钱应划入bucket0,10港元至50港元的价钱应划入bucket1,依这种推。
在选择bucket边界以后,怎么使用TensorFlow将数值价钱映射到bucket索引呢?诸如,给出以下bucket边界和物品价钱:
# Input tensors
boundaries = [10, 50, 100, 1000]
prices = [15, 3, 50, 90, 100, 1001]
估算每位项的bucket编号:
# Output tensor
bucketed_prices = [1, 0, 2, 2, 3, 4]
虽然TensorFlow具备多种bucketing操作,但要弄清楚哪种操作适宜执行这些bucketing,也是比较棘手的事情。因为TF-Coder可以通过行为辨识数百个Tensor操作,因而你可以通过提供输入-输出示例来查找正确的操作:
# Input-output example
inputs = {
'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-Coder:用聪明的方法结合函数
如今我们来看另一个问题:估算一个0-1张量,它可以找出输入张量每一行中的最大元素。
# Input tensor
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 tensor
top_scores = [[1, 0, 0],
[0, 1, 0],
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]
注意,假若一行内相同的最大元素重复出现(如scores中的第三行),则标记第一次出现的最大元素,这样top_scores的每一行都只有一个1。
与上一个问题不同,这儿不存在可执行该估算的TensorFlow函数。在文档中搜索「max」,你可能找到tf.reduce_max、tf.argmax和tf.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 example
inputs = {
'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_hot和tf.argmax,得到问题的解:
tf.cast(tf.one_hot(tf.argmax(scores, axis=1), 3), tf.int32)
通过对TensorFlow操作组合进行详尽搜索,TF-Coder一般才能发觉高贵的解决方案,进而简化步骤,加速TensorFlow程序。
TF-Coder:用更少的debug,写出确切的代码
考虑通过将每一行减去该行之和,把整数出现次数列表归一化为机率分布。诸如:
# Input tensor
counts = [[0, 1, 0, 0],
[0, 1, 1, 0],
[1, 1, 1, 1]]
# Output tensor
normalized = [[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_sumfollowedbytf.divide),写出正确的代码也并非易事。第一次尝试可能是这样的:
# First attempt
normalized = tf.divide(counts, tf.reduce_sum(counts, axis=1))
然而以上代码是正确吗?我们须要考虑许多潜在的问题:
而使用TF-Coder,你只须要给出以下输入-输出示例:
# Input-output example
inputs = {
'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.expand_dims步骤,使张量形状与乘法兼容;tf.divide的答案必须是tf.float32类型。
通过这些方法,TF-Coder可以帮助开发者编撰简单确切的代码,且无需苦闷的debug过程。
局限性
不过,TF-Coder也有其局限性。目前它可以在一分钟内找到涉及3到4种运算的解决方案,但短时间内找到涉及6种及以上操作的解决方案,对它来说还是太过复杂。据悉淘宝装修模版代码自动生成器,TF-Coder尚不支持复张量、字符串张量或RaggedTensor。
TF-Coder支持操作的完整列表,参见:#scrollTo=Q6uRr4x9WHRC
据悉,TF-Coder只能保证解决方案对给出的输入-输出示例有效。该工具会搜索一个与给定输入-输出示例相匹配的简单TensorFlow表达式,但有时侯「过于简单」,不能按预期进行泛化。尽可能让示例无歧义会有所帮助,这通常可以通过向输入和输出张量添加更多数值来实现。一起交流
重磅推荐!NewBeeNLP目前早已构建了多个不同方向交流群(机器学习/深度学习/自然语言处理/笔试交流/大厂内推等),赶快添加下方陌陌加入一起讨论学习吧!
-END-
记得把NewBeeNLP设为星标哦
等你在看
暂无评论内容