上次讲了谷歌这篇论文中的 两个技术债,一个是 复杂模型的边界问题,一个是 数据依赖问题。
本文讲解反馈循环和机器学习系统的反模式。
反馈循环(Feedback Loops)
这个是说在人工智能系统中,经常存在输出影响输入这样的反馈循环的问题,比如ctr预估问题,你根据ctr预估的值算一个出价,然后根据出价进行排序,决定出不出广告,这样你出的广告就是被选过的,反过来影响你训练的数据分布,这就是反馈循环。这个例子是显示反馈,当然还有隐式的,具体定义如下:
Direct Feedback Loops(显式反馈):
显示反馈就是说这个反馈是在一个系统里面,比如ctr预估。对于这种反馈,文中列举了几种解决方法
1、使用brandit算法
2、随机探索
3、隔离少部分样本,不被算法影响,对于ctr,可以隔离少部分用户流量实现。
上面几种方法的总结起来就是其实就是解决系统的探索与发现问题(EE问题)
Hidden Feedback Loops(隐式反馈):
这种只两个系统之间存在的反馈,这种一般不是那么明显,所以称为隐式反馈,比如电商中,有一个推荐系统,又一个用户评论分析系统,推荐系统的反馈,是会影响用户评论分析系统的,因为推荐的商品变了,评论的分布也会变。作者指出了这种问题,但是也没好的办法解决。
机器学习系统反模式(ML-System Anti-Patterns)
经过多年的实践,传统软件工程总结了很多设计模式和系统设计范式,让系统有很好的测试性、可扩展性等等。机器学习系统也有类似的模式,文中总结了几个模式:
Glue Code(胶水代码):
胶水代码指项目中调用开源的包,为了调包,一般会适配包的输入输出。文中作者指出,这样的行为可能导致后续,如果又要用别的包,导致成本极大,跟软件工程中可扩展性差一个道理。
解决方案是可以将包做成通用接口,也就是说不是针对某一具体任务的,然后数据处理、输出数据处理都是统一的格式,这样就能很好的适配不同的任务了。
Pipeline Jungles(pipeline丛林):
这是胶水代码的一个特例,一般发生在数据处理阶段,项目中为了处理数据,可能使用了很多pipeline去处理、关联很多表,这样就容易导致很难去测试、检查数据处理中的错误。
作者给出的建议是全局的考虑数据收集和特征抽取,比如工业届的落特征日志。
Dead Experimental Codepaths(无效实验路径):
传统的软件工程可以用flag(如gflag)控制代码的执行路径,为了快速对比不同的实验,可能项目中不同的人使用也类似设置了各种if else路径。最后越来越多,存在非常大的代码隐患。
作者的建议是定时清除无效的实验路径。
Abstraction Debt(抽象债务):
别的领域如数据库,都有很强的抽象术语来描述这个任务,人工智能这块缺少一个统一的抽象,各搞个的,很容易出现系统不兼容,系统迁移的风险。
无形中增加了系统的风险,这部分作者只是吐槽,也没具体的建议,只是指出这个风险。
Common Smells(常见坏的设计):
软件工程中通常用bad smells表示一些常见的设计编码错误。人工智能系统的也存在。
比如下面几个例子:
- Plain-Old-Data Type Smell
这个是说直接使用float、int这种数据类型表示人工智能的计算,这样是损失信息量的,比如一个predictor需要知道它的生产者和消费者。 - Multiple-Language Smell
为了省事、快速开发,系统用多种语言开发,这样导致系统后期难以测试和转交他人。 - Prototype Smell
使用简单的原型代码测试idea,这样导致后续为了仓促上线,让系统各方面没考虑清楚,整个系统是很脆弱的,所以系统上线前一定要用完整的代码。