Giter VIP home page Giter VIP logo

sequential-line-search's Introduction

Sequential Line Search

GitHub

A C++ library for performing the sequential line search method (which is a human-in-the-loop variant of Bayesian optimization).

The core algorithm is implemented in include/sequential-line-search/*.hpp and src/*.cpp. This repository also contains the following example demos:

  • bayesian_optimization_1d: A simple demo of the standard Bayesian optimization applied to a one-dimensional test function.
  • sequential_line_search_nd: A simple demo of the sequential line search method applied to a multi-dimensional test function.
  • bayesian_optimization_1d_gui: A visual demo of the standard Bayesian optimization applied to a one-dimensional test function.
  • bayesian_optimization_2d_gui: A visual demo of the standard Bayesian optimization applied to a two-dimensional test function.
  • preferential_bayesian_optimization_1d_gui: A visual demo of the preferential Bayesian optimization with a simple pairwise comparison query style applied to a one-dimensional test function.
  • sequential_line_search_2d_gui: A visual interactive demo of the sequential line search method applied to a two-dimensional test function.
  • sequential_line_search_photo: A visual interactive demo of the sequential line search method where a photograph is enhanced using six-dimensional parameters.

This library has a python binding, named pySequentialLineSearch.

Project Web Site

https://koyama.xyz/project/sequential_line_search/

Publication

Yuki Koyama, Issei Sato, Daisuke Sakamoto, and Takeo Igarashi. 2017. Sequential Line Search for Efficient Visual Design Optimization by Crowds. ACM Trans. Graph. 36, 4, pp.48:1--48:11 (2017). (a.k.a. Proceedings of SIGGRAPH 2017) DOI: https://doi.org/10.1145/3072959.3073598

Dependencies

Required for Core Algorithms

Required for Command Line Demos

  • (None)

To build these demos, the CMake variable: SEQUENTIAL_LINE_SEARCH_BUILD_COMMAND_DEMOS should be set ON.

Required for Visual Demos

To build these demos, the CMake variable: SEQUENTIAL_LINE_SEARCH_BUILD_VISUAL_DEMOS should be set ON.

Required for Photo Enhancement Demos

To build these demos, the CMake variable: SEQUENTIAL_LINE_SEARCH_BUILD_PHOTO_DEMOS should be set ON. They require runtime environments to support OpenGL 3.2 Core Profile and GLSL 3.3.

Required for Experimental Python Binding

To enable python binding, the CMake variable: SEQUENTIAL_LINE_SEARCH_BUILD_PYTHON_BINDING should be set ON.

How to Compile and Run (C++)

We use cmake (3.3 or above) for managing the source codes. You can compile the core module and the demo applications at once by, for example,

git clone https://github.com/yuki-koyama/sequential-line-search.git --recursive
cd sequential-line-search
mkdir build
cd build
cmake ../
make

Then you can run the applications by, for example,

./demos/sequential_line_search_nd/SequentialLineSearchNd

We tested on macOS (10.15) only. We are aware that the visual demos cannot be built as it is in other OSs; some OpenGL paths etc. need to be resolved. Pull requests welcome.

How to Install (Python)

pySequentialLineSearch is a subset of Python bindings of the C++ library. Tested on Python 3.6, 3.7, and 3.8.

It can be installed via PyPI:

pip install git+https://github.com/yuki-koyama/sequential-line-search

Prerequisites

macOS

brew install cmake eigen

Ubuntu 18.04/20.04

sudo apt install cmake libeigen3-dev

Examples

Note: User interaction part is omitted from these examples.

C++

#include <iostream>
#include <sequential-line-search/sequential-line-search.hpp>

using Eigen::VectorXd;
using sequential_line_search::SequentialLineSearchOptimizer;

double AskHumanForSliderManipulation(const std::pair<VectorXd, VectorXd>& slider_ends)
{
    // ...
    // ...

    return slider_position;
}

int main()
{
    // Instantiate an optimizer
    constexpr int dim = 6;
    SequentialLineSearchOptimizer optimizer(dim);

    // Iterate optimization steps
    constexpr int num_iters = 15;
    for (int i = 0; i < num_iters; ++i)
    {
        // Retrieve a slider space
        const std::pair<VectorXd, VectorXd> slider_ends = optimizer.GetSliderEnds();

        // Query slider manipulation
        const double slider_position = AskHumanForSliderManipulation(slider_ends);

        // Feed the slider manipulation result to the optimizer
        optimizer.SubmitLineSearchResult(slider_position);
    }

    // Display the found solution
    std::cout << optimizer.GetMaximizer() << std::endl;

    return 0;
}

Python

import pySequentialLineSearch
import numpy

def ask_human_for_slider_manipulation(slider_ends):
    # ...
    # ...

    return slider_position

def main():
    optimizer = pySequentialLineSearch.SequentialLineSearchOptimizer(6)

    for i in range(15):
        slider_ends = optimizer.get_slider_ends()
        slider_position = ask_human_for_slider_manipulation(slider_ends)
        optimizer.submit_line_search_result(slider_position)

    print(optimizer.get_maximizer())

if __name__ == '__main__':
    main()

Supported Environments

We have tested the C++ portion of our codebase on macOS using the clang compiler and on Ubuntu 20.04 using the g++ compiler. As for the Python portion, it has been tested on versions 3.7 through 3.11.

Technical Details

Gaussian Process Kernel

  • ARD Matern 5/2 kernel (default; recommended in [Snoek et al. NIPS 2011])
  • ARD squared exponential kernel (used in [Koyama et al. SIGGRAPH 2017])

Gaussian Process Kernel Hyperparameters

The optimizer API takes a boolean named use_map_hyperparameters as input. If this is true, the optimizer calculates the kernel hyperparameters for every iteration via the MAP estimation, as described in [Koyama et al. SIGGRAPH 2017]. If this is false, the optimizer just uses default values, making the optimization more efficient.

Finding Maximizer of Acquisition Function

Finding the global maximizer of the acquisition function is a difficult problem since it often has multiple local maxima and is high-dimensional.

This implementation offers two approaches for this problem:

  • The first option is to perform DIRECT (a derivative-free global optimization algorithm) and then refine the solution using L-BFGS (a gradient-based local optimization algorithm).
  • The second option is to perform L-BFGS multiple times with many different initial solutions and then pick up the best solution.

See src/acquisition-function.cpp for details.

Acquisition Function Choices

The following acquisition functions are supported:

  • Expected improvement (EI) [default; used in the original paper]
  • Gaussian process upper confidence bound (GP-UCB)

Search Space

This implementation assumes that the search space is always [0, 1]^D. When you want to handle a different search space, you need to normalize the target space into [0, 1]^D manually.

Construction of Slider Space

A slider space is constructed by choosing two end points. One of the two end points is always selected by maximizing the acquisition function (i.e., x^{EI} when using EI as the acquisition function). The other end point is selected by one of the following options:

  • The point that provides the largest expected value (i.e., x^{+}) (default; used in the original paper)
  • The point that is selected in the last subtask (i.e., x^{chosen}) (suggested in [Koyama+, 2020])

See Also

Sequential Gallery (SIGGRAPH 2020) is a more recent publication on the same topic (i.e., human-in-the-loop design optimization).

BO as Assistant (UIST 2022) is a research project using this library for a different purpose (i.e., for generating design suggestions during slider manipulation).

License

MIT License.

Contributing

Issue reports, suggestions, requests, and PRs are highly welcomed.

Contact

Yuki Koyama ([email protected])

sequential-line-search's People

Contributors

stnoh avatar yuki-koyama avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

sequential-line-search's Issues

The latest version with Release (-O3) build option fails to find solutions

I found that the latest version with the Release (-O3) build option often fails to find solutions in optimization.

It works correctly in the demo:

  • sequential_line_search_2d_gui

but it does not seem to work (NLopt raises "failure" exceptions) at least in the demos:

  • bayesian_optimization_1d_gui
  • bayesian_optimization_2d_gui

The Debug build option works fine, but of course the computation becomes much slower.

GP-UBC support?

It currently supports only EI (expected improvement) as an acquisition function, but it is also popular to use GP-UBC for that purpose. It is better to support different acquisition functions, especially GP-UBC.

Reference: https://arxiv.org/abs/1012.2599

Warnings during pip installation

pip3 install git+https://github.com/yuki-koyama/sequential-line-search --verbose

displays the following warning multiple times during the installation process:

    /usr/lib/python3.6/distutils/dist.py:261: UserWarning: Unknown distribution option: 'long_description_content_type'
      warnings.warn(msg)

CMake error in Xcode project generation

Problem

When generating an Xcode project file by

cmake -G Xcode /path/to/repository

we get the following error seemingly caused by nlopt:

CMake Error in external/nlopt/CMakeLists.txt:
   The custom command generating

     /path/to/build/external/nlopt/nlopt.f

   is attached to multiple targets:

     generate-fortran
     nlopt

   but none of these is a common dependency of the other(s).  This is not
   allowed by the Xcode "new build system".

A Tentative Solution

The error can be avoided by using a legacy setting specified by -T buildsystem=1. That is,

cmake -G Xcode -T buildsystem=1 /path/to/repository

Reference: https://stackoverflow.com/a/65474688

Use as a Library

The current implementation of the method is not designed to be used as a library. However, allowing it would be beneficial.

Update Python Versions

The build test currently runs for Python 3.8 and 3.9 only. Libraries should support Python 3.11 these days.

Minimize demos

I am aware that the current demos are not very minimalistic. It would be much better to have a minimal demo to convey how the library can be used.

Kernel selection API?

The default kernel choice has been changed to the automatic relevance determination (ARD) Matern 5/2 kernel. However, it does not provide APIs to reverse the kernel to the ARD squared exponential kernel. This is inconvenient if one wants to reproduce the settings presented in the original paper.

Bug: python binding fails to be built on Linux

Travis CI fails to build the python binding on Linux.

https://travis-ci.com/yuki-koyama/sequential-line-search/jobs/184545826

Error messages:

$ cmake -DSEQUENTIAL_LINE_SEARCH_BUILD_COMMAND_DEMOS=OFF -DSEQUENTIAL_LINE_SEARCH_BUILD_VISUAL_DEMOS=OFF -DSEQUENTIAL_LINE_SEARCH_BUILD_PHOTO_DEMOS=OFF -DSEQUENTIAL_LINE_SEARCH_BUILD_PYTHON_BINDING=ON . && make
-- NLopt version 2.5.0
-- Found PythonInterp: /opt/pyenv/shims/python3.7 (found version "1.4") 
CMake Error at external/pybind11/tools/FindPythonLibsNew.cmake:95 (message):
  Python config failure:
  pyenv: python3.7: command not found
  
  The `python3.7' command exists in these Python versions:
    3.7
    3.7.1
  
Call Stack (most recent call first):
  external/pybind11/tools/pybind11Tools.cmake:16 (find_package)
  external/pybind11/CMakeLists.txt:33 (include)
-- Configuring incomplete, errors occurred!
See also "/home/travis/build/yuki-koyama/sequential-line-search/CMakeFiles/CMakeOutput.log".
See also "/home/travis/build/yuki-koyama/sequential-line-search/CMakeFiles/CMakeError.log".

Warnings about destructor

Current codes will get some warnings like

warning: destructor called on non-final 'GaussianProcessRegressor' that has virtual functions but non-virtual destructor

This should be fixed.

Environment: Apple LLVM version 10.0.0 (clang-1000.11.45.2)

Build error on Ubuntu (isnan)

/root/sequential-line-search/demos/bayesian_optimization_1d_gui/mainwidget.cpp: In member function ‘virtual void MainWidget::paintEvent(QPaintEvent*)’:
/root/sequential-line-search/demos/bayesian_optimization_1d_gui/mainwidget.cpp:56:26: error: ‘isnan’ was not declared in this scope
     if (!isnan(core.y_max))
                          ^

Build error: python binding fails to be linked on Linux

pySequentialLineSearch.a fails to be linked: https://travis-ci.com/yuki-koyama/sequential-line-search/jobs/185067869

/usr/bin/ld: ../libSequentialLineSearch.a(acquisition-function.cpp.o): relocation R_X86_64_32S against `_ZNK22sequential_line_search24GaussianProcessRegressor4getyEv' can not be used when making a shared object; recompile with -fPIC
../libSequentialLineSearch.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
python/CMakeFiles/pySequentialLineSearch.dir/build.make:86: recipe for target 'python/pySequentialLineSearch.cpython-37m-x86_64-linux-gnu.so' failed
make[2]: *** [python/pySequentialLineSearch.cpython-37m-x86_64-linux-gnu.so] Error 1
CMakeFiles/Makefile2:314: recipe for target 'python/CMakeFiles/pySequentialLineSearch.dir/all' failed
make[1]: *** [python/CMakeFiles/pySequentialLineSearch.dir/all] Error 2
Makefile:162: recipe for target 'all' failed
make: *** [all] Error 2

Remove the TeX dependency

TeX is used in the test of the python scripts, but it is not essential. It should be removed for easier maintenance.

Option for spherical parameter space shape

The method currently assumes samples are drawn from the hypercube [0..1]^k. However, latent spaces often have a different shape, mostly they follow a gaussian distribution N(0, I). This gives a latent space closer to a hypersphere. It would be beneficial to have the option of instead doing the line search over the hypersphere B_k(0, 1).

Bug: parallel-util fails to be built on Linux

Travis CI fails to build the demo on Linux due to parallel-util.

https://travis-ci.com/yuki-koyama/sequential-line-search/jobs/184545826

Error messages:

$ cmake -DSEQUENTIAL_LINE_SEARCH_BUILD_COMMAND_DEMOS=OFF -DSEQUENTIAL_LINE_SEARCH_BUILD_VISUAL_DEMOS=OFF -DSEQUENTIAL_LINE_SEARCH_BUILD_PHOTO_DEMOS=ON -DSEQUENTIAL_LINE_SEARCH_BUILD_PYTHON_BINDING=OFF . && make
-- NLopt version 2.5.0
-- Found OpenGL: /usr/lib/x86_64-linux-gnu/libGL.so   
-- Looking for C++ include pthread.h
-- Looking for C++ include pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Configuring done
-- Generating done
-- Build files have been written to: /home/travis/build/yuki-koyama/sequential-line-search
[  2%] Built target rand-util
[ 71%] Built target nlopt
[ 82%] Built target SequentialLineSearch
[ 84%] Generating qrc_enhancer-resources.cpp
Scanning dependencies of target enhancer
[ 85%] Building CXX object external/enhancer/CMakeFiles/enhancer.dir/src/enhancerwidget.cpp.o
[ 86%] Building CXX object external/enhancer/CMakeFiles/enhancer.dir/qrc_enhancer-resources.cpp.o
[ 88%] Linking CXX static library libenhancer.a
[ 88%] Built target enhancer
Scanning dependencies of target SequentialLineSearchPhoto_autogen
[ 89%] Automatic MOC and UIC for target SequentialLineSearchPhoto
[ 89%] Built target SequentialLineSearchPhoto_autogen
Scanning dependencies of target SequentialLineSearchPhoto
[ 91%] Building CXX object demos/sequential_line_search_photo/CMakeFiles/SequentialLineSearchPhoto.dir/core.cpp.o
[ 92%] Building CXX object demos/sequential_line_search_photo/CMakeFiles/SequentialLineSearchPhoto.dir/imagemodifier.cpp.o
In file included from /home/travis/build/yuki-koyama/sequential-line-search/demos/sequential_line_search_photo/imagemodifier.cpp:5:
/home/travis/build/yuki-koyama/sequential-line-search/external/parallel-util/include/parallel-util.hpp:97:14: error: 
      no type named 'mutex' in namespace 'std'
        std::mutex queue_mutex;
        ~~~~~^
1 error generated.
demos/sequential_line_search_photo/CMakeFiles/SequentialLineSearchPhoto.dir/build.make:75: recipe for target 'demos/sequential_line_search_photo/CMakeFiles/SequentialLineSearchPhoto.dir/imagemodifier.cpp.o' failed
make[2]: *** [demos/sequential_line_search_photo/CMakeFiles/SequentialLineSearchPhoto.dir/imagemodifier.cpp.o] Error 1
CMakeFiles/Makefile2:390: recipe for target 'demos/sequential_line_search_photo/CMakeFiles/SequentialLineSearchPhoto.dir/all' failed
make[1]: *** [demos/sequential_line_search_photo/CMakeFiles/SequentialLineSearchPhoto.dir/all] Error 2
Makefile:162: recipe for target 'all' failed
make: *** [all] Error 2

Build error on Ubuntu (make_shared)

This bug needs to be fixed.

/root/sequential-line-search/sequential_line_search/sliderutility.cpp: In function ‘std::pair<Eigen::Matrix<double, -1, 1>, Eigen::Matrix<double, -1, 1> > SliderUtility::enlargeSliderEnds(const VectorXd&, const VectorXd&, double, double)’:
/root/sequential-line-search/sequential_line_search/sliderutility.cpp:78:17: error: ‘make_shared’ is not a member of ‘std’
     auto data = std::make_shared<Data>(c, r, scale);
                 ^
/root/sequential-line-search/sequential_line_search/sliderutility.cpp:78:38: error: expected primary-expression before ‘>’ token
     auto data = std::make_shared<Data>(c, r, scale);

Namespace

It would be better to add an appropriate namespace to the core codes

Avoid matrix inverse and direct log-det calculation

The current preference-regressor.cpp contains matrix inversion and direct log-det calculation in its objective function, which may be numerically unstable and so should be avoided in general. These can be eliminated, but it will require some efforts to reimplement some functions.

[TODO] Use consistent naming convention

I'm aware that the current codes use inconsistent naming convention (e.g., mixing camel, snake, and Pascal) across files. We need to create a naming convention guideline and fix codes based on it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.