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