Как работает tf.nn.ctc_greedy_decoder

Я пытаюсь понять как работает tf.nn.ctc_greedy_decoder. Моя модель выдает тензор размера [тайм, батч_сайз, нум_классес]. Для обучения я использую tf.nn.ctc_loss. Для получения декодера я делаю так:

seqLen = tf.Variable([32]*batch_size, dtype=tf.int32)
y_ = model(input)
loss = tf.nn.ctc_loss(labels=y, inputs=y_, sequence_length=seqLen)
decoder = tf.argmax(tf.transpose(y_, [1,0,2]), axis=-1)
ctc_decoder = tf.nn.ctc_greedy_decoder(inputs=y_, sequence_length=seqlen, merge_repeated=True)

для получения строки из decoder - так:

def decoderOutputToText_(pred, charList):
    rec = []
    p = -1
    for i in pred:
        w = ""
        for j in i:
            if j != len(charList) and j != p:
                w+=charList[j]
                p = j
        rec.append(w)
    return rec

для получения строки из ctc_decoder - так:

def decoderOutputToText(ctcOutput, batchSize, charList):
    "extract texts from output of CTC decoder"
    
    # contains string of labels for each batch element
    encodedLabelStrs = [[] for i in range(batchSize)]
    # ctc returns tuple, first element is SparseTensor 
    decoded=ctcOutput[0][0] 

    # go over all indices and save mapping: batch -> values
    idxDict = { b : [] for b in range(batchSize) }
    for (idx, idx2d) in enumerate(decoded.indices):
        label = decoded.values[idx]
        batchElement = idx2d[0] # index according to [b,t]
        encodedLabelStrs[batchElement].append(label)

    # map labels to chars for all batch elements
    return [str().join([charList[c] for c in labelStr]) for labelStr in encodedLabelStrs]

Так вот проблема в том, что ctc_decoder и decoder выдают разные результаты. ctc_decoder лучше чем decoder и выдает повторяющиеся символы.

Есть подозрение что tf.nn.ctc_loss создает набор весов на которые потом умножается inputs из ctc_greedy_decoder перед декодированием.

Я планирую импортировать модель в tensorrt, а там нет аналога ctc_greedy_decoder.


Ответы (0 шт):