I have used the following code to test the behaviour of CTC loss.
def get_char_maps (vocab):
char_to_index={}
index_to_char={}
cnt=0
for c in vocab:
char_to_index[c]=cnt
index_to_char[cnt]=c
cnt+=1
vocab_size=cnt
return (char_to_index, index_to_char, vocab_size)
loss_function = CTCLoss()
char_to_index, index_to_char, vocab_size = get_char_maps(['~', 'a', 'b', 'c', 'd', 'e', 'f', 'g', ' '])
empty_char = '~'
label = 'abc'
seq_len = 20
predict = 'abc'
pred_out = predict[0]
for i in range(1, len(predict)):
if predict[i] == predict[i - 1]:
pred_out += empty_char + predict[i]
else:
pred_out += predict[i]
print(pred_out)
predict = pred_out
label_len = len(label)
left_side = (seq_len - len(predict))//2
right_side = seq_len - left_side - len(predict)
seq_predict = [empty_char]*left_side + list(predict) + [empty_char]*right_side
out = []
for char in seq_predict:
temp = [0]*vocab_size
temp[char_to_index[char]] = 1
out.append([temp])
out = torch.FloatTensor(out)
scores = fn.log_softmax(out, dim=2)
out_size = torch.tensor([seq_len]*1, dtype=torch.int)
y_size = torch.tensor([len(label)], dtype=torch.int)
y = [char_to_index[c] for c in label]
y_var = torch.tensor(y, dtype=torch.int)
l = loss_function(scores, y_var, out_size, y_size)
print(l.item())
With this code, when the target is abc
and the prediction is also abc
, it produces a loss of 7.770
. However with same target when the prediction is g
, it produces a loss of 7.654
. Which is lower than the perfect prediction. This behaviour seems counterintuitive.
Is this the expected behaviour from CTC loss? Or is this test code has an error?
Thanks.