在Tensorflow2.0中进行模型训练的CTC_Loss

时间:2020-09-13 04:53:03

标签: tensorflow ctc

我正在一个项目中,我们必须使用ctc_batch_cost进行损失。我定义了返回CTC损失的函数,并尝试在“ model.compile”语句中使用它。但是在这里,我不知道如何获得“ y_pred”。有人可以帮我修复此“ model.compile”语句吗?

CTC损失功能

    def ctc_loss_func(args):
       y_pred, labels, input_length, label_length = args
       return K.ctc_batch_cost(labels, y_pred, input_length, label_length)

根据tensorflow文档here,我们需要提供['y_true','y_pred','input_length','label_length']。我的数据框有10000个数据点,模型的输出层为{{ 1}}

所以我创建了一个包含10000个元素的78s列表作为input_length model.add(Dense(78, activation='softmax'))

我将原始单词的长度输入到label_length中,如下所示:

input_length = [78]*10000

我已经将样本中的每个单词编码为一个包含78个字符的向量,并创建了一个大小为(10000,78)的数组。我将其传递为y_true

但是在编译模型之前如何获得y_pred?我应该首先使用其他损失函数(例如“ categorical_cross_entropy”)编译并训练模型以获得y_pred吗?如果是,那是否意味着我必须编译和训练我的模型两次。首先使用“ categorical_cross_entropy”,然后使用“ ctc_loss”

编译模型

    label_length = []
    for item in y.iteritems():
       tex = item[1]
       l = len(tex)
       label_length.append(l)

1 个答案:

答案 0 :(得分:0)

损失函数应该只接受 y_truey_pred。例如:

def foo(y_true, y_pred):
    loss = abs(y_true - y_pred) # or other logic
    return loss

所以你通常不能将四个值传递给损失函数。您有多种方法可以解决此问题。

  1. 如果您不关心长度,您可以为 ctc_batch_cost 编写一个包装器,或者它们是常量并将它们硬编码为常量或将它们作为张量的维度:

    def ctc_loss(y_true, y_pred):
        batch_size = tf.shape(y_true)[0]
        input_length = tf.shape(y_pred)[1]
        label_length = tf.shape(y_true)[1]
    
        input_length = input_length * tf.ones(shape=(batch_size, 1), dtype="int64")
        label_length = label_length * tf.ones(shape=(batch_size, 1), dtype="int64")
        loss = K.ctc_batch_cost(y_true,y_pred,input_length,label_length)
    
        return loss
    # Now you can compile model
    model.compile(loss=ctc_loss, optimizer='adam', metrics=['acc'])
    
  2. 您可以将有关 input_length 的信息连接到您的 y_true 并在 ctc_loss 函数中提取:

    def ctc_loss(y_true, y_pred):
        batch_size = tf.shape(y_true)[0]
    
        input_length = tf.shape(y_pred)[1]
        label_length = y_true[:,-1:]
        y_true = y_true[:,:-1]
        input_length = input_length * tf.ones(shape=(batch_size, 1), dtype="int64")
        label_length = label_length * tf.ones(shape=(batch_size, 1), dtype="int64")
        loss = K.ctc_batch_cost(y_true,y_pred,input_length,label_length)
    
        return loss
    
  3. 您可以编写自定义 keras 层,将计算放在那里,并通过 self.addloss(calculated_ctc_loss) 增加损失