如何将decode_batch_predictions()方法添加到Keras Captcha OCR模型中?

lee*_*emm 5 ocr decoding keras ctc

当前的Keras Captcha OCR 模型返回 CTC 编码输出,需要推理后解码。

要对其进行解码,需要在推理之后作为单独的步骤运行解码实用函数。

preds = prediction_model.predict(batch_images)
pred_texts = decode_batch_predictions(preds)
Run Code Online (Sandbox Code Playgroud)

解码的效用函数使用keras.backend.ctc_decode,而 又使用贪婪解码器或波束搜索解码器。

# A utility function to decode the output of the network
def decode_batch_predictions(pred):
    input_len = np.ones(pred.shape[0]) * pred.shape[1]
    # Use greedy search. For complex tasks, you can use beam search
    results = keras.backend.ctc_decode(pred, input_length=input_len, greedy=True)[0][0][
        :, :max_length
    ]
    # Iterate over the results and get back the text
    output_text = []
    for res in results:
        res = tf.strings.reduce_join(num_to_char(res)).numpy().decode("utf-8")
        output_text.append(res)
    return output_text
Run Code Online (Sandbox Code Playgroud)

我想使用 Keras 训练 Captcha OCR 模型,该模型返回解码后的 CTC 作为输出,而无需在推理后执行额外的解码步骤。

我将如何实现这一目标?

lee*_*emm 2

实现此目的最可靠的方法是添加一个作为模型定义的一部分调用的方法:

def CTCDecoder():
  def decoder(y_pred):
    input_shape = tf.keras.backend.shape(y_pred)
    input_length = tf.ones(shape=input_shape[0]) * tf.keras.backend.cast(
        input_shape[1], 'float32')
    unpadded = tf.keras.backend.ctc_decode(y_pred, input_length)[0][0]
    unpadded_shape = tf.keras.backend.shape(unpadded)
    padded = tf.pad(unpadded,
                    paddings=[[0, 0], [0, input_shape[1] - unpadded_shape[1]]],
                    constant_values=-1)
    return padded

return tf.keras.layers.Lambda(decoder, name='decode')
Run Code Online (Sandbox Code Playgroud)

然后定义模型如下:

prediction_model = keras.models.Model(inputs=inputs, outputs=CTCDecoder()(model.output))
Run Code Online (Sandbox Code Playgroud)

功劳归于tulasiram58827

此实现支持导出到 TFLite,但仅支持 float32。量化 (int8) TFLite 导出仍然抛出错误,并且是 TF 团队的开放票证。