2013年4月30日,星期二

学习比优化容易

此博客文章的标题是一个短语,归因于 莱昂·波托(Leon Bottou) (尽管您不会从网络搜索中了解到这一点:显然,创业社区有一个 类似的格言)。这是机器学习中为数不多的深层真理之一,我认为在进入一个勇敢的新世界时要牢记这一点特别重要 数据指数压倒了计算指数。要点是,训练错误是我们真正关心的泛化错误的代名词,因此,过度花费计算精力来优化训练错误可能会适得其反。适得其反产生于(至少)两种不同的方式。首先是过多的计算工作可能会导致您使用较少的数据来补偿计算时间,而使用较少的数据意味着代理的准确性较低。第二个是不太积极的优化可以充当正则化器,当用``更好''的优化例程进行校正时,实际上会导致更严重的泛化错误。

我想到了这种现象的两个例子。一,主导地位 随机梯度下降 (SGD)。当神经网络首次出现时,SGD是唯一的优化算法,但人们很快开始尝试使用基于准牛顿的更先进技术。如今,神经网络仍然使用接近SGD的算法进行训练,可以说,我们今天看到的主要区别在于体系结构和正则化器(而体系结构是一种正则化器)。事实是,SGD是一种一般的优化算法,但它是一种很棒的学习算法。

第二个例子是 哈希技巧 。对于在实际矢量表示上运行的算法(即所有算法afaik),必须将特征转换为索引,因此一种策略是构建和维护字典将特征映射到索引。对于非常高的基数特征空间,这不仅繁琐,而且可能导致无法满足的内存需求。当使用散列技巧时,将散列函数应用于特征标识以便确定特征索引。第一次遇到这种情况的每个人都认为:“那里没有碰撞吗?”。答案是:“是的,有冲突”,“在实践中似乎没有多大关系”。可以谈论它如何保留期望的点积,或者说在存在冗余的情况下统计稳定的联结特征如何提供信息,但这是真正的巧妙之处:我已经看到很多例子,其中增加了位数哈希函数会降低性能。换句话说,冲突更少,但泛化能力更差;这是因为哈希冲突为模型的复杂性提供了有用的约束, 学习比优化容易.

好吧,那又如何呢?我们所有人都应该在编码中草率行事吗? 通过把自己扔在地上而失踪飞行?不,但我认为值得保持开放的态度。特别是,要跟上现代数据的洪流,就需要开发分布式算法,而并行编程的最大低效率之一就是同步。因此,我建议对无同步学习算法保持开放的态度。

牛等等他们一直在这种思维的最前沿 霍格威尔德! 关于共享表示形式的无锁并行SGD的建议。当我第一次听说这件事时,我想:“那不可能。”但是,这就是我第一次听说该哈希技巧时所想到的。所以我还没有尝试过霍格威尔德!就个人而言,我不能保证,但是我也不愿意将其驳回。

而牛等。等建议做``脏写'', 松岛等等 提出更直观的``脏读''想法。在提出的多个想法中,有一个解析线程可以维护示例的缓冲区,而并发学习线程可以从缓冲区中训练示例,而这两者之间的同步最少。对于许多在线算法而言,解析是瓶颈,因此学习算法会在解析线程替换示例之前按预期对每个示例进行几次训练。因此,这看起来像一个迷你批处理算法,但是随着时间的推移,迷你批处理的变化缓慢,这听起来是个好主意。我在和他们玩 流支持 软件,手指交叉!

5条评论:

  1. 嗨,保罗。您有什么确切的例子说明何时'我看到增加位数时哈希算法的效果更差吗?
    I'我从来没有遇到过这样的现象。由于散列就像一个正则化器,因此在我看来,只要您调整正则化参数,就应该使用更多的位获得更好的测试错误。
    当然,有时候找到一个好的正则器并不是那么容易,但是我可以'很难想象一个场景'不能提出比散列技巧提供的纯随机投影更好的正则化策略。

    谢谢

    回复 删除
    回覆
    1. I'当您具有许多功能时,就会发生这种情况,在这种情况下,L1正则化也会有所帮助。它'如果我彻底探索了(哈希位,L1 eta)组合的空间,则可能会发现具有更多哈希位的对象效果更好,但是由于增加哈希位而导致的速度下降确实是令人沮丧的。

      删除
  2. 感谢您的快速答复。

    I'遇到过您描述的那种情况。我凭经验发现的最佳解决方案是使用L1 reg和一些SGD求解器。但是调整正则化参数+放置尽可能多的位始终效果最佳。对我来说,当每个服务器的RAM数量有限时,我认为哈希技巧是处理非常稀疏的特征空间的便捷方法,从而避免使用参数服务器等更复杂的基础结构。正则化效果只是蛋糕上的樱桃。

    我不't真正理解了速度降低的论点:但是,如果观察到的n大于总特征空间基数d,则在具有稀疏特征的典型大规模设置下,学习算法的CPU复杂度将与每个观测的活动特征,而不是d(对于SGD和QN方法,因为传递数据将主导参数的更新)。因此,当您增加哈希位时,并不会真的变慢。

    回复 删除
    回覆
    1. 速度降低来自散列位增加导致缓存效率降低。

      删除
    2. 好吧,我猜 '这是一个值范围的问题,因为一旦您对约20位以上的位进行散列,参数向量就可能太大而无法容纳在任何CPU高速缓存中,因此应该增加它'改变(不存在)内存局部加速的程度。但是对于少于1M的参数,我知道这可以带来很大的不同,您'd更好地学习使用更少参数的更多数据。

      删除