Scikit-learn 多核:“AttributeError: StdIn 实例没有属性 'close'”

3 投票
3 回答
1610 浏览
提问于 2025-04-18 09:29

我在用PyCharm运行Scikit-learn里的RandomForestRegressor,这个在执行整个脚本的时候没问题:

clf = ensemble.RandomForestClassifier(n_estimators=100, n_jobs = 4, verbose=1, oob_score=True)
clf = clf.fit(x_train, y_train)

但是当我试着在控制台运行某一行代码时,就一直出现这个错误:

AttributeError: StdIn instance has no attribute 'close'
  File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/process.py", line 249, in _bootstrap
    sys.stdin.close()

如果我把n_jobs参数改成n_jobs=1,就不会出错了,但这样就不能利用多线程的优势了。

我猜这可能跟PyCharm控制台重定向输入有关,但我不太确定怎么才能让它正常工作。希望大家能给点建议,谢谢!

3 个回答

0

为了让像我这样的Python新手更容易理解,我总结了之前回答和评论中的一个解决方案。打开 process.py 文件,在我的Linux系统上是这样做的:

sudo gedit /usr/lib/python2.7/multiprocessing/process.py

在修改之前,我会先备份一下,这样如果出错了可以方便恢复,然后在 process.py 文件中找到“bootstrap”,并把它改成这样开始:

def _bootstrap(self):
    from . import util
    global _current_process
    if not hasattr(sys.stdin, 'close'):
        def dummy_close():
            pass
        sys.stdin.close = dummy_close
    try:
0

PyCharm主要是一个集成开发环境(IDE),它支持快速输入源代码、自动检查代码、原型设计和调试工作。

一般来说,检查一下你的{硬件 | 虚拟机}是否能支持并行处理:

import multiprocessing
multiprocessing.cpu_count()

在PyCharm IDE中进行并行多进程处理

不要浪费CPU时间在IDE里运行已经调试好的代码,不管是使用IDE自带的Python引擎还是远程Python引擎(像PyScripter IDE等情况)。

一段写得好的Python代码在命令行中运行会更安全、更快,比如C:\Python2.7\python.exe aRandomForestJOB.py

如果PyCharm的控制台阻碍了你进行多进程处理,试着在独立的Python解释器中运行相同的代码,看看问题是否还存在,如果代码崩溃了,可以把错误信息发出来。

PyCharm sys.stdin.close() 错误的解决方法

Nathan Lemoine报告说:

''' PyCharm 3包含一个本地终端。我在那个终端中打开Python,运行得很好,这让我可以调试和进行交互式工作。这让我觉得这是PyCharm运行其交互式解释器的方式特有的问题。但由于解决方法很简单,所以这并不算什么大问题。 '''

6

我来得有点晚,但我刚才也遇到了同样的问题。

其他回答中提到的解决办法是避免使用PyCharm的交互式解释器。这个方法当然有效,但我不太满意,因为我非常喜欢使用交互式解释器。

我找到了一种不同的解决办法,它不仅解决了问题,还允许使用交互式解释器。在每次通过 multiprocessing.Process() 创建新进程之前,都需要执行以下代码:

if not hasattr(sys.stdin, 'close'):
    def dummy_close():
        pass
    sys.stdin.close = dummy_close

现在,multiprocessing 可以顺利地对 sys.stdin 调用 close(),一切都运行得很顺利。

请注意,仅在启动阶段附加一次虚拟的 close() 是不够的。我发现必须在每次调用 multiprocessing.Process() 之前都执行这个操作;不过我没有尝试过进程池的情况。

撰写回答