| 143 | } |
| 144 | |
| 145 | int main(const int argc, const char** argv) |
| 146 | try |
| 147 | { |
| 148 | // The default settings are fine for the example already. |
| 149 | command_line_parser parser; |
| 150 | parser.add_option("batch", "set the mini batch size per GPU (default: 64)", 1); |
| 151 | parser.add_option("dims", "set the projector dimensions (default: 128)", 1); |
| 152 | parser.add_option("lambda", "off-diagonal terms penalty (default: 1/dims)", 1); |
| 153 | parser.add_option("learning-rate", "set the initial learning rate (default: 1e-3)", 1); |
| 154 | parser.add_option("min-learning-rate", "set the min learning rate (default: 1e-5)", 1); |
| 155 | parser.add_option("num-gpus", "number of GPUs (default: 1)", 1); |
| 156 | parser.add_option("fraction", "fraction of labels to use (default: 0.1)", 1); |
| 157 | parser.add_option("patience", "steps without progress threshold (default: 10000)", 1); |
| 158 | parser.set_group_name("Help Options"); |
| 159 | parser.add_option("h", "alias for --help"); |
| 160 | parser.add_option("help", "display this message and exit"); |
| 161 | parser.parse(argc, argv); |
| 162 | |
| 163 | if (parser.number_of_arguments() < 1 || parser.option("h") || parser.option("help")) |
| 164 | { |
| 165 | cout << "This example needs the CIFAR-10 dataset to run." << endl; |
| 166 | cout << "You can get CIFAR-10 from https://www.cs.toronto.edu/~kriz/cifar.html" << endl; |
| 167 | cout << "Download the binary version the dataset, decompress it, and put the 6" << endl; |
| 168 | cout << "bin files in a folder. Then give that folder as input to this program." << endl; |
| 169 | parser.print_options(); |
| 170 | return EXIT_SUCCESS; |
| 171 | } |
| 172 | |
| 173 | parser.check_option_arg_range("fraction", 0.0, 1.0); |
| 174 | const double labels_fraction = get_option(parser, "fraction", 0.1); |
| 175 | const size_t num_gpus = get_option(parser, "num-gpus", 1); |
| 176 | const size_t batch_size = get_option(parser, "batch", 64) * num_gpus; |
| 177 | const long dims = get_option(parser, "dims", 128); |
| 178 | const double lambda = get_option(parser, "lambda", 1.0 / dims); |
| 179 | const double learning_rate = get_option(parser, "learning-rate", 1e-3); |
| 180 | const double min_learning_rate = get_option(parser, "min-learning-rate", 1e-5); |
| 181 | const size_t patience = get_option(parser, "patience", 10000); |
| 182 | |
| 183 | // Load the CIFAR-10 dataset into memory. |
| 184 | std::vector<matrix<rgb_pixel>> training_images, testing_images; |
| 185 | std::vector<unsigned long> training_labels, testing_labels; |
| 186 | load_cifar_10_dataset(parser[0], training_images, training_labels, testing_images, testing_labels); |
| 187 | |
| 188 | // Initialize the model with the specified projector dimensions and lambda. |
| 189 | // According to the second paper, lambda = 1/dims works well on CIFAR-10. |
| 190 | model::train net((loss_barlow_twins_(lambda))); |
| 191 | layer<1>(net).layer_details().set_num_outputs(dims); |
| 192 | disable_duplicative_biases(net); |
| 193 | dlib::rand rnd; |
| 194 | std::vector<int> gpus(num_gpus); |
| 195 | iota(gpus.begin(), gpus.end(), 0); |
| 196 | |
| 197 | // Train the feature extractor using the Barlow Twins method on all the training |
| 198 | // data. |
| 199 | { |
| 200 | dnn_trainer<model::train, adam> trainer(net, adam(1e-6, 0.9, 0.999), gpus); |
| 201 | trainer.set_mini_batch_size(batch_size); |
| 202 | trainer.set_learning_rate(learning_rate); |
nothing calls this directly
no test coverage detected