引用:Wu Z, Johnson E, Yang W, et al. REINAM: reinforcement learning for input-grammar inference[C]. foundations of software engineering, 2019: 488-498.

摘要:程序输入语法有助于软件工程中的各种应用,例如符号执行和增量调试。通过现有方法合成的文法只能覆盖有效输入空间的一小部分,这主要是由于程序中的无法分析的代码(例如本机代码)以及缺乏高质量和高多样性的种子输入所致。为了解决这些问题,我们提出了 REINAM,一种强化学习方法,用于在没有任何种子输入的情况下合成基于概率的、上下文无关的程序输入语法。REINAM 使用工业级符号执行引擎为给定的目标程序生成一组初始输入,然后使用语法泛化的迭代过程主动生成其他输入,以推断从这些初始种子输入中泛化的语法。为了在候选运算符的巨大搜索空间中有效地搜索目标,RENAM 使用了一种新颖的搜索问题形式,即强化学习问题。我们对 11 个实际基准进行的评估表明,REINAM 在精确度方面优于现有的最佳的合成语法的调用方法,并且基于 REINAM 的模糊测试大大增加了有效输入空间的覆盖范围。REINAM 能够为某些基准合成涵盖整个有效输入空间的语法,而不会降低语法的准确性。

1. 介绍

许多程序将符号字符串作为输入。程序接受的这种字符串的集合称为语言,它由程序输入语法表示。程序输入语法有助于理解输入结构,并且对于多种应用程序都是必不可少的。尽管程序输入语法很重要,但是获取语法通常需要耗费大量的人力,并且这些语法通常没有规范或规范的形式对机器不友好(例如,文本文档)。

对于未以机器友好形式指定输入语法的程序,已有使用程序分析,语言推断和机器学习来合成输入语法的方法。但是,由于以下三个主要问题,这些现有的语法推断方法无法为现实世界的软件系统生成足够质量(就完整性和准确性而言)的语法。

不可分析的代码。基于程序分析的现有方法无法处理无法检测的程序(例如 Web 服务),也无法对难以处理的程序进行静态程序分析(例如本机代码或动态语言功能)。

种子输入的多样性和质量不足。基于语法泛化的现有方法利用算法在给定一组种子输入的情况下合成输入语法。但是,语言泛化算法的有效性在很大程度上取决于种子输入的种类和质量。

缺乏种子输入。通常没有足够的有效示例可供机器学习模型来学习。

我们旨在通过解决现有的最新语法推理方法一个的关键瓶颈来应对上述挑战。现有方法通常利用主动学习——即,它们使用泛化步骤的迭代过程,每个步骤都根据给定的种子输入生成新的候选语法。如果目标程序拒绝了其生成的字符串中的任何一个,则此类方法将舍弃候选语法。这种设计选择在主动学习方法中很常见,从而导致一种严格的策略“不允许过度泛化”,以确保每个泛化步骤中的候选语法都是精确的。

但是,该设计选择放弃了潜在地扩展最终合成语法所实现的覆盖范围的机会。例如,泛化运算符可能以少量的泛化为代价来增加覆盖范围,但是现有方法仍会拒绝这种泛化。此外,正如我们在第 3 节中说明的那样,即使泛化运算符经常导致语法不正确,多个此类不正确的泛化的组成也可能以形成准确的复合泛化的方式相互补充。

我们提出了 REINAM,这是一个使用强化学习来合成程序输入语法的框架。特别地,REINAM 通过保留接受不正确的泛化步骤的能力,同时仍然合成可实现高精度的最终语法,对现有方法进行了改进。REINAM 使用三个关键设计选择实现了这一目标。

第一,REINAM 不是将语法表示为确定性的上下文无关语法(CFG),而是将每个生产规则的准确度表示为概率性上下文无关文法(PCFG)中的概率。这种表示使 REINAM 不仅可以简单地确定规则是否过于泛化,还可以量化候选生产规则的质量。例如,它使 REINAM 可以在单个泛化步骤中保留不准确的生产规则,并在以后通过复合泛化减少或消除不准确性。

第二,REINAM 通过逐步改进不完善的候选语法,而不是像先前方法中使用的严格的“不允许过度泛化”策略那样丢弃这些语法,从而增强了最终合成语法的完整性。特别是,REINAM 使用机器学习来逐步调整 PCFG 模型中候选生产规则的可能性,以使规则更加准确。

