Как прогнозировать более одного пакета из набора данных Tensorflow, используя .predict_on_batch? - PullRequest
0 голосов
/ 24 апреля 2020

Как следует из вопроса, я могу предсказывать только по моей модели с помощью model.predict_on_batch (). Keras пытается объединить все вместе, если я использую model.predict (), и это не работает.
Для моего приложения (от последовательности к модели последовательности) группирование выполняется быстрее. Но даже если бы я сделал это в Pandas, а затем использовал только набор данных для дополненного пакета, .predict () по-прежнему не должен работать?

Если я могу заставить предикат работать, то это то, что работает. Но я могу предсказать только по первой партии набора данных. Как я могу получить прогнозы для остальных? Я не могу l oop над набором данных, я не могу использовать его ...

Вот пример кода меньшего размера. Группа такая же, как лейблы, но в реальном мире это, очевидно, две разные вещи. Есть 3 класса, максимум 2 значения в последовательности, 2 строки данных на пакет. Там много комментариев, и я где-то выделил части окон на StackOverflow. Я надеюсь, что это довольно разборчиво для большинства.

Если у вас есть какие-либо другие предложения по улучшению кода, пожалуйста, оставьте комментарий. Но нет, совсем не так выглядит моя модель. Так что предложения по этой части, вероятно, бесполезны.

РЕДАКТИРОВАТЬ: версия Tensorflow 2.1.0

import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Bidirectional, Masking, Input, Dense, GRU
import random
import numpy as np

random.seed(100)
# input data
feature = list(range(3, 14))
# shuffle data
random.shuffle(feature)
# make label from feature data, +1 because we are padding with zero
label = [feat // 5 +1 for feat in feature]
group = label[:]
# random.shuffle(group)
max_group = 2
batch_size = 2

print('Data:')
print(*zip(group, feature, label), sep='\n')

# make dataset from data arrays
ds = tf.data.Dataset.zip((tf.data.Dataset.from_tensor_slices({'group': group, 'feature': feature}), 
                          tf.data.Dataset.from_tensor_slices({'label': label})))
# group by window
ds = ds.apply(tf.data.experimental.group_by_window(
    # use feature as key (you may have to use tf.reshape(x['group'], []) instead of tf.cast)
    key_func=lambda x, y: tf.cast(x['group'], tf.int64),
    # convert each window to a batch
    reduce_func=lambda _, window: window.batch(max_group),
    # use batch size as window size
    window_size=max_group))

# shuffle at most 100k rows, but commented out because we don't want to predict on shuffled data
# ds = ds.shuffle(int(1e5)) 
ds = ds.padded_batch(batch_size,
                     padded_shapes=({s: (None,) for s in ['group', 'feature']}, 
                                    {s: (None,) for s in ['label']}))
# show dataset contents
print('Result:')
for element in ds:
    print(element)

# Keras matches the name in the input to the tensor names in the first part of ds
inp = Input(shape=(None,), name='feature')
# RNNs require an additional rank, even if it is a degenerate dimension
duck = tf.expand_dims(inp, axis=-1)
rnn = GRU(32, return_sequences=True)(duck)
# again Keras matches names
out = Dense(max(label)+1, activation='softmax', name='label')(rnn)
model = Model(inputs=inp, outputs=out)
model.summary()
model.compile(loss='sparse_categorical_crossentropy', metrics=['accuracy'])

model.fit(ds, epochs=3)

model.predict_on_batch(ds)

1 Ответ

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

Вы можете перебирать набор данных, например, вспоминая, что такое "x" и что такое "y" в типичной записи:

for item in ds:
    xi, yi = item
    pi = model.predict_on_batch(xi)
    print(xi["group"].shape, pi.shape)

Конечно, это предсказывает для каждого элемента в отдельности. В противном случае вам придется определять партии самостоятельно, группируя совпадающие фигуры, поскольку сам размер партии может быть переменным.

...