a
和b
a
和b
X_train
示例: array([[ 6220, 15403],
[ 3197, 8054],
[ 1723, 3711],
...,
[ 9500, 14979],
[ 2642, 16547],
[15169, 19332]], dtype=int64)
Y_train
示例: array([ 95806660, 25748638, 6394053, ..., 142300500, 43717174,
293247108], dtype=int64)
def get_model():
model = Sequential()
model.add(Dense(20, input_shape=(2,), kernel_initializer='normal', activation='linear'))
model.add(LeakyReLU(alpha=.001))
model.add(Dense(20, kernel_initializer='normal', activation='linear'))
model.add(LeakyReLU(alpha=.001))
model.add(Dense(20, kernel_initializer='normal', activation='linear'))
model.add(LeakyReLU(alpha=.001))
model.add(Dense(20, kernel_initializer='normal', activation='linear'))
model.add(LeakyReLU(alpha=.001))
model.add(Dense(1, activation=None))
model.compile(loss='mean_squared_error', optimizer='adam')
return model
estimator = KerasRegressor(build_fn=get_model, epochs=20, batch_size=20, verbose=1)
estimator.fit(np.array(X_train), np.array(Y_train))
似乎在一些时代之后趋同,伴随着巨大的训练损失:
Epoch 1/20
8000/8000 [==============================] - 3s 378us/step - loss: 8970757661335224.0000
Epoch 2/20
8000/8000 [==============================] - 1s 187us/step - loss: 1368236980395048.7500
Epoch 3/20
8000/8000 [==============================] - 2s 189us/step - loss: 731455474934743.0000
Epoch 4/20
8000/8000 [==============================] - 2s 200us/step - loss: 731256021644738.6250
Epoch 5/20
8000/8000 [==============================] - 2s 209us/step - loss: 729734634673274.8750
Epoch 6/20
8000/8000 [==============================] - 2s 215us/step - loss: 730761901553746.0000
Epoch 7/20
8000/8000 [==============================] - 2s 224us/step - loss: 729841294691532.7500
Epoch 8/20
8000/8000 [==============================] - 2s 235us/step - loss: 728911536487137.2500
Epoch 9/20
8000/8000 [==============================] - 2s 229us/step - loss: 731467433524592.6250
Epoch 10/20
所有这些行动都不会改善损失。使用较少的层会使结果更糟。
如果有人想玩它 - 我已经创建了一个(IPython / Google Colab)笔记本here。
我现在也尝试过:
glorot_normal
进行初始化→无显着性更改sklearn.preprocessing.StandardScaler
通过sc.fit_transform(dataset)
进行规范化并推断sc.inverse_transform(result)
→改进自~7.3e14至~2.0e11 math.log
进行规范化(将c = a * b
转换为log(c) = log(a) + log(b)
,使用exp(predicted)
进行推理→看起来更好→1.02e9
,但它仍然很远从准确 - 在一个简单的任务,如乘法答案 0 :(得分:2)
规范化您的数据(输入和输出),使其具有零均值和单位差异。
在第二步中,将初始值设定项更改为glorot_normal
。
答案 1 :(得分:0)
您正在使用非常大的值。查看平均相对绝对误差(id=:arg0
),以便在评估过程中更好地估计模型的性能,而与输入比例无关。
进一步考虑使用较小的值,例如在mean(abs((output - target) / target))
范围内,将输出限制在[0; 10]
范围内,以避免爆炸梯度。您可以将输入除以某些[0; 100]
(scale
),然后将输出乘以>> 1
。
如果您不使用scale^2
和ln
的技巧来将乘法转换为加法,则需要更多的层,还应考虑残差连接。
答案 2 :(得分:0)
建模存在几个问题:
a
和b
具有不同的范围,则它们的参数需要不同的学习率。为了避免所有这些问题,您应该将数据按比例缩小,例如缩小为0均值,1方差。但是这种缩放可能会影响乘法精度。更适合此问题的是日志缩放。 请注意,如果您使用对数缩放,则问题甚至更简单,只需将两个数字相加即可。您只能将1个输出层与1个线性神经元一起使用,而无需隐藏层。 但是,主要问题是框架/硬件。
即使使用精确的权重([[1.,1.],[0.]]),模型输出仍然不准确,测试集上的MSE仍然约为10 ^ 4。我认为这是因为在TF和/或Colab中计算精度较低的浮点数,因此无法正确计算大数。