为了在训练我的模型(用 TensorFlow 版本 2.1.0 编写)期间产生更多指标,例如字符错误率 (CER) 和字错误率 (WER),我创建了一个回调以传递给我的 fit 函数模型。它能够在一个纪元结束时生成 CER 和 WER。这是我的第二选择,因为我想为此创建一个自定义指标,但您只能将 Keras 后端功能用于自定义指标。有没有人对如何将下面的回调转换为自定义指标(然后可以在验证和/或训练数据的训练期间计算)有任何建议?
我遇到的一些障碍是:
- 未能将 K.ctc_decode 结果转换为稀疏张量
- 如何使用 Keras 后端计算像 editdistance 这样的距离?
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 defines 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]))