如何以有效的方式调整图像处理算法的参数?

在为我的问题开始实施解决方案之前,我只想确定我是否会“重新发明轮子”,如果我可以重复使用以前曾做过的工作。 所以我的问题是:

我使用OpenCV库制作了图像匹配器。 此匹配器接收一组图像文件,并尝试在数据库中查找类似的图像。 最后,它根据ROC曲线定义(真阳性,真阴性,假阳性和假阴性匹配数)返回统计结果。 由于OpenCV的库算法参数值大约为10,因此这些结果可能会有所不同。这意味着参数调整将带来更多的True Positive匹配和更少的False Positive匹配。 由于我必须调整或多或少10个参数,powershell调节器将非常缓慢。 蛮力我的意思是:

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

我想要做的是随机选择参数,然后分析统计结果是否变得更好。 然后这个分析将有助于改变随机生成参数的方法,以便选择更好的参数。

所以我的问题是,如果Java中有库或者是否有任何AI算法,它将根据True Positive和False Positive值的评估返回更好的参数集?

可以感谢一些帮助,谢谢。

爬山

您可以尝试一些随机优化算法,例如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个向量同时最小化成本的算法

上面的所有代码都可以在这里找到。

有一系列算法优化技术,从您的示例中的简单网格搜索到各种自适应算法。 如果你想了解更高级的技术,我建议先看看Frank Hutter的研究。 他的博士论文包含了该领域的一个很好的概述。

如果您不想花太多时间,那么您可以做的一项重大改进是随机生成参数,而不是使用常规网格。 这样,如果某些参数变得不重要,那么您就不会浪费时间来保持其他参数的固定。 你想要的东西:

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

这种方法的另一个优点是,您可以根据需要收集样本点,而不必等到整个网格被探索。 通过使用准随机参数序列,您可以做得更好,这将保持点均匀分布。 有些库可以为您生成这些库。

生成点后,您可以简单地选择最佳组合,或使用图形工具分析它们或使用模式查找算法,例如MeanShift。