我有一些代码会生成一个CTC
不再适用于 TensorFlow2.7.0
但适用于2.6.1
. 导致问题的有问题的代码是:
class CTCLayer(layers.Layer):
def __init__(self, name=None):
super().__init__(name=name)
self.loss_fn = keras.backend.ctc_batch_cost
def call(self, labels, label_length, predictions): #input_length,
batch_len = tf.cast(tf.shape(labels)[0], dtype="int64")
input_length = tf.cast(tf.shape(predictions)[1], dtype="int64")
label_length = tf.cast(label_length, dtype="int64")#tf.cast(tf.shape(labels)[1], dtype="int64")
input_length = input_length * tf.ones(shape=(batch_len, 1), dtype="int64")
label_length = label_length * tf.ones(shape=(batch_len, 1), dtype="int64")
loss = self.loss_fn(y_true=labels, y_pred=predictions, input_length=input_length, label_length=label_length)#, logits_time_major=False)
self.add_loss(loss)
return predictions
并在模型构建期间调用该函数时崩溃,并ctc_batch_cost
出现以下错误:
ValueError: Exception encountered when calling layer "CTC_LOSS" (type CTCLayer).
追溯:
File "<ipython-input-10-0b2cf7d5ab7d>", line 16, in call *
loss = self.loss_fn(y_true=labels, y_pred=predictions, input_length=input_length, label_length=label_length)#, logits_time_major=False)
File "/usr/local/lib/python3.7/dist-packages/keras/backend.py", line 6388, in ctc_batch_cost
ctc_label_dense_to_sparse(y_true, label_length), tf.int32)
File "/usr/local/lib/python3.7/dist-packages/keras/backend.py", line 6340, in ctc_label_dense_to_sparse
range_less_than, label_lengths, initializer=init, parallel_iterations=1)
ValueError: Input tensor `CTC_LOSS/Cast_5:0` enters the loop with shape (1, 1), but has shape (1, None) after one iteration. To allow the shape to vary across iterations, use the `shape_invariants` argument of tf.while_loop to specify a less-specific shape.
Call arguments received:
• labels=tf.Tensor(shape=(None, 1), dtype=int32)
• label_length=tf.Tensor(shape=(None, 1), dtype=int32)
• predictions=tf.Tensor(shape=(None, 509, 30), dtype=float32)
我怀疑这个问题很容易解决,并且与 TensorFlow 不再执行升级2.7.0
说明中所述的事实有关:
Model.fit()、Model.predict() 和 Model.evaluate() 方法将不再将形状 (batch_size,) 的输入数据提升为 (batch_size, 1)。这使模型子类能够在其 train_step()/test_step()/predict_step() 方法中处理标量数据。请注意,此更改可能会破坏某些子类模型。您可以通过在 train_step()/test_step()/predict_step() 方法中添加自己来恢复到以前的行为,例如 if x.shape.rank == 1: x = tf.expand_dims(x, axis=-1 )。功能模型以及使用显式输入形状构建的顺序模型不受影响。
任何想法将不胜感激。谢谢!