图 1 显示了 REINAM 如何将语法综合任务表述为强化学习问题。在我们的公式中,代理(PCFG)正在与环境(目标程序)交互。代理选择一个导致状态转换(到目前为止构建的程序输入部分)的动作(用于生成程序输入的产品选择)。采取行动后,代理会观察下一个状态。最终(一旦程序输入被完全构建),代理就会从环境中获得奖励(基于输入是被接受还是被拒绝)。然后,REINAM 使用强化学习算法来更新代理参数(PCFG 概率)。

一个关键的问题是 REINAM 不仅需要调整 PCFG 的概率,而且还需要调整 PCFG 的结构(例如,通过添加新的候选词)来合成更通用的语法。但是,传统的强化学习算法仅调整代理的参数。因此,除了使用强化学习来调整 PCFG 的权重之外,REINAM 还使用修改 PCFG 结构的泛化运算符来调整 PCFG。特别地,REINAM 首先应用泛化运算符构造候选语法,然后优化相应 PCFG 的概率,最后使用 PCFG 概率来确定是否接受候选语法中的产物。

第三,REINAM 使用自动测试生成算法来生成其他种子输入。通过这样做,REINAM 改善了泛化能力,并弥补了现有的最先进方法的不足。

我们使用 11 种实际基准对 REINAM 进行了评估,并在实际场景中使用了手动编写的语法输入。我们测量合成语法的准确度和召回率,以及合成语法在基于语法的模糊测试中的优势。我们的评估结果表明,在大多数基准测试中,RENAM 在准确性,召回率和模糊测试覆盖率方面均优于 Glade。在我们的基准测试之一中,即 GNU Grep 接受的输入语法编码正则表达式,REINAM 将召回率从 0.02 提高到 1.0,这表明 REINAM 推断出的语法实际上覆盖了整个程序输入空间。

本文的主要贡献如下:

  • 以 PCFG 为主体,将输入的样本作为动作,将输入的接受作为奖励,以新颖的语法合成形式作为强化学习问题。

  • REINAM 学习算法,该算法反复选择要应用到当前 PCFG 的泛化运算符,使用强化学习来调整 PCFG 的概率,然后仅保留通用且准确的生产规则。

  • 对 11 个实际基准进行评估,以显示 REINAM 有效地合成了程序输入语法,并进一步提高了模糊测试的有效性。

2. 例子

Glade 的主要缺点是它依赖于“不允许过度泛化”的条件。在本节中,我们给出一个示例,说明为什么这种设计选择可能会引起问题。特别是,我们发现,由于这种设计选择,在 Glade 评估中使用的 Grep 程序只能实现非常低的有效输入空间覆盖率。

此外,Grep 查询的语法非常粗糙,因为特殊字符既可以用作查询的内容,也可以用作查询中的控制字符。此属性使 Grep 对 Glade 充满挑战,因为种子输入必须涵盖所有特殊字符的行为。因此,随机生成的种子输入不足以使 Glade 合成所需的语法。

由于种子输入的质量极大地影响了 Glade 的性能,因此我们建议使用测试生成工具自动生成种子输入。Pex 是基于动态符号执行的白盒自动化测试工具。它探索了可能的程序执行路径,以生成覆盖程序尽可能多部分的测试输入。我们的结果表明,借助 Pex,我们大大提高了 Grep 基准的准确度和召回率。

第二个缺点是 Glade 努力避免过度泛化,即使发生过度泛化,这也是由于用于检测过度泛化的检查中的缺陷而不是故意的选择。事实上,REINAM 将语法表示为 PCFG,并使用强化学习来调整该 PCFG 的概率以提高性能。因此,REINAM 可以在每个步骤中保留一定程度的泛化,从而实现更大的覆盖范围,而只牺牲一小部分准确性。如果理想的语法不是上下文无关的,则此功能将更加强大。在这种情况下,REINAM 将学习可以实现较高覆盖率的过度泛化的语法,而 Glade 常常由于无法捕获的有效输入上的非上下文无关约束而常常无法泛化。

