Как я могу эффективно настроить параметры алгоритма обработки изображений?

Прежде чем приступить к реализации решения моей проблемы, я просто хочу быть уверенным, что не буду «изобретать велосипед» и смогу ли я повторно использовать работу, которую кто-то сделал раньше. Итак, моя проблема:

Я сделал сопоставление изображений, используя библиотеку OpenCV. Этот сопоставитель получает набор файлов изображений и пытается найти похожие изображения в базе данных. В конце он возвращает статистические результаты в соответствии с определением кривых ROC (истинно положительные, истинно отрицательные, ложноположительные и ложноотрицательное количество совпадений). Эти результаты могут различаться из-за значений параметров алгоритма библиотеки OpenCV, которые составляют около 10. Это означает, что настройка параметров приведет к большему количеству истинно положительных совпадений и меньшему количеству ложных положительных совпадений. Поскольку мне нужно настроить более или менее 10 параметров, перебор будет очень медленным. Под грубой силой я подразумеваю:

While(param1 < 50){
  While(param2 < 50){
    While(param3 < 50){
      …
      PerformMatching();
      param3 +=2;
    }
    param2++;
  }
  pram1 +=5;
}

Что я хочу сделать, так это выбрать параметры случайным образом, а затем проанализировать, улучшаются ли статистические результаты. Затем этот анализ поможет изменить метод, который случайным образом генерирует параметры, чтобы выбрать лучшие параметры.

Итак, мой вопрос: есть ли библиотека на Java или какой-либо алгоритм ИИ, который вернет лучший набор параметров на основе оценки истинно положительных и ложноположительных значений?

Не могли бы помочь, спасибо.


person andriy    schedule 30.11.2012    source источник


Ответы (2)


Скалолазание

Вы можете попробовать некоторые алгоритмы стохастической оптимизации, например, Hill Climbing, в котором вы начинаете со случайного решение (как указал @Don Reba) и посмотрите на набор соседних решений для тех, которые лучше с точки зрения функции стоимости. Я буду использовать пример кода Python, чтобы объяснить идею.

Получить соседние решения

Для соседей в вашем случае вы можете использовать простую функцию, например:

n_params = 5  # number of parameters
upper_bound = 5  # upper limit of your parameters
lower_bound = 0  # lower limit of your parameters

def get_neighbors(solution):
    neighbors = []
    for i in range(n_params):
        x = copy.deepcopy(solution)
        if x[i] < upper_bound:
            x[i] += 1 # increment one of the components
            neighbors.append(x)
        x = copy.deepcopy(solution)
        if x[i] > lower_bound:
            x[i] -= 1 # decrement one of the components
            neighbors.append(x)
    return neighbors 

Если у вас есть текущее решение [1,3,4,2,2], увеличивая или уменьшая любой из компонентов, вы получаете 10 разных соседей, как показано ниже:

 [2, 3, 4, 2, 2],
 [0, 3, 4, 2, 2],
 [1, 4, 4, 2, 2],
 [1, 2, 4, 2, 2],
 [1, 3, 5, 2, 2],
 [1, 3, 3, 2, 2],
 [1, 3, 4, 3, 2],
 [1, 3, 4, 1, 2],
 [1, 3, 4, 2, 3],
 [1, 3, 4, 2, 1]

Здесь мы предполагаем, что каждый параметр является целым числом. Вы можете добиться большей детализации, отрегулировав размер шага (например, 0,05).

Итерации подъема в гору

def hill_climb():
    initial_solution = np.random.randint(lower_bound, upper_bound, n_params)
    current_solution = initial_solution
    print 'initial solution', initial_solution
    current_cost = get_cost(initial_solution)
    step = 1
    while True:
        #try to replace each single component w/ its neighbors
        lowest_cost = current_cost
        lowest_solution = current_solution
        print 'hill-climbing cost at step %6d: %d' % (step, lowest_cost)
        neighbors = get_neighbors(current_solution)
        for new_solution in neighbors:
            neighbor_cost = get_cost(new_solution)
            if neighbor_cost < lowest_cost:
                lowest_cost = neighbor_cost
                lowest_solution = new_solution

        if lowest_cost >= current_cost:
            break
        else: 
            current_solution= lowest_solution
            current_cost = lowest_cost
            step += 1
    return current_solution

Функция стоимости

Для полноты картины я буду использовать свою собственную функцию стоимости (просто для демонстрационных целей), которая

f(x) = x1^1 - x2^2 + x3^3 - x4^4 + x5^5

То есть :

def get_cost(solution):
    cost = 0
    for i,param in enumerate(solution):
        cost += (-1.)**i * param**(i+1)  
    return cost

Результат оптимизации:

Вот результат. Мы используем случайное начальное предположение [4, 0, 1, 3, 1]. После 14 шагов (оценка 14 * 10 = 140 соседей) мы находим оптимальный ответ [0, 5, 0, 5, 0], который минимизирует стоимость. Для грубой силы вы должны оценить 6 ^ 6 = 46656 решений. Можно сэкономить гораздо больше времени работы, если у вас есть решение с высокой размерностью.

Обратите внимание, поскольку это стохастический метод, в качестве конечного результата находится локальный минимум (хотя иногда он идентичен глобальному минимуму, это не гарантируется). Однако практически это достаточно хорошо.

initial solution:               [4 0 1 3 1]
hill-climbing cost at step      1: -75
hill-climbing cost at step      2: -250
hill-climbing cost at step      3: -619
hill-climbing cost at step      4: -620
hill-climbing cost at step      5: -621
hill-climbing cost at step      6: -622
hill-climbing cost at step      7: -623
hill-climbing cost at step      8: -624
hill-climbing cost at step      9: -627
hill-climbing cost at step     10: -632
hill-climbing cost at step     11: -639
hill-climbing cost at step     12: -648
hill-climbing cost at step     13: -649
hill-climbing cost at step     14: -650
Final solution:                 [0 5 0 5 0]

Связанный пост

Связанный, но более сложный вопрос здесь: Алгоритм выбора n векторов из набора при минимальных затратах

Все приведенные выше коды можно найти здесь.

person greeness    schedule 02.12.2012

Существует ряд методов оптимизации алгоритмов, от простого поиска по сетке в вашем примере до различных адаптивных алгоритмов. Если вы хотите узнать о более продвинутых методах, я рекомендую начать с просмотра Frank Hutter исследования. Его докторская диссертация содержит отличный обзор области.

Если вы не хотите тратить слишком много времени, одно большое улучшение, которое вы можете сделать, — это генерировать параметры случайным образом вместо использования обычной сетки. Таким образом, если какие-то параметры окажутся неважными, вы не будете тратить время на фиксирование других. Вы хотите что-то вроде:

param1 = random.Next(50);
param2 = random.Next(50);
...
PerformMatching();

Еще одним преимуществом этого подхода является то, что вы можете собирать точки выборки столько, сколько хотите, и вам не нужно ждать, пока будет исследована вся сетка. Вы можете сделать еще лучше, используя последовательность параметров квазислучайная, которая сохранит точки равномерно раскидан. Есть библиотеки, которые сгенерируют их для вас.

После того, как вы сгенерировали свои точки, вы можете просто выбрать наилучшую комбинацию или проанализировать их с помощью графических инструментов или использовать алгоритм поиска режима, такой как MeanShift.

person Don Reba    schedule 30.11.2012