在开始实施解决方案之前,我想确保自己不会“重复造轮子”,看看是否可以利用之前他人的工作成果。因此,我的具体问题是:
我使用OpenCV库开发了一个图像匹配器。这个匹配器接收一组图像文件,并尝试在数据库中查找相似的图像。最终,它会根据ROC曲线的定义(真阳性、真阴性、假阳性和假阴性匹配的数量)返回统计结果。这些结果会因OpenCV库算法参数的不同值而有所变化,这些参数大约有10个。这意味着调整参数可以增加真阳性匹配的数量,并减少假阳性匹配的数量。由于我需要调整大约10个参数,采用暴力调整法会非常慢。我所说的暴力法是指:
While(param1 < 50){ While(param2 < 50){ While(param3 < 50){ … PerformMatching(); param3 +=2; } param2++; } pram1 +=5;}
我想做的是随机选择参数,然后分析统计结果是否有所改善。然后,这样的分析将有助于调整随机生成参数的方法,以便选择更好的参数。
所以我的问题是,Java中是否有库,或者是否有任何AI算法,可以根据真阳性和假阳性值的评估返回更好的参数集?
希望能得到一些帮助,谢谢。
回答:
爬山算法
你可以尝试一些随机优化算法,例如爬山算法,在这个算法中,你从一个随机解开始(就像@Don Reba指出的那样),然后查看邻近解集,寻找那些在成本函数方面更好的解。我将使用一些示例Python代码来解释这个想法。
获取邻居解
对于你的情况,可以使用一个简单的函数来获取邻居解:
n_params = 5 # 参数数量upper_bound = 5 # 参数的上限lower_bound = 0 # 参数的下限def get_neighbors(solution): neighbors = [] for i in range(n_params): x = copy.deepcopy(solution) if x[i] < upper_bound: x[i] += 1 # 增加一个组件 neighbors.append(x) x = copy.deepcopy(solution) if x[i] > lower_bound: x[i] -= 1 # 减少一个组件 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: #尝试用其邻居替换每个单一组件 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: -75hill-climbing cost at step 2: -250hill-climbing cost at step 3: -619hill-climbing cost at step 4: -620hill-climbing cost at step 5: -621hill-climbing cost at step 6: -622hill-climbing cost at step 7: -623hill-climbing cost at step 8: -624hill-climbing cost at step 9: -627hill-climbing cost at step 10: -632hill-climbing cost at step 11: -639hill-climbing cost at step 12: -648hill-climbing cost at step 13: -649hill-climbing cost at step 14: -650Final solution: [0 5 0 5 0]
相关帖子
一个相关但更复杂的问题在这里:从集合中选择n个向量以最小化成本的算法
以上所有代码都可以在这里找到。