寻找黑盒模型最优输入组合以获得最大输出

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

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

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

设置一个黑盒模型,在本例中是一个神经网络

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)最大输出的最优输入组合。


回答:

这是一个如何从模型中获取“最佳结果”的例子。关键部分是optimize_get_simplex_call_model。通过这种方式,你可以减少对模型调用的次数。

from sklearn.ensemble import GradientBoostingRegressorimport numpy as npfrom scipy.optimize import minimizefrom copy import copyclass 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。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注