|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <dlib/dnn.h> |
|
#include <iostream> |
|
#include <dlib/data_io.h> |
|
|
|
using namespace std; |
|
using namespace dlib; |
|
|
|
|
|
|
|
|
|
template <typename SUBNET> using block_a1 = relu<con<10,1,1,1,1,SUBNET>>; |
|
template <typename SUBNET> using block_a2 = relu<con<10,3,3,1,1,relu<con<16,1,1,1,1,SUBNET>>>>; |
|
template <typename SUBNET> using block_a3 = relu<con<10,5,5,1,1,relu<con<16,1,1,1,1,SUBNET>>>>; |
|
template <typename SUBNET> using block_a4 = relu<con<10,1,1,1,1,max_pool<3,3,1,1,SUBNET>>>; |
|
|
|
|
|
|
|
|
|
template <typename SUBNET> using incept_a = inception4<block_a1,block_a2,block_a3,block_a4, SUBNET>; |
|
|
|
|
|
|
|
|
|
template <typename SUBNET> using block_b1 = relu<con<4,1,1,1,1,SUBNET>>; |
|
template <typename SUBNET> using block_b2 = relu<con<4,3,3,1,1,SUBNET>>; |
|
template <typename SUBNET> using block_b3 = relu<con<4,1,1,1,1,max_pool<3,3,1,1,SUBNET>>>; |
|
template <typename SUBNET> using incept_b = inception3<block_b1,block_b2,block_b3,SUBNET>; |
|
|
|
|
|
|
|
using net_type = loss_multiclass_log< |
|
fc<10, |
|
relu<fc<32, |
|
max_pool<2,2,2,2,incept_b< |
|
max_pool<2,2,2,2,incept_a< |
|
input<matrix<unsigned char>> |
|
>>>>>>>>; |
|
|
|
int main(int argc, char** argv) try |
|
{ |
|
|
|
if (argc != 2) |
|
{ |
|
cout << "This example needs the MNIST dataset to run!" << endl; |
|
cout << "You can get MNIST from http://yann.lecun.com/exdb/mnist/" << endl; |
|
cout << "Download the 4 files that comprise the dataset, decompress them, and" << endl; |
|
cout << "put them in a folder. Then give that folder as input to this program." << endl; |
|
return 1; |
|
} |
|
|
|
|
|
std::vector<matrix<unsigned char>> training_images; |
|
std::vector<unsigned long> training_labels; |
|
std::vector<matrix<unsigned char>> testing_images; |
|
std::vector<unsigned long> testing_labels; |
|
load_mnist_dataset(argv[1], training_images, training_labels, testing_images, testing_labels); |
|
|
|
|
|
|
|
net_type net; |
|
cout << "The net has " << net.num_layers << " layers in it." << endl; |
|
cout << net << endl; |
|
|
|
|
|
cout << "Training NN..." << endl; |
|
dnn_trainer<net_type> trainer(net); |
|
trainer.set_learning_rate(0.01); |
|
trainer.set_min_learning_rate(0.00001); |
|
trainer.set_mini_batch_size(128); |
|
trainer.be_verbose(); |
|
trainer.set_synchronization_file("inception_sync", std::chrono::seconds(20)); |
|
|
|
trainer.train(training_images, training_labels); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
net.clean(); |
|
serialize("mnist_network_inception.dat") << net; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<unsigned long> predicted_labels = net(training_images); |
|
int num_right = 0; |
|
int num_wrong = 0; |
|
|
|
for (size_t i = 0; i < training_images.size(); ++i) |
|
{ |
|
if (predicted_labels[i] == training_labels[i]) |
|
++num_right; |
|
else |
|
++num_wrong; |
|
|
|
} |
|
cout << "training num_right: " << num_right << endl; |
|
cout << "training num_wrong: " << num_wrong << endl; |
|
cout << "training accuracy: " << num_right/(double)(num_right+num_wrong) << endl; |
|
|
|
|
|
|
|
predicted_labels = net(testing_images); |
|
num_right = 0; |
|
num_wrong = 0; |
|
for (size_t i = 0; i < testing_images.size(); ++i) |
|
{ |
|
if (predicted_labels[i] == testing_labels[i]) |
|
++num_right; |
|
else |
|
++num_wrong; |
|
|
|
} |
|
cout << "testing num_right: " << num_right << endl; |
|
cout << "testing num_wrong: " << num_wrong << endl; |
|
cout << "testing accuracy: " << num_right/(double)(num_right+num_wrong) << endl; |
|
|
|
} |
|
catch(std::exception& e) |
|
{ |
|
cout << e.what() << endl; |
|
} |
|
|
|
|