Вопрос по scipy, mathematical-optimization, python – Многопоточные вызовы целевой функции scipy.optimize.leastsq

1

Я используюscipy.optimize.leastsq в сочетании с симулятором.leastsq вызывает пользовательскую целевую функцию и передает ей входной вектор. В свою очередь, целевая функция возвращает вектор ошибок.leastsq оптимизирует входной вектор таким образом, чтобы сумма квадратов вектора ошибки была минимальной.

В моем случае целевая функция будет запускать всю симуляцию каждый раз, когда она вызывается. Используемый симулятор является однопоточным и требует несколько минут для каждого запуска. Поэтому я хотел бы запускать несколько экземпляров симулятора одновременно. Однако вызовы целевой функции выполняются последовательно.

Как я могу получитьleastsq выполнить несколько вызовов целевой функции одновременно?

Ваш Ответ

5   ответов
6

leastsq предоставляя свою собственную функцию для расчета производных (Dfun параметр), при условии, что у вас есть несколько параметров. Если эта функция не предоставляется,leastsq выполняет итерации по каждому из параметров для вычисления производной каждый раз, что занимает много времени. Похоже, это занимает большую часть времени на примерку.

Вы можете использовать свой собственныйDfun функция, которая вычисляет производные для каждого параметра, используяmultiprocessing.Pool делать работу. Эти производные могут быть рассчитаны независимо и должны быть тривиально распараллелены.

Вот пример, показывающий, как это сделать:

import numpy as np
import multiprocessing
import scipy.optimize

def calcmod(params):
    """Return the model."""
    return func(params)

def delta(params):
    """Difference between model and data."""
    return calcmod(params) - y

pool = multiprocessing.Pool(4)

def Dfun(params):
    """Calculate derivatives for each parameter using pool."""
    zeropred = calcmod(params)

    derivparams = []
    delta = 1e-4
    for i in range(len(params)):
        copy = np.array(params)
        copy[i] += delta
        derivparams.append(copy)

    results = pool.map(calcmod, derivparams)
    derivs = [ (r - zeropred)/delta for r in results ]
    return derivs

retn = scipy.optimize.leastsq(leastfuncall, inputparams, gtol=0.01,
                              Dfun=Dfun, col_deriv=1)
-1

http://docs.python.org/library/multiprocessing.html

Я всегда находил, что Pool является самым простым для многопроцессорной работы с python.

-2

отрели на загрузку своего ЦП, чтобы убедиться, что во время симуляции используется только одно ядро? В противном случае вам нечего получить от запуска нескольких экземпляров.

Если он на самом деле однопоточный, то лучше всего использоватьmultiprocessing модуль. Он запускает несколько экземпляров интерпретатора Python, поэтому вы можете сделать несколько одновременных вызовов SciPy.

6

leastsqЛевенбергу-Марквардту необходимо знать значение целевой функции в текущей точке, прежде чем определять следующую точку. Короче говоря, не существует простого способа распараллелить такой последовательный алгоритм.

Однако в некоторых случаях вы можете распараллелить вашу целевую функцию. Это может быть сделано, если оно имеет вид:

def objective_f(params):
    r = np.zeros([200], float)
    for j in range(200):
        r[j] = run_simulation(j, params)
    return

def run_simulation(j, params):
    r1 = ... compute j-th entry of the result ...
    return r1

Здесь вы можете четко распараллелить через циклjНапример, используя многопроцессорный модуль. Как то так: (не проверено)

def objective_f(params):
    r = np.zeros([200], float)
    def parameters():
        for j in range(200):
            yield j, params
    pool = multiprocessing.Pool()
    r[:] = pool.map(run_simulation, parameters())
    return r

Другая возможность для распараллеливания возникает, если вам нужно разместить несколько наборов данных - это (смущающе) параллельная проблема, и различные наборы данных могут быть установлены параллельно.

Если это не поможет, вы можете посмотреть обсуждение литературы по распараллеливанию алгоритма LM. Например:http://dl.acm.org/citation.cfm?id=1542338  Основной оптимизацией, предложенной в этой статье, является параллелизм численного вычисления якобиана. Вы можете сделать это, предоставив свою собственную параллельную функцию Якобианаleastsq, Однако оставшееся предположение о работе, предполагающее параллелизацию этапов поиска Левенберга-Марквардта, труднее реализовать и требует изменений в алгоритме LM.

Я не знаю библиотек Python (или других языков), реализующих алгоритмы оптимизации, предназначенные для параллельных вычислений, хотя их может быть несколько. Если вам удастся внедрить / найти один из них, пожалуйста, сообщите об этом в списке рассылки пользователей Scipy - несомненно, есть интерес к одному из них!

-1

scipy.least_squares, это гораздо лучший вариант, и когда я использую его для оптимизации функции, он использует все доступные потоки. Поэтому именно то, что вы спросили

Похожие вопросы