caret::train(neuralnet)与直接调用neuralnet()的运行耗时差异问询
问题原因与解决办法
1. 耗时差异的核心原因:caret的重采样机制
直接调用neuralnet()是单次训练模型,而caret::train()默认会执行10折交叉验证(即使tuneGrid仅包含一组参数)。这意味着caret会在10个不同的训练子集上分别训练模型并验证,总计算量是直接调用的10倍以上,自然耗时剧增。
2. 收敛差异的可能原因
- 参数传递不一致:
caret调用neuralnet时,部分默认参数可能和直接调用时不同。比如你直接调用的模型在18364步收敛,但caret中设置stepmax=1e5仍未收敛,大概率是因为caret没有同步传递neuralnet的隐含参数(如默认算法"rprop+"),或是重采样后的子数据集分布导致收敛路径变慢。 - 初始权重随机性:神经网络初始权重是随机生成的,不同训练会话或交叉验证fold的收敛路径可能存在差异,但你遇到的极端差异更可能是参数传递不匹配导致的。
3. 具体解决步骤
(1)快速匹配直接调用的速度
如果不需要交叉验证,给train()添加trControl参数关闭重采样:
nn.LYS.grid <- expand.grid('layer1' = 2, 'layer2' = 2, 'layer3' = 0) nn.LYS <- caret::train(form.LYS, data.all.scaled.train, method = 'neuralnet', tuneGrid = nn.LYS.grid, lifesign = 'full', trControl = trainControl(method = "none")) # 关闭重采样
此时caret仅训练一次模型,速度与直接调用neuralnet()基本一致。
(2)统一收敛相关参数
显式传递neuralnet的核心参数到train()中,确保和直接调用完全一致:
nn.LYS <- caret::train(form.LYS, data.all.scaled.train, method = 'neuralnet', tuneGrid = nn.LYS.grid, lifesign = 'full', stepmax = 20000, # 设置为比直接收敛步数更大的值 algorithm = "rprop+") # 匹配neuralnet默认算法
(3)解决并行化警告
若并行化导致连接警告,可临时关闭并行验证:
nn.LYS <- caret::train(form.LYS, data.all.scaled.train, method = 'neuralnet', tuneGrid = nn.LYS.grid, lifesign = 'full', allowParallel = FALSE) # 关闭并行
若需要保留并行,检查并行后端的注册逻辑(如doParallel::registerDoParallel()后是否正确注销),避免残留连接问题。
(4)若需交叉验证,优化重采样设置
如果必须使用交叉验证,可减少折数或重复次数来降低耗时:
ctrl <- trainControl(method = "cv", number = 5) # 改为5折CV,默认是10折 nn.LYS <- caret::train(form.LYS, data.all.scaled.train, method = 'neuralnet', tuneGrid = nn.LYS.grid, lifesign = 'full', trControl = ctrl)
内容的提问来源于stack exchange,提问作者padj
相关产品推荐
相关产品推荐