Glade 的第三个缺点是将泛化运算符严格地分为两个步骤,即在步骤 1 中进行重复和替换,在步骤 2 中进行合并。Glade 在步骤 1 中仅执行重复和替换并转换所得的正则表达式,在步骤 2 中放入 CFG 中。但是,重复和替换仍然可行,并且在步骤 2 中经常需要。

例如,图 3 中,假定最左侧的语法是 Glade 步骤 2 执行期间的中间状态。中间语法和右侧语法是通过首先应用替换运算符来构造的,该替换运算符将 T 形式的产物 PQ 更改为 P|Q(从左到中),然后在符号 T 和 S 上应用合并运算符。但是,在 Glade 中,这种泛化是不可能的,因为在步骤 2 中不执行重复和替换。相反,REINAM 将 Glade 的这两个步骤结合在一起 ——REINAM 可以在当前 CFG 上执行任何不同种类的泛化步骤。

3. REINAM

在较高的层次上,REINAM 将我们要为其合成输入语法的目标程序作为输入,然后分两个阶段进行。在阶段 1 中,REINAM 使用自动测试生成来生成各种高质量的种子输入,然后使用现有的语法合成器(例如 Glade)来合成初始 CFG。在阶段 2 中,REINAM 将 CFG 从阶段 1 转换为 PCFG,然后使用强化学习来完善此 PCFG。REINAM 的概览如图 4 所示。

强化学习包括迭代执行五个步骤:(i)应用泛化运算符,(ii)来自 PCFG 的样本字符串,(iii)计算每个生产规则的奖励,(iv)根据计算出的奖励调整概率分布,(v)删除低概率规则。请注意,可以为不同的语法定制用于修改当前 PCFG 的泛化运算符,包括本文所述以外的运算符,从而为我们的方法带来灵活性。

3.1 第一阶段:用 Pex 生成种子输入

阶段 1 首先在目标程序的汇编代码上运行符号执行引擎(我们使用 Pex)。接下来,它使用引擎的输出作为种子输入来运行语法合成器(我们使用 Glade)。Pex 通过重复执行程序以生成基于路径的约束,并使用 SMT(可满足性模理论)求解器来求解这些约束,以获得可能导致不同执行路径的程序输入,从而执行路径受限的动态符号执行。如第 3 节所述,一组种子输入的质量主要取决于该种子集可以覆盖的输入的各种“类别”,与实现高代码覆盖率的输入相对应。测试生成工具(例如 Pex)旨在生成可实现高代码覆盖率的输入。

3.2 第二阶段:通过强化学习泛化 PCFGs

初始化 PCFG。阶段 2 首先将 CFG 从阶段 1 转换为 PCFG。对于每个非终端 S,我们计算可扩展 S 的生产规则的数量 k(即 S 位于规则的左侧);然后,我们为每个规则分配概率 1/k。

强化学习。强化学习(RL)是受行为心理学启发的机器学习领域。基本思想是软件代理在环境中采取行动以最大化给定指标(称为奖励)。在我们的语法合成问题中,这些概念有:

  • 代理:PCFG。

  • 环境:目标程序。

  • 状态:PCFG 的部分派生。

  • 动作:选择生产规则以应用于当前状态下处于 α 的一个非终止符号。

  • 奖励:目标程序是否接受构造的输入——如果接受则为 1,如果拒绝则为 0。

RL 的目标是优化代理的参数,以便其采取使奖励最大化的操作。在我们的上下文中,目的是提高语法的质量(即精确度和召回率)。然而,现有的 RL 算法设计为最大化实值参数。我们可能还需要修改 PCFG 本身的结构。为此,我们将传统的 RL 算法与泛化运算符的应用交织到 PCFG 中。具体来说,我们迭代执行以下操作:(i)应用泛化运算符,(ii)运行传统的 RL 算法来调整 PCFG 概率,并且(iii)使用概率低于 PCFG 的固定阈值。

泛化运算符。我们使用四种泛化运算符。首先,我们使用第 2 节中描述的字符泛化运算符,该运算符适用于 PCFG。我们将的概率分配给新添加的字符,并按比例减少其他概率。

使用 PCFG 构造输入。我们对 PCFG 的输入执行以下步骤:

在对输入进行采样之后,我们在该输入上执行程序,并记录该程序是接受还是拒绝输入。

