float compute_reject_threshold(WERD_CHOICE* word) { float threshold; // rejection threshold float bestgap = 0.0f; // biggest gap float gapstart; // bottom of gap // super iterator BLOB_CHOICE_IT choice_it; // real iterator int blob_count = word->length(); GenericVector<float> ratings; ratings.init_to_size(blob_count, 0.0f); for (int i = 0; i < blob_count; ++i) { ratings[i] = word->certainty(i); } ratings.sort(); gapstart = ratings[0] - 1; // all reject if none better if (blob_count >= 3) { for (int index = 0; index < blob_count - 1; index++) { if (ratings[index + 1] - ratings[index] > bestgap) { bestgap = ratings[index + 1] - ratings[index]; // find biggest gapstart = ratings[index]; } } } threshold = gapstart + bestgap / 2; return threshold; }
// Runs forward propagation of activations on the input line. // See NetworkCpp for a detailed discussion of the arguments. void Parallel::Forward(bool debug, const NetworkIO& input, const TransposedArray* input_transpose, NetworkScratch* scratch, NetworkIO* output) { bool parallel_debug = false; // If this parallel is a replicator of convolvers, or holds a 1-d LSTM pair, // or a 2-d LSTM quad, do debug locally, and don't pass the flag on. if (debug && type_ != NT_PARALLEL) { parallel_debug = true; debug = false; } int stack_size = stack_.size(); if (type_ == NT_PAR_2D_LSTM) { // Special case, run parallel in parallel. GenericVector<NetworkScratch::IO> results; results.init_to_size(stack_size, NetworkScratch::IO()); for (int i = 0; i < stack_size; ++i) { results[i].Resize(input, stack_[i]->NumOutputs(), scratch); } #ifdef _OPENMP #pragma omp parallel for num_threads(stack_size) #endif for (int i = 0; i < stack_size; ++i) { stack_[i]->Forward(debug, input, nullptr, scratch, results[i]); } // Now pack all the results (serially) into the output. int out_offset = 0; output->Resize(*results[0], NumOutputs()); for (int i = 0; i < stack_size; ++i) { out_offset = output->CopyPacking(*results[i], out_offset); } } else { // Revolving intermediate result. NetworkScratch::IO result(input, scratch); // Source for divided replicated. NetworkScratch::IO source_part; TransposedArray* src_transpose = nullptr; if (IsTraining() && type_ == NT_REPLICATED) { // Make a transposed copy of the input. input.Transpose(&transposed_input_); src_transpose = &transposed_input_; } // Run each network, putting the outputs into result. int out_offset = 0; for (int i = 0; i < stack_size; ++i) { stack_[i]->Forward(debug, input, src_transpose, scratch, result); // All networks must have the same output width if (i == 0) { output->Resize(*result, NumOutputs()); } else { ASSERT_HOST(result->Width() == output->Width()); } out_offset = output->CopyPacking(*result, out_offset); } } if (parallel_debug) { DisplayForward(*output); } }
// Displays the segmentation state of *this (if not the same as the last // one displayed) and waits for a click in the window. void WERD_CHOICE::DisplaySegmentation(TWERD* word) { #ifndef GRAPHICS_DISABLED // Number of different colors to draw with. const int kNumColors = 6; static ScrollView *segm_window = NULL; // Check the state against the static prev_drawn_state. static GenericVector<int> prev_drawn_state; bool already_done = prev_drawn_state.size() == length_; if (!already_done) prev_drawn_state.init_to_size(length_, 0); for (int i = 0; i < length_; ++i) { if (prev_drawn_state[i] != state_[i]) { already_done = false; } prev_drawn_state[i] = state_[i]; } if (already_done || word->blobs.empty()) return; // Create the window if needed. if (segm_window == NULL) { segm_window = new ScrollView("Segmentation", 5, 10, 500, 256, 2000.0, 256.0, true); } else { segm_window->Clear(); } TBOX bbox; int blob_index = 0; for (int c = 0; c < length_; ++c) { ScrollView::Color color = static_cast<ScrollView::Color>(c % kNumColors + 3); for (int i = 0; i < state_[c]; ++i, ++blob_index) { TBLOB* blob = word->blobs[blob_index]; bbox += blob->bounding_box(); blob->plot(segm_window, color, color); } } segm_window->ZoomToRectangle(bbox.left(), bbox.top(), bbox.right(), bbox.bottom()); segm_window->Update(); window_wait(segm_window); #endif }