LSTM, Взрывающиеся градиенты или неправильный подход? - PullRequest
1 голос
/ 23 апреля 2020

Наличие набора данных о ежемесячной активности пользователей, сегменте по стране и браузеру. В каждой строке суммируется 1 день активности пользователя и балл за эту ежедневную активность. Например: количество сеансов в день - это одна функция. Оценка представляет собой число с плавающей запятой, рассчитанное по этим ежедневным функциям.

Моя цель - попытаться предсказать оценку «среднего пользователя» в конце месяца, используя всего 2 дня пользователей. data.

У меня есть данные за 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
_________________________________________________________________

Во время обучения я получаю значение NaN в 19-ю эпоху

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: Что я здесь не так делаю?

1 Ответ

1 голос
/ 23 апреля 2020

Вы решаете задачу регрессии, использование точности здесь не имеет смысла.

Используйте mean_absollute_error, чтобы проверить, уменьшается ваша ошибка с течением времени или нет.

Вместо слепого предсказания оценка, вы можете сделать счет ограниченным до (0, 1).

Просто используйте минимальную минимальную нормализацию, чтобы вывести результат в диапазон https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html

После этого вы можно использовать сигмоид в последнем слое.

Кроме того, вы выбираете несколько более длинные последовательности для этой простой модели 4283, насколько искажены длины вашей последовательности?

Может быть, сделать гистограмму для всех длина сигнала и посмотреть, является ли 4283, действительно, хорошим выбором или нет. Может быть, вы можете свести это к чему-то вроде 512, что может стать легче для модели.

Кроме того, заполнение с -10 кажется довольно странным выбором, если это что-то определенное c для ваших данных или для вас » выбираете случайно? Это -10 также означает, что вы не нормализуете свои входные данные, что может стать проблемой с LSTM с помощью relu, возможно, вам следует попытаться нормализовать их перед тренировкой.

После этого добавьте проверочный график среднего абсолютного значения. ошибка, если производительность все еще не хорошая.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...