Python Keras未能找到线性凸问题的解

Python Keras未能找到线性凸问题的解,python,numpy,keras,linear-regression,Python,Numpy,Keras,Linear Regression,我编写了这个可复制的代码来演示这个问题: 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 @

我编写了这个可复制的代码来演示这个问题:

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))
基本上,我是用两种方法求解线性方程组的欠定方程组,一种是用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没有找到解决办法。我们得到的结果还不够接近零,我被卡住了。更改学习速率或添加迭代不会显著改变结果。为什么会发生这种情况

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


TLDR:我正拼命地想让自己过胖。我知道有一个解决方案可以让我零损失。我的问题是线性和凸的,典型的欠确定系统,keras无法找到该解决方案,并给我0训练损失。

您缺少层定义中的
输入\u形状
参数。不太清楚为什么在没有定义的
输入\u形状
的情况下它不工作(权重的形状似乎正常);但是,根据该报告:

通常,如果您知道序列模型的输入形状是什么,建议您始终提前指定该形状,这是一种最佳做法

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

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

经过10000个时代后,结果是:

Keras MSE is 1.9258555439788135e-10
在迭代10000多个历元(即总计20000个历元)时,我们得到:


重复运行,我们得到的结果在质量上是相似的(当然不是完全相同的)。

对于那些投票以意见为基础(或者可能也被否决)结束这项研究的人和评论员来说:这是一个完全合法的编码问题,有一个完全可复制的例子(现在很少见),它没有任何基于意见的内容。与您的问题无关,但将独立的
keras
tf.keras
混合使用不是一个好主意;我建议您删除
import keras
并将代码中的
keras
替换为
tf.keras
。我没有投票支持任何东西,但我想知道这个问题是否不是比较苹果和橙子?我不知道
np.linalg.lstsq
如何计算它的解,但我在文档中找不到梯度下降的参考。因此,将其与新加坡元的Keras进行比较是不公平的。至少,应该使用衰减的学习速率计划(理论上)来保证收敛。此外,问题还应该包括生成数据的特定随机种子——事实上,更好的结果可能只是偶然的结果。@xdurch0随机种子的公平点,但即使不复制所提供的代码,我也会多次得到与报告结果非常相似的结果。我建议的解决方案一致地改变了这一点,即使是多次运行
np.linalg.lstsq
很可能不使用SGD,但我原则上理解这样一种期望,即Keras在这里不会表现得那么差。你确定你没有做任何其他事情吗?我仍然得到不好的结果。@OriaGruber你是对的-我的道歉:(.我还使用了
batch\u size=32
(加上前面提到的更改
keras
->
tf.keras
)。我正在更新答案…但这改变了算法。现在这不再是“普通的”梯度下降法。这很好,但对我没有太大帮助,因为我正在处理的是关于规则GD的定理,而不是任何随机现象。@OriaGruber不确定你所说的“香草”是什么意思,因为实际使用的是SGD;但在任何情况下,如果答案没有真正解决您的问题,请随意取消接受,从而保持开放性并邀请其他想法(我承认,这种Keras行为非常奇怪,您最好将其作为一个可能的问题发布到Keras/Tensorflow回购协议)我的意思是x=x-学习率*df/dx。最陡下降。我知道这在实践中并不经常使用。我会把这个答案作为公认的答案。
Keras MSE is 1.9258555439788135e-10
Keras MSE is 1.2521153241468356e-13