概率调整。回想一下,在我们的 PCFG 中,每种概率都量化了相应的生成规则的正确性,即该规则是否存在于理想语法中。与 Glade 不同,我们允许偶尔过度泛化。在 Glade 中,如果程序拒绝使用新生产规则生成的任何输入,则该规则将被拒绝。相反,如果规则未通过检查,则我们的算法不一定会拒绝该规则,只要它产生至少一个被接受的输入即可。特别是,我们使用强化学习来自动调整每个生产规则的概率。为此,我们跟踪那些使用了新的生产规则来构造每个输入。然后,我们为每个新生产规则 ri 定义以下汇总奖励:

规则移除。最后,在调整了概率之后,我们的算法会移除概率低于收敛阈值的生产规则(或等效地,将其概率设置为零)。此步骤的作用是撤销失败的泛化运算符,还可以避免在调整错误生产规则的概率上浪费计算时间。

3.3 讨论

4. 评估

4.1 基准

我们使用的手工编写的语法的基准来自 Glade 评估:

  • 用于匹配 URL 的语法。

  • GNU Grep 接受作为输入的正则表达式的语法。该语法如图 2 所示。

  • 简单的 Lisp 解析器的语法,包括对带引号的字符串和注释的支持。

  • XML 解析器的语法,包括所有 XML 构造,但仅包含固定数量的标记(以确保语法不受上下文限制)。我们使用.NET XML 库,并且其字母为标签可供选择。Glade 和 REINAM 均未附带字母。

  • 级联样式表(CSS)解析器的语法;CSS 是一种用于描述以标记语言(例如 HTML)编写的文档的表示形式。

除了 Glade 基准测试外,我们还包括用于匹配 IPv4 和 IPv6 地址的语法,以及从 ANTLR(一种广泛使用的解析器生成器)生成的两个基准测试。我们使用这两个基准来评估 REINAM 在为自动解析器生成器生成的程序合成语法时的性能。我们选择以下语法(来自 ANTLR 的官方网站),该语法的非终结符少于 100 个:

  • 用于匹配 CSV 文件的语法。

  • 用于描述简单的一阶逻辑(FOL)公式的语法。

4.2 评估准备

为简单起见,当对字符串进行采样以测量精度和召回率时,我们在产品上使用均匀分布。相反,我们的 RL 算法使用 PCFGG 中的概率对字符串进行采样。在这里,我们丢弃这些概率,因为它们不一定捕获输入的真实分布。

用于评估的程序。由于 Pex 需要源代码来执行动态符号执行并生成程序输入,因此我们编写 C#程序来解析 4.1 节中描述的语法。我们在.NET 系统库中使用解析器来解析 URL,IP 地址,正则表达式和 XML 文档的语法。我们还针对开源 Lisp 解析器和开源 CSS 解析器进行了测试。这两个 ANTLR 语法的程序是通过在 C#模式下使用 ANTLR 生成的。

模糊测试。模糊测试是一种自动化的软件测试技术。一个有效的模糊器会生成“足够有效”的输入,然后监视这些输入上程序的执行情况。使用模糊测试的目的之一是观察目标程序在各种输入下的行为,因此我们希望模糊测试器获得较高的代码覆盖率。

4.3 RQ1:精确度和召回率

平均而言,精度几乎保持不变,变化不到 1%(平均为-0.36%),而召回率则大幅提高了 49.2%。通过将第一行减去第三行的数字并取各基准测试的平均值来计算此比率。在我们的 11 个基准测试中,REINAM 在召回率上均优于 Glade,而不会损失精度。在三个基准“css”,“xml”和“lisp”中,Glade 已经达到 1.0 调用率,这表明 Glade 合成的语法已经覆盖了三个程序的整个输入空间。对于这些基准,RENAM 无法进一步提高召回率,但是设法保持预期的完美分数。

如第 4.1 节所述,我们有意将“url”语法分为四个基准“http”,“https”,“nntp”和“mailto”。对于这四个基准,我们发现召回率大大提高。Glade 的表现很差,在所有四个基准上的召回率均低于 0.15,这是由于 Glade 的局限性,即合成语法的质量很大程度上取决于种子输入的质量。由于 Glade 的输入字符串以“http”(其他三个基准中的“ https”,“ nntp”或“ mailto”)开头作为种子输入,因此 Glade 无法探究其他可能的 URL 协议。同时,REINAM 在第一阶段利用 Pex 的帮助来生成一组种子输入,以实现更高的覆盖率。因此,针对这四个基准的 REINAM 最终合成语法在 0.70 以上的频率下回想起来,而没有实质性的精度损失。

