当前位置: 首页 > 科技观察

输入例子,自动生成代码:TensorFlow官方工具TF-Coder开源了

时间:2023-03-21 12:17:05 科技观察

如何让编程更方便?近日,谷歌TensorFlow开源了一款程序合成工具TF-Coder,帮助开发者编写TensorFlow代码。项目地址:https://github.com/google-research/tensorflow-coderGoogleColab试用地址:https://colab.research.google.com/github/google-research/tensorflow-coder/blob/master/TF-Coder_Colab.ipynb论文地址:https://arxiv.org/pdf/2003.09040.pdf用过TensorFlow框架的人应该知道,在操作张量时,需要跟踪多个维度、张量形状和数据类型兼容性。当然也需要考虑数学上的正确性。此外,TensorFlow有数百个操作,找到正确的操作是一项挑战。因此,与其直接对张量操作进行编码,不如直接浏览一个说明性示例并自动获取相应的代码会怎么样?这个想法听起来很诱人,而TensorFlowCoder(TF-Coder)使之成为可能!TF-Coder的原理是:给定期望张量变换的输入输出例子,TF-Coder进行组合搜索,找出可以进行这种变换的TensorFlow表达式,最终输出对应的TensorFlow代码。给定输入输出示例,TF-Coder在1.3秒内找到解决方案。TF-Coder的合成算法如下:下面的动画展示了使用TF-Coder解决张量操纵问题的过程:那么,TF-Coder工具可以在哪些场景下发挥作用呢?TF-Coder:TensorFlowprogrammingbyexample如果你想依次添加一个包含M个元素的向量(下例中的'rows')和一个包含N个元素的向量(下例中的'cols'),生成一个包含Mx所有成对总和的N矩阵。使用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工具一秒内自动找到合适的TensorFlow代码:tf.add(cols,tf.expand_dims(rows,1))这个简单的例子旨在用例子来说明TF-Coder编程的思想。而TF-Coder的功能还不止于此,它还可以用在更难的编程问题中。TF-Coder帮助您找到正确的函数假设您正在处理数字特征,例如商品的价格。数据集中的价格范围很广,例如从不到10美元到超过1000美元。如果直接将这些价格用作特征,则模型可能会过拟合,并且在模型评估阶段可能难以处理离群值价格。要解决上述问题,您可能需要使用分桶将数字价格转换为分类特征。例如,使用桶边界[10,50,100,1000]意味着低于10美元的价格应该进入桶0,价格在10美元和50美元之间应该进入桶1,等等。选择桶边界后,如何使用TensorFlow将数字价格映射到桶索引?例如,给定以下存储桶边界和项目价格:#Inputtensorsboundaries=[10,50,100,1000]prices=[15,3,50,90,100,1001]计算每个项目的存储桶编号:#Outputtensorsbucketed_prices=[1,0,2,2,3,4]尽管TensorFlow有多种分桶操作,但要弄清楚哪一个适合执行这种分桶操作可能很棘手。由于TF-Coder可以按行为识别数百种Tensor操作,您可以通过提供输入输出示例找到正确的操作:#Input-outputexampleinputs={'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='右')TF-Coder:以巧妙的方式组合函数现在我们来看另一个问题:计算一个0-1张量,它在输入张量的每一行中找到最大的元素。#Inputtensorscores=[[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]]#Outputtensortop_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-outputexampleinputs={'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:用更少的调试编写准确的代码考虑通过将每一行除以行的总和来将出现的整数列表归一化为概率分布。例如:#Inputtensorcounts=[[0,1,0,0],[0,1,1,0],[1,1,1,1]]#Outputtensornormalized=[[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),也不容易编写出正确的代码。第一次尝试可能看起来像这样:#Firstattemptnormalized=tf.divide(counts,tf.reduce_sum(counts,axis=1))但上面的代码正确吗?我们需要考虑很多潜在的问题:代码中axis的值是否正确?axis=0应该改变吗?counts和tf.reduce_sum(counts,axis=1)的形状是否与除法兼容?需要重塑或执行转置?counts和tf.reduce_sum(counts,axis=1)都是tf.int32张量。tf.int32张量可以被分割吗?我需要先将它转换为float数据类型吗?两个参数的顺序是否正确?需要换地方吗?输出的类型是tf.int32、tf.float32还是其他?有没有更简单或更好的方法?使用TF-Coder,您只需给出以下输入输出示例:#Input-outputexampleinputs={'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可以帮助开发人员编写简单准确的代码,而无需痛苦的调试过程。局限性然而,TF-Coder也有其局限性。目前它可以在一分钟内找到涉及3或4个操作的解决方案,但在短时间内找到涉及6个或更多操作的解决方案对它来说仍然太复杂了。此外,TF-Coder尚不支持复数张量、字符串张量或RaggedTensors。有关TF-Coder支持的操作的完整列表,请参阅:https://colab.research.google.com/github/google-research/tensorflow-coder/blob/master/TF-Coder_Colab.ipynb#scrollTo=Q6uRr4x9WHRC此外,TF-Coder只能保证解决方案适用于给定的输入输出示例。该工具搜索与给定输入输出示例匹配的简单TensorFlow表达式,但有时“太简单”而无法按预期进行概括。它有助于使示例尽可能明确,通常是通过向输入和输出张量添加更多值。