int main (int argc, char* argv[]) { // Initialize CN24 Conv::System::Init(); // Capture command line arguments std::string net_config_fname; if(argc > 1) { net_config_fname = std::string(argv[1]); LOGDEBUG << "Using user specified net: " << net_config_fname; } unsigned int CLASSES = 10; unsigned int INPUTMAPS = 3; unsigned int BENCHMARK_PASSES_FWD = 30; unsigned int BENCHMARK_PASSES_BWD = 15; std::istream* net_config_stream; if(argc > 1) { // Open network and dataset configuration files std::ifstream* net_config_file = new std::ifstream(net_config_fname,std::ios::in); if(!net_config_file->good()) { FATAL("Cannot open net configuration file!"); } net_config_stream = net_config_file; } else { LOGINFO << "Using hardcoded net."; std::stringstream* ss = new std::stringstream(hardcoded_net); net_config_stream = ss; } // Parse network configuration file Conv::ConfigurableFactory* factory = new Conv::ConfigurableFactory(*net_config_stream, 238238, false); // Set image dimensions unsigned int width = 512; unsigned int height = 512; Conv::Tensor data_tensor(factory->optimal_settings().pbatchsize, width, height, INPUTMAPS); data_tensor.Clear(); // Assemble net Conv::NetGraph graph; Conv::InputLayer input_layer(data_tensor); Conv::NetGraphNode input_node(&input_layer); input_node.is_input = true; graph.AddNode(&input_node); bool complete = factory->AddLayers(graph, Conv::NetGraphConnection(&input_node), CLASSES); if (!complete) FATAL("Failed completeness check, inspect model!"); factory->InitOptimalSettings(); LOGINFO << "Initializing net, this may take a while..." << std::flush; graph.Initialize(); graph.SetIsTesting(true); graph.FeedForward(); graph.BackPropagate(); LOGINFO << "Benchmark information"; LOGINFO << "====================="; LOGINFO << "Input width : " << width; LOGINFO << "Input height : " << height; LOGINFO << "Parallel inputs: " << factory->optimal_settings().pbatchsize; LOGINFO << "====================="; LOGINFO << "Running forward benchmark...\n" << std::flush; { auto t_begin = std::chrono::system_clock::now(); for(unsigned int p = 0; p < BENCHMARK_PASSES_FWD; p++) { graph.FeedForward(); std::cout << "." << std::flush; } std::cout << "\n"; auto t_end = std::chrono::system_clock::now(); std::chrono::duration<double> t_diff = t_end - t_begin; double total_pixels = (double)width * (double)height * (double)(factory->optimal_settings().pbatchsize) * (double)BENCHMARK_PASSES_FWD; double total_frames = (double)BENCHMARK_PASSES_FWD * (double)(factory->optimal_settings().pbatchsize); double pixels_per_second = total_pixels / t_diff.count(); double frames_per_second = total_frames / t_diff.count(); LOGINFO << "Forward speed: " << pixels_per_second << " pixel/s"; LOGINFO << "Forward speed: " << frames_per_second << " fps"; LOGINFO << "====================="; } graph.SetIsTesting(false); LOGINFO << "Running forward+backward benchmark...\n" << std::flush; { auto t_begin = std::chrono::system_clock::now(); for(unsigned int p = 0; p < BENCHMARK_PASSES_BWD; p++) { graph.FeedForward(); graph.BackPropagate(); std::cout << "." << std::flush; } std::cout << "\n"; auto t_end = std::chrono::system_clock::now(); std::chrono::duration<double> t_diff = t_end - t_begin; double total_pixels = (double)width * (double)height * (double)(factory->optimal_settings().pbatchsize) * (double)BENCHMARK_PASSES_BWD; double total_frames = (double)BENCHMARK_PASSES_BWD * (double)(factory->optimal_settings().pbatchsize); double pixels_per_second = total_pixels / t_diff.count(); double frames_per_second = total_frames / t_diff.count(); LOGINFO << "F+B speed : " << pixels_per_second << " pixel/s"; LOGINFO << "F+B speed : " << frames_per_second << " fps"; LOGINFO << "====================="; } Conv::Tensor* net_output_tensor = &graph.GetDefaultOutputNode()->output_buffers[0].combined_tensor->data; Conv::Tensor image_output_tensor(1, net_output_tensor->width(), net_output_tensor->height(), 3); //LOGINFO << "Colorizing..." << std::flush; //dataset->Colorize(*net_output_tensor, image_output_tensor); LOGINFO << "DONE!"; LOGEND; return 0; }
int main(int argc, char* argv[]) { if (argc < 2) { LOGERROR << "USAGE: " << argv[0] << " <dataset configuration file>"; LOGEND; return -1; } Conv::System::Init(); // Open tensor stream std::string dataset_config_file(argv[1]); std::ifstream dataset_config_fstream(dataset_config_file, std::ios::in); if(!dataset_config_fstream.good()) { FATAL("Cannot open " << dataset_config_file << "!"); } Conv::Dataset* dataset = Conv::TensorStreamDataset::CreateFromConfiguration(dataset_config_fstream); Conv::Tensor data_tensor(1, dataset->GetWidth(), dataset->GetHeight(), dataset->GetInputMaps()); Conv::Tensor weight_tensor(1, dataset->GetWidth(), dataset->GetHeight(), 1); Conv::Tensor label_tensor(1, dataset->GetWidth(), dataset->GetHeight(), dataset->GetLabelMaps()); Conv::Tensor helper_tensor(1, dataset->GetWidth(), dataset->GetHeight(), 2); std::vector<Conv::datum> class_weights = dataset->GetClassWeights(); std::vector<std::string> class_names = dataset->GetClassNames(); long double* pixel_counts = new long double[dataset->GetClasses()]; long double* pixel_counts_weighted = new long double[dataset->GetClasses()]; for(unsigned int clazz = 0; clazz < dataset->GetClasses(); clazz++) { pixel_counts[clazz] = 0; pixel_counts_weighted[clazz] = 0; } for(unsigned int sample = 0; sample < dataset->GetTrainingSamples(); sample++) { LOGINFO << "Processing sample " << sample+1 << "/" << dataset->GetTrainingSamples() << std::flush; dataset->GetTrainingSample(data_tensor, label_tensor, helper_tensor, weight_tensor, 0, sample); for(unsigned int y = 0; y < dataset->GetHeight(); y++) { for(unsigned int x = 0; x < dataset->GetWidth(); x++) { unsigned int pixel_class = label_tensor.PixelMaximum(x,y,0); Conv::datum weight = *weight_tensor.data_ptr_const(x,y); pixel_counts[pixel_class] += (long double)weight; pixel_counts_weighted[pixel_class] += (long double)(weight * class_weights[pixel_class]); } } } long double total_pixels = 0; long double total_pixels_weighted = 0; long double total_classes = 0; long double total_classes_weighted = 0; for(unsigned int clazz = 0; clazz < dataset->GetClasses(); clazz++) { total_pixels += pixel_counts[clazz]; total_pixels_weighted += pixel_counts_weighted[clazz]; if(pixel_counts[clazz] > 0) total_classes++; if(pixel_counts_weighted[clazz] > 0) total_classes_weighted++; } long double expected_ratio = 1.0 / total_classes; long double expected_ratio_weighted = 1.0 / total_classes_weighted; long double correction_ratio_sum = 0; long double correction_ratio_sum_weighted = 0; for(unsigned int clazz = 0; clazz < dataset->GetClasses(); clazz++) { if(pixel_counts[clazz] > 0) correction_ratio_sum += expected_ratio/(pixel_counts[clazz]/total_pixels); if(pixel_counts_weighted[clazz] > 0) correction_ratio_sum_weighted += expected_ratio_weighted/(pixel_counts_weighted[clazz]/total_pixels_weighted); } // Ignoring weights LOGINFO << "Stats when ignoring weights"; LOGINFO << "==========================="; LOGINFO << "Classes counted: " << total_classes; LOGINFO << "Expected ratio: " << 100.0 * expected_ratio << "%"; for(unsigned int clazz = 0; clazz < dataset->GetClasses(); clazz++) { long double actual_ratio = pixel_counts[clazz]/total_pixels; long double correction_ratio = 0; if(pixel_counts[clazz] > 0) { correction_ratio = expected_ratio / actual_ratio; } LOGINFO << "Class " << std::setw(30) << class_names[clazz] << " | " << std::setw(14) << static_cast<long>(pixel_counts[clazz]) << std::setw(14) << 100.0 * actual_ratio << "%" << std::setw(14) << correction_ratio << std::setw(14) << static_cast<long>(correction_ratio * pixel_counts[clazz]); } // Not ignoring weights LOGINFO << "Stats when not ignoring weights"; LOGINFO << "==========================="; LOGINFO << "Classes counted: " << total_classes_weighted; LOGINFO << "Expected ratio: " << 100.0 * expected_ratio_weighted << "%"; for(unsigned int clazz = 0; clazz < dataset->GetClasses(); clazz++) { long double actual_ratio = pixel_counts_weighted[clazz]/total_pixels_weighted; long double correction_ratio = 0; if(pixel_counts_weighted[clazz] > 0) { correction_ratio = expected_ratio_weighted / actual_ratio; } LOGINFO << "Class " << std::setw(30) << class_names[clazz] << " | " << std::setw(14) << static_cast<long>(pixel_counts_weighted[clazz]) << std::setw(14) << 100.0 * actual_ratio << "%" << std::setw(14) << correction_ratio << std::setw(14) << static_cast<long>(correction_ratio * pixel_counts_weighted[clazz]); } LOGINFO << "DONE!"; LOGEND; return 0; }
int main (int argc, char* argv[]) { if (argc < 6) { LOGERROR << "USAGE: " << argv[0] << " <dataset config file> <net config file> <net parameter tensor> <input image file> <output image file>"; LOGEND; return -1; } // Capture command line arguments std::string output_image_fname (argv[5]); std::string input_image_fname (argv[4]); std::string param_tensor_fname (argv[3]); std::string net_config_fname (argv[2]); std::string dataset_config_fname (argv[1]); // Initialize CN24 Conv::System::Init(); // Open network and dataset configuration files std::ifstream param_tensor_file(param_tensor_fname,std::ios::in | std::ios::binary); std::ifstream net_config_file(net_config_fname,std::ios::in); std::ifstream dataset_config_file(dataset_config_fname,std::ios::in); if(!param_tensor_file.good()) { FATAL("Cannot open param tensor file!"); } if(!net_config_file.good()) { FATAL("Cannot open net configuration file!"); } if(!dataset_config_file.good()) { FATAL("Cannot open dataset configuration file!"); } // Parse network configuration file Conv::ConfigurableFactory* factory = new Conv::ConfigurableFactory(net_config_file, 238238, false); // Parse dataset configuration file Conv::TensorStreamDataset* dataset = Conv::TensorStreamDataset::CreateFromConfiguration(dataset_config_file, true); unsigned int CLASSES = dataset->GetClasses(); // Load image Conv::Tensor original_data_tensor(input_image_fname); // Rescale image unsigned int width = original_data_tensor.width(); unsigned int height = original_data_tensor.height(); if(width & 1) width++; if(height & 1) height++; if(width & 2) width+=2; if(height & 2) height+=2; if(width & 4) width+=4; if(height & 4) height+=4; Conv::Tensor data_tensor(1, width, height, original_data_tensor.maps()); data_tensor.Clear(); Conv::Tensor::CopySample(original_data_tensor, 0, data_tensor, 0); // Assemble net Conv::NetGraph graph; Conv::InputLayer input_layer(data_tensor); Conv::NetGraphNode input_node(&input_layer); input_node.is_input = true; graph.AddNode(&input_node); bool complete = factory->AddLayers(graph, Conv::NetGraphConnection(&input_node), CLASSES); if (!complete) FATAL("Failed completeness check, inspect model!"); graph.Initialize(); // Load network parameters graph.DeserializeParameters(param_tensor_file); graph.SetIsTesting(true); LOGINFO << "Classifying..." << std::flush; graph.FeedForward(); Conv::Tensor* net_output_tensor = &graph.GetDefaultOutputNode()->output_buffers[0].combined_tensor->data; // &net.buffer(output_layer_id)->data; Conv::Tensor image_output_tensor(1, net_output_tensor->width(), net_output_tensor->height(), 3); LOGINFO << "Colorizing..." << std::flush; dataset->Colorize(*net_output_tensor, image_output_tensor); // Recrop image down Conv::Tensor small(1, original_data_tensor.width(), original_data_tensor.height(), 3); for(unsigned int m = 0; m < 3; m++) for(unsigned int y = 0; y < small.height(); y++) for(unsigned int x = 0; x < small.width(); x++) *small.data_ptr(x,y,m,0) = *image_output_tensor.data_ptr_const(x,y,m,0); small.WriteToFile(output_image_fname); LOGINFO << "DONE!"; LOGEND; return 0; }