基准“grep”和“csv”的性能相似。我们已经在第 3 节中分析了 Glade 为什么在“ grep”上仅获得 0.02 的召回率。我们可以看到 REINAM 获得了 1.0 的召回率,即 REINAM 的最终综合语法涵盖了程序可以接受的所有可能字符串。假设精度相似(0.78 对 0.79),则改进幅度很大。“ csv”基准类似于“ grep”基准,因为它包含许多具有特殊行为的字符。特别是,由于语法描述了所有可能的 CSV 文件,因此在数据字段中可以有许多特殊字符,并且几个特殊字符既可以用作分隔符号又可以用作内容符号。因此,REINAM 通过将召回率从 0.24 提高到 1.0,胜过 Glade。

“fol”基准的情况是独特的。尽管 REINAM 将召回率从 0.3 提高到 0.45,但其精度从 0.90 降低到 0.75。该基准是 REINAM 无法达到 0.5 以上的召回率的唯一基准。直观上,一阶逻辑(FOL)公式编写起来更复杂。直观地讲,FOL 公式的理想语言非常稀疏,这表明如果我们考虑 FOL 解析器的整个输入空间,它将比 URL 解析器的输入空间小得多。因此,REINAM 中的泛化运算符可能难以泛化为 FOL 语法的复杂结构。

4.4 RQ2:模糊器的应用

在模糊测试实验中,从表 2 和图 5 可以看出,REINAM 大大提高了代码覆盖率。

在基准“xml”和“grep”中,所有模糊器均实现了完美的代码覆盖率。有趣的是,由 Glade(“LI”)合成的语法在表 1 中仅实现 0.02 的召回率,但是使用该语法的模糊器仍实现了完美的代码覆盖率。原因是,从同一语法生成的不同字符串可以共享相同或相似的执行路径,这些路径将覆盖代码中的相似基本块。因此,覆盖范围并不总是与召回率相关。

REINAM 忽略了在所有方法上有良好覆盖率的两个基准。与 Glade 基于语法的模糊测试相比,RENAM 在“css”基准中的性能稍差一些,但在所有其他基准上均优于 Glade。之所以具有这种优势,是因为与 REINAM 相比,Glade 产生的拒绝输入更多,因此我们允许过度泛化。这些拒绝的输入涵盖了接受的输入无法涵盖的部分源代码,例如,用于处理无效输入的代码。

另一个观察结果是,Radamsa 模糊器在括号匹配模式“lisp”和“css”的基准上以及在基准“fol”上均表现不佳。特别是对于“css”基准,Radamsa 甚至无法达到 40%的代码覆盖率。原因是,正如我们所讨论的,“lisp”,“css”和“fol”的理想语法比其他基准的语法更结构化。非基于语法的模糊器使用的字符级修改不能合成这些结构化的字符串,而 REINAM 使用的归纳运算符可以推断出这类结构。

4.5 RQ3:阶段 1 和阶段 2 的比较

从表 1,表 2 和图 5 中,我们可以看出,第一阶段和第二阶段对 Glade 的精度/召回率和模糊性的贡献不同。

在 RQ1 中,如果我们比较行“LI + SE”和行“LI”,行“LI + SE”显示通过在 Pex 生成的种子输入(REINAM 阶段 1)上运行 Glade 合成的语法结果,行“ LI”显示合成语法的结果对于 Glade 本身,我们发现第 1 阶段的平均精度提高了 9.2%,召回率提高了 29.1%。

在三个括号匹配模式基准“css”,“xml”和“lisp”中,Glade 已经实现了 1.0 召回率,对此无法改进。但是,第 1 阶段确实提高了“xml”和“lisp”基准测试的精度,并在“css”基准测试中保持了相同的精度。原因是 Pex 生成了一组具有较高覆盖率的种子输入。一组具有较高覆盖率的种子输入将导致具有较高覆盖率的初始规则语法,因此需要较少的进一步泛化来推断理想语法。由于在泛化过程中会发生不精确性,因此泛化次数越少,精度越高。对于其他基准,我们观察到类似的行为,尤其是当 Glade 合成的语法精度较低时。

