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
重复运行,我们得到质量相似(但当然不相同)的结果。
我写了这个可重现的代码来演示问题:
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
重复运行,我们得到质量相似(但当然不相同)的结果。