I am training an auto-encoder network used to encodes multivariate time sequences over a large data set. I uploaded a fully working example as a gist.
Even though it is working, I have to decide between an extremely memory inefficient or a slow solution. And I would like to get my memory efficient solution faster.
In my memory inefficient setup I prepare the training set as in plain_dataset. I.e. by materializing sliding windows over the whole data set. (in my real training setup those are highly overlapping)
Instead I want to define my training set like in idx_dataset as a list of (dataset_index, row_index, size) - tuples. Before each training step this references are resolved and actual training example is compiled.
I converted the time series data set to a RaggedTensor rt to be able to access the data in graph mode. Then I implemented the index resolution in resolve_index_batch as part of my custom_fit function.
My hope was that composing this training example is quite cheap compare to the actual training step but the throughput is almost half when using the index training set.
Any ideas how to make the resolve_index_batch function more efficient?
@tf.function
def resolve_index_batch(idx_batch):
"""
param idx_batch: (32x3) int32 tensor. Each row containing [time_series_idx, row_idx, window_size]
"""
return tf.map_fn(fn=lambda idx: tf.slice(rt[idx[0]], [idx[1], 0], [idx[2], -1]), elems=idx_batch, fn_output_signature=tf.float32)
@tf.function
def train_step(batch):
if mode == 'idx':
# apply the conversion from indexes batch to data_series batch
batch = resolve_index_batch(batch)
# train on reversed time series
batch_flip = tf.reverse(batch, [1])
with tf.GradientTape() as tape:
m = model(batch, training=True)
loss = loss_fun(batch_flip, m)
grad = tape.gradient(loss, model.trainable_weights)
opt.apply_gradients(zip(grad, model.trainable_weights))
return loss