Python LSTM,爆炸梯度还是错误的方法?
拥有用户每月活动的数据集,按国家和浏览器划分。每行是1天用户活动的总和,以及该日常活动的分数。例如:每天的会话数是一项功能。分数是一个浮点数,根据每日特征计算得出 我的目标是尝试在月底使用2天的用户数据预测“平均用户”的得分 我有25个月的数据,有些已经满了,有些只占总天数的一部分,为了有一个固定的批量大小,我对序列进行了如下填充:Python LSTM,爆炸梯度还是错误的方法?,python,tensorflow,keras,Python,Tensorflow,Keras,拥有用户每月活动的数据集,按国家和浏览器划分。每行是1天用户活动的总和,以及该日常活动的分数。例如:每天的会话数是一项功能。分数是一个浮点数,根据每日特征计算得出 我的目标是尝试在月底使用2天的用户数据预测“平均用户”的得分 我有25个月的数据,有些已经满了,有些只占总天数的一部分,为了有一个固定的批量大小,我对序列进行了如下填充: from keras.preprocessing.sequence import pad_sequences padded_sequences = pad_sequ
from keras.preprocessing.sequence import pad_sequences
padded_sequences = pad_sequences(sequences, maxlen=None, dtype='float64', padding='pre', truncating='post', value=-10.)
因此,序列小于最大值,其中填充-10行。我决定创建一个LSTM模型来消化数据,因此在每一批的末尾,该模型应该预测平均用户分数。然后稍后我将尝试使用2天的样本进行预测 我的模型是这样的:
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dropout,Dense,Masking
from tensorflow.keras import metrics
from tensorflow.keras.callbacks import TensorBoard
from tensorflow.keras.optimizers import Adam
import datetime, os
model = Sequential()
opt = Adam(learning_rate=0.0001, clipnorm=1)
num_samples = train_x.shape[1]
num_features = train_x.shape[2]
model.add(Masking(mask_value=-10., input_shape=(num_samples, num_features)))
model.add(LSTM(64, return_sequences=True, activation='relu'))
model.add(Dropout(0.3))
#this is the last LSTM layer, use return_sequences=False
model.add(LSTM(64, return_sequences=False, stateful=False, activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam' ,metrics=['acc',metrics.mean_squared_error])
logdir = os.path.join(logs_base_dir, datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
tensorboard_callback = TensorBoard(log_dir=logdir, update_freq=1)
model.summary()
Model: "sequential_13"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
masking_5 (Masking) (None, 4283, 16) 0
_________________________________________________________________
lstm_20 (LSTM) (None, 4283, 64) 20736
_________________________________________________________________
dropout_14 (Dropout) (None, 4283, 64) 0
_________________________________________________________________
lstm_21 (LSTM) (None, 64) 33024
_________________________________________________________________
dropout_15 (Dropout) (None, 64) 0
_________________________________________________________________
dense_9 (Dense) (None, 1) 65
=================================================================
Total params: 53,825
Trainable params: 53,825
Non-trainable params: 0
_________________________________________________________________
在训练中,我在19世纪得到了NaN值
Epoch 16/1000
16/16 [==============================] - 14s 855ms/sample - loss: 298.8135 - acc: 0.0000e+00 - mean_squared_error: 298.8135 - val_loss: 220.7307 - val_acc: 0.0000e+00 - val_mean_squared_error: 220.7307
Epoch 17/1000
16/16 [==============================] - 14s 846ms/sample - loss: 290.3051 - acc: 0.0000e+00 - mean_squared_error: 290.3051 - val_loss: 205.3393 - val_acc: 0.0000e+00 - val_mean_squared_error: 205.3393
Epoch 18/1000
16/16 [==============================] - 14s 869ms/sample - loss: 272.1889 - acc: 0.0000e+00 - mean_squared_error: 272.1889 - val_loss: nan - val_acc: 0.0000e+00 - val_mean_squared_error: nan
Epoch 19/1000
16/16 [==============================] - 14s 852ms/sample - loss: nan - acc: 0.0000e+00 - mean_squared_error: nan - val_loss: nan - val_acc: 0.0000e+00 - val_mean_squared_error: nan
Epoch 20/1000
16/16 [==============================] - 14s 856ms/sample - loss: nan - acc: 0.0000e+00 - mean_squared_error: nan - val_loss: nan - val_acc: 0.0000e+00 - val_mean_squared_error: nan
Epoch 21/1000
我试图应用所描述的方法,但没有真正成功
更新:
我已经将我的激活从relu更改为tanh,它解决了NaN问题。然而,当损失降低时,我的模型的精度似乎保持在0
Epoch 100/1000
16/16 [==============================] - 14s 869ms/sample - loss: 22.8179 - acc: 0.0000e+00 - mean_squared_error: 22.8179 - val_loss: 11.7422 - val_acc: 0.0000e+00 - val_mean_squared_error: 11.7422
Q:我做错了什么?您正在解决一项回归任务,使用精度在这里没有意义 使用
mean\u absollute\u error
检查您的错误是否随时间而减少
您可以将分数限制在(0,1)
,而不是盲目预测分数
只需使用最小-最大规格化即可使输出在一个范围内
之后,您可以在最后一层中使用sigmoid
另外,您正在为这个简单模型选择稍长的序列4283
,序列长度的偏差有多大
也许做一个所有信号长度的柱状图,看看4283
实际上是否是一个好的选择。也许您可以将其简化为512
,这对模型来说可能会更容易
此外,用-10填充似乎是一个非常奇怪的选择,是针对您的数据的特定内容还是随机选择的?这-10还表明您没有规范化输入数据,这可能会成为使用relu的LSTM的问题,也许您应该在培训之前尝试规范化输入数据
之后,如果性能仍然不好,则添加平均绝对误差的验证图。我可以想象,这与在LSTM层中使用relu激活有关——因为它没有边界,这将增加爆发激活/梯度的可能性。你试过使用默认的tanh激活吗?我会尝试发布我的反馈请查看我的更新谢谢你的输入,我会尝试并发布我的反馈谢谢你所有超级有用的输入,4283是最大序列,这意味着这是用户流量最多的部分,也就是说,对于某一天,一个细分市场可以有100名访客,另一个细分市场可以有1000名访客,每个批次是整个月的用户会话总量。我确实规范化了这些值,但稍后我用-10填充。-10只是我选择的一个数字,我在模型中屏蔽了它,这有关系吗?是的,我理解,但通常选择最大序列长度可能是一个不好的选择,如果大多数片段的长度接近1000,那么选择1000是一个更好的选择。填充值应该是序列中不常见的值。明白了,我将按平均序列进行检查和选择感谢提示,模型似乎在正确的路径上,我将进行一些预测并发布结果