Tiny_cnn用自己的数据训练和测试
来源:互联网 发布:爱五子棋打谱软件 编辑:程序博客网 时间:2024/05/29 17:24
Tiny_cnn是一个简洁的纯C++11实现的深度学习框架。在Windows系统只需高版本的VS(VS2013或者更高本)+opencv即可,本人用的是VS2013+opencv2.4.11。关于tiny-cnn的具体细节,很多博客写得很详细。本人只介绍一种基于tiny-cnn快速简单的使用方法。
Tiny_cnn下载地址:https://github.com/nyanp/tiny-cnn
该方法很简单,只需自己准备好训练数据与测试数据。不需要像caffe那样制作标签和转换数据格式。把训练图像放到一个文件夹下,如文件夹train,把所有的图像直接批量重命名,但要保证每一类图像是连续存放的。如图1所示,7张dogs图片(1)—(7)、7张goats图片(8)—(14)、10张cats图片(15)—(24),一共24个训练样本。 测试图像文件夹test与文件夹train一样,只不过样本数量少一点。如图2所示,每一类的顺序与train相同,dog、goat、cat,一共10个测试数据。这样,就可以直接跑程序了。
图1.训练图像集
图2.测试图像集
在程序运行的过程中,加入标签。如图3所示。只需输入每一个类别的个数,程序自动制作标签。
最终结果界面:
对于输出的4*4的表格,第一行0,1,2与第一列0,1,2就是分类的标签。
剩下的3*3,位于对角线上的就是分类正确的,不在对角线上,就是分错的。如图,对角线上只有3,accuracy=3/10。其中,每一列的和就是测试数据中该类的个数。
注:该例子只为说明tiny-cnn训练数据的方法,在真正运用中,样本数量比这多得多。
补充:
运行程序时,很多人反应,准确率accuracy保持不变的情况。针对这个问题,本人今天又测试了一下。
用到的数据:http://download.csdn.net/detail/u012507022/9679177
需要说明几点
(1)此程序的卷积神经网络LeNet,是为手写字体识别设计的网络,所以针对不同的问题,还需选着网络结构。
(2)此程序只能处理灰度图像,虽然读取的是RGB图像,但是imread()直接转换成灰度图了;而且图像也被放缩为 32*32。(处理RGB格式图像的程序在最下面)
(3)刚开始,我使用的.bmp格式的图像;后来证明.jpg图像也可以。
直接上代码:(注:此程序网络为LeNet)
/*tiny-cnn训练*/#include <iostream>#include "tiny_cnn/tiny_cnn.h"#include <opencv2/opencv.hpp>#include<strstream>using namespace std;using namespace cv;using namespace tiny_cnn;using namespace tiny_cnn::activation;//**********************************************************************************////定义全局变量const int TRNUM = 24; //训练样本的个数const int TENUM =10; //测试样本的个数const int C = 3; //分类的个数//**********************************************************************************////定义网络结构void construct_net(network<mse, adagrad>& nn) { // connection table [Y.Lecun, 1998 Table.1]#define O true#define X false static const bool tbl[] = { O, X, X, X, O, O, O, X, X, O, O, O, O, X, O, O, O, O, X, X, X, O, O, O, X, X, O, O, O, O, X, O, O, O, O, X, X, X, O, O, O, X, X, O, X, O, O, O, X, O, O, O, X, X, O, O, O, O, X, X, O, X, O, O, X, X, O, O, O, X, X, O, O, O, O, X, O, O, X, O, X, X, X, O, O, O, X, X, O, O, O, O, X, O, O, O };#undef O#undef X // construct nets nn << convolutional_layer<tan_h>(32, 32, 5, 1, 6) // C1, 1@32x32-in, 6@28x28-out << average_pooling_layer<tan_h>(28, 28, 6, 2) // S2, 6@28x28-in, 6@14x14-out << convolutional_layer<tan_h>(14, 14, 5, 6, 16, connection_table(tbl, 6, 16)) // C3, 6@14x14-in, 16@10x10-in << average_pooling_layer<tan_h>(10, 10, 16, 2) // S4, 16@10x10-in, 16@5x5-out << convolutional_layer<tan_h>(5, 5, 5, 16, 120) // C5, 16@5x5-in, 120@1x1-out << fully_connected_layer<tan_h>(120,C); // F6, 120-in, 10-out}//**********************************************************************************//// convert image to vec_tvoid convert_image(const string& imagefilename,double scale,int w,int h,std::vector<vec_t>& data){auto img = imread(imagefilename, IMREAD_GRAYSCALE);if (img.data == nullptr) return; // cannot open, or it's not an image//imshow("img", img);//cvWaitKey(0);cv::Mat_<uint8_t> resized;cv::resize(img, resized, cv::Size(w, h));vec_t d;std::transform(resized.begin(), resized.end(), std::back_inserter(d),[=](uint8_t c) { return c * scale; });data.push_back(d);}//int 转换stringstring int2string(int&i){strstream ss; string str;ss << i; ss >> str;return str;}int main() {//【第一步】定义网络结构 specify loss-function and learning strategystd::cout << "load models..." << std::endl;network<mse, adagrad> nn;construct_net(nn); //**********************************************************************************////【第二步】加载数据 //加载训练数据std::vector<label_t> train_labels, test_labels;std::vector<vec_t> train_images, test_images;for (int i = 1; i <= TRNUM; i++){string str0 = int2string(i);string trainpath = "E:/2013Mycode/Mytin_cnn/train/animal ("+str0+").jpg"; //训练集路径//转换图像格式convert_image(trainpath, 1.0, 32, 32, train_images);}cout <<"cout << train_images.size():"<< train_images.size()<< endl;//加载训练数据for (int i = 1; i <= TENUM; i++){string str1 = int2string(i);string testpath = "E:/2013Mycode/Mytin_cnn/test/animal (" + str1 + ").jpg"; //测试集路径convert_image(testpath, 1.0, 32, 32, test_images);}cout << "cout << test_images.size():" << test_images.size() << endl;//**********************************************************************************////【第三步】加载标签 手工添加 标签从0开始printf("加载训练集标签\n"); int Ci; //每一类训练样本的个数for (size_t k = 0; k < C; k++){ // C 分类的个数printf("第i类样本的个数:"); scanf("%d", &Ci);for (size_t j = 1; j <= Ci; j++){train_labels.push_back((label_t)k);}}cout<<"train_labels" << train_labels.size() << endl;printf("/加载测试集标签\n"); int Ti; //每一类测试样本的个数for (size_t k = 0; k < C; k++){ // C 分类的个数printf("第i类样本的个数:"); scanf("%d", &Ti);for (size_t j = 1; j <= Ti; j++){test_labels.push_back((label_t)k);}}cout << "test_labels" << test_labels.size() << endl;//**********************************************************************************////【第四步】训练std::cout << "start training" << std::endl;progress_display disp(train_images.size());//进度显示,初始化对象disptimer t;int minibatch_size = 10;int num_epochs = 30; //迭代次数nn.optimizer().alpha *= std::sqrt(minibatch_size);// create callbackauto on_enumerate_epoch = [&](){std::cout << t.elapsed() << "s elapsed." << std::endl;tiny_cnn::result res = nn.test(test_images, test_labels);std::cout << res.num_success << "/" << res.num_total << std::endl;disp.restart(train_images.size());t.restart();};auto on_enumerate_minibatch = [&](){disp += minibatch_size;};// trainingnn.train(train_images, //训练数据train_labels, //标签minibatch_size, num_epochs,on_enumerate_minibatch,on_enumerate_epoch);std::cout << "end training." << std::endl;// test and show resultsnn.test(test_images, test_labels).print_detail(std::cout);// 保存训练好的分类器std::ofstream ofs("LeNet-weights"); ofs << nn;system("pause");}
补充:
运行程序时,可能出现准确率accuracy保持不变的情况。针对这个问题。需要说明几点
(1)此程序的卷积神经网络LeNet,是为手写字体识别设计的网络,所以针对不同的问题,还需选着网络结构。
(2)使用.bmp格式的图像效果比较好,不会出现accuracy不变的情况;可能是因为.bmp是无压缩的。
(3)此程序只能处理灰度图像,虽然读取的是RGB图像,但是imread()直接转换成灰度图了;而且图像也被放缩为 32*32。处理RGB格式图像的程序如下:
void convert_image(const std::string& filename,std::vector<vec_t> &data,float min,float max,int padding){Mat src = imread(filename, -1);int W = src.cols;int H = src.rows;float denominator = 255;vec_t img(3 * (H + 2 * padding)*(W + 2 * padding), min);for (int i = 0; i < H; i++) { // Go over all rowsfor (int j = 0; j < W; j++) { // Go over all columnsfor (int c = 0; c < 3; c++) { // Go through all channelsimg[W*H*c + W*(i + padding) + (j + padding)] = src.at<cv::Vec3b>(i, j)[c]/denominator*(max - min) + min;}}}data.push_back(img);}
我用300个mnist数据的测试结果如下:
- Tiny_cnn用自己的数据训练和测试
- Tiny_cnn用自己的数据训练和测试
- 用自己的数据训练和测试“caffenet”
- Caffe下自己的数据训练和测试
- Caffe下自己的数据训练和测试
- windows-caffe 训练和测试自己的数据集
- Caffe训练和测试自己的数据集
- Caffe训练和测试自己的数据集
- Caffe训练和测试自己的数据集
- FCN制作自己的数据集、训练和测试 caffe
- pytorch: 准备、训练和测试自己的图片数据
- Ubuntu系统,用digist可视化界面实现自己的数据训练和测试
- Caffe_Windows学习笔记(二)用自己的数据训练和测试CaffeNet
- [caffe学习笔记]用自己的数据进行训练和测试
- caffe 训练测试自己的数据集
- caffe训练测试自己的数据集
- Caffe训练、测试自己的图片数据
- windows 训练、微调caffenet 训练测试自己的数据
- KNN算法思想与应用例子
- 图片适配 压缩比例 (纯代码)
- HDU5706 GirlCat
- 从如何提升自己开始吧
- 面对用户的需求设计
- Tiny_cnn用自己的数据训练和测试
- 基础算法之冒泡排序
- abort remove_if of vector
- C++卷积神经网络实例:tiny_cnn代码详解(2)——代码试运行
- http session
- 《众病之王-癌症传》
- Random Forest 实用经验(转)
- TCP /IP 协议-(传输层)TCP 协议
- 糖果机器人_0001_简单的界面设计