| 128 | // ---------------------------------------------------------------------------------------- |
| 129 | |
| 130 | int main(int argc, char** argv) try |
| 131 | { |
| 132 | if (argc != 2) |
| 133 | { |
| 134 | cout << "This example needs the MNIST dataset to run!" << endl; |
| 135 | cout << "You can get MNIST from http://yann.lecun.com/exdb/mnist/" << endl; |
| 136 | cout << "Download the 4 files that comprise the dataset, decompress them, and" << endl; |
| 137 | cout << "put them in a folder. Then give that folder as input to this program." << endl; |
| 138 | return 1; |
| 139 | } |
| 140 | |
| 141 | std::vector<matrix<unsigned char>> training_images; |
| 142 | std::vector<unsigned long> training_labels; |
| 143 | std::vector<matrix<unsigned char>> testing_images; |
| 144 | std::vector<unsigned long> testing_labels; |
| 145 | load_mnist_dataset(argv[1], training_images, training_labels, testing_images, testing_labels); |
| 146 | |
| 147 | |
| 148 | // dlib uses cuDNN under the covers. One of the features of cuDNN is the |
| 149 | // option to use slower methods that use less RAM or faster methods that use |
| 150 | // a lot of RAM. If you find that you run out of RAM on your graphics card |
| 151 | // then you can call this function and we will request the slower but more |
| 152 | // RAM frugal cuDNN algorithms. |
| 153 | set_dnn_prefer_smallest_algorithms(); |
| 154 | |
| 155 | |
| 156 | // Create a network as defined above. This network will produce 10 outputs |
| 157 | // because that's how we defined net_type. However, fc layers can have the |
| 158 | // number of outputs they produce changed at runtime. |
| 159 | net_type net; |
| 160 | // So if you wanted to use the same network but override the number of |
| 161 | // outputs at runtime you can do so like this: |
| 162 | net_type net2(num_fc_outputs(15)); |
| 163 | |
| 164 | // Now, let's imagine we wanted to replace some of the relu layers with |
| 165 | // prelu layers. We might do it like this: |
| 166 | using net_type2 = loss_multiclass_log<fc<number_of_classes, |
| 167 | avg_pool_everything< |
| 168 | pres<res<res<res_down< // 2 prelu layers here |
| 169 | tag4<repeat<9,pres, // 9 groups, each containing 2 prelu layers |
| 170 | res_down< |
| 171 | res< |
| 172 | input<matrix<unsigned char>> |
| 173 | >>>>>>>>>>>; |
| 174 | |
| 175 | // prelu layers have a floating point parameter. If you want to set it to |
| 176 | // something other than its default value you can do so like this: |
| 177 | net_type2 pnet(prelu_(0.2), |
| 178 | prelu_(0.25), |
| 179 | repeat_group(prelu_(0.3),prelu_(0.4)) // Initialize all the prelu instances in the repeat |
| 180 | // layer. repeat_group() is needed to group the |
| 181 | // things that are part of repeat's block. |
| 182 | ); |
| 183 | // As you can see, a network will greedily assign things given to its |
| 184 | // constructor to the layers inside itself. The assignment is done in the |
| 185 | // order the layers are defined, but it will skip layers where the |
| 186 | // assignment doesn't make sense. |
| 187 |
nothing calls this directly
no test coverage detected