【问题标题】:ValueError: None values not supported. Code working properly on CPU/GPU but not on TPUValueError:不支持任何值。代码在 CPU/GPU 上正常工作,但在 TPU 上不能正常工作
【发布时间】:2021-12-13 12:51:28
【问题描述】:

我正在尝试训练一个用于语言翻译的 seq2seq 模型,并且我正在 Google Colab 上从 Kaggle Notebook 复制粘贴代码。该代码在 CPU 和 GPU 上运行良好,但在 TPU 上训练时给了我错误。 here 已经问过同样的问题。

这是我的代码:

    strategy = tf.distribute.experimental.TPUStrategy(resolver)
    
    with strategy.scope():
      model = create_model()
      model.compile(optimizer = 'rmsprop', loss = 'categorical_crossentropy')
    
    model.fit_generator(generator = generate_batch(X_train, y_train, batch_size = batch_size),
                        steps_per_epoch = train_samples // batch_size,
                        epochs = epochs,
                        validation_data = generate_batch(X_test, y_test, batch_size = batch_size),
                        validation_steps = val_samples // batch_size)

追溯:

Epoch 1/2
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-60-940fe0ee3c8b> in <module>()
      3                     epochs = epochs,
      4                     validation_data = generate_batch(X_test, y_test, batch_size = batch_size),
----> 5                     validation_steps = val_samples // batch_size)

10 frames
/usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/func_graph.py in wrapper(*args, **kwargs)
    992           except Exception as e:  # pylint:disable=broad-except
    993             if hasattr(e, "ag_error_metadata"):
--> 994               raise e.ag_error_metadata.to_exception(e)
    995             else:
    996               raise

ValueError: in user code:
    /usr/local/lib/python3.7/dist-packages/keras/engine/training.py:853 train_function  *
    return step_function(self, iterator)
    /usr/local/lib/python3.7/dist-packages/keras/engine/training.py:842 step_function  **
    outputs = model.distribute_strategy.run(run_step, args=(data,))
...
ValueError: None values not supported.

我无法弄清楚错误,我认为错误是因为这个generate_batch函数:

X, y = lines['english_sentence'], lines['hindi_sentence']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 34)

def generate_batch(X = X_train, y = y_train, batch_size = 128):
    while True:
        for j in range(0, len(X), batch_size):
 
            encoder_input_data = np.zeros((batch_size, max_length_src), dtype='float32')
            decoder_input_data = np.zeros((batch_size, max_length_tar), dtype='float32')
            decoder_target_data = np.zeros((batch_size, max_length_tar, num_decoder_tokens), dtype='float32')
            
            for i, (input_text, target_text) in enumerate(zip(X[j:j + batch_size], y[j:j + batch_size])):
                for t, word in enumerate(input_text.split()):
                    encoder_input_data[i, t] = input_token_index[word]
                for t, word in enumerate(target_text.split()):
                    if t<len(target_text.split())-1:
                        decoder_input_data[i, t] = target_token_index[word]
                    if t>0:

                        decoder_target_data[i, t - 1, target_token_index[word]] = 1.
            yield([encoder_input_data, decoder_input_data], decoder_target_data)

我的 Colab 笔记本 - here
Kaggle 数据集 - here
TensorFlow 版本 - 2.6

编辑 - 请不要告诉我将 TensorFlow/Keras 版本降级为 1.x。我可以将其降级为TensorFlow 2.0, 2.1, 2.3,但不能降级为1.x。我不明白TensorFlow 1.x。此外,使用 3 年前的版本没有任何意义。

【问题讨论】:

  • 您的数据集是否有 None/Null 值?您使用的是什么版本的 Tensorflow?它应该可以在 TF 2.5+ 上正常工作。
  • @Gagik, TF 2.6 :是的,它有一些 NaN 值,我已经删除了它们,但它仍然给我同样的错误。
  • 我查看了您的代码,但您没有将 OOV 标记添加到您的词汇表中(+1)如果一个看不见的单词进入模型会发生什么?
  • 你能试试这样的虚拟数据模型吗? xx = [np.random.rand(20,30), np.random.rand(20,30)] yy = np.random.rand(20,30) model.fit(x=xx, y=yy, epochs = 2)我无法弄清楚您的模型输入输出形状。如果您尝试在 TPU 上使用虚拟数据,也许我们可以了解错误在哪里
  • 哦,好吧,我以为你设计了这个模型。 Cpu 和 gpu 训练发生在一个处理器上,但对于 tpu 训练:模型为每个 tpu 内核镜像自身。因此,您需要更加谨慎地重新分配损失和其他指标

标签: python tensorflow machine-learning deep-learning tpu


【解决方案1】:

如您提供的链接中的参考答案所述,tensorflow.data API 更适用于 TPU。为了适应您的情况,请尝试在 generate_batch 函数中使用 return 而不是 yield

def generate_batch(X = X_train, y = y_train, batch_size = 128):
    ...
    return encoder_input_data, decoder_input_data, decoder_target_dat

encoder_input_data, decoder_input_data, decoder_target_data = generate_batch(X_train, y_train, batch_size=128)

然后使用tensorflow.data 构造您的数据:

from tensorflow.data import Dataset

encoder_input_data = Dataset.from_tensor_slices(encoder_input_data)
decoder_input_data = Dataset.from_tensor_slices(decoder_input_data)
decoder_target_data = Dataset.from_tensor_slices(decoder_target_data)
ds = Dataset.zip((encoder_input_data, decoder_input_data, decoder_target_data)).map(map_fn).batch(1024)

map_fn 定义为:

def map_fn(encoder_input ,decoder_input, decoder_target):
    return (encoder_input ,decoder_input), decoder_target

最后用Model.fit代替Model.fit_generator

model.fit(x=ds, epochs=epochs)

【讨论】:

    【解决方案2】:

    您需要更新 Keras,您的问题将得到解决

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    • 我用的是TensorFlow 2.6(包括Keras),2.6是最新版本,不能再更新了。
    【解决方案3】:

    需要降级到 Keras 1.0.2 如果有效,那就太好了,否则我会告诉其他解决方案。

    【讨论】:

    • 不,我想使用 TensorFlow 和 Keras 2.x。我不明白 1.x 版本。你能告诉我任何使用 2.x 的解决方案吗?
    猜你喜欢
    • 1970-01-01
    • 2019-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    相关资源
    最近更新 更多