Байесовская оптимизация широко используется для поиска глобального максимума или глобального минимума функции черного ящика. Хотя он в основном изучается для настройки гиперпараметров моделей машинного обучения, он также может применяться к любым проблемам, если вы можете определить целевую функцию.
Например, Facebook анонсировал Топор и Боторч. Они планируют использовать это программное обеспечение в самых разных проектах, таких как:
- Настройка алгоритмов потоковой передачи видео
- Настройка моделей машинного обучения
- Аппаратный дизайн AR / VR
- Настройка компилятора Just-In-Time (для HHVM)
Пожалуйста, посмотрите доклад на F8 2019, чтобы получить более подробную информацию Оптимизация продукта с помощью адаптивного экспериментирования. Я думаю, что у алгоритмов оптимизации черного ящика есть большой потенциал для каждого разработчика программного обеспечения.
В этой статье я исследую существующую библиотеку байесовской оптимизации, написанную на Go, а затем представляю Goptuna, которую я опубликовал вчера. Его можно использовать для оптимизации количества горутин на наших серверах, написанных на Go, и оптимизации размера буфера памяти наших систем кэширования.
Библиотека байесовской оптимизации для функций черного ящика, написанная на Go.
https://github.com/c-bata/goptuna
Введение байесовской оптимизации
Сначала я объясню, что делают байесовские алгоритмы оптимизации. Когда у нас есть система something, и ее производительность зависит от чего-то непрерывного параметра в диапазоне от 0 до 10. Я хотел бы указать оптимальный параметр, который дает наилучшую производительность нашей системы.
Наивные подходы, такие как поиск по сетке и случайный поиск, требуют множества вычислений, чтобы найти оптимальный параметр. Но мы можем представить многообещающие параметры на основе прошлых результатов. Рядом с теми значениями, которые давали хорошие результаты в прошлом, могут быть даже лучшие оценочные значения. И могут быть лучшие оценки в той области, которую мы еще не оцениваем. Используя байесовские алгоритмы оптимизации, мы можем выбирать значения параметров, такие как человеческие.
Существует 3 современных байесовских метода оптимизации:
Алгоритмы на основе GP (гауссовского процесса) (например, GP-EI)
- Библиотека Python: scikit-optimize, GPyOpt
- Статья: Практическая байесовская оптимизация алгоритмов машинного обучения
TPE (дерево оценщиков парзена)
- Библиотека Python: Hyperopt, Optuna
- Статья: Алгоритмы оптимизации гиперпараметров.
SMAC (конфигурация алгоритма на основе последовательной модели)
- Библиотека Python: SMAC3
- Статья: Последовательная оптимизация на основе моделей для общей конфигурации алгоритма
Изучение существующей библиотеки байесовской оптимизации для Go
Я поискал в Google существующие библиотеки для байесовской оптимизации в Go и нашел go-bayesopt, библиотеку байесовской оптимизации на основе гауссовских процессов. Я подготовил задачу минимизации, как показано ниже.
f(x1, x2) = (x1–1)²+ (x2–2)²
Оптимальный параметр указанной выше функции (x1, x2) = (1, 2). Я подготовил следующую программу, используя go-bayesopt для оптимизации функции.
После выбора 10 параметров с помощью случайного поиска GP-UCB выбирает 90 параметров (GP - суррогатная модель, а UCB - функция сбора данных). Результаты исполнения следующие.
$ go run _examples/main.go ... 2019/07/25 15:23:23 x: map[bayesopt.Param]float64{bayesopt.UniformParam{Name:"X1", Max:10, Min:-10}:1.0221672603083967, bayesopt.UniformParam{Name:"X2", Max:10, Min:-10}:1.8540991095989217} 2019/07/25 15:23:23 y: 0.021778
Целевая функция вызывается 100 раз, после чего я получил f (1,022, 1,854) = 0,021778 как лучшее значение оценки. Глядя на следующий график, вы можете увидеть, что go-bayesopt фокусируется на точках, которые могут иметь высокую оценку.
Работает нормально. Но, вероятно, он реализован для учебных целей, поэтому функциональных возможностей не хватает. Для 100 оценок требуется 5 минут, потому что выводы из регрессионных моделей GP требуют вычисления обратных матриц, и, как правило, время вычислений обычно велико. Требуется O (t³), t - это количество итераций. А если вы хотите использовать другую функцию сбора данных, такую как EI (ожидаемое улучшение), вам необходимо реализовать ее самостоятельно.
Библиотека Python использует LAPACK через numpy и scipy, но в Go мы не хотим использовать cgo для сохранения переносимости. Чтобы применять самые разные проекты, лучше реализовывать их на чистом Go.
Байесовская оптимизация TPE с использованием Goptuna
TPE (древовидный оценщик парзенов) требует O (t), t - это количество итераций. Я искал в Google выход из реализации TPE в Go, но не нашел. Я реализовал это и вчера опубликовал Гоптуна.
Судя по названию, это голангский порт Оптуны. Goptuna использует интерфейс Define-by-Run наподобие Optuna. Таким образом, мы можем использовать его интуитивно следующим образом.
Результаты представлены ниже:
Случайный поиск со 100 оценками
$ go run _examples/simple_random_search/main.go ... Result: - best value 2.5904889254208054 - best param map[x1:0.4405659427118902 x2:0.7883530201915825]
TPE со 100 оценками (включая 10 оценок случайного поиска)
$ go run _examples/simple_tpe/main.go ... Result: - best value 0.6195459685895217 - best param map[x1:0.7770961438621743 x2:1.2451093857329996]
В этом случае результат TPE лучше, чем случайный поиск, и хуже, чем go-bayesopt. Пространства поиска целевой функции низкоразмерны (двумерны) и не содержат категориальных переменных. Eggensperger et al. подтвердил, что байесовская оптимизация на основе гауссовского процесса работает лучше, чем TPE и SMAC в низкоразмерных пространствах непрерывного поиска (см. На пути к эмпирической основе для оценки байесовской оптимизации гиперпараметров). Так что в случае с многомерными и категориальными параметрами, я думаю, Гоптуна работает лучше.
Далее сравним время выполнения. Поскольку целевая функция проста и требует мало времени, время, затрачиваемое на это выполнение, во многом определяется временем, затрачиваемым библиотекой оптимизации черного ящика.
Вывод
Goptuna кажется практической библиотекой оптимизации в Go. Я надеюсь, что все будут использовать Гоптуна и обратятся ко мне!