为了在我的模型(用TensorFlow 2.1.0版编写)的训练过程中生成更多指标,比如字符错误率(CER)和单词错误率(WER),我创建了一个回调函数传递给我的模型的fit函数,它能够在一个时期结束时生成CER和WER。
这是我的第二个选择,因为我想为此创建一个自定义指标,但你只能使用keras后端功能来自定义指标。有人对如何将下面的回调转换为自定义指标有什么建议吗(然后可以在验证和/或训练数据的训练过程中计算)?
我遇到的一些障碍包括:
- 无法将K.ctc_decode结果转换为稀疏Tensor
- 如何使用Keras后端计算像edit-distance这样的距离?
class Metrics(tf.keras.callbacks.Callback):
def __init__(self, valid_data, steps):
"""
valid_data is a TFRecordDataset with batches of 100 elements per batch, shuffled and repeated infinitely.
steps define the amount of batches per epoch
"""
super(Metrics, self).__init__()
self.valid_data = valid_data
self.steps = steps
def on_train_begin(self, logs={}):
self.cer = []
self.wer = []
def on_epoch_end(self, epoch, logs={}):
imgs = []
labels = []
for idx, (img, label) in enumerate(self.valid_data.as_numpy_iterator()):
if idx >= self.steps:
break
imgs.append(img)
labels.extend(label)
imgs = np.array(imgs)
labels = np.array(labels)
out = self.model.predict((batch for batch in imgs))
input_length = len(max(out, key=len))
out = np.asarray(out)
out_len = np.asarray([input_length for _ in range(len(out))])
decode, log = K.ctc_decode(out,
out_len,
greedy=True)
decode = [[[int(p) for p in x if p != -1] for x in y] for y in decode][0]
for (pred, lab) in zip(decode, labels):
dist = editdistance.eval(pred, lab)
self.cer.append(dist / (max(len(pred), len(lab))))
self.wer.append(not np.array_equal(pred, lab))
print("Mean CER: {}".format(np.mean([self.cer], axis=1)[0]))
print("Mean WER: {}".format(np.mean([self.wer], axis=1)[0]))
2条答案
按热度按时间y3bcpkx11#
已在TF 2.3.1中解决,但也应适用于2.x的先前版本。
一些备注:
on_epoch_end
的显式额外计算),至少我是这么认为的。将其实现为tensorflow.keras.metrics.Metric
的子类似乎是正确的方法,并且在时期正在进行时产生结果(如果verbose被正确设置)。tf.edit_distance
(使用稀疏Tensor)计算CER的编辑距离是相当容易的,这可以随后用于使用某种tf逻辑计算WER。self.model.compile(optimizer=opt, loss=loss, metrics=[CERMetric(), WERMetric()])
第一个
mspsb9vt2#
唉,我还没有找到如何在一个度量中同时实现CER和WER(因为它有相当多的重复代码),如果有人知道如何做到这一点,请与我联系。
嘿,这个解决方案真的帮了我很大的忙。到目前为止,有TensorFlow 2.10版本,所以对于这个版本,我写了一个WER和CER指标的组合,下面是最终的工作代码:
我仍然需要检查它是否计算正确的CER和WER,我会发现有些东西是失踪,我会更新这一点。