但是,对于三个基准“fol”,“ip”和“mailto”,我们发现 Glade 合成的语法已经达到了完美或接近完美的精度。在这些情况下,第 1 阶段后的召回率会大大提高;但是,阶段 1 之后的精度会降低。这种减少是为了获得更好的召回率的牺牲。原因是一组具有较高覆盖率的种子输入会带来更多的泛化机会,但也会导致 Glade 中的检查机制更频繁地失败,从而导致未捕获的泛化程度更高,从而降低了精度。

接下来,在 RQ1 中,如果我们比较“LI + SE”行和“LI + SE + RL”行,其中“ LI + SE”显示通过在 Pex 生成的种子输入上运行 Glade 合成的语法结果(REINAM 第 1 阶段)。显示了 REINAM 合成的最终语法的结果,我们发现平均而言,第 2 阶段后的结果使查全率提高 20.1%,但准确性下降 9.5%。

特别是,我们观察到与第 1 阶段的结果相比,所有基准的精度都下降了。由于第 2 阶段的强化学习算法允许过度泛化以进一步泛化语法,因此可以预料到这一发现。与 Glade 中使用的“不允许过度泛化”策略相比,我们对过度泛化的允许导致精度降低。

此外,我们注意到在第 1 阶段之后,在 URL 语法的基准测试以及“grep”和“csv”基准测试中,仍然很低。最高的是“https”,召回率为 0.64;所有其他均小于 0.50。第 2 阶段中的强化学习进一步泛化了语法,以实现更高的覆盖率。表 1 显示,在这六个基准中,召回率比第一阶段平均提高了 35.1%。另外,“grep”和“csv”实际上达到了 1.0 的调用率,表明 REINAM 合成的最终语法可以完美地覆盖整个程序输入空间。这个结果表明我们的强化学习方法特别有效,特别是在输入空间很大但现有方法可以合成仅覆盖部分输入空间的语法的情况下。

在模糊测试任务中,使用 REINAM 的语法(行“LI + SE + RL”)的基于语法的模糊器所获得的覆盖率平均提高到使用阶段 1 语法(行“LI”的基于语法的模糊器所实现的覆盖率)+ SE”)为 3.2%。类似地,“LI + SE”行相对于“LI”行的平均改进为 1.7%。从数据中,我们可以看到第二阶段为覆盖范围的改善做出了更大贡献。这种比较显示了在我们的 RL 算法中保留一些过度泛化的规则的好处。我们看到,对于“css”之类的基准,第二阶段不会增加召回率,后者仍为 1.0。但是,与阶段 1 相比,最终的综合语法将覆盖率提高了 8.6%(1809 对 1642 年)。因此,尽管阶段 2 并未提高理想语言的覆盖率,但它可以提高使用模糊测试获得的实际代码覆盖率。该结果进一步表明,我们的强化学习方法不仅对探索所有有效程序输入的输入空间有效,而且对于生成覆盖无效输入所不能执行的执行路径的无效程序输入也是有效的。

4.6 RQ4:执行时间

从表 3 中可以看出,RL 阶段平均花费了总执行时间的 49.2%。Pex 在阶段 1 中平均花费 34.2%的时间。可以通过设置超时参数来调整 Pex 的执行时间。评估中的超时设置为 900 秒。Pex 在五个基准中超时。

RL 阶段的执行时间主要取决于语法的大小和程序的执行时间。RL 阶段的时间开销不令人满意;但是,阶段 2 的瓶颈正在等待对采样字符串执行程序的结果。通过同时对 k 个采样字符串执行程序,可以并行化此步骤。当前,我们在 4 个线程上并行处理 1500 个采样字符串上的程序。通过更多线程并行执行程序,可以改善结果。

