早停陷阱:我如何在 RL 训练学会之前就把它们扼杀了

早停(early stopping)本应帮你省下算力,避免在一个已经学完的模型上继续浪费计算。然而在很长一段时间里,它恰恰是那个在烧我自己算力的东西——因为它在那些优秀的智能体变得优秀之前,就把它们扼杀了。

死在我自己早停规则下的强化学习训练,比死于糟糕想法的还要多。我为了让系统更有纪律而搭建的这个”急停开关”,最后却成了整个系统里最没纪律的部分。

一条带噪声的示意性 reward 曲线,先出现回落并被提前停止,虚线延续部分展示了它本可达到却未曾抵达的攀升 示意图,非真实表现数据。该智能体在一次正常的回落中被停掉了——恰好就在它本该开始攀升的那一段之前。

适得其反的急停开关

我把早停从监督学习里搬了过来。在那里它是金科玉律:盯着 validation loss,一旦它在一段时间内不再改善,就停下——再往后你只会过拟合(overfitting)。这套做法干净、安全,在监督学习里通常都管用。

于是我把同样的思路接进了 RL 训练:盯着指标,遇到 plateau 之后耗尽 patience,停掉这次训练,省下 GPU 小时。这感觉很负责任。但实际上它悄无声息地一次又一次丢弃了训练——其中很多被停得很早,早到智能体还根本什么都没学到。最后我攒了满满一个文件夹的训练,它们其实压根从未真正开始

RL 为何打破了这条规则

监督学习的 validation 曲线相当平滑,基本上是单调的。强化学习智能体的进步则不然。reward 在本质上就带噪声:它取决于一个本身就在不断变化的 policy,而这个 policy 又在一个充满方差的环境里交互。改善是断断续续地出现的——长时间的平台、突然的跃升、回落之后又恢复。在 RL 里,plateau 往往不是学习的终点,而恰恰是学习开始前的那一段。

所以,一个为监督学习的平滑性调好的 patience,会在完全正常的 RL 方差中触发。你抓住的并不是一个已经学完的模型;你处决的是一个正要变得有意思的模型。而所谓的”节省”不过是幻觉——你照样为每一次提前夭折、什么都没返回的训练付了账。

别再提前停了

真正的修复并不是换一个更好的数字,而是把默认设定反过来。早停应该是罕见的,而不是急切的——它是防范真正的、持续的过拟合的一道防线,而不是对噪声一触即发的扳机。这意味着要把门槛设在噪声现实中根本够不着的地方,并且在一个足够长、长到能让训练本身的自然方差相形见绌的窗口上去判断性能退化——而不是凭寥寥几次评估。默认必须是继续跑下去。举证责任在于”停下”,而不在于”继续”。

说白了:patience 也是一个 hyperparameter,而大多数新手——包括我自己——设置它时仿佛 RL 就是监督学习。它不是。

人类仍然该待的位置

这与第一篇文章的教训遥相呼应。我并不会逐次训练地去决定什么时候拔掉插头——那只不过是又一次把一个猜测冻结进系统里。我决定的是*“真正在变差””正常噪声”*之间的界线,然后让这个定义去执行停止。我设计的是裁判,而不是亲手给出每一次裁决。把裁判设计对了,你就不会再丢弃那些本来会成功的训练。

核心要点

在 RL 里,最昂贵的 bug 往往是缺乏耐心。过早地去优化你的算力预算并不会省下算力——它让你赔上了那个智能体,而残酷之处在于,你永远看不到自己亲手扼杀掉的那个结果。

所以,如果你的训练总是”跑不起来”,先检查它们究竟有没有得到过这个机会。有时候并不是模型在失败,而是你。


这是一份持续进行、匿名记录的系列文章的第 2 部分,记录的是构建一套强化学习交易系统的过程。它谈的是方法与错误,而非交易信号——这里的内容不构成任何投资建议,也不会透露任何策略细节。