我正在处理一个项目,在该项目中,我们必须使用ctc_batch_cost来表示损失。我定义了返回CTC丢失的函数,并尝试在"model.compile"语句中使用它。但在这里,我不知道如何获得"y_pred"。有人能帮我修复这个"模型.编译"语句吗?
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','put_length','label_length']。我的数据帧有10000个数据点,我的模型有一个输出层model.add(Dense(78, activation='softmax'))
所以我创建了一个78的列表,其中有10000个元素作为input_lengthinput_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'])
损失函数应仅接受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)
添加损失