根据文法画出语法树_输入语法推断的强化学习相关推荐

  1. 编译原理学习笔记(二十九)~习题:分析句子 id--id*id的 最右推导过程,画出分析树,找出和分析过程中每一步的对应关系。

    题目 分析句子 id–id*id的 最右推导过程,画出分析树,找出和分析过程中每一步的对应关系. 语法如下: E → E - T (1) E → T (2) T → T * F (3) T → F(4 ...

  2. 【ICLR 2018录用结果出炉】23篇oral干货,强化学习、对抗网络、可解释性最受关注...

    Oral Papers:23篇 1.AmbientGAN: Generative models from lossy measurements (AmbientGAN:来自有损测量的生成模型) 作者: ...

  3. 根据文法画出语法树_更多确定子句语法

    本章有两个主要目标: 1.研究DCG表示法提供的两个重要功能:额外的参数和额外的 目标. 2.讨论DCGs的现状和局限性. 1  额外参数 在上一章中,我们介绍了基本的DCG表示法.但是DCG所提供的 ...

  4. 根据文法画出语法树_几种常用的英语教学法误导了语法教学

    多年来,我国的英语教学一直采用语法翻译法,教法比较单一.上世纪八十年代初,随着国际交流的日益加强和教学改革的进一步深入,各种英语教学法,尤其是从国外推介的教学法都相继进入英语教学领域.尽管有一些教学法 ...

  5. 【LaTex树状图】LaTex画树状图_编译原理语法树_直角分叉_Forking links

    语法树 过程 使用Overleaf在线编辑LaTex,由于使用汉字ctex包,需在overleaf中将编译器换成XeLaTex(界面左上角Menu→Compiler→XeLaTex). 详细语法参考V ...

  6. java抽象语法树_抽象语法树AST的全面解析(一)

    Javac编译概述 将.java源文件编译成.class文件,这一步大致可以分为3个过程: 1.把所有的源文件解析成语法树,输入到编译器的符号表: 2.注解处理器的注解处理过程: 3.分析语法树并生成 ...

  7. python根据频率画出词云_利用pandas+python制作100G亚马逊用户评论数据词云

    原标题:利用pandas+python制作100G亚马逊用户评论数据词云 数据挖掘入门与实战 公众号: datadw 我们手里面有一个差不多100G的亚马逊用户在购买商品后留下的评论数据(数据格式为j ...

  8. matlab 聚类分析 画出聚类树,plot单独画出pheatmap返回的聚类结果(聚类树)

    前面两篇文章介绍到pheatmap返回行和列的hclust结果: 1.按照前两篇文章的基础数据获得的热图结果,对行(基因的聚类结果)聚类树单独进行绘制,可以借助plot()函数: 默认画法 >  ...

  9. python 抽象语法树_抽象语法树(Abstract Syntax Tree)

    一般来说,程序中的一段源代码在执行之前会经历下面三个步骤 1 分词/词法分析 这个过程会将由字符组成的字符串分解成有意义的代码快,这些代码块被称为词法单元.例如 var a = 4:会被分解成 var ...

最新文章

  1. haskell,lisp,erlang你们更喜欢哪个?
  2. 病毒行为分析初探(三)
  3. .Net Core in Docker极简入门(下篇)
  4. 多线程启动定时器 会等待上一次执行完成?_Java多线程
  5. 微软Azure IoT
  6. 做机器学习的是些什么样的人?Kaggle做了一份居委会式的调查
  7. HNU信息院大二夏季实训——利用单片机制作游戏
  8. python读取文件夹中的所有图片并将图片名逐行写入txt中
  9. 大数据时代下的SQL Server第三方负载均衡方案 ----Moebius测试
  10. php下一页的代码,php 下一页的代码
  11. 传奇服务器人物技能怎么修改,传奇服务端上线0级技能,直接设置3级技能的设置方法...
  12. 科研ABC - 数据图表的绘制
  13. 程序员用简单C语言一顿神操作,瞬间打造植物大战僵尸,无人不服
  14. CVPR2019目标检测方法进展
  15. word域锁定和更新
  16. 人工智能帮助千万用户完成「隐形征信」计算 1
  17. 加速PG中vacuum
  18. 如何用python写游戏脚本?
  19. 在PS中多种类抠图的教程(第一课)后附PS软件可下载
  20. rk3399 hdmi HDCP key烧录

热门文章

  1. 网络协议IPV6基础知识点集锦
  2. XNA实现不停循环的路的效果
  3. 将centos字符编码换成utf-8
  4. KMP算法的C++实现
  5. linux文件IO的操作
  6. android 拖动按钮
  7. 合并模块和安装文件的区别
  8. SHELL编程Nginx源码多版本脚本
  9. Nginx之location详解
  10. Eclipse插件安装之,使用(已经下载的zip)安装包直接安装插件(例:glassfish 插件 plugin)