Модель tensorflow lstm не предсказывает результаты

Я построил модель LSTM в тензорном потоке, но она не предсказывает каких-либо полезных результатов. Мои данные, по сути, представляют собой последовательность кодов для нескольких идентификаторов, и я хочу, чтобы моя модель предсказывала следующий код в последовательности для каждого идентификатора (классификации).

Я структурировал свою модель так, чтобы она включала 5 последовательностей (ID, dx1, dx2, dx3), каждая из которых имеет один и тот же ID, а затем хочу, чтобы она выводила следующий dx1, dx2, dx3 в последовательности.

num_cats = 4 # number of categorical features
n_steps = 5 # number of timesteps in each sample
cat_size = [df['enrolid'].nunique(),  df['dx1'].nunique(), df['dx2'].nunique(), df['dx3'].nunique()] # number of categories in each categorical feature
cat_embd_dim = [1191095, 100, 50, 20] # embedding dimension for each categorical feature



input_enrolid = Input(shape=(n_steps,), name='input_enrolid')    
input_dx1 = Input(shape=(n_steps,), name='input_dx1')
input_dx2 = Input(shape=(n_steps,), name='input_dx2')
input_dx3 = Input(shape=(n_steps,), name='input_dx3')

embed_dx1 =  Embedding(df['dx1'].nunique(), cat_embd_dim[1])(input_dx1)
embed_dx2 =  Embedding(df['dx2'].nunique(), cat_embd_dim[2])(input_dx2)
embed_dx3 =  Embedding(df['dx3'].nunique(), cat_embd_dim[3])(input_dx3)

lstm_dx1 = LSTM(32, input_shape=(n_steps, num_cats))(embed_dx1)
lstm_dx2 = LSTM(32, input_shape=(n_steps, num_cats))(embed_dx2)
lstm_dx3 = LSTM(32, input_shape=(n_steps, num_cats))(embed_dx3)

output_dx1 = Dense(1, activation='softmax')(lstm_dx1)
output_dx2 = Dense(1, activation='softmax')(lstm_dx2)
output_dx3 = Dense(1, activation='softmax')(lstm_dx3)

model = Model( [input_enrolid, input_dx1, input_dx2, input_dx3], [output_dx1, output_dx2, output_dx3])

Мой model.summary() выглядит следующим образом:

Model: "functional_15"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_dx1 (InputLayer)          [(None, 5)]          0                                            
__________________________________________________________________________________________________
input_dx2 (InputLayer)          [(None, 5)]          0                                            
__________________________________________________________________________________________________
input_dx3 (InputLayer)          [(None, 5)]          0                                            
__________________________________________________________________________________________________
embedding_39 (Embedding)        (None, 5, 100)       154500      input_dx1[0][0]                  
__________________________________________________________________________________________________
embedding_40 (Embedding)        (None, 5, 50)        79750       input_dx2[0][0]                  
__________________________________________________________________________________________________
embedding_41 (Embedding)        (None, 5, 20)        28600       input_dx3[0][0]                  
__________________________________________________________________________________________________
lstm_51 (LSTM)                  (None, 32)           17024       embedding_39[0][0]               
__________________________________________________________________________________________________
lstm_52 (LSTM)                  (None, 32)           10624       embedding_40[0][0]               
__________________________________________________________________________________________________
lstm_53 (LSTM)                  (None, 32)           6784        embedding_41[0][0]               
__________________________________________________________________________________________________
input_enrolid (InputLayer)      [(None, 5)]          0                                            
__________________________________________________________________________________________________
dense_21 (Dense)                (None, 1)            33          lstm_51[0][0]                    
__________________________________________________________________________________________________
dense_22 (Dense)                (None, 1)            33          lstm_52[0][0]                    
__________________________________________________________________________________________________
dense_23 (Dense)                (None, 1)            33          lstm_53[0][0]                    
==================================================================================================
Total params: 297,381
Trainable params: 297,381
Non-trainable params: 0

Затем я компилирую и подгоняю свою модель:

model.compile(optimizer=Adam(lr=0.1), loss='categorical_crossentropy',metrics='accuracy' )
model.fit([ X_tr_cat1, X_tr_cat2, X_tr_cat3, X_tr_cat4], [y_train_dx1, y_train_dx2, y_train_dx3], epochs=3, batch_size = 1000)

Однако, подобрав мою модель, я вижу некоторые неточности и потери, которые не выглядят слишком обнадеживающими:

