是否可以在 scikit-learn 的 MLPRegressor 中自定义激活函数?

数据挖掘 scikit-学习 回归 激活函数
2022-03-01 22:32:09

与关于 MLPClassifier 的这个问题类似,我怀疑答案是否定的,但无论如何我都会问。

是否可以在 scikit-learn中更改MLPRegressor神经网络中输出层的激活函数?

我想用它来进行函数逼近。IE

y = f(x)

其中 x 是不超过 10 个变量的向量,y 是单个连续变量。

所以我想将输出激活更改为线性或tanh。现在它看起来像 sigmoid。

如果没有,我看不出你如何将 scikit-learn 用于分类以外的任何事情,这将是一种耻辱。

是的,我意识到我可以使用 tensorflow 或 PyTorch,但我的应用程序太基础了,我认为 scikit learn 非常适合(请原谅那里的双关语)。

是否可以使用MultiLayerPerceptron或从单个层(sknn.mlp )构建更定制的网络

更新:

在 MultiLayerPerceptron 的文档中,它确实说:

对于输出层,您可以使用以下层类型:Linear 或 Softmax。

但再往下说:

使用多层感知器时,应直接初始化 Regressor 或 Classifier。

并且没有关于如何实例化 MultiLayerPerceptron 对象的示例。

2个回答

我在 MLPRegressor 的代码中看到,最终激活来自父类中的一般初始化函数:BaseMultiLayerPerceptron,并且您想要的逻辑显示在Line 271周围。

# Output for regression
if not is_classifier(self):
    self.out_activation_ = 'identity'
# Output for multi class
...

然后在向前传递期间,这self.out_activation_被称为(在此处定义):

# For the last layer
output_activation = ACTIVATIONS[self.out_activation_]
activations[i + 1] = output_activation(activations[i + 1])

那个看起来不祥的变量ACTIVATIONS只是一个字典,关键字是您可以选择作为 MLP 中的参数的描述,每个都映射一个实际函数。这是字典

ACTIVATIONS = {'identity': identity, 'tanh': tanh, 'logistic': logistic,
               'relu': relu, 'softmax': softmax}

有了所有这些信息,您可能会想出一些方法来放入您的自定义函数。在我的脑海中,我看不到简单地提供功能的快速方法。例如,您可以:

  1. 定义您的函数,其中定义了所有其他激活函数
  2. 将其添加到该ACTIVATIONS字典
  3. makeself.out_activation_等于您的自定义函数(甚至是一个新参数MLPRegressor
  4. 交叉你的手指它不会破坏其他地方的东西
  5. 运行它并解决一些地方不可避免的小调整

恐怕我以前从未看过该库的源代码,因此无法提供更细致入微的建议。也许有一种我们都忽略的精美优雅的方式来做到这一点。

我尝试注入修改后的初始化,它允许您设置输出激活:

from sklearn.neural_network import MLPRegressor
model = MLPRegressor()
from sklearn.neural_network._base import ACTIVATIONS, DERIVATIVES

def inplace_capped_output(X):
    """Compute a capped linear function inplace.
    Parameters
    ----------
    X : {array-like, sparse matrix}, shape (n_samples, n_features)
        The input data.
    """
    np.clip(X, -40,40)
    

ACTIVATIONS["custom"]=inplace_capped_output

model._old_initialize=model._initialize
def _initialize(self, y, layer_units, dtype):
    self._old_initialize(y, layer_units, dtype)
    self.out_activation_="custom"
    
model._initialize = _initialize.__get__(model)

修改后的初始化函数的绑定遵循这篇文章

由于反向传播算法,您需要对 DERIVATIVES 执行类似的操作。

请注意,您需要调整https://github.com/scikit-learn/scikit-learn/blob/2beed55847ee70d363bdbfe14ee4401438fba057/sklearn/neural_network/_multilayer_perceptron.py#L274因为 deltas[last] = activations[-1] - y 是如果您提供任意的自定义输出激活,则不正确。