Я хочу обработать многофайловый набор данных TFRecord с последовательностями переменной длины из 12 объектов по модели CuDNNLSTM и классифицировать его по 7 классам. Чтобы иметь возможность выполнять пакетную обработку, мне нужно дополнить последовательности в каждом пакете, чтобы иметь фиксированную длину. Я знаю, что могу сделать это с помощью функции padded_batch набора данных tenorflow, но я хочу замаскировать заполненные нули во время обучения, и CuDNNLSTM не поддерживает использование маскирующего слоя. Поэтому я решил дополнить все последовательности во время разбора примера TFRecord до глобальной максимальной длины (скажем, 100) и использовать выборочное взвешивание, чтобы замаскировать заполненные временные метки на выходе набора данных, и прочитать все файлы набора данных, а также создать пакеты с дополнением и маскированием, используя приведенные нижекод:
featuresDict = {# Data: Variable-length sequence of 12 features
'data': tf.FixedLenFeature([], dtype=tf.string),
# rows: Length of sequence (for decoding it back to an array)
'rows': tf.FixedLenFeature([], dtype=tf.int64),
# label: Label of sequence for classification (0 to 6)
'label': tf.FixedLenFeature([], dtype=tf.int64)}
def parse_tfrecord(example):
features = tf.parse_single_example(example, featuresDict)
label = tf.one_hot(features['label'], 7)
rows = features['rows']
data = tf.decode_raw(features['data'], tf.int64)
data = tf.reshape(data, (rows, 12))
dataLen = tf.shape(data)[0]
mask = tf.ones(dataLen)
data = tf.pad(data, [[0, 100-dataLen],[0,0]])
mask = tf.pad(mask, [[0, 100-dataLen]])
return data, label, mask
def read_datasets(pattern, numFiles, numEpochs=None, batchSize=None):
files = tf.data.Dataset.list_files(pattern)
def _parse(x):
x = tf.data.TFRecordDataset(x, compression_type='GZIP')
return x
dataset = files.interleave(_parse, cycle_length=numFiles, block_length=1).map(parse_tfrecord)
dataset = dataset.batch(batchSize)
dataset = dataset.prefetch(buffer_size=batchSize)
dataset = dataset.repeat(numEpochs)
return dataset
Затем я определяю свою модель keras (которая состоит из нескольких слоев LSTM плюс плотный слой с размером 7 и активацией softmax) и компилирую ее, как показано ниже. Я предполагаю, что train_data должен включать данные, метки и данные маскирования в качестве весов выборки:
train_data = read_datasets(pattern, numFiles, numEpochs=epochs, batchSize=batch_size)
model.compile(optimizer, loss='categorical_crossentropy', sample_weight_mode="temporal")
model.fit(train_data, epochs=epochs, steps_per_epoch = train_steps)
Но я получаю ошибку ниже:
Traceback (most recent call last):
"C:/Users/sshahhey.ESFADMIN.000/.PyCharmCE2019.2/config/scratches/scratch.py", line 323, in doWork
model.fit(train_data, epochs=epochs, steps_per_epoch = train_steps)
File "C:\Python36\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1536, in fit
validation_split=validation_split)
File "C:\Python36\lib\site-packages\tensorflow\python\keras\engine\training.py", line 992, in _standardize_user_data
class_weight, batch_size)
File "C:\Python36\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1165, in _standardize_weights
feed_sample_weight_modes)
File "C:\Python36\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1164, in <listcomp>
for (ref, sw, cw, mode) in zip(y, sample_weights, class_weights,
File "C:\Python36\lib\site-packages\tensorflow\python\keras\engine\training_utils.py", line 677, in standardize_weights
'an input with shape ' + str(y.shape) + '. '
ValueError: Found a sample_weight array for an input with shape (?, 7). Timestep-wise sample weighting (use of sample_weight_mode="temporal") is restricted to outputs that are at least 3D, i.e. that have a time dimension.
В чем причина этой ошибки? Как я могу сделать свою маскировку без написания индивидуального цикла обучения?