Epoch 1/3
1192/1192 [==============================] - 37s 31ms/step - loss: 0.0000e+00 - dense_21_loss: 0.0000e+00 - dense_22_loss: 0.0000e+00 - dense_23_loss: 0.0000e+00 - dense_21_accuracy: 0.0000e+00 - dense_22_accuracy: 8.3956e-07 - dense_23_accuracy: 8.3956e-07
Epoch 2/3
1192/1192 [==============================] - 37s 31ms/step - loss: 0.0000e+00 - dense_21_loss: 0.0000e+00 - dense_22_loss: 0.0000e+00 - dense_23_loss: 0.0000e+00 - dense_21_accuracy: 0.0000e+00 - dense_22_accuracy: 8.3956e-07 - dense_23_accuracy: 8.3956e-07
Epoch 3/3
1192/1192 [==============================] - 37s 31ms/step - loss: 0.0000e+00 - dense_21_loss: 0.0000e+00 - dense_22_loss: 0.0000e+00 - dense_23_loss: 0.0000e+00 - dense_21_accuracy: 0.0000e+00 - dense_22_accuracy: 8.3956e-07 - dense_23_accuracy: 8.3956e-07

Нет не только нулевых потерь на трех выходных сигналах и нулевой точности для первого плотного слоя, но и ни одно из значений не меняется в каждую эпоху!

Кроме того, когда я пытаюсь заставить модель предсказывать данные, которые я использовал для ее обучения, я получаю:

> y_prob=model.predict([ X_tr_cat1, X_tr_cat2, X_tr_cat3, X_tr_cat4])

> [array([[1.],
        [1.],
        [1.],
        ...,
        [1.],
        [1.],
        [1.]], dtype=float32),
 array([[1.],
        [1.],
        [1.],
        ...,
        [1.],
        [1.],
        [1.]], dtype=float32),
 array([[1.],
        [1.],
        [1.],
        ...,
        [1.],
        [1.],
        [1.]], dtype=float32)]

При попытке увидеть фактические прогнозы для dx1:

> y_prob[0].argmax(axis=-1)
> array([0, 0, 0, ..., 0, 0, 0], dtype=int64)

Похоже, он предсказывает одно и то же предсказание 0 dx1 для каждой последовательности, где пустая строка '' была закодирована как 0 в моих данных.

Для дополнительного пояснения мой ввод X_tr_cat1 выглядит как

> X_tr_cat1
> array([[     0,      0,      0,      0,      0],
       [     0,      0,      0,      0,      0],
       [     0,      0,      0,      0,      0],
       ...,
       [238218, 238218, 238218, 238218, 238218],
       [238218, 238218, 238218, 238218, 238218],
       [238218, 238218, 238218, 238218, 238218]])

и имеет форму (1191095, 5).

Хотя cat2, cat3, cat4 может содержать разные значения, форма и структура одинаковы - они просто относятся к кодам, в то время как cat1 относится к id: первый [0,0, 0, 0, 0] означает, что идентификатор был 0 для идентификатора 0 временами 1,2,3,4. , 5.

Мой вывод y_train_dx1 выглядит так:

array([[ 877],
       [1313],
       [1313],
       ...,
       [   0],
       [   0],
       [   0]])

и имеет форму (1191095, 1) - просто следующий код dx1 в последовательности для каждой входной последовательности. Я действительно не знаю, что здесь не так с моей моделью - я думаю, что мои входные массивы отформатированы правильно? Но я не уверен, так как я новичок в TF.

Есть предложения, что исправить?

Dense(1, activation='softmax') у вас есть 1 единица, поэтому ваши прогнозы в форме (1,). Выводы Softmax будут суммировать до одного (1), с 1 единицей вы просто выводите вектор единиц (1 с) каждый раз. Также argmax с формой (1,) не имеет смысла.
Frightera 30.03.2021 01:02

@Frightera Думаю, я просто пытаюсь найти наиболее вероятный прогноз для каждого из выходов dx1,dx2,dx3 вместе с их вероятностями. Стоит ли мне тогда использовать другую функцию активации? Я вижу, что sigmoid - это еще одна функция активации классификации, но она эквивалентна 2-элементному softmax, так что это тоже звучит неправильно?

lvnwrth 30.03.2021 01:14

Если бы я попытался использовать Dense(num_categories, activation = 'softmax') для получения вероятностей каждой категории в последнем слое, пришлось бы мне переформатировать мои данные y_train_dx1? Я получаю сообщение об ошибке "Фигуры несовместимы".

lvnwrth 30.03.2021 01:23
0
3
24
0

Другие вопросы по теме