私は現在、C++ で書かれたベイジアン最適化を実行しています。Ruben Martinez-Cantin ( http://rmcantin.bitbucket.org/html/ ) のツールボックス コール Bayesopt を使用します。ベイジアン最適化に関する論文を書いています ( https://en.wikipedia.org/wiki/Bayesian_optimization )。
以前にこのツールボックスを試したことがありますが、今週、コードの実行が記憶よりもずっと遅いことに気付きました。このツールボックスで動作するコードをいくつか書きました。
なぜこれが起こっているのかを理解しようと決心したところ、コードの実行が本来よりもはるかに遅くなっていることを目の当たりにしました。
それが私のコードのせいなのか、そうでないのかを理解するために、私のコードを一切使用しない例を試してみました。
次の例を検討してください。
#include <iostream>
#include <bayesopt.hpp>
class ExampleMichalewicz: public bayesopt::ContinuousModel
{
public:
ExampleMichalewicz(bopt_params par);
double evaluateSample(const vectord& x);
bool checkReachability(const vectord &query) {return true;};
void printOptimal();
private:
double mExp;
};
ExampleMichalewicz::ExampleMichalewicz(bopt_params par):
ContinuousModel(10,par)
{
mExp = 10;
}
double ExampleMichalewicz::evaluateSample(const vectord& x)
{
size_t dim = x.size();
double sum = 0.0;
for(size_t i = 0; i<dim; ++i)
{
double frac = x(i)*x(i)*(i+1);
frac /= M_PI;
sum += std::sin(x(i)) * std::pow(std::sin(frac),2*mExp);
}
return -sum;
}
void ExampleMichalewicz::printOptimal()
{
std::cout << "Solutions: " << std::endl;
std::cout << "f(x)=-1.8013 (n=2)"<< std::endl;
std::cout << "f(x)=-4.687658 (n=5)"<< std::endl;
std::cout << "f(x)=-9.66015 (n=10);" << std::endl;
}
int main(int nargs, char *args[])
{
bopt_params par = initialize_parameters_to_default();
par.n_iterations = 20;
par.n_init_samples = 30;
par.random_seed = 0;
par.verbose_level = 1;
par.noise = 1e-10;
par.kernel.name = "kMaternARD5";
par.crit_name = "cBEI";
par.crit_params[0] = 1;
par.crit_params[1] = 0.1;
par.n_crit_params = 2;
par.epsilon = 0.0;
par.force_jump = 0.000;
par.verbose_level = 1;
par.n_iter_relearn = 1; // Number of samples before relearn kernel
par.init_method = 1; // Sampling method for initial set 1-LHS, 2-Sobol (if available),
par.l_type = L_MCMC; // Type of learning for the kernel params
ExampleMichalewicz michalewicz(par);
vectord result(10);
michalewicz.optimize(result);
std::cout << "Result: " << result << "->"
<< michalewicz.evaluateSample(result) << std::endl;
michalewicz.printOptimal();
return 0;
}
この例だけをコンパイルすると、実行時間は約 23 秒です。
このcmakeファイルで
PROJECT ( myDemo )
ADD_EXECUTABLE(myDemo ./main.cpp)
find_package( Boost REQUIRED )
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
else(Boost_FOUND)
find_library(Boost boost PATHS /opt/local/lib)
include_directories(${Boost_LIBRARY_PATH})
endif()
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories("../bayesopt/include")
include_directories("../bayesopt/utils")
set(CMAKE_CXX_FLAGS " -Wall -std=c++11 -lpthread -Wno-unused-local-typedefs -DNDEBUG -DBOOST_UBLAS_NDEBUG")
target_link_libraries(myDemo libbayesopt.a libnlopt.a)
ここで、同じメインの例を考えてみましょう。ただし、cmake プロジェクトに 3 つのファイルを追加します (main.cpp には含めません)。これら 3 つのファイルは、すべてのコードの一部です。
PROJECT ( myDemo )
ADD_EXECUTABLE(myDemo ./iCubSimulator.cpp ./src/DatasetDist.cpp ./src/MeanModelDist.cpp ./src/TGPNode.cpp)
find_package( Boost REQUIRED )
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
else(Boost_FOUND)
find_library(Boost boost PATHS /opt/local/lib)
include_directories(${Boost_LIBRARY_PATH})
endif()
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories("../bayesopt/include")
include_directories("../bayesopt/utils")
set(CMAKE_CXX_FLAGS " -Wall -std=c++11 -lpthread -Wno-unused-local-typedefs -DNDEBUG -DBOOST_UBLAS_NDEBUG")
target_link_libraries(myDemo libbayesopt.a libnlopt.a)
今回の走行時間は約3分。これは私の仕事にとって非常に重要です。増加par.n_iterations
すると悪化する傾向があるからです。
さらに、TGPNode.cpp の行にコメントを付けると、次のような結論に達しました。
utils::cholesky_decompose(K,L); (NOTICE THAT THIS LINE IS NEVER CALLED).
私は23秒を取得します。この関数は、bayesopt ツールボックスのファイル ublas_cholesky.hpp に属しています。
ツールボックス コード内でも同じ関数が呼び出されることに注意することも重要です。この行はコメント化されておらず、実行中に実行されmichalewicz.optimize(result);
ます。
なぜこれが起こっているのか誰にも分かりますか?誰かが主題についての洞察を持っているなら、それは大きな助けになるでしょう.
大変感謝しています。
親切に、 ホセ・ノゲイラ