做者|莱斯 出品|阿里巴巴新零售淘系技术部前端
导读:做为阿里经济体前端委员会四大技术方向之一,前端智能化项目经历了 2019 双十一的阶段性考验,交出了不错的答卷,天猫淘宝双十一会场新增模块 79.34% 的线上代码由前端智能化项目自动生成。在此期间研发小组经历了许多困难与思考,本次 《前端代码是怎样智能生成的》 系列分享,将与你们分享前端智能化项目中技术与思考的点点滴滴。算法
无线大促页面的前端代码中,存在大量的业务模块或业务组件(下文统称业务模块),即具备必定业务功能的代码单位。获取页面中业务模块的信息以后,能够用于复用代码、绑定业务字段等后续功能。所以从视觉稿识别出业务模块,在前端智能化领域中成为用途普遍的功能环节。markdown
与面向中后台的基础组件识别和表单识别功能不一样,业务模块识别主要面向无线端页面,而且来源主要是视觉稿。相对的,业务模块 UI 结构更加复杂,而且视觉稿提供的内容已经有较多可辨别的信息(如文本内容、图片尺寸等),所以咱们没有直接使用图片深度学习的方案,而是从视觉稿产出的 DSL 中提取预约义的特征值,用传统学习多分类的方法来实现模块识别。本识别功能最终返回业务模块的类别、视觉稿中的位置等信息。网络
整体功能以下图所示。包括:机器学习
一、样本构造,根据用户配置和自定义的数据加强规则对视觉稿进行 UI 层的加强,以获得视觉多样化的样本。而后在定义好业务字段的基础上,进行特征值抽取并存储。 二、算法选择,目前提供的都是传统机器学习方法中的多分类算法。布局
三、模型实现,基于集团机器学习平台实现模型搭建及相关算法工程,作到自动化训练与部署。学习
四、接口提供,模型对外提供预测识别服务以及结果反馈服务。测试
整体功能见下图:优化
以下图所示,咱们的业务模块识别服务位于物料识别层,为视觉稿导出的 DSL 提供进一步的业务定制化的识别能力,在后续代码生成的过程当中渗透到字段绑定、业务逻辑等功能之中。D2C 功能分层见下图:编码
机器学习是基于大量真实数据的训练过程,一个好的样本库可让你的模型训练事半功倍。咱们的样原本源是视觉稿(Sketch),但同一个模块的 Sketch 视觉稿可能只有寥寥几张,可获取的样本数量过少。所以首先要解决量的问题。
为解决样本数量问题,咱们采用了数据加强的方法。数据加强有一套默认的规则,同时也是可配置的。用户可自行根据视觉稿上各个元素在真实场景中可能发生的变化,如“是否可隐藏”,“文本字数可变范围”等维度来调整属性,产出自定义的配置项。所以样本制做者能够清晰的知道本身所造样本侧重的差别点在哪里。
咱们根据这些配置项对属性进行发散、组合,生成大量不一样的视觉稿 DSL。这些 DSL 之间随机而有规律地彼此相异,据此咱们能够得到大数量的样本。
加强配置的界面以下图所示,左侧与中部是 DSL 树及渲染区域,右侧就是加强配置的区域。配置项由如下 2 部分组成:
一、加强属性:尺寸、位置、隐藏、前景背景色、内容
二、加强方式:连续范围、指定枚举值
样本生成的界面见下图:
获得大量加强后的视觉 DSL 后,如何生成样本呢?首先明确咱们所需的样本格式应该是表格型数据,以配合传统机器学习方法的输入格式:一条样本数据即一个特征向量。所以咱们要对 DSL 进行特征提取。
基于此前的模型训练经验,咱们发现某些视觉信息对于模块的类别判断尤其重要。所以咱们对 UI 信息进行抽象,自定义并提取为特征维度,如 DSL 的宽、高、布局方向、包含图片数量、包含文本数量等。经过各类视觉信息的抽象,咱们获得 40 多维的视觉特征。
除了视觉特征维度之外,咱们还增长了自定义的业务特征。即根据必定的“业务规则”,将某些元素块定义为具备业务含义的元素,如“价格”、“人气”等,并抽象出 10 个维度的业务特征。在这一过程当中一样支持用户自定义业务规则,可经过正则匹配等方式实现。
视觉抽象特征加上业务特征,组成一个特征向量。特征向量加上分类 label,即一个样本。
首先咱们的输入是 Sketch 设计稿提取出的标准化 DSL,目标是认出该 DSL 是哪一个业务模块,能够归结为一个多分类问题。沿着这一思路,前文咱们从大量加强后的 DSL 中提取特征值、生成数据集以供训练。咱们使用的多分类模型基于算法平台提供的各类组件进行搭建。
模型搭建
最初咱们选择随机森林模型做为多分类模型,由于随机森林的执行速度快、自动化流程顺畅,几乎无需额外操做就知足了咱们算法工程的需求;而且对特征值处理的要求较低,会自行处理连续和离散变量,规则以下表所示。
随机森林变量类型自动解析规则见下图:
所以能够迅速的搭建出十分简洁的模型,以下图所示。
线上使用的随机森林模型见下图:
调参过程
咱们发现随机森林对于样本库内的数据,偶尔会有不自信的状况发生,即 positive true 的置信度较低,被置信阈值卡住。尤为是视觉很是类似的样本,如图所示的两个类似模块就给咱们的分类结果带来偏差。
类似模块见下图:
为优化这种“不自信”的问题,咱们对随机森林进行了调参,包括单棵树随机样本数、单棵树最大深度、ID3/Cart/C4.5 树的种类配比等参数,也预接入特征选择组件,效果均不理想。最终在特征值重要性评估后手动反馈到特征选择并从新训练这一链路中取得了较好的结果,以下图所示。但这一过程没法融入到自动化训练流程中,最终被咱们放弃。
调参过程当中使用过的随机森林模型见下图:
离散特征问题
随机森林虽然能够自动处理离散变量,可是若是测试集中出现了训练集之外的离散值,算法没法处理这样的状况。要解决这一问题,需确保每一个离散特征的所有取值都出如今训练集中。因为有多个离散特征,也没法经过简单的分层采样来解决。这也是随机森林模型应用中的痛点之一。
综上是咱们在随机森林模型上作的工做,随机森林简单易上手、快速出结果,而且在大多数业务场景下都能知足识别需求,成为模块识别功能的 1.0 版本算法。但因为其算法缺陷,咱们后来引入了另外一种模型 XGBoost。
模型搭建
XGBoost 经过 Boosting 的方法提高树的“准确率”,相较于随机森林算法在咱们的数据集上表现更优越。可是算法平台的 XGBoost 模型有许多流程不标准的地方,所以为了实现自动化链路,咱们搭建了如图所示模型。
XGBoost 模型见下图:
预处理
XGBoost 模型须要更多的预处理方法来实现,包括:
一、Label Encoding:预处理过程。XGBoost 仅支持从 0 开始到(分类数-1)的 label 数值。但为了映射方便,咱们存储的 label 值对应的是平台的分类 ID,并非 0~N 的,甚至可能不是连续整数。所以须要用 Label Encoding 组件编码到符合 XGBoost 需求的数值。
二、存储 Label 映射表:数据转存,由于预测接口会用到这一映射表来转义平台分类,所以要额外保存。
三、数据重整:预处理过程,为防止随机拆分算法将训练集的 label 拆分为不完备的数据集,把训练集 label 的缺失数据捞回来。对模型会有必定干扰,可是在数据极少的极端状况下才会发挥做用。
XGBoost 在测试数据上的表现颇为自信,下降了阈值划分的困难,预测结果也可以很好的知足咱们“识别正确组件”的业务需求,而且也能够支持自动化流程,所以成为后续咱们主推的传统训练模型。
值得一提的是,咱们没法对当前模块库之外的全部视觉样本进行全面的收集,这样的工程就如同为了作一个阿里内部的面部识别系统,而去收集 70 亿人类的面部照片同样。样本库之外的数据缺失致使咱们实际上是少了一个隐藏的分类——负样本分类。也就引起了 Out-of-Distribution 问题,即样本库之外数据带来的预测失准问题,其本质是分类结果中 false positive 过多。
在咱们的场景下,这是一个很难解决的问题,由于收集所有负样本的困难性。目前咱们是如何应对这一问题的呢?
阈值设定
咱们将分类模型输出的置信度 prob 做为肯定分类结果的参考依据,高于某一阈值则认为匹配到某个分类。这一方法具备经验意义,实践中有效的屏蔽了大部分 OOD 错误。
逻辑控制
对于算法模型的部分 OOD 误判,咱们能够经过逻辑关系来辨别。如咱们认为 DSL 树的同一条路径上不可能有多个相同组件(不然造成自嵌套),若是该路径上识别出多个相同组件,那么咱们经过置信度大小来选择识别结果。此类逻辑帮咱们筛选了大部分误判。
负样本录入
咱们提供的反馈服务,容许用户将识别错误的 DSL 上传,上传后加强为必定数量的负样本并存储。在此基础上从新训练,能够解决 OOD 问题。
目前 OOD 问题仍是依赖逻辑和反馈的方法来规避,算法层面仍然没有解决该问题,这是咱们下一阶段计划去作的事。
算法平台支持将模型部署为线上接口,即预测服务,经过 imgcook 平台可一键调用部署。为了实现自动化训练、部署的流程,咱们还作了一系列算法工程的工做,在此不做详述。
预测服务,输入为设计稿提取的 DSL(JSON),输出为业务模块信息,包括 ID、在设计稿上的位置等。
在调用算法平台的预测接口以前,咱们加入了逻辑上的过滤,包括:
一、尺寸过滤:对于模块尺寸误差较大的,不进入预测逻辑,直接认为不匹配
二、层级过滤:对于叶子节点(即纯文本、纯图片),咱们不认为该节点具备业务含义,所以也过滤不用。
结果反馈链路包括自动结果检测和用户手动反馈,目前仅提供了预测结果错误的样本上传功能。
咱们的业务模块识别功能最终在 99 大促中首次在线上使用。上述的模型、前置逻辑、以及 OOD 规避等环节,最终带来的效果是:业务场景内的识别准确率可达 100%(纯模型的实际准确率未统计)。
难点问题解决
如前所述,OOD 问题是一个难点,目前仍没有很好的解决。针对这一问题咱们有一些解决思路,计划在后续工做中进行尝试。
基于 DNN 的 loss function 优化:仍基于手动 UI 特征值搭建 DNN 网络,经过 loss function 的优化,扩大不一样类别之间的距离、压缩同类别内部的距离,在优化后的模型上设定距离阈值来鉴别 OOD 数据。
负样本自动生成的优化:在 XGBoost 算法基础上,增长一个前置的二分类模型,用于区分集合内和集合外数据,并据此对负样本生成的随机范围进行优化。具体方案待调研。
深度学习
手动特征提取的方法虽然快速有效,可是在泛化能力上没法与 CNN 之类的深度学习方法相比。所以后续咱们会尝试基于图片的算法,使用 CNN 模型提取 UI 特征向量,再经过向量距离计算或二分类模型比对输入数据与各个 UI 组件的类似度。
在深度学习领域还能够有更多尝试,不限于以上算法设想。
目前咱们的样本生成功能存在配置效率低、支持算法类型少等问题,所以在后续工做中,咱们计划将样本生成进行更丰富的产品化设计。样本平台的功能大体如图所示。
样本平台产品功能见下图:
**来源扩展:**目前咱们的样本生成链路是从 Sketch 到 ODPS 表格数据,在后续的业务场景中咱们还但愿能支持从 HTML、前端代码生成样本。不论何种来源,在数据加强这一层都会有许多相通之处,咱们将抽象出通用的加强算法服务,开放调用。
**算法扩展:**最终生成的样本,能够是特征值表格数据,用于多分类;也能够是 PASCAL、COCO 等格式的图片与标注数据,提供给目标检测模型使用。
**加强智能化:**目前用户在使用样本生成功能时感到配置复杂、难上手,甚至常由于误操做而致使样本不可用。所以咱们指望能经过数据加强的“智能化”,来尽可能减小用户操做,迅速生成有效样本。
综上,算法优化与样本平台产品化是咱们下一期的核心工做。