如何解决在Tensorflow2.0中进行模型训练的CTC_Loss
我正在一个项目中,我们必须使用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,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)
解决方法
损失函数应该只接受 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,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,label_length) return loss
-
您可以编写自定义 keras 层,将计算放在那里,并通过
self.addloss(calculated_ctc_loss)
增加损失
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。