// Helper returns true if the null_char is the winner at t, and it beats the // null_threshold, or the next choice is space, in which case we will use the // null anyway. static bool NullIsBest(const NetworkIO& output, float null_thr, int null_char, int t) { if (output.f(t)[null_char] >= null_thr) return true; if (output.BestLabel(t, null_char, null_char, NULL) != UNICHAR_SPACE) return false; return output.f(t)[null_char] > output.f(t)[UNICHAR_SPACE]; }
// Helper computes min and mean best results in the output. void LSTMRecognizer::OutputStats(const NetworkIO& outputs, float* min_output, float* mean_output, float* sd) { const int kOutputScale = MAX_INT8; STATS stats(0, kOutputScale + 1); for (int t = 0; t < outputs.Width(); ++t) { int best_label = outputs.BestLabel(t, NULL); if (best_label != null_char_ || t == 0) { float best_output = outputs.f(t)[best_label]; stats.add(static_cast<int>(kOutputScale * best_output), 1); } } *min_output = static_cast<float>(stats.min_bucket()) / kOutputScale; *mean_output = stats.mean() / kOutputScale; *sd = stats.sd() / kOutputScale; }
// Converts the network output to a sequence of labels, with scores, using // the simple character model (each position is a char, and the null_char_ is // mainly intended for tail padding.) void LSTMRecognizer::LabelsViaSimpleText(const NetworkIO& output, GenericVector<int>* labels, GenericVector<int>* xcoords) { labels->truncate(0); xcoords->truncate(0); int width = output.Width(); for (int t = 0; t < width; ++t) { float score = 0.0f; int label = output.BestLabel(t, &score); if (label != null_char_) { labels->push_back(label); xcoords->push_back(t); } } xcoords->push_back(width); }