【问题标题】:Finding the optimal combination of inputs which return maximal output for a black box model为黑盒模型找到返回最大输出的最佳输入组合
【发布时间】:2023-04-10 10:06:01
【问题描述】:

在我的工作中将 ANN 应用于回归任务时,我面临的一个挑战是,为了找到给定输入范围的最佳输出,我必须向我的模型提供一个多维网格,然后简单地选择最高值。然而,这总体上是一个计算成本非常高的解决方案。以下文字的长度可能有点吓人,但这只是我试图更好地解释它。

让我用其他词来解释。假设我的 ANN 有 9 个输入,然后我想检查我的特征值的哪些组合返回了最高的结果。我目前正在通过创建一个 9D 网格并简单地预测每个样本的值然后确定最佳行来克服这个问题。然而,这需要大量的时间来工作。因此,如果可能的话,我正在寻找一种能够更有效地达到这个最佳输出值的方法。

在代码中,它看起来像这样:(只是一个简单的虚构示例,在 python 中并不现实):

import numpy as np
from itertools import product
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split 
import tensorflow.keras
from keras.models import Sequential
from keras.layers import Dense
import pandas as pd
import math

x1 = np.linspace(0,20,6)
x2 = np.linspace(0,20,6)
X = pd.DataFrame((product(*[x1,x2])))
y1 = 5*np.cos(np.deg2rad(X[0]))
y2 = 5 - 1*np.exp((-X[0]**2/np.deg2rad(10)**2)*np.cos(np.deg2rad(X[1])))
y = np.array([y1 + y2]).T

设置黑盒模型,在本例中为神经网络

x_scaler = MinMaxScaler()
y_scaler = MinMaxScaler()
X_scaled = x_scaler.fit_transform(X)
y_scaled = y_scaler.fit_transform(y)
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y_scaled, test_size=0.2, random_state=0)

model = Sequential()
model.add(Dense(100, input_dim = 2, activation = 'relu'))
model.add(Dense(100, activation='relu'))
model.add(Dense(100, activation='relu'))
model.add(Dense(1, activation = 'relu'))
model.compile(optimizer = 'Adam', loss = 'mean_squared_error')
epochs_hist = model.fit(X_train, y_train, epochs = 100, batch_size = 50, validation_split = 0.2)

现在我拟合了我的模型,我将在几个区间内使用网格网格,以便在指定范围内找到最优值:

x1_pred = np.linspace(0,20,21) 
x2_pred = np.linspace(0,20,21)
X_pred = pd.DataFrame((product(*[x1_pred,x2_pred])))
X_pred_test = x_scaler.fit_transform(X_pred)
y_pred = model.predict(X_pred_test)
y_pred = y_scaler.inverse_transform(y_pred)

所以,假设我做了类似的事情来达到最优,但在这种情况下有 9 个输入,那么很明显该计算在计算上是多么不可行。因此,我的问题是如何找到能够返回黑盒模型(如 ANN)的最大输出的最佳输入组合。

【问题讨论】:

  • 您会考虑遗传算法吗?我不知道评估可能的输入组合有多昂贵。
  • 我不确定我是否理解你想要做什么,但如果你想找到最小值/最大值,你应该看看scipy.optimize,它实现了几个算法这可以帮助你
  • @MayowaAyodele 这是一种可能性。但是,我不确定在那种情况下我会如何使用它。
  • @Nathan 不幸的是,由于我们正在使用黑盒模型,因此无法使用 scipy.optimize。因此,没有明确的方程来优化和找到最小值和最大值。
  • 你不能将模型包装成一个函数并将其传递给 scipy 吗?

标签: python machine-learning neural-network regression supervised-learning


【解决方案1】:

以下是如何从模型中获得“最佳结果”的示例。重要的部分是optimize_get_simplex_call_model。通过这样做,您可以减少模型所需的调用量。

from sklearn.ensemble import GradientBoostingRegressor
import numpy as np
from scipy.optimize import minimize
from copy import copy


class Example:

    def __init__(self):
        self.X = np.random.random((10000, 9))
        self.y = self.get_y()
        self.clf = GradientBoostingRegressor()
        self.fit()

    def get_y(self):
        # sum of squares, is minimum at x = [0, 0, 0, 0, 0 ... ]
        return np.array([[self._func(i)] for i in self.X])

    def _func(self, i):
        return sum(i * i)

    def fit(self):
        self.clf.fit(self.X, self.y)

    def optimize(self):
        x0 = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]
        initial_simplex = self._get_simplex(x0, 0.1)
        result = minimize(fun=self._call_model,
                          x0=np.array(x0),
                          method='Nelder-Mead',
                          options={'xatol': 0.1,
                                   'initial_simplex': np.array(initial_simplex)})
        return result

    def _get_simplex(self, x0, step):
        simplex = []
        for i in range(len(x0)):
            point = copy(x0)
            point[i] -= step
            simplex.append(point)

        point2 = copy(x0)
        point2[-1] += step
        simplex.append(point2)
        return simplex

    def _call_model(self, x):
        prediction = self.clf.predict([x])
        return prediction[0]

example = Example()
result = example.optimize()
print(result)

当然,如果你想最大化而不是最小化,你可以返回-prediction[0]而不是prediction[0]来欺骗scipy。

【讨论】:

  • 有趣的解决方案,但是,对于像 ANN 这样的黑盒模型,这种优化如何工作?至少从我目前的理解来看,因为你找不到一个显式的函数,所以不可能应用最小化的优化器
  • 您不需要 nelder-mead 的显式函数,有多种方法可以优化黑盒模型。您需要的取决于您的计算能力、时间、局部最小值的存在以及结果的波动性。
  • docs.scipy.org/doc/scipy/reference/generated/… 您可以查看可能感兴趣的可用模型列表
  • 在这个例子中,我正在优化的问题也是一个黑盒模型。我真的不知道GradientBoostingRegressor 做了什么
  • @Nathan 我有同样的问题,但有限制。我尝试了 SLSQP,但它总是返回我最初猜测的值。可能需要我无法提供的梯度信息。 Nelder-mead 不支持约束。你有什么建议?
猜你喜欢
  • 2023-04-10
  • 2021-10-27
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
  • 2017-11-05
  • 2015-01-18
  • 2020-08-26
  • 2015-11-19
相关资源
最近更新 更多