【发布时间】:2021-01-29 19:33:40
【问题描述】:
我编写了这个可重现代码来演示这个问题:
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没有找到解决方案。我们得到的结果还不够接近于零,我被卡住了。改变学习率或增加迭代不会显着改变结果。为什么会这样?
我知道有一个解决方案。对于大尺寸数据,例如 n = 200 d = 300 的情况,我希望误差最多为 10^(-10),使用 keras
TLDR:我拼命想过度拟合。我知道有一个解决方案可以让我零损失。我的问题是线性和凸的,经典的欠定系统,keras 找不到那个解决方案,给我 0 训练损失。
【问题讨论】:
-
致以基于意见(也可能被否决)和审阅者投票结束此问题的人:这是一个完全合法的编码问题,具有完全可重现示例(如今很少见),并且其中没有任何基于意见的内容。
-
与您的问题无关,但将独立的
keras与tf.keras混合使用不是一个好主意;我建议您删除import keras并将代码中的keras替换为tf.keras。 -
我没有投票给任何东西,但我想知道这个问题是不是比较苹果和橘子?我不知道
np.linalg.lstsq如何计算其解决方案,但我在文档中找不到对梯度下降的参考。因此,将其与带有 SGD 的 Keras 进行比较是不公平的。至少,应该使用衰减的学习率计划来(理论上)保证收敛。此外,问题应包括生成数据的特定随机种子——事实上,desertnauts 更好的结果可能仅仅是由于机会。 -
@xdurch0 随机种子的公平点,但是即使没有它,也可以多次复制提供的代码,我得到的结果与报告的结果非常相似。我建议的解决方案始终如一地改变了这一点,即使是多次运行。
np.linalg.lstsq很可能不使用 SGD,但我原则上理解 Keras 不应该在这里表现那么糟糕的期望。
标签: python numpy keras linear-regression