| 157 | // ---------------------------------------------------------------------------------------- |
| 158 | |
| 159 | int main(int argc, char** argv) try |
| 160 | { |
| 161 | if (argc < 2 || argc > 3) |
| 162 | { |
| 163 | cout << "To run this program you need a copy of the PASCAL VOC2012 dataset." << endl; |
| 164 | cout << endl; |
| 165 | cout << "You call this program like this: " << endl; |
| 166 | cout << "./dnn_semantic_segmentation_train_ex /path/to/VOC2012 [minibatch-size]" << endl; |
| 167 | return 1; |
| 168 | } |
| 169 | |
| 170 | cout << "\nSCANNING PASCAL VOC2012 DATASET\n" << endl; |
| 171 | |
| 172 | const auto listing = get_pascal_voc2012_train_listing(argv[1]); |
| 173 | cout << "images in dataset: " << listing.size() << endl; |
| 174 | if (listing.size() == 0) |
| 175 | { |
| 176 | cout << "Didn't find the VOC2012 dataset. " << endl; |
| 177 | return 1; |
| 178 | } |
| 179 | |
| 180 | // a mini-batch smaller than the default can be used with GPUs having less memory |
| 181 | const unsigned int minibatch_size = argc == 3 ? std::stoi(argv[2]) : 23; |
| 182 | cout << "mini-batch size: " << minibatch_size << endl; |
| 183 | |
| 184 | const double initial_learning_rate = 0.1; |
| 185 | const double weight_decay = 0.0001; |
| 186 | const double momentum = 0.9; |
| 187 | |
| 188 | bnet_type bnet; |
| 189 | dnn_trainer<bnet_type> trainer(bnet,sgd(weight_decay, momentum)); |
| 190 | trainer.be_verbose(); |
| 191 | trainer.set_learning_rate(initial_learning_rate); |
| 192 | trainer.set_synchronization_file("pascal_voc2012_trainer_state_file.dat", std::chrono::minutes(10)); |
| 193 | // This threshold is probably excessively large. |
| 194 | trainer.set_iterations_without_progress_threshold(5000); |
| 195 | // Since the progress threshold is so large might as well set the batch normalization |
| 196 | // stats window to something big too. |
| 197 | set_all_bn_running_stats_window_sizes(bnet, 1000); |
| 198 | |
| 199 | // Output training parameters. |
| 200 | cout << endl << trainer << endl; |
| 201 | |
| 202 | std::vector<matrix<rgb_pixel>> samples; |
| 203 | std::vector<matrix<uint16_t>> labels; |
| 204 | |
| 205 | // Start a bunch of threads that read images from disk and pull out random crops. It's |
| 206 | // important to be sure to feed the GPU fast enough to keep it busy. Using multiple |
| 207 | // thread for this kind of data preparation helps us do that. Each thread puts the |
| 208 | // crops into the data queue. |
| 209 | dlib::pipe<training_sample> data(200); |
| 210 | auto f = [&data, &listing](time_t seed) |
| 211 | { |
| 212 | dlib::rand rnd(time(0)+seed); |
| 213 | matrix<rgb_pixel> input_image; |
| 214 | matrix<rgb_pixel> rgb_label_image; |
| 215 | matrix<uint16_t> index_label_image; |
| 216 | training_sample temp; |
nothing calls this directly
no test coverage detected