2015-11-05 39 views
0

我目前正在運行貝葉斯優化,用C++編寫。我使用Ruben Martinez-Cantin的工具箱調用Bayesopt(http://rmcantin.bitbucket.org/html/)。我在做關於貝葉​​斯優化的論文(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的項目(不包括他們的main.cpp)。這三個文件是我所有代碼的子部分。

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);期間運行。

有沒有人有任何理念爲什麼發生這種情況?如果有人對這個主題有一些瞭解,這將是一個很大的幫助。

非常感謝。

請問,何塞諾蓋拉

+1

您是否使用調試器('gdb')?你用所有的警告和調試信息('-Wall -Wextra -g')編譯了('g ++')嗎?通過優化('-O2 -march = native')?分析('-pg')然後'gprof'和/或'oprofile'? –

+0

此外,我懷疑其中一個文件有一些全局靜態變量,其初始化需要一些時間。但這只是一個猜測。 –

+0

_「本週我注意到代碼運行速度比我記得的慢很多」_ - 你能回到以前使用的版本嗎? – sehe

回答

1

它不會返回。

它將無限遞歸(對堆棧溢出)。

下面的代碼讀取什麼樣子:

bopt_params initialize_parameters_to_default(void) 
{ 
    bayesopt::Parameters par; 
    return par.generate_bopt_params(); 

而且generate_bopt_params

bopt_params Parameters::generate_bopt_params(){ 
    bopt_params c_params = initialize_parameters_to_default(); 

它看起來像有人試圖刪除重複代碼,而無需實際測試的東西。完全一樣。您可以恢復第一個功能的註釋掉的主體

+0

嗯。破壞這個版本的修訂版是[2861d213e4 oct 28](https://bitbucket.org/rmcantin/bayesopt/commits/4561d213e4dd2b6aeb82dfd8153c46b59a421ba2)。因爲你似乎有一箇舊版本,所以看得更遠。 – sehe

相關問題