重现基线模型

基线模型原理

我们选用的的模型为DeepCS,接下来我将解释一下它的原理。

我们要进行代码搜索,其实就是希望寻找一个代码片段(code snoppets)和它的自然语言描述(description)的一个对应关系,然而,由于编程语言和自然语言间存在的差异,如果仅仅依靠文本内容的相似性,很容易出现误匹配。我们就需要在另一个空间去寻找一种表征,或者说寻找一种或多种映射,让对应的代码片段和自然语言描述通过各自的映射,在新的空间足够的相似,这样也就能很方便的去根据相似性去搜索代码。

所以论文中提出了CODEnn模型(Code-Description Embedding Neural Network),所谓的embedding通俗来讲,就是用向量来表示一种实体(单词、图像等等),使得相似的物体在embedding的向量空间也足够相似(如余弦相似性)。如下图,由于代码和自然语言描述是两种不同的东西,我们也采用了两个不同的网络来分别进行embedding,使得语义对应的代码和描述在向量空间足够接近,而语义不同的代码和描述在向量空间则没有那么近。


代码和查询的联合embbeding

由于代码语言和自然语言都存在序列性,一句话前后的单词构成了一个序列,适合采用循环神经网络(RNN)来进行embedding,具体RNN方面的知识这里也就不详细介绍了,我们对各个时刻的隐藏层状态做一个最大值池化,来作为最终embedding的结果,它下面是CODEnn的一个整体结构图。


CODEnn结构图

对于代码,我们不是直接采用源代码,而是从中提取三部分,分别是方法的名字(采用驼峰法分解)、API的调用序列(代码中调用的各种函数接口)、源代码中的token(通俗的理解指不可分的最小符号,如一个一个单词,采用驼峰法分解)。对于描述,训练时我们通常采用文档描述的第一句话。下面是分解提取的一个例子。


代码元素提取示例

代码的三部分分别进行embedding(token部分无序列性,直接采用MLP,其余采用RNN),再通过一个全连接层将它们融合起来,作为最后的向量表示,而描述部分也进行embedding,然后采用余弦相似性来比较二者的相似程度。在训练的过程中,每个代码C都有一个正描述D+和负描述D-(D-从所有代码描述中随机选择),通过构造损失函数$\cal{L}(\theta) $,使得C和D+尽可能相似,而C和D-尽可能不同。

\[
\cal{L}(\theta) = \sum\limits_{\langle C, D+, D-\rangle \in P} max(0, \epsilon - cos({\bf c}, {\bf d+})+cos({\bf c}, {\bf d-}))
\]

训练好网络进行搜索时,整个模型的工作流如下图。


DeepCS工作流

搜索的代码库(search codebase)可以是用户自己定义的,代码库中的代码通过CoNN生成向量库,搜索时输入的查询语句通过DeNN也生成一个向量,再和所有的代码向量计算余弦相似性,选择相似性排前K的代码作为结果返回,完成搜索过程。

模型的优缺点

优点:

  • 可以理解查询语句的语义信息,而不是只是通过其中的关键词去比较。比如可以区分 "queue an event to be run on the thread"​ 和"run an event on a thread queue",这两句话中的关键词几乎一样,但是意思却完全不一样。
  • 搜索结果更鲁棒,不容易受不相关或者不重要的关键词影响。比如"get the content of an input stream as a string using a specified character encoding",不太重要的关键词就有specified和character等,而DeepCS可以识别出那些是最重要的关键词。
  • 它搜索的范围更大,不仅仅会返回关键词比较匹配的结果,也会返回关键词不是那么匹配但是语义相关的结果,也为查询的用户提供了更多可以参考的代码。

缺点:

  • 它的一个缺点是有时一些相关性不是那么高的代码反而会排在准确的代码的前面,这可能是因为模型返回结果完全是按照向量的相似性来排序的,然后向量的表示能力也与训练时选择的方式有很大关系,这些也是可以改进的地方。

模型重现结果

