Keras-GRU模型仅预测[0,0,0,0]

2024-03-28 23:02:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图根据前50个输入值预测加密货币的5个周期性价格。在

>>> X_train.shape, X_test.shape, Y_train.shape, Y_test.shape
((291314, 50, 8), (72829, 50, 8), (291314, 5), (72829, 5))

这里我有50个以前的样本x 8个功能作为输入样本,价格为5个下一个时期作为输出

我用以下代码构建了模型:

^{pr2}$

这给了我输出:

Train on 291314 samples, validate on 72829 samples
Epoch 1/2
291314/291314 [==============================] - 487s 2ms/step - loss: 0.0107 - val_loss: 0.2502
Epoch 2/2
291314/291314 [==============================] - 463 2ms/step - loss: 0.0103 - val_loss: 0.2502

在这一步之后,我试着预测X\U测试的输出,但我得到的不是预测,而是形状正确的矩阵,而是充满了零,而不是任何预测:

>>> model.predict(X_test)
array([[-0., -0., -0., -0., -0.],
       [-0., -0., -0., -0., -0.],
       [-0., -0., -0., -0., -0.],
       ...,
       [-0., -0., -0., -0., -0.],
       [-0., -0., -0., -0., -0.],
       [-0., -0., -0., -0., -0.]], dtype=float32)

为什么我变得这么糟糕?我用正确的方式做我想做的事吗?在

UPDHere是完整的笔记本。在


Tags: test功能onstep货币train价格val
2条回答

首先需要缩放测试(X_test)输入。您确实缩放了训练数据(X_train),但没有缩放测试集。在

所以您需要像使用X_train那样缩放它:

X_test = preprocessing.MinMaxScaler().fit_transform(X_test.reshape(-1, 50*8)).reshape(-1, 50, 8)

此外,在输出层中使用'ReLU'激活是有问题的。因为即使最后一层权重为负输出,也始终会得到正输出。在

这里的问题是这些负输出的权重不会得到更新,因为损失非常低。在

假设您的权重集导致输出-23435235,而目标是0.9。当在输出上使用'ReLU'激活时,它将从-23435235映射到{},这会导致低损耗。但低损耗意味着变化较小,而高损耗则会导致体重发生很大变化。在

所以你想要一个高的损失,以便得到一个强有力的修正你的体重。因为-23435235不是你想要的。在

所以不要在最后一层使用'ReLU',我在这里改为'linear'。在

所以说(我把'tanh'改为'ReLU'顺便说一句)代码:

^{pr2}$

输出:

Train on 291314 samples, validate on 72829 samples
Epoch 1/15
291314/291314 [==============================] - 22s 75us/step - loss: 0.1523 - val_loss: 0.2442
Epoch 2/15
291314/291314 [==============================] - 16s 56us/step - loss: 0.0652 - val_loss: 0.2375
Epoch 3/15
291314/291314 [==============================] - 16s 56us/step - loss: 0.0420 - val_loss: 0.2316
Epoch 4/15
291314/291314 [==============================] - 16s 56us/step - loss: 0.0337 - val_loss: 0.2262
Epoch 5/15
291314/291314 [==============================] - 16s 56us/step - loss: 0.0271 - val_loss: 0.2272
Epoch 6/15
291314/291314 [==============================] - 16s 56us/step - loss: 0.0219 - val_loss: 0.2256
Epoch 7/15
291314/291314 [==============================] - 16s 56us/step - loss: 0.0179 - val_loss: 0.2245
Epoch 8/15
291314/291314 [==============================] - 16s 56us/step - loss: 0.0149 - val_loss: 0.2246
Epoch 9/15
291314/291314 [==============================] - 16s 56us/step - loss: 0.0125 - val_loss: 0.2244
Epoch 10/15
291314/291314 [==============================] - 16s 57us/step - loss: 0.0108 - val_loss: 0.2213
Epoch 11/15
291314/291314 [==============================] - 16s 57us/step - loss: 0.0096 - val_loss: 0.2197
Epoch 12/15
291314/291314 [==============================] - 16s 56us/step - loss: 0.0087 - val_loss: 0.2189
Epoch 13/15
291314/291314 [==============================] - 16s 57us/step - loss: 0.0080 - val_loss: 0.2178
Epoch 14/15
291314/291314 [==============================] - 16s 56us/step - loss: 0.0075 - val_loss: 0.2148
Epoch 15/15
291314/291314 [==============================] - 16s 57us/step - loss: 0.0072 - val_loss: 0.2129
<tensorflow.python.keras.callbacks.History at 0x7f8a93637b70>

