Keras 未能找到线性凸问题的解决方案

Keras fails to find solution to linear convex problem

我写了这个可重现的代码来演示问题:

import numpy as np
import keras
import tensorflow as tf

n, d = 2, 3
A = np.random.random((n, d))
b = np.random.random((n, 1))
x = np.linalg.lstsq(A, b, rcond=None)[0]
print("Numpy MSE is {}".format((np.linalg.norm(A @ x - b) ** 2) / n))

model = keras.models.Sequential()
model.add(keras.layers.Dense(1, use_bias=False, activation='linear'))
opt = tf.keras.optimizers.SGD(learning_rate=0.01, momentum=0, nesterov=False)
model.compile(loss="mse", optimizer=opt)
model.fit(A, b, batch_size=A.shape[0], epochs=10000, verbose=0)
x = model.layers[0].get_weights()[0]
print("Keras MSE is {}".format((np.linalg.norm(A @ x - b) ** 2) / n))

基本上我用两种方法求解欠定线性方程组Ax=b,一次用numpy,一次用keras标准梯度下降。

当我 运行 它时,我得到这个输出:

Numpy MSE is 6.162975822039155e-33
Keras MSE is 1.3108133821545518e-10

numpy 产生了更好的结果,但我仍然愿意接受 keras 作为解决方案,10^(-10) 相当小。

现在将 n 增加到 200,将 d 增加到 300。 现在的输出是:

Numpy MSE is 1.4348640308871558e-30
Keras MSE is 0.0001953624326696054

现在不仅numpy好多了,就我而言,keras也没有找到解决办法。我们得到的结果不够接近零,我被卡住了。改变学习率或增加迭代不会显着改变结果。为什么会这样?

我知道有解决办法。我希望误差最多为 10^(-10),使用 keras,对于大维数据,例如 n = 200 d = 300 case

TLDR:我正在拼命尝试过拟合。我知道有一个解决方案可以让我损失 0。我的问题是线性和凸的,经典的欠定系统,keras 找不到那个解决方案并给我 0 训练损失。

您在图层定义中缺少 input_shape 参数。不太确定为什么没有定义的 input_shape 它不起作用(权重的形状似乎没问题);但是,根据 documentation:

In general, it's a recommended best practice to always specify the input shape of a Sequential model in advance if you know what it is.

另一件事是,通过设置batch_size=A.shape[0],你实际上使用的是batch梯度下降,而不是stochastic;为了使用 SGD,您需要将 batch_size 设置为小于数据样本的大小。

因此,在高维情况下对代码进行以下更改(加上将所有 keras 的使用替换为 tf.keras,因为将两者混合不是很好的做法):

# n, d = 200, 300

model.add(tf.keras.layers.Dense(1, input_shape=(A.shape[1],), use_bias=False, activation='linear'))

model.fit(A, b, batch_size=32, epochs=10000, verbose=0)

10,000个epoch后,结果为:

Keras MSE is 1.9258555439788135e-10

再迭代 10,000 个时期(即总共 20,000 个),我们得到:

Keras MSE is 1.2521153241468356e-13

重复运行,我们得到质量相似(但当然不相同)的结果。