首先放上参考的结果( lr=1e-3, epoch=800)。

dataset acc@top 5 acc@10
validation set(pool=200) 0.806875 0.884375
validation set(pool=800) 0.621563 0.726250
test set(pool=200) 0.780667 0.860333
test set(pool=800) 0.596250 0.711250

由于时间等多方面的原因,我们未能完整的训练完800个epoch,但我们在训练的过程中发现,210个epoch后,测试的acc就开始成下降趋势(如下图),可能出现了过拟合,表现最好的测试结果如表格(210个epoch)。


训练过程acc

dataset acc@top 5 acc@10
validation set(pool=200) 0.763946 0.854014
validation set(pool=800) 0.560868 0.674792
test set(pool=200) 0.762517 0.853707
test set(pool=800) 0.557396 0.672014

由于训练的epoch不一样,也不便于直接比较,但可以看出,模型还是比较有效的。复现的一个难度主要还是时间问题,训练需要的时间太长了。

提出改进

改进动机

  • 考虑模型的主要缺点,即有时一些相关性不是那么高的代码反而会排在准确的代码的前面,说明模型embedding的结果不是那么鲁棒,有时原本不是那么相关的代码和描述,经过embedidng后在向量空间却相似了。一个可能的原因是训练的时候,缺少了相关的样本,所以模型没有学习到这一点。模型训练时,采用的时三元组,即(代码C,正描述D+,负描述D-),而代码中D-时随机采样得到的,因此可以考虑在构造三元组时,选择D-可以更有针对性一点,如果这一点比较难做到,也可以一个选更多不同的D-来构成一个多元组(当然Loss的表达式形式也要适当的调整)。

  • 同样考虑上一点,原模型中采用的是余弦相似度来衡量相似性,可能可以尝试其他的衡量方式,如欧氏距离、曼哈顿距离等。

  • 模型结构方面,首先是每个网络可以优化,如RNN、MLP的具体结构等,如代码中对于token集,其实并没有经过MLP,只是embedding后直接进行了dropout和pooling操作,这部分也可以改进。

  • 另一方面我们的训练样本代码部分是提取了三部分(方法的名字、API的调用序列、源代码中的token),可能对源代码的表示能力不够,也可以在数据处理上思考更合理的方式,如token现在不考虑顺序以及相互之间的关系,可以把这个也考虑进去。

新模型框架

以上改进并没有对原来的模型框架进行大幅度的调整,只是在具体的一些细节上提出了一些可能有效的改进,因此也就没有重新画一个结构图了。

评价合作伙伴

其实这次结对作业主要的贡献还是在他,我十一回家了,跑代码也不太方便,所以实验完全是由他在跑,我只是后来提出了一些改进建议,不过由于时间等问题,我们也没法具体实现了。总之,我的合作伙伴是非常靠谱的,之前也曾经多次合作过。至于可以改进的地方,其实应该是我们都可以改进的地方,就是不要太拖延吧,如果我们可以早一些开始工作,这次作业应该可以完成度更高一些。

