LSTM,爆炸性梯度还是错误的方法?

时间:2020-04-23 10:01:23

标签: python tensorflow keras

具有按用户细分的国家/地区和浏览器每月活动的数据集。每行是1天的用户活动总和,以及该日常活动的得分。例如:每天的会话数是一项功能。分数是根据每日功能计算得出的浮点数。

我的目标是仅使用2天的用户数据来尝试预测月底的“平均用户” 得分。

我有25个月的数据,有的是完整的,有的仅占总天数的一部分,为了获得固定的批次大小,我将序列填充如下:

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

我试图应用here中描述的方法,但没有真正的成功。

更新: 我将激活方式从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

问:我在这里做错什么了吗?

1 个答案:

答案 0 :(得分:1)

您正在解决回归任务,在这里使用准确性没有意义。

使用mean_absollute_error检查您的错误是否随着时间的推移而减少。

您可以将分数限制为(0, 1),而不是盲目地预测分数。

只需使用最小最大规格化即可将输出置于https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html范围内

在那之后,您可以在最后一层使用sigmoid。

此外,您为此简单模型4283选择的序列稍长,序列长度有多偏斜?

也许可以绘制所有信号长度的直方图,然后查看4283实际上是否是一个不错的选择。也许您可以将其简化为512之类的东西,对于模型来说可能会变得更容易。

此外,用-10填充似乎是一个很奇怪的选择,它是针对您的数据的特定内容还是您是随机选择的?此-10还建议您不对输入数据进行规范化,这可能会对带有relu的LSTM造成问题,也许您应该在训练之前尝试对其进行规范化。

在这些之后,如果性能仍然不好,请添加一个平均绝对误差的验证图。

相关问题