起个主贴把则个问题讲讲透。一般来说不可能写出一个各方面全优的算法。
比如速度,占用内存,精度一般不能同时做到最优。精度有各种评价方法,
一般也不能同时做到最优。所有这些方面构成一个design space。软件设
计的时候一般就是选design space的一个子空间,然后允许用户通过调整
(meta)参数来微调子空间中的位置。这个子空间的形状一般不是规则的,
参数一般也不是正交的。参数之间的各种关系可能连作者本人都未必想清
楚了。比如有时候程序写着写着会出来一个可以加参数的位置,然后就
出来一个参数。而且这种参数往往很多,一般会被命名为alpha,beta,
gamma,delta,eta,lambda等等,因为含义作者也没法用一两个英文字母
说清(有例外,比如regularization权重一般也是希腊字母)。
Grid search的问题是,很可能就碰到了那种作者都没有想清楚的奇葩
combination,这个combination恰好在用户的某个评价标准下(比如AUC)
高了0.001,但是在别的标准下差得比较多(比如accuracy差0.01,
cross entropy差0.02,速度慢10倍,内存占用多10倍,稳定性变差)。
新手搞kaggle喜欢grid search,是因为kaggle只看一个分数。但是在
机器学习实战中,我最怕的就是准确度评价标准定错了。而且事实上评
价标准肯定和现实有超过0.001的差距。电器的额定功率一般只是最大
功率的50%。偶尔超出额定功率也没事,但是长期超出额定功率使用会
导致寿命缩短。(初中物理,别告诉我你老师没教过。)软件其实也相似,
只是参数又多,程序员又懒,额定不过来。为了某个不完全可靠的指标
的一星星点提高而不顾别的一切考虑,这个是一种非常危险的行为。
这个就是我说的伤人品。某个评价标准到了极值,本身就意味着软件
工作在某种边界状态上。根据边界效益递减原理,很可能就是有别的
某种标准做了极大的牺牲。有时候就是说不清原因,稍微把accuracy调
低一点点使用,留点余地,也未必就不是明智的做法。
CS作为一个实战学科,可以硬碰硬看分数是很多软学科所不及的。但是CS
作为一个engineering学科,还有非常重要的一点就是trade off。
当年我在北大时教体系结构的老师叫程序,天天挂在嘴边的就是
trade off,有舍才有得。你百尺竿头跟进一步accuracy得来了艰难的0.001,
又不知道自己舍了什么,难道不是一件细思恐极的事情?