在开始解决我的问题的解决方案之前,我只想确定我是否会“重新发明轮子”,如果我可以重复使用以前曾做过的工作。所以我的问题是:
我使用OpenCV库制作了图像匹配器。此匹配器接收一组图像文件,并尝试在数据库中查找类似的图像。最后,它根据ROC Curves定义返回统计结果(True Positive,True Negative,False Positive和False Negative of matches)。由于OpenCV的库算法参数值大约为10,因此这些结果可能会有所不同。这意味着参数调整将带来更多的True Positive匹配和更少的False Positive匹配。由于我必须调整或多或少10个参数,强力调节器将非常缓慢。蛮力我的意思是:
While(param1 < 50){
While(param2 < 50){
While(param3 < 50){
…
PerformMatching();
param3 +=2;
}
param2++;
}
pram1 +=5;
}
我想要做的是随机选择参数,然后分析统计结果是否变得更好。然后这个分析将有助于改变随机生成参数的方法,以便选择更好的参数。
所以我的问题是Java中是否有库或者是否存在任何AI算法,它会根据对True Positive和False Positive值的评估返回更好的参数集?
可以感谢一些帮助,谢谢。
答案 0 :(得分:4)
您可以尝试一些随机优化算法,例如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]
这里有一个相关但更复杂的问题:Algorithm for selecting n vectors out of a set while minimizing cost
上面的所有代码都可以找到here。
答案 1 :(得分:3)
有一系列算法优化技术,从您的示例中的简单网格搜索到各种自适应算法。如果您想了解更高级的技术,我建议您首先查看Frank Hutter的研究。他的PhD thesis包含对该领域的精彩概述。
如果您不想花太多时间,那么您可以做的一项重大改进是随机生成参数,而不是使用常规网格。这样,如果某些参数变得不重要,那么您就不会浪费时间来保持其他参数的固定。你想要这样的东西:
param1 = random.Next(50);
param2 = random.Next(50);
...
PerformMatching();
这种方法的另一个优点是,您可以根据需要收集样本点,而不必等到整个网格被探索。使用quasi-random参数序列可以做得更好,这样可以保持点均匀分布。有些库可以为您生成这些库。
生成积分后,您可以选择最佳组合,或使用图形工具分析它们或使用模式查找算法,例如MeanShift。