ASE —— 第二次结对作业的更多相关文章

  1. 【ASE高级软件工程】第二次结对作业

    重现baseline 我们选择重现CODEnn模型(论文:Deep Code Search),因为它结构简单.端到端可训练,且相比其它方法拥有较高的性能. Baseline原理 为了根据给定的quer ...

  2. 第二次结对作业-WordCount进阶需求

    原博客 队友博客 github项目地址 目录 具体分工 需求分析 PSP表格 解题思路描述与设计实现说明 爬虫使用 代码组织与内部实现设计(类图) 算法的关键与关键实现部分流程图 附加题设计与展示 设 ...

  3. [W班]第二次结对作业成绩评价

    作业地址: https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1715W/homework/1016 作业要求: 1.代码具有规范性. ...

  4. UML第二次结对作业

    |作业要求|https://edu.cnblogs.com/campus/fzzcxy/2018SE1/homework/11250| | ---------- | ----------------- ...

  5. ASE第二次结对编程——Code Search

    复现极限模型 codenn 原理 其原理大致是将代码特征映射到一个向量,再将描述文字也映射到一个向量,将其cos距离作为loss训练. 对于代码特征,原论文提取了函数名.调用API序列和token集: ...

  6. 2017-2018-2 1723《程序设计与数据结构》第九周作业 & 第二周结对编程 总结

    作业地址 第九次作业:https://edu.cnblogs.com/campus/besti/CS-IMIS-1723/homework/1878 (作业界面已评分,可随时查看,如果对自己的评分有意 ...

  7. ASE——第一次结对作业

    ASE--第一次结对作业 问题定义 很早就听说了MSRA的黄金点游戏,让大家写Bot来参加比赛看谁的AI比较聪明可以操盘割韭菜.深感ASE课程老师设计的任务太用心了,各种接口都准备好了,大家只用专注于 ...

  8. 【第二次个人作业】结对作业Core第一组:四则运算生成PB16061082+PB16120517

    [整体概况] 1.描述最终的代码的实现思路以及关键代码. 2.结对作业两个人配合的过程和两个人分工. 3.API接口文档和两个组的对接. 4.效能分析,优化分析和心得体会. [代码实现] 一. 实现功 ...

  9. 第6次结对作业--郑锦伟&古维城

    第6次结对作业 在线英语学习平台客户端原型 1.结对成员 郑锦伟 2015034643034 古维城 2015034643033 2.原型设计工具实现-Photoshop 3.需求分析 使用NABCD ...

随机推荐

  1. 使用java自带线程池

    java提供自带的线程池,而不需要自己去开发一个自定义线程池了. 线程池类ThreadPoolExecutor在包java.util.concurrent下   ThreadPoolExecutor ...

  2. PAT 甲级 1045 Favorite Color Stripe (30 分)(思维dp,最长有序子序列)

    1045 Favorite Color Stripe (30 分)   Eva is trying to make her own color stripe out of a given one. S ...

  3. .NET CORE添加引用包

    一 .添加服务端引用 1.直接右键添加项目引用,添加后再csproj文件中如下②,也可以直接用这种格式写入csproj文件中 2.直接右键添加DLL引用,添加后再csproj文件中如下③,也可以直接用 ...

  4. <configSections> 位置引起的错误

    今天在配置一个项目的时候,花了挺长时间配置完成,然后一启动项目,懵了,启动报错:错误显示 Configuration Error Description: An error occurred duri ...

  5. 求数值的n次方根

    二分法 float SqrtByBisection(float n) //用二分法 { if(n<0) //小于0的按照你需要的处理 return n; float mid,last; floa ...

  6. 【c# 学习笔记】类与结构体的区别

    由于类与结构体在语法和使用上都非常类似,导致我们这些初学者容易混淆.为更好理解,特做以下区分记录: ① 语法上的区别在于,定义类要使用关键词class,而定义结构体则使用关键词struct. ② 结构 ...

  7. Linux中查找最耗CPU的Java代码问题

    第一步: 查看消耗CPU最高的进程PID [lolaage@web2 tomcat-ns]$ top top - 13:23:32 up 42 days, 19:11,  3 users,  load ...

  8. 【Python | opencv+PIL】常见操作(创建、添加帧、绘图、读取等)的效率对比及其优化

    一.背景 本人准备用python做图像和视频编辑的操作,却发现opencv和PIL的效率并不是很理想,并且同样的需求有多种不同的写法并有着不同的效率.见全网并无较完整的效率对比文档,遂决定自己丰衣足食 ...

  9. vmware 安装XP 32位Professional版本

    VMware14 安装XP 专业版,总部报错Dicrectory Boot not found   下载了N多个XP的版本发现,原来是XP版本的问题,现将正确版本写在这里,以备后用 百度网盘共享位置 ...

  10. Itellij IDEA下Maven的配置

    maven基本配置 配置阿里云镜像 打开settings.xml,添加 <mirrors> <mirror> <id>alimaven</id> < ...