- 机器学习:软件工程方法与实现
- 张春强 张和平 唐振
- 3538字
- 2021-01-07 17:12:23
1.2.1 机器学习中的软件工程
软件工程是一门用工程化思维和方法解决软件项目问题的学科,也是一门注重实践的学科。下面给出软件工程的形式化定义:软件工程是研究和应用如何以系统性、规范化、可定量的过程化方法去开发和维护软件,以及如何把经过时间考验而证明正确的管理技术和当前能够得到的最好的技术方法结合起来的学科。软件工程是一门工程学科,涉及软件生产的各个方面,从最初的需求描述到投入使用后维护的整个生命周期都在其范畴内,包括软件项目管理、使用的工具和方法等活动。一切涉及软件开发的活动都能从软件工程方法论中受益。
软件工程这一概念最初是在1969年的NATO大会上提出来的,旨在探讨解决软件系统总是延期、不能交付预计的功能、成本超出预期、软件可靠性等问题。
软件工程涉及“人和事”两个方面:人参与规划和实施;人使用工具,遵循某种方法做事。软件工程可以概括为3类对象:过程、资源和产出。过程是人参与项目实施相关活动的集合,例如确定需求、制定规范、详细设计和开发过程;资源是这一过程所需的实体,例如人、软硬件资源;产出是这一过程产生的结果,例如文档、代码等一切可交付的成果。
软件工程的目的是在一定的时间和资源下获得所要求品质的成果,对应到机器学习中则是在有限的时间和资源下获得较好的模型性能。要避免完美主义,模型性能只有更好,没有最好。
软件产品不仅是程序,还包括相关文档,对应到机器学习中为模型和项目报告文档。
软件产品要具有可维护性、安全性、效率和可接受性,对应到机器学习中即为满足可接受的模型和算法性能的、可维护的,可升级的、安全的模型前后端系统。
下面进一步说明软件工程中的过程。一般来说,软件开发过程包含以下4项基本活动。
1)软件描述:需求与开发双方定义所要生产软件的需求和约束。
2)软件开发:软件设计与编码。
3)软件有效性验证:检查软件功能与需求是否匹配,排除Bug。
4)软件进化与迭代:随着需求的变化对软件进行修改、定制或升级。
将以上活动映射到机器学习中,得到以下过程。
1)机器学习建模项目描述:描述目标,明确需求、模型设计和场景、数据、资源等相关约束。
2)建模过程:数据分析、特征处理、算法选用和调参的过程。
3)模型性能评估与报告:评估模型效果是否达到预期并总结报告。
4)模型的迭代和更新:外部环境变化导致数据变化,需要对模型重构或重建。
很多机器学习的项目失败或不顺利的主要原因,往往是前期的需求分析和计划没有做到位。机器学习领域有这样的说法:80%的时间花在数据和特征工程上,20%的时间花在算法模型上。从项目的角度看机器学习,上述说法有一定的局限性,实际上初期的项目规划、定义和需求拆解研究同样要花费大量的时间来论证,需要明确目标、判断可行性和可验证性、理顺一切可能的数据和资源等,这些直接决定了项目的成败。当我们这样做时,我们就已经进入软件工程范畴。
软件工程中的过程按照“做事的方式”又可分为计划驱动和敏捷过程。对应两种软件过程的模式分别是瀑布模式和增量模式。
明确地将如上4个基本活动依次排列并界限分明地实施,这就属于瀑布模式。在瀑布模式下,各个事项没有循环和返工,按顺序执行,如瀑布之水。瀑布模式要求事先对该过程制定详细的计划和进度安排,非常便于项目管理。例如,传统软件开发的瀑布模式是需求定义→统合软件设计→编码与单元测试→集成与系统测试→运行与维护。
而在增量模式下,各过程节点活动时常交织在一起,当前版本基于上一个版本增量添加新功能和新方法,发现错误时回滚,最终在不断迭代中逼近预期目标。增量模式符合人们做事的直觉:先做出来再检验效果。这种模式常出现在互联网产品的开发过程中,毕竟计划和设计出来的需求并不一定符合用户的真实想法,而且还有原有设计存在缺陷、需求紧急、计划变更等多种情况。
当然,上述过程实践模式并不互相排斥和明确隔离,而是时常混用,本质上就是我们做事惯用的方式。在机器学习项目中,当需求明确、企业内经验成熟时,适合使用瀑布模式。人们制定详细的计划、分工协作、记录详细的文档,这样项目可控,也便于项目传承。而当需求不确定、项目大、涉及面广、经验不成熟、需要的资源多时,采用增量模式能有效避免因后续节点依赖前面的节点而导致进展缓慢的问题。
软件工程的实践者们基于增量模式,又提出了敏捷开发方法,例如极限编程、敏捷开发(Scrum)等,但这些增量快跑的方式可能会导致一些问题,例如系统Bug增多、代码结构不清晰等,也常常造成该过程的一些节点缺失,比如没有形成良好的文档记录,导致后续项目升级、重构、移交困难。为了解决这些问题,人们提出了结对编程、代码重构、测试驱动开发、持续集成等软件工程的最佳实践。
除了上述软件工程方法外,机器学习实践中同样面临很多工程性问题。机器学习中常见的工程性问题可分为算法层和应用层,尤以应用层面临的问题居多。具有科研性质的新算法侧重于算法的理论与逻辑、公式的优美程度与复杂性,以及高精尖程度。而工程实践中则要考虑实现难度、运行环境、运行效率、稳定性等问题,实现起来往往不那么优雅,甚至要牺牲一定的精度做折中处理。机器学习实践过程中时常面临的工程问题需要工程师进行权衡与抉择,这正是软件工程看问题的角度。
1)算法性能与健壮性:算法的运算性能和健壮性直接影响机器学习的效率,间接影响模型的效果和推广应用。算法从性能上可考虑在线还是离线训练的模式,以及是单机还是分布式的算法,进而考虑直接开源还是自实现,以及如何选择编程语言等实际问题。
2)特征数量:特征数量过多,除了会造成学习算法困难,还会提高数据获取和数据处理的难度,进而直接提高上线的难度,增大上线后的监控工作量。在业务层面则会增加解释的难度。
3)数据转换:要求数据转换的一致性,此处数据转换包括数据处理和特征衍生。模型上线预测阶段的数据转换过程要与模型训练阶段的处理过程保持一致,这个过程包括一致的处理方法和一致的元信息。例如模型训练过程中空值填充了均值,那么线上的预测数据处理过程也要填充均值,且该均值为训练集上的均值,即处理方法和训练集上的均值这一元信息都需要存储并运用到后续的预测阶段。特征衍生亦是如此。
4)模型大小:模型文件的大小将影响加载启动效率甚至预测效率,在嵌入式系统(智能设备)中直接影响系统资源分配。
5)机器学习环境:一般模型上线要求和模型训练具有相同的运行环境,即环境一致性要求。环境准备的难易程度直接影响模型上线的难度。
6)调用或集成方式:是否将模型设置为独立的功能模块或者模型是否便于嵌入式地集成到宿主机中,例如API调用便于解耦和维护。此外,还需进一步考虑大批量调用的效率、容错处理、日志收集、数据库等系统集成问题。
7)预测效率与实时性:一般来说,模型越复杂,预测效率越低;系统越复杂,实时性越差。使用复杂模型时尤其要注意,比如多层或嵌套的集成模型,模型复杂度非常高,预测效率往往非常低。线上预测往往要求实时性,复杂模型并不合适。
8)功耗:智能设备的功耗和发热也是实践中要关注的点。
很多时候,机器学习项目实践并不需要一味追求“高精尖”的方法和技巧,反而是简单、直接、有效的方式常常成为首选,这些需要机器学习算法工程师综合考虑并提出自己的看法。当我们从项目应用的角度考虑问题时,就真正体现了“机器学习工程师”中“工程”二字的真实含义。只有这样,我们才算有了机器学习的工程思维。
在我们实践机器学习项目时,除了遵循以上的过程方法论外,还会用到相关方法和工具。例如,如何分析需求、设计实验、设计模型、设计系统架构等,使用什么样的机器学习开发和测试环境、自动化测试工具、开源工具包、部署工具、代码管理工具等。本书将在第2、3和15章介绍一些必要的软件工程知识和工具的应用。
最后,用图1-5简要描述机器学习、人工智能与软件工程的关系。
经过对上述对照关系和软件工程方法的学习,我们对机器学习的认识将得到进一步扩展,这正是本书的目标——展现完整的机器学习项目从开始到结束的全过程。
图1-5 机器学习、人工智能、软件工程关系
机器学习与软件工程的交叉点还有另外的领域,在这些领域中机器学习方法被用来开发更好的软件产品,并使软件开发更加高效。例如,使用机器学习方法预测或评估软件项目,包括自动发现软件质量缺陷、定位系统故障、评估开发或维护成本等。
如果把机器学习中的算法等理论研究看作机器学习的深度,那么机器学习的工程化实践则可称为广度。本书中并不能覆盖软件工程与机器学习交叉领域的各个方面,而仅从一些结合点来扩展读者对机器学习认识的广度。本书尽量借用软件工程中的方法实践机器学习的多个方面。
本书中的软件工程内容只涉及几个点,这只是软件工程的冰山一角。软件工程发展了几十年,市面上已有大量的相关专著,感兴趣的读者可参考Ian Sommerville的《软件工程》一书。