Как работает 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.