Training CNN for NIST digits using tiny-dnn
I have been trying to train a CNN using tiny-dnn library for digit recognition. The database used was NIST 19. The
number of samples per class is 1000 for training and 30 for testing. So total number of samples for training is
1000*10=10000. OpenCV is used for image processing. The maximum accuracy obtained was 40%. Is this due to low number of samples? How to improve the accuracy?
The code is given below
ConvolutionalNN::train()
{
network<sequential> net;
// add layers
net << conv(32, 32, 5, 1, 6) << tiny_dnn::activation::tanh() // in:32x32x1, 5x5conv, 6fmaps
<< ave_pool(28, 28, 6, 2) << tiny_dnn::activation::tanh() // in:28x28x6, 2x2pooling
<< fc(14 * 14 * 6, 120) << tiny_dnn::activation::tanh() // in:14x14x6, out:120
<< fc(120, 10); // in:120, out:10
assert(net.in_data_size() == 32 * 32);
assert(net.out_data_size() == 10);
DatabaseReader db;
db.readTrainingFiles();
// hold labels -> training filenames
std::vector<int> labels = db.getTrainLabels();
std::vector<std::string> trainingFilenames = db.getTrainFileNames();
std::vector<label_t> train_labels;
std::vector<vec_t> train_images;
// loop over training files
for(int index=0; index<trainingFilenames.size(); index++)
{
// output on which file we are training
std::cout << "Analyzing label -> file: " << labels[index] << "|" << trainingFilenames[index] << std::endl;
// read image file (grayscale)
cv::Mat imgMat = cv::imread(trainingFilenames[index], 0);
Mat nonZero;
Mat invert = 255 - imgMat;
findNonZero(invert, nonZero);
Rect bb = boundingRect(nonZero);
Mat img = invert(bb);
int w=32, h=32,scale=1;
cv::Mat resized;
cv::resize(img, resized, cv::Size(w, h));
imshow("img", resized);
waitKey(30);
//convert to float
resized.convertTo(resized, CV_32FC1);
cv::normalize(resized,resized, -1, 1, NORM_MINMAX);
//convert to vec_t
vec_t d;
tiny_dnn::float_t *ptr = resized.ptr<tiny_dnn::float_t>(0);
d = tiny_dnn::vec_t(ptr, ptr + resized.cols * resized.rows );
train_images.push_back(d);
train_labels.push_back(labels[index]);
}
// declare optimization algorithm
adagrad optimizer;
cout << "Training Started" << endl;
// train (50-epoch, 30-minibatch)
net.train<mse, adagrad>(optimizer, train_images, train_labels, 30, 50);
cout << "Training Completed" << endl;
// save
net.save("net");
}
Thanks Amal
ok.. i will try this out The mnist database example in the tiny-dnn website does a -1 to 1 normalisation. This is the reason for doing so.
yes, i've seen that, too. (and redacted that part of the comment)
and in mnist digits they are getting more than 98% accuracy with this architecture..so the doubt.
"in mnist digits they are getting more than 98% accuracy" a link?
32x32 in mnist data base? it is 28*28
link text
This is the link
The change in size should be because of padding
@LBerger, yes, the original images are 28x28, but they add 2px padding
Using caffe with 1000*10 images( I'm not sure that there is 1000 images per class) I have got
and proto.txt is here
That is 97% accuracy..on mnist.. right So I wonder why we are not getting accuracy on NIST (link text
In database do you read only digit (30->39) and do you shuffle data?