我正在一个项目中,我们必须使用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)
答案 0 :(得分:0)
损失函数应该只接受 y_true
和 y_pred
。例如:
def foo(y_true, y_pred):
loss = abs(y_true - y_pred) # or other logic
return loss
所以你通常不能将四个值传递给损失函数。您有多种方法可以解决此问题。
如果您不关心长度,您可以为 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'])
您可以将有关 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
您可以编写自定义 keras 层,将计算放在那里,并通过 self.addloss(calculated_ctc_loss)
增加损失