// 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]; }
// Prints debug output detailing activations and 2nd choice over a range // of positions. void LSTMRecognizer::DebugActivationRange(const NetworkIO& outputs, const char* label, int best_choice, int x_start, int x_end) { tprintf("%s=%d On [%d, %d), scores=", label, best_choice, x_start, x_end); double max_score = 0.0; double mean_score = 0.0; int width = x_end - x_start; for (int x = x_start; x < x_end; ++x) { const float* line = outputs.f(x); double score = line[best_choice] * 100.0; if (score > max_score) max_score = score; mean_score += score / width; int best_c = 0; double best_score = 0.0; for (int c = 0; c < outputs.NumFeatures(); ++c) { if (c != best_choice && line[c] > best_score) { best_c = c; best_score = line[c]; } } tprintf(" %.3g(%s=%d=%.3g)", score, DecodeSingleLabel(best_c), best_c, best_score * 100.0); } tprintf(", Mean=%g, max=%g\n", mean_score, max_score); }
// 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; }