进一步的X_test结果:

代码:

prediction = model.predict(X_test[:10])
prediction

输出:

array([[0.03562379, 0.06016447, 0.0987532 , 0.01986726, 0.0336756 ],
       [0.03518523, 0.06041833, 0.0983481 , 0.01864071, 0.03437094],
       [0.03487844, 0.06067847, 0.09811568, 0.0175517 , 0.03480709],
       [0.03491565, 0.05986937, 0.09927133, 0.02029082, 0.03347992],
       [0.03466946, 0.06018706, 0.09859383, 0.01869587, 0.03432   ],
       [0.03459518, 0.06030918, 0.09850594, 0.01805007, 0.03444977],
       [0.03448001, 0.06019764, 0.09864715, 0.01818896, 0.034256  ],
       [0.03450274, 0.05936757, 0.10001318, 0.02131432, 0.03305689],
       [0.03424717, 0.05954869, 0.09983289, 0.0208826 , 0.03378636],
       [0.03426195, 0.05959999, 0.09991242, 0.02090426, 0.03394405]],
      dtype=float32)

我用你的笔记本和数据来训练上述模型。在

正如您所看到的,在epoch15中验证损失仍然在减少,而且测试输出看起来非常接近目标。在


还有一点需要注意的是,我还没有看过笔记本中所有的预处理代码,但在我看来,你使用的是绝对值。在

如果是这种情况,则应考虑使用百分比变化(例如从当前时间点到未来的预测点)。这也为你做了缩放。(10%变化=0.1)

进一步的绝对值确实变化太大。如果十个月前的价格是~5.4324,而今天的价格是~50.5534,那么这些数据对你来说是无用的,而价格变化的相对模式可能仍然有效。在

这只是一个旁注-我希望它有帮助。在

嗯,我认为@blue phoenox的答案中建议的标准化方案是有缺陷的。这是因为您永远不应该独立地对测试数据进行标准化(即使用不同的统计数据)。相反,您应该使用训练数据规范化期间计算的统计数据来规范化测试数据。所以一定是这样的:

mms = preprocessing.MinMaxScaler()
X_train = mms.fit_transform(X_train)
X_test = mms.transform(X_test) # you should not use fit_transform

这是有意义的,因为考虑以下场景,您已经训练了模型,现在将其部署到生产中以供实际使用。现在一个用户给它提供一个新的样本。你需要首先规范化这个新的样本,但是怎么做呢?您不能独立缩放其值,因为它只有一个采样(即,如果使用“最小最大缩放器”(min-max scaler),则所有采样值都将为1或0)。相反,您应该使用(在使用minmax scaler的情况下)在训练数据上计算的“min”和“max”值来规范化这个新的测试数据。在

这在图像模型中非常常见,例如:

^{pr2}$

请注意,我们将训练和测试数据除以同一个数字(即255)。或者更复杂的标准化方案:

X_mean = X_train.mean(axis=0)
X_std = X_train.std(axis=0)
X_train -= X_mean
X_train /= X_std + 1e-8   # add a small constant to prevent division by zero

# Now to normalize test data we use the same X_mean and X_std already computed
X_test -= X_mean
X_test /= X_std + 1e-8

旁注(正如我在my comment中提到的):如果您在GPU上运行训练,那么您可以考虑使用^{}而不是{}(或{}而不是{}),因为它是专门针对GPU优化的,可以加快训练过程。在

相关问题 更多 >