使用大数据集在 Google Colab TPU 上训练 seq2seq 模型 - Keras

时间:2021-02-13 20:19:00

标签: tensorflow keras google-colaboratory seq2seq google-cloud-tpu

我正在尝试在 Google Colab TPU 上使用 Keras 训练用于机器翻译的序列到序列模型。 我有一个可以加载到内存中的数据集,但我必须对其进行预处理才能将其提供给模型。特别是我需要将目标词转换为一个热向量,并且有很多例子我无法在内存中加载整个转换,所以我需要批量制作数据。

我将此函数用作批处理生成器:

def generate_batch_bert(X_ids, X_masks, y, batch_size = 1024):
    ''' Generate a batch of data '''
    while True:
        for j in range(0, len(X_ids), batch_size):
          # batch of encoder and decoder data
          encoder_input_data_ids = X_ids[j:j+batch_size]
          encoder_input_data_masks = X_masks[j:j+batch_size]
          y_decoder = y[j:j+batch_size]
          

          # decoder target and input for teacher forcing
          decoder_input_data = y_decoder[:,:-1]
          decoder_target_seq = y_decoder[:,1:]
          
          # batch of decoder target data
          decoder_target_data = to_categorical(decoder_target_seq, vocab_size_fr)
          # keep only with the right amount of instances for training on TPU
          if encoder_input_data_ids.shape[0] == batch_size:
            yield([encoder_input_data_ids, encoder_input_data_masks, decoder_input_data], decoder_target_data)

问题是,每当我尝试按如下方式运行拟合函数时:

model.fit(x=generate_batch_bert(X_train_ids, X_train_masks, y_train, batch_size = batch_size),
                    steps_per_epoch = train_samples//batch_size,
                    epochs=epochs,
                    callbacks = callbacks,
                    validation_data = generate_batch_bert(X_val_ids, X_val_masks, y_val, batch_size = batch_size),
                    validation_steps = val_samples//batch_size)

我收到以下错误:

/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/tensor_util.py:445 make_tensor_proto
    raise ValueError("None values not supported.")

ValueError: None values not supported.

不知道出了什么问题以及如何解决这个问题。

编辑

我尝试在内存中加载较少量的数据,以便转换为目标词的一种热编码不会使内核崩溃,并且它确实可以工作。所以我生成批次的方式显然有问题。

1 个答案:

答案 0 :(得分:0)

由于您没有提供模型,因此很难说出什么问题 定义或任何样本数据。不过,我很确定你是 遇到同样的 TensorFlow bug 我最近被咬了。

解决方法是使用 tensorflow.data API,它非常有效 使用 TPU 效果更好。像这样:

from tensorflow.data import Dataset
import tensorflow as tf

def map_fn(X_id, X_mask, y):
    decoder_target_data = tf.one_hot(y[1:], vocab_size_fr)
    return (X_id, X_mask, y[:-1]), decoder_target_data
...
X_ids = Dataset.from_tensor_slices(X_ids)
X_masks = Dataset.from_tensor_slices(X_masks)
y = Dataset.from_tensor_slices(y)
ds = Dataset.zip((X_ids, X_masks, y)).map(map_fn).batch(1024)
model.fit(x = ds, ...)