使用RcppEnsmallen调用Adam优化器编译报错求助
问题解决:RcppEnsmallen中Adam优化器编译报错
问题分析
编译报错的核心原因是Adam优化器的构造参数与当前RcppEnsmallen依赖的Ensmallen库版本不兼容。Ensmallen的API在不同版本中可能调整构造函数的参数顺序、可选参数规则,你直接使用的全参数构造方式不符合当前安装版本的要求。而L-BFGS能正常运行,是因为它采用默认构造+参数设置的方式,兼容性更强,没有依赖特定版本的构造签名。
解决方案
方案1:使用默认构造+分步设置参数(推荐)
避免直接使用全参数构造函数,改用默认构造后逐个配置参数,这种方式兼容性更好,也更易维护:
// 替换原有的Adam初始化代码 ens::Adam opt; opt.LearningRate() = 0.001; opt.BatchSize() = 16; opt.Beta1() = 0.9; opt.Beta2() = 0.999; opt.Epsilon() = 1e-8; opt.MaxIterations() = 10000; opt.Tolerance() = 1e-5; opt.Shuffle() = true;
方案2:升级RcppEnsmallen版本
如果坚持使用全参数构造,先确保安装最新版RcppEnsmallen:
在R中执行:
install.packages("RcppEnsmallen")
升级后,对照Ensmallen官方文档确认Adam构造函数的参数签名,再调整代码中的参数顺序或类型。
方案3:统一参数类型为向量(可选优化)
虽然L-BFGS能运行,但优化问题中通常用向量表示参数,将arma::mat替换为arma::vec更符合Ensmallen优化器的预期输入,也能减少类型转换的潜在问题:
#include <RcppEnsmallen.h> // [[Rcpp::depends(RcppEnsmallen)]] class Himmelblau{ public: double Evaluate(const arma::vec& x) { return ( x[0]*x[0] + x[1] - 11.0 )*( x[0]*x[0] + x[1] - 11.0 ) + (x[0] + x[1]*x[1] - 7.0)*(x[0] + x[1]*x[1] - 7.0); } void Gradient(const arma::vec& x, arma::vec& gradient){ gradient[0] = 4*x[0]*(-11.0 + x[0]*x[0] + x[1]) + 2.0*(-7.0 + x[0] + x[1]*x[1]); gradient[1] = 2*(-11.0 + x[0]*x[0] + x[1]) + 4*x[1]*(-7.0 + x[0] + x[1]*x[1]); } void Shuffle(){} size_t NumFunctions(){ return 1; } }; // [[Rcpp::export]] arma::vec himmelblau_adam(const arma::vec& x){ Himmelblau hb; arma::vec beta = x; // 直接复用输入向量,无需转换为矩阵 ens::Adam opt; opt.LearningRate() = 0.001; opt.BatchSize() = 16; opt.Beta1() = 0.9; opt.Beta2() = 0.999; opt.Epsilon() = 1e-8; opt.MaxIterations() = 10000; opt.Tolerance() = 1e-5; opt.Shuffle() = true; opt.Optimize(hb, beta); arma::vec result(3); result[0] = beta[0]; result[1] = beta[1]; result[2] = hb.Evaluate(beta); return result; }
验证
修改后在R中重新执行Rcpp::sourceCpp("himmelblau_adam.cpp"),即可正常编译。调用函数测试:
himmelblau_adam(c(0, 0))
内容的提问来源于stack exchange,提问作者Elias Ardila
相关产品推荐
相关产品推荐

