0

我正在做一个项目,我们必须使用 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 文档,我们需要提供 ['y_true','y_pred','input_length','label_length']。我的数据框有 10000 个数据点,我的模型有一个输出层model.add(Dense(78, activation='softmax'))

所以我创建了一个包含 10000 个元素的 78 列表作为 input_length input_length = [78]*10000

我将原始单词的长度转换为 label_length 如下:

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

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

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

编译模型

    model.compile(loss=ctc_loss_func(y_true,y_pred,input_length,label_length), optimizer='adam', metrics=['acc'])
4

1 回答 1

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)

于 2021-07-23T07:54:43.033 回答