阿里淘系技术出品
导读:
智能生成代码平台 imgcook 以 Sketch、PSD、静态图片等形式的视觉稿作为输入,可以一键生成可维护的前端代码,但从设计稿中获取的都是 div、img、span 等元件,而前端大多是组件化开发,我们希望能从设计稿直接生成组件化的代码,这就需要能够将设计稿中的组件化元素,例如 Searchbar、Button、Tab 等识别出来。识别网页中的 UI 元素在人工智能领域是一个典型的的目标检测问题,我们可以尝试使用深度学习目标检测手段来自动化解决。
本文介绍了使用机器学习的方式来识别 UI 界面元素的完整流程,包括:现状问题分析、算法选型、样本准备、模型训练、模型评估、模型服务开发与部署、模型应用等。
应用背景
imgcook 以 Sketch、PSD、静态图片等形式的视觉稿作为输入,通过智能化技术一键生成可维护的前端代码,Sketch/Photoshop 设计稿的代码生成需要安装插件,在设计稿中通过 imgcook 插件导出视觉稿的 JSON 描述信息(D2C Schema)粘贴到 imgcook 可视化编辑器,在编辑器中可以进行视图编辑、逻辑编辑等来改变 JSON 描述信息。
我们可以选择 DSL 规范来生成对应的代码。例如生成 React 规范的代码,需要实现从 JSON 树转换成 React 代码 (自定义 DSL)。
如下图,左侧为 Sketch 中的视觉稿, 右侧为使用 React 开发规范生成的按钮部分的代码。
从 Sketch 视觉稿「导出数据」生成「React 开发规范」的代码,图为按钮部分代码片段。 生成的代码都是由 div、img、span 这些标签组成,但实际应用开发有这样的问题:
- web页面开发为提升可复用性,页面组件化,例如:Searchbar、Button、Tab、Switch、Stepper
- 一些原生组件不需要生成代码,例如状态栏 Statusbar、Navbar、Keyboard
我们的需求是,如果想要使用组件库,例如 Ant Design,我们希望生成的代码能像这样:
// Antd Mobile React 规范
import { Button } from "antd-mobile";
<div style={styles.ft}> <Button style={styles.col1}>进店抢红包</Button> <Button style={styles.col2}>加购物车</Button></div>
"smart": { "layerProtocol": { "component": { "type": "Button" } }}
为此我们在 JSON 描述中添加了 smart 字段, 用来描述节点的类型。
我们需要做的,就是找到视觉稿中需要组件化的元素,用这样的 JSON 信息来描述它, 以便在 DSL 转换代码时, 通过获取 JSON 信息中的 smart 字段来生成组件化代码。
现在问题转化为:如何找到视觉稿中需要组件化的元素,它是什么组件,它在 DOM 树中的位置或者在设计稿中的位置。
解决方案
▐ 约定生成规则
通过指定设计稿规范来干预生成的 JSON 描述,从而控制生成的代码结构。例如在我们的 设计稿高级干预规范 中关于组件的图层命名规范:将图层中的组件、组件属性等显性标记出来。
#component:组件名?属性=值##component:Button?id=btn#
在使用 imgcook 的插件导出 JSON 描述数据时就通过规范解析拿到图层中的约定信息。
▐ 学习识别组件
人工约定规则的方式需要按照我们制定的协议规范来修改设计稿,一个页面上的组件可能会有很多,这种人工约定方式让开发者多了很多额外工作,不符合使用 imgcook 提高开发效率的宗旨,我们期望通过智能化手段自动识别视觉稿中的可组件化元素,识别的结果最终会转换并填充在 smart 字段中,与手动约定组件协议所生成的 json 中的 smart 字段内容相同。
这里需要完成两件事情:
-
找到组件信息:类别、位置、尺寸等信息。
-
找到组件中的属性, 例如 button 中的文字为“提交”
第二个事情我们可以根据 json 树来解析组件的子元素。第一个事情我们可以通过智能化来自动化的完成,这是一个在人工智能领域典型的的目标检测问题,我们可以尝试使用深度学习目标检测手段来自动化解决这个手动约定的流程。
学习识别 UI 组件
▐ 业界现状
目前业界也有一些使用深度学习来识别网页中的 UI 元素的研究和应用,对此有一些讨论:
-
Use R-CNN to detect UI elements in a webpage?
-
Is machine learning suitable for detecting screen elements?
-
Any thoughts on a good way to detect UI elements in a webpage?
-
How can I detect elements of GUI using opencv?
-
How to recognize UI elements in image?
讨论中的诉求主要有两种:
-
期望通过识别 UI 界面元素来做 Web 页面自动化测试的应用场景。
-
期望通过识别 UI 界面元素来自动生成代码。
既然是使用深度学习来解决 UI 界面元素识别的问题, 带有元素信息的 UI 界面数据集则是必须的。目前业界开放且使用较多的数据集有 Rico 和 ReDraw。
ReDraw
一组 Android 屏幕截图,GUI 元数据和标注了 GUI 组件图像,包含 RadioButton、ProgressBar、Switch、Button、CheckBox 等 15 个分类,14,382 个 UI 界面图片和 191,300 个带有标签的GUI组件,该数据集经过处理之后使每个组件的数量达到 5000 个。关于该数据集的详细介绍可查看 The ReDraw Dataset。
这是用于训练和评估 ReDraw 论文中提到的 CNN 和 KNN 机器学习技术的数据集,该论文于 2018 年在IEEE Transactions on Software Engineering上发布。该论文提出了一种通过三个步骤来实现从 UI 转换为代码自动化完成的方法:
1、检测 Detection
先从设计稿中提取或使用 CV 技术提取 UI 界面元信息,例如边界框(位置、尺寸)。
2、分类 Classification
再使用大型软件仓库挖掘、自动动态分析得到 UI 界面中出现的组件,并用此数据作为 CNN 技术的数据集学习将提取出的元素分类为特定类型,例如 Radio、Progress Bar、Button 等。
3、组装 Assembly
最后使用 KNN 推导 UI 层次结构,例如纵向列表、横向 Slider。
在 ReDraw 系统中使用这种方法生成了 Android 代码。评估表明,ReDraw 的 GUI 组件分类平均精度达到 91%,并组装了原型应用程序,这些应用程序在视觉亲和力上紧密地反映了目标模型,同时展现了合理的代码结构。
Rico
迄今为止最大的移动 UI 数据集,创建目的是支持五类数据驱动的应用程序:设计搜索,UI布局生成,UI代码生成,用户交互建模和用户感知预测。 Rico 数据集包含 27 个类别、1 万多个应用程序和大约 7 万个屏幕截图。
该数据集在 2017 年第30届ACM年度用户界面软件和技术研讨会上对外开放(RICO: A Mobile App Dataset for Building Data-Driven Design Applications)。
此后有一些基于 Rico 数据集的研究和应用。例如: Learning Design Semantics for Mobile Apps, 该论文介绍了一种基于代码和视觉的方法给移动 UI 元素添加语义注释。根据 UI 屏幕截图和视图层次结构可自动识别出 25 UI组件类别,197 个文本按钮概念和 99 个图标类。
▐ 应用场景
这里列举一些基于以上数据集的研究和应用场景。
智能生成代码
Machine Learning-Based Prototyping of Graphical User Interfaces for Mobile Apps | ReDraw Dataset
智能生成布局
Neural Design Network: Graphic Layout Generation with Constraints | Rico Dataset
用户感知预测
Modeling Mobile Interface Tappability Using Crowdsourcing and Deep Learning | Rico Dataset
UI 自动化测试
A Deep Learning based Approach to Automated Android App Testing | Rico Dataset
▐ 问题定义
在上述介绍的基于 Redraw 数据集生成 Android 代码的应用中,我们了解了它的实现方案, 对于第 2 步需要使用大型软件仓库挖掘和自动动态分析技术来获取大量组件样本作为 CNN 算法的训练样本,以此来得到 UI 界面中存在的特定类型组件,例如 Progress Bar、Switch 等。
对于我们 imgcook 的应用场景,其本质问题也是需要找到 UI 界面中这种特定类型的组件信息:类别和边界框,我们可以把这个问题定义为一个目标检测的问题,使用深度学习对 UI 界面进行目标检测。那么我们的目标是什么?
检测目标就是 Progress Bar、Switch、Tab Bar 这些可在代码中组件化的页面元素。
UI 界面目标检测
▐ 基础知识
机器学习
人类是怎么学习的?通过给大脑输入一定的资料,经过学习总结得到知识和经验,有当类似的任务时可以根据已有的经验做出决定或行动。
机器学习(Machine Learning)的过程与人类学习的过程是很相似的。机器学习算法本质上就是获得一个 f(x) 函数表示的模型,如果输入一个样本 x 给 f(x) 得到的结果是一个类别,解决的就是一个分类问题,如果得到的是一个具体的数值那么解决的就是回归问题。
机器学习与人类学习的整体机制是一致的,有一点区别是人类的大脑只需要非常少的一些资料就可以归纳总结出适用性非常强的知识或者经验,例如我们只要见过几只猫或几只狗就能正确的分辨出猫和狗,但对于机器来说我们需要大量的学习资料,但机器能做到的是智能化不需要人类参与。
深度学习
深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。
深度学习与传统机器学习的区别可以看这篇 Deep Learning vs. Machine Learning,有数据依赖性、硬件依赖、特征处理、问题解决方式、执行时间和可解释性这几个方面。
深度学习对数据量和硬件的要求很高且执行时间很长,深度学习与传统机器学习算法的主要不同在于对特征处理的方式。在传统机器学习用于现实任务时,描述样本的特征通常需要由人类专家来设计,这称为“特征工程”(Feature Engineering),而特征的好坏对泛化性能有至关重要的影响,要设计出好特征并非易事。深度学习可以通过特征学习技术分析数据自动产生好特征。
目标检测
机器学习有很多应用,例如:
-
计算机视觉(Computer Vision,CV) 用于车牌识别和面部识别等的应用。
-
信息检索 用于诸如搜索引擎的应用 - 包括文本搜索和图像搜索。
-
市场营销 针对自动电子邮件营销和目标群体识别等的应用
-
医疗诊断 诸如癌症识别和异常检测等的应用。
-
自然语言处理(Natural Language Processing, NLP) 如情绪分析和照片标记等的应用。
目标检测(Object Detection)就是一种与计算机视觉和图像处理有关的计算机技术,用于检测数字图像和视频中特定类别的语义对象(例如人,动物物或汽车)。
而我们在 UI 界面上的目标是一些设计元素, 可以是原子粒度的 Icon、Image、Text、或是可组件化的 Searchbar、Tabbar 等。
▐ 算法选型
用于目标检测的方法通常分为基于机器学习的方法(传统目标检测方法)或基于深度学习的方法(深度学习目标检测方法),目标检测方法经历了从传统目标检测方法到深度学习目标检测方法的变迁:
传统目标检测方法
对于基于机器学习的方法 ,需要先使用以下方法之一来定义特征,然后使用诸如支持向量机(SVM)的技术进行分类。
-
基于 Haar 功能的 Viola–Jones 目标检测框架
-
尺度不变特征变换(SIFT)
-
定向梯度直方图(HOG)特征
深度学习目标检测方法
对于基于深度学习的方法,无需定义特征即可进行端到端目标检测,通常基于卷积神经网络(CNN)。基于深度学习的目标检测方法可分为 One-stage 和 Two-stage 两类,还有继承这两种类方法优点的 RefineDet 算法。
✎ One-stage
基于 One-stage 的目标检测算法直接通过主干网络给出类别和位置信息,没有使用RPN网路。这样的算法速度更快,但是精度相对Two-stage目标检测网络了略低。典型算法有:
-
SSD(Single Shot MultiBox Detector)系列
-
YOLO (You Only Look Once)系列(YOLOv1、YOLOv2、YOLOv3)
-
RetinaNet
✎ Two-stage
基于 Two-stage 的目标检测算法主要通过一个卷积神经网络来完成目标检测过程,其提取的是 CNN 卷积特征,在训练网络时,其主要训练两个部分,第一步是训练 RPN 网络,第二步是训练目标区域检测的网络。
即先由算法生成一系列作为样本的候选框,再通过卷积神经网络进行样本分类。网络的准确度高、速度相对 One-stage 慢。典型算法有:
- R-CNN,Fast R-CNN,Faster R-CNN
✎ 其他(RefineDet)
RefineDet (Single-Shot Refinement Neural Network for Object Detection) 是基于SSD算法的改进。继承了两种方法(例如,单一阶段设计方法,两阶段设计方法)的优点,并克服了它们的缺点。
目标检测方法对比
✎ 传统方法 VS 深度学习
基于机器学习的方法和基于深度学习的方法的算法流程如图所示,传统目标检测方法需要手动设计特征,通过滑动窗口获取候选框,再使用传统分类器进行目标区域判定,整个训练过程分成多个步骤。而深度学习目标检测方法则通过机器学习特征,通过更高效的 Proposal 或直接回归的方式获取候选目标,它的准确度和实时性更好。
关于目标检测算法的研究现在基本都是基于深度学习的,传统的目标检测算法已经很少用到了,深度学习目标检测方法更适合工程化, 具体对比如下:
✎ One-stage VS Two-stage
✎ 算法优缺点
这里就不写各个算法的原理了,直接看下优缺点。
总结
由于对 UI 界面元素检测的精度要求比较高, 所以最终选择 Faster RCNN 算法。