MLP回归器在keras和scikit-learn中的不同损失值和精度

Different loss values and accuracies of MLP regressor in keras and scikit-learn

我有一个神经网络,其中一个隐藏层在 Keras 和 scikit-learn 中实现,用于解决回归问题。在 scikit-learn 中,我使用的 MLPregressor class 大部分都是默认参数,而在 Keras 中,我有一个隐藏的 Dense 层,其参数设置为与 scikit-learn 相同的默认值(它使用具有相同学习率和 epsilon 的 Adam 和 batch_size 共 200 个)。当我训练网络时,scikit-learn 模型的损失值大约是 keras 的一半,而且它的准确性(以平均绝对误差衡量)也更好。如果损失值不相同且准确度也相似,那么损失值不应该相似吗?有没有人经历过类似的事情并能够使 Keras 模型更准确?

Scikit-learn 模型:

clf = MLPRegressor(hidden_layer_sizes=(1600,), max_iter=1000, verbose=True, learning_rate_init=.001)

Keras 模型:

inputs = keras.Input(shape=(cols,))
x = keras.layers.Dense(1600, activation='relu', kernel_initializer="glorot_uniform", bias_initializer="glorot_uniform", kernel_regularizer=keras.regularizers.L2(.0001))(inputs)
outputs = keras.layers.Dense(1,kernel_initializer="glorot_uniform", bias_initializer="glorot_uniform", kernel_regularizer=keras.regularizers.L2(.0001))(x)
model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(optimizer=keras.optimizers.Adam(epsilon=1e-8, learning_rate=.001),loss="mse")
model.fit(x=X, y=y, epochs=1000, batch_size=200)

因为scikit-learn的均方损失(MSE)公式和tensorflow的不一样

来自scikit-learn的源代码:

def squared_loss(y_true, y_pred):
    return ((y_true - y_pred) ** 2).mean() / 2

而来自 tensorflow 的 MSE:

backend.mean(math_ops.squared_difference(y_pred, y_true), axis=-1)

正如你所见,scikit-learn 被除以 2,与你所说的一致:

the scikit-learn model has a loss value that is about half of keras

这意味着来自 keras 和 scikit-learn 的模型实际上实现了相似的性能。这也意味着 scikit-learn 中的学习率 0.001 不等同于 tensorflow 中的相同学习率。

此外,另一个较小但显着的差异是 L2 正则化的公式。

来自scikit-learn的源码,

# Add L2 regularization term to loss
values = 0
for s in self.coefs_:
   s = s.ravel()
   values += np.dot(s, s)
loss += (0.5 * self.alpha) * values / n_samples

而tensorflow的是loss = l2 * reduce_sum(square(x)).

因此,同样的l2正则化参数,tensorflow one的正则化更强,会导致对训练数据的拟合更差。