如何使Scikit-learn的MLPRegressor利用全部12个可用核心?
如何让Scikit-learn的MLPRegressor用上全部12个核心
嘿,这个问题我之前折腾过!首先得给你划个重点:MLPRegressor的单模型训练本身是单线程的——因为神经网络的梯度计算、参数更新这些核心逻辑,Scikit-learn的默认实现里没做CPU多线程并行(和RandomForest这类树模型的并行分裂节点逻辑完全不同)。不过咱们可以通过并行执行多个MLP相关任务来充分利用你的12个核心,joblib确实是解决这个问题的核心工具,下面给你具体的实操方案:
方案1:用joblib配合超参数搜索(最常用)
Scikit-learn的GridSearchCV或者RandomizedSearchCV本身就支持n_jobs参数,它底层就是靠joblib实现并行的。你只需要把n_jobs设为-1(表示调用全部可用核心),这样不同超参数组合的模型训练就会在不同核心上同时跑:
from sklearn.neural_network import MLPRegressor from sklearn.model_selection import GridSearchCV from sklearn.datasets import make_regression import joblib # 生成示例回归数据(替换成你的真实数据即可) X, y = make_regression(n_samples=1000, n_features=20, random_state=42) # 初始化基础MLP模型 mlp_base = MLPRegressor(random_state=42, max_iter=500) # 定义要搜索的超参数网格 param_grid = { 'hidden_layer_sizes': [(64,), (128, 64), (256, 128, 64)], 'alpha': [0.0001, 0.001, 0.01], 'learning_rate': ['constant', 'adaptive'] } # 初始化网格搜索,n_jobs=-1用上全部核心 grid_search = GridSearchCV( estimator=mlp_base, param_grid=param_grid, cv=5, # 5折交叉验证 n_jobs=-1, verbose=2 # 打印并行训练的日志 ) # 启动训练,这里会自动用joblib并行跑各个超参数组合的模型 grid_search.fit(X, y) # 保存找到的最佳模型 joblib.dump(grid_search.best_estimator_, 'best_mlp_regressor.pkl')
方案2:手动用joblib并行训练多个模型
如果你不需要超参数搜索,只是想并行训练多个不同配置的MLP(比如后续做模型集成提升效果),可以直接用joblib的Parallel和delayed来手动实现并行:
from sklearn.neural_network import MLPRegressor from sklearn.datasets import make_regression from joblib import Parallel, delayed import numpy as np # 生成数据 X, y = make_regression(n_samples=1000, n_features=20, random_state=42) # 定义一组不同的MLP配置(可以多写几个,直到占满你的12个核心) mlp_configs = [ {'hidden_layer_sizes': (64,), 'alpha': 0.0001}, {'hidden_layer_sizes': (128, 64), 'alpha': 0.001}, {'hidden_layer_sizes': (256, 128, 64), 'alpha': 0.01}, {'hidden_layer_sizes': (32, 32), 'alpha': 0.0001}, {'hidden_layer_sizes': (128,), 'alpha': 0.01}, # 继续加配置... ] # 用Parallel启动并行训练,n_jobs=-1用上全部核心 trained_models = Parallel(n_jobs=-1, verbose=2)( delayed(MLPRegressor(max_iter=500, random_state=42, **config)).fit(X, y) for config in mlp_configs ) # 后续可以把这些模型做成集成,比如取所有模型预测的平均值 def ensemble_predict(models, X): all_preds = np.array([model.predict(X) for model in models]) return np.mean(all_preds, axis=0) # 生成集成模型的预测结果 ensemble_predictions = ensemble_predict(trained_models, X)
避坑提醒
- 别指望单一个MLPRegressor的
fit()能用上多核心——这是算法特性决定的。如果真的需要单模型的并行加速,建议换用TensorFlow/PyTorch实现的神经网络,它们支持CPU多线程或者GPU加速。 - 在Windows系统上用joblib多进程的时候,记得把训练代码放在
if __name__ == '__main__':块里,不然会出现进程重复创建的问题。
内容的提问来源于stack exchange,提问作者strateeg32




