我有一个函数,根据输入计算并返回一个评分。下面是一个非常简单的例子。
def score(i, j): if i <= 2 and j <= 3: return i * j return 0
我们可以看到,该函数的理想输入是 i
=2 和 j
=3,可以得到最高的评分6。我希望有一个方法可以搜索这些理想的输入值。最简单的方法是
max_score = 0ideal_i = ideal_j = Nonefor i in range(5): for j in range(5): s = score(i, j) if s > max_score: ideal_i, ideal_j = i, j max_score = sprint(ideal_i, ideal_j) # prints 2 3
但是,如果理想值是浮点数怎么办?如果它们超出了0到4的范围怎么办?如果我想找到3个输入值呢?
这感觉像是一个机器学习和微积分问题,但我对能够解决的实现方法不太熟悉。我想象一个2D图表,i
和j
分别在x和y轴上,还有一个热图显示每个坐标上的score(i, j)
的值。算法将在这个图表中搜索局部最大值(类似于机器学习中搜索局部最小损失值)。任何关于这方面的见解,或应该搜索什么内容的建议都将受到欢迎。
回答:
你可能在寻找的是黑盒优化或无导数优化。问题的表述是优化一个你不知道其分析形式的函数(一个黑盒,你只能评估函数的输入),并且你没有(直接)访问导数。请注意,这些方法不能保证找到全局最优解。
有几种方法可以做到这一点,最简单的方法对于浮点数和你的整数示例一样有效。你定义一个等间隔的网格,在每个网格点上评估函数,并记录最大值。然而,如果你不知道函数的边界或者你的函数是高维的,这种方法的扩展性差,可能无法找到任何“好”的最优解。一个稍微好一些的方法是定义一个非均匀或随机的点网格,这将被称为蒙特卡洛方法,它在高维度上扩展性更好。受物理学启发的更复杂版本是模拟退火。然而,不知道边界的问题仍然存在。
更复杂的方法是进化策略算法,如CMA-ES。简而言之,这类算法在每次迭代步骤中提出一个点集,从这些点中选择最好的点,并基于选定的点提出下一代点。通常这是通过提出一个概率函数(例如正态分布)并使用最大似然方法与选定的点一起优化这些函数的参数来完成的。这里的优势是你不需要预先定义或知道函数的边界。
优化这种黑盒函数的第三种方法是贝叶斯优化,这在评估黑盒函数代价高昂或涉及噪声时特别有用。想法是为要优化的函数提出一个先验函数,在某些点上进行测量(这是关键部分),并更新我们对真实函数形态的信念。这通常是通过使用高斯过程作为函数类,以迭代方式完成的。说实话,对于你简单的例子来说,这种方法有点大材小用。
关于你最后提到的神经网络:神经网络是函数逼近器,即它们可以表示任何函数,将某个输入空间映射到某个输出空间,输入和输出已经给定(数据和标签)。神经网络是参数化的,并且有一个已知分析形式的损失函数(例如均方误差、交叉熵等)。因此,可以使用访问导数的方法,如随机梯度下降来找到最佳参数。在你的情况下,函数已经给出(尽管没有它的分析形式),你希望找到使其最大化的输入。