算法工程师 の 自我修养
引用:Hidden technical debt in Machine learning systems [1]
在学好机器学习、深度学习的理论基础之后,如何使用自己的理论知识来解决实际数据分析中的算法问题呢?对于该问题,在此分享下自己在工业界的一点感受。
作为一个萌新初出校门从学术界转移到工业界,必然会遇到非常多的问题。首先是对工业界项目接触较少(个人感觉在学校写论文其实也算一个小型项目😊),关于不同企业的开发环境、项目流程、工作汇报等工作都不熟悉,因此,都会需要一定的时间来适应这种新环境。当然,考虑问题也不仅仅是满足个人需求,例如服务器配置开发环境时需要同时考虑到不同开发人员的调用情形和存在的问题等等。每个人会遇到的问题很多但在此就不详细介绍了,本文主要分享下作为算法工程师可能遇到的问题和需要具备的素养。
作为“炼丹”新手,最大的问题可能就是解决实际问题时的逻辑思路不清晰,也是本人存在的问题。例如,部门中有一个新项目时,如果在学校时间充裕都可以可以使用“蛮力法”来解决问题,思路简述如下:
- Github 搜索开源代码;
- 尝试跑下模型或算法,调下参数;
- 效果不好,接着搜下个模型,又回到第 1 步;
- 效果好,留下备用或集成模型。
按照这种思路可能解决问题,但也可能陷入无限尝试死循环中,一直再跑模型试模型改参数,不仅效率非常低而且对问题理解不够深入。
在此分享下个人在实习过程中学习到的“炼丹”总结,希望能够提升“炼丹”萌新的解决问题的能力。(当然不能解决所有的问题,不要以为一招在手天下我有!别想多了😂)
主要可以分为以下四部分:
- 算法调研
- 迭代过程
- 提速策略
- 实验管理
算法调研
遇到一个新的算法问题时,可以首先定位该算法问题所对应的学术会议或者期刊,或者该领域某个大牛的科研成果。
例如,如果是计算机视觉相关的问题,可以首先查看 CVPR、ICCV、ECCV 等会议。如果是自然语言处理的问题,可以查看 ACL,EMNLP,NAACL、CLONG 等。如果不在这两大领域,可以看看 ICLR、NIPS、AAAI、IJCAI 这些比较混合的领域顶会。当然这些顶会都包含很多的细分方向,可以按照自己的需求和与算法问题最接近的论文标题搜索文章。
找到几篇与算法问题相关的文章之后,那么接下来就是如何看论文的问题了。
下面分享下个人看论文的方法:
- 首先需要看这篇论文的 Abstract,确定是否与问题相关或该论文解决了当前存在的问题。
- 论文中提出的模型可以先大概扫一遍,等确定该方法合适才细看。尤其是 paper 分享的时候需要讲清楚。
- Related work 需仔细看一遍。如果是刚涉入某一领域,那么可以从这里了解该领域的经典的方法和早前的工作内容。
- 实验部分也需仔细看一遍。从这部分不仅可以了解论文中提出方法的有效性,还可以找到这个领域的经典方法和 SOTA。这样不就有几个 baseline,说不定还有作者整理的源码惊喜!
以上方式并不通用,可以根据自己的实际问题、个人习惯或者时间问题来选择。
迭代过程
作为算法工程师需养成自己分析、解决问题的习惯以避免遇到一个新问题不知从何下手的情况。下面说说自己学习到的一种迭代过程:
- 数据集分析
- 数据预处理
- 模型/算法选择
- 模型/算法评价
- 实际案例分析
数据集分析
拿到数据集之后,不要直接上模型或者算法。首先对这个数据集作简单的分析,可以有助于理解数据特征、选择参数等。
比如观察数据的格式以决定采用何种编码方法;统计下样本特征分布以了解每个属性的取值范围和分布曲线;统计下每个类别的样本分布以了解正负样本比确定模型准确率,等等等等。
数据预处理
不同类型的数据预处理方法很多,这其实也可以划分为一个研究方向。简单推荐两个资源:
- 非常齐全的 python 资源库:https://github.com/jobbole/awesome-python-cn
- 缺失值处理库:https://github.com/eltonlaw/impyute
模型/算法选择
其实这一步就是上述算法调研过程,采用合适的论文算法/模型。paper 无限多但是 paper 中模型适用场景却是有限的。所以需要根据自己的实际问题和目的来进行选择。不要成为简单的“掉包侠”和“调参侠”,要成为高效的“攻城狮”!
模型/算法评价
模型评价就需要在测试集中进行,每个方向的评价指标都不相同。例如对于分类问题可能就采用 ACC、F1 或者 AUC 等等;聚类问题采用聚类系数、NMI 等等。但需要注意的是评价指标都是有偏的,点刷得高不一定说明在实际应用中的效果非常好,所以也需要选用一个合适的指标来评价你的模型。一般情况下都是选用经典且广泛使用的指标了,毕竟用得少的也没人承认效果😂。
案例分析
这一步主要是防止新手胡乱尝试各种创新的算法模型问题。在尝试和选择模型上可以预使用数据集中的小部分案例来测试模型的效果,发现当前模型中存在的问题,然后有针对性的选择模型和并使用自己创新的方法。不要一顿操作猛如虎,一看战绩一个可用的模型都没有。
提速策略
如何提高解决问题的速度,在此就简单分享几点内容:
- 克制自己的强迫症,能忍受 codebase 中的乱七八糟代码格式。例如在旷视实习时第一次看到人脸识别的 codebase,简直是难以忍受都想自己用 pytorch 重新写一遍,然后一顿疯狂操作发现掉点严重,哭了哭了🤣。
- 推荐使用 bash 和 jupyter notebook 共同开发,保留数据处理现场。在此基础上最好熟悉 bash 和 vim 操作,远程开发时这样可以提高处理效果。
- 验证模型时分不同数据规模。不要开始就将全部训练集用来跑模型,这样效率太低了。首先使用 100 条左右样本调试代码;然后采用 1000 条数据验证模型的收敛性;再小规模实验分析超参数和隐藏 bug;最后大规模实验训练完整的模型,一般大规模训练需要几天时间,因此执行最后一步保证代码无 bug,否则前功尽弃了啊。
- 超参敏感性分析。这一步我这小菜鸡也在一直学习,需要自己的经验或论文中的取值来进行选择,智能不断学习了。
实验管理
在训练模型的过程中,强烈推荐将对应模型的配置、参数和实验结果记录下来,训练日志和测试日志最好是通过文件形式保存下来,而不是显示在终端中成为过眼云烟了。否则可能就会出现“我这模型相同的配置怎么掉点了???”的情况了。至于如何保存就看个人习惯了,小编一般是在云笔记中备份。
模型训练/测试时最好写一个脚本如 run.sh 一键运行,这样效率高很多。
强烈推荐 github 进行版本管理,定期将代码 push 到 github 中保存。多人协作出现错误时也可以恢复现场。
以上是本人作为算法攻城狮在实习期间的学习到的主要内容和感受。作为菜鸟必然会存在很多的不足,希望诸位看官在留言中多提出一些意见大家共同学习、共同进步!🙌🙌🙌