【问题标题】:Scikit Learn RandomForest Memory ErrorScikit Learn RandomForest 内存错误
【发布时间】:2014-05-31 20:23:04
【问题描述】:

我正在尝试在 mnist 手写数字数据集上运行 scikit 学习随机森林算法。在算法训练期间,系统进入内存错误。请告诉我应该怎么做才能解决这个问题。

CPU 统计数据: Intel Core 2 Duo with 4GB RAM

数据集的形状是60000, 784。 linux终端上的完整错误如下:

> File "./reducer.py", line 53, in <module>
>     main()   File "./reducer.py", line 38, in main
>     clf = clf.fit(data,labels) #training the algorithm   File "/usr/lib/pymodules/python2.7/sklearn/ensemble/forest.py", line 202,
> in fit
>     for i in xrange(n_jobs))   File "/usr/lib/pymodules/python2.7/joblib/parallel.py", line 409, in
> __call__
>     self.dispatch(function, args, kwargs)   File "/usr/lib/pymodules/python2.7/joblib/parallel.py", line 295, in
> dispatch
>     job = ImmediateApply(func, args, kwargs)   File "/usr/lib/pymodules/python2.7/joblib/parallel.py", line 101, in
> __init__
>     self.results = func(*args, **kwargs)   File "/usr/lib/pymodules/python2.7/sklearn/ensemble/forest.py", line 73, in
> _parallel_build_trees
>     sample_mask=sample_mask, X_argsorted=X_argsorted)   File "/usr/lib/pymodules/python2.7/sklearn/tree/tree.py", line 476, in fit
>     X_argsorted=X_argsorted)   File "/usr/lib/pymodules/python2.7/sklearn/tree/tree.py", line 357, in
> _build_tree
>     np.argsort(X.T, axis=1).astype(np.int32).T)   File "/usr/lib/python2.7/dist-packages/numpy/core/fromnumeric.py", line
> 680, in argsort
>     return argsort(axis, kind, order) MemoryError

【问题讨论】:

  • 你使用什么参数来创建 RandomForest?
  • 我只是在使用 n_estimators=10
  • 尝试设置n_jobs=1

标签: python python-2.7 scikit-learn


【解决方案1】:

设置 n_jobs=1 或升级到 scikit-learn 的前沿版本。问题在于当前发布的版本使用多个进程来并行拟合树,这意味着需要将数据(Xy)复制到这些进程中。下一个版本将使用线程而不是进程,因此树学习器共享内存。

【讨论】:

  • 我确实尝试添加 n_jobs=1 但仍然得到同样的错误。您能否提供一些我可以使用新版本 scikit-learn 的方法?
  • @Piyush 如果您在使用n_jobs=1 时遇到此错误,那么升级将无济于事。 X 最初是 np.float32 格式吗?它是 Fortran 排序的(以列为主)吗?
【解决方案2】:

Scikit-learn 开发团队在 .ensemble 方法上的内存管理和性能方面都有很大改进

在充分尊重其他意见的情况下,scikit-learn 0.16.1 并不证明自己有“讨厌Xy 副本,在一些早期版本中引用。

由于其他一些原因,我花了相当长的时间研究 RandomForestRegressor() 超参数的景观,包括。他们的内存占用问题。

截至0.16.1,与默认n_jobs = 1{ 2, 3, ... }

相比,parallel-joblib 内存需求增加不到 2% >

最近 scikit-learn 发布的共同父亲,@glouppe,发布 a marvelous & insight-full presentation (2014-Aug, rel. 0.15.0),包括。与基于 R 和其他已知 RandomForest 框架的比较。

恕我直言,第 25 页以上谈到了提高速度的技术,包括。 np.asfortranarray(...),但是在我看来,这些(没有任何实验证明)只是 Scikit-learn 开发团队内部共享的内部方向,而不是对我们这些生活在“外面的世界”。

回归还是分类?

是的,这很重要。如果不进行全面的 FeatureSET 矢量装袋,可能会进行一些额外的特征工程工作和测试。您的学习者似乎是分类器案例,因此请深入研究:

  1. max_features 等人的非默认设置进行实验
  2. 使用 O/S 服务来处理更大的虚拟内存mkswap + swapon(如果需要)在 1 中调整学习器后。

附录

经过另一轮测试,出现了一个有趣的观察结果。

虽然 .set_params( n_jobs = -1 ).fit( X, y ) 配置在训练 RandomForestRegressor() 时成功使用,但后来出现了丑陋的惊喜,曾经尝试在这样的预训练中使用 .predict( X_observed )对象。

报告了类似的 map/reduce 绑定内存问题(现在是 0.17.0)。

尽管如此,同样的.set_params( n_jobs = 1 ).predict( X_observed )单独工作在.predict()上得到了很好的服务

【讨论】:

    【解决方案3】:

    一种解决方案是使用 scikit-learn 的最新版本 (0.19)。在更改日志中,他们在bug fixes section 中提到(确实有重大改进):

     Fixed excessive memory usage in prediction for random forests estimators. #8672 by Mike Benfield.
    

    您可以使用以下方法安装此版本:

    pip3 install scikit-learn==0.19.0
    

    【讨论】:

      【解决方案4】:

      请用一棵树训练随机森林并检查树的深度。默认情况下,完整的树在 scikit-learn 中生长。深度可能非常大,因此即使森林中的几棵树也可以使用大量内存。您可以尝试使用max_depth 超参数限制树的深度。

      当我将树的深度从 42(森林中树的平均深度)降低到 6 时,我运行了experiment。内存减少了 66 倍,而性能稍微好一些(大约 4%)。

      【讨论】:

        猜你喜欢
        • 2018-02-15
        • 1970-01-01
        • 2012-06-27
        • 2016-06-28
        • 2015-06-23
        • 1970-01-01
        • 2014-06-28
        • 2016-01-26
        • 1970-01-01
        相关资源
        最近更新 更多