caffe用自己的数据训练模型,并测试输出图片类别
来源:互联网 发布:淘宝卖家发货怎么打印 编辑:程序博客网 时间:2024/04/30 09:01
一、制作自己的数据集
首先将所有图片放在一个文件夹中,文件夹中根据类别建几个子文件夹,每个子文件夹放某一类所有图片,并根据类别编号。
如我这里是要对stanfdog数据集进行分类,该数据集总共有20580张狗狗的图片,分成120类,每类狗的图片张数不一样但相差不是很大. 我的狗狗图片放在Stanford-Dogs(文件夹命名最好不要出现空格,避免中文)中,Stanford-Dogs 中有些子文件夹,每个子文件夹代表一类,子文件夹中放该类狗的图片
我这里把训练用的图片集和训练用的图片集放在一起了,你也可以把训练图片集和验证图片集分开放。
然后可以用下面的matlab代码,生成||图片路径/图片名 类别名||的trainval.txt文件,和||类别编号 类别名||的labels.txt文件,进而生成训练集的||图片路径/图片名 类别名||的train.txt文件,||图片路径/图片名 类别名||val.txt文件。( 注在生成trainval.txt和labels.txt后注意检查下生成的文件内容对不对,有时可能会出现一些其他乱七八糟的符号,直接删除保存就好,再生成train.txt和val.txt,Stanford-Dogs文件夹下不要包含其他无关文件)
clc; clear; %%下面生成顺序的trainval.txt和labels文件 %先设置train占数据集的百分比,余下部分为val % maindir='caffe-new/data/Stanford-Dogs/'; maindir='/home/nielsen/caffe-new/data/Stanford-Dogs/'; %图片文件夹存放路径,注意这里windows下是‘\',linnux下是'/' wf = fopen('trainval.txt','w'); lbf=fopen('labels.txt','w'); train_percent=0.6;%val_percent=1-train_percent subdir = dir(maindir); %获取图片目录下的子目录个数(注意这里最好不要放除子图片文件夹以外的文件夹和文件,否则会一起统计进去) ii=-1; numoffile=0; for i = 1:length(subdir)%第一层目录 if ~strcmp(subdir(i).name ,'.') && ~strcmp(subdir(i).name,'..') ii=ii+1; %标签从0开始 label = subdir(i).name; %子文件夹的名字 fprintf(lbf,'%s\n',label); label=strcat(label,'/'); subsubdir = dir(strcat(maindir,label)); for j=1:length(subsubdir) %第二层目录,即子目录下的图片 if ~strcmp(subsubdir(j).name ,'.') && ~strcmp(subsubdir(j).name,'..') numoffile=numoffile+1; %记录行数,即图片总数 fprintf(wf,'%s%s %d\n',label,subsubdir(j).name,ii); %图片路径/图片名 图片所属类别编号 fprintf('处理标签为%d的第%d张图片\n',ii,j-2); %j之所以-2是因为生成的子文件目录都包含'.'和'..',j要将这两种情况排除在外 end end end end fclose(wf); fclose(lbf); if 0 %不需要打乱顺序 %% %下面将trainval的顺序打乱 file=cell(1,numoffile); fin=fopen('trainval.txt','r'); i=1; while ~feof(fin) tline=fgetl(fin); %获得每行信息 file{i}=tline; i=i+1; end fclose(fin); fprintf('\ntrainval.txt共%d行,开始打乱顺序....\n',numoffile); pause(1); rep=randperm(numoffile); fout=fopen('trainval.txt','w'); for i=1:numoffile fprintf(fout,'%s\n',file{rep(i)}); %按rep生成的顺序重排文本内容 end fprintf('生成的trainval.txt已打乱顺序.\n'); fclose(fout); end %% %下面根据打乱顺序的trainval.txt生成train.txt和val.txt fprintf('开始生成train.txt和val.txt...\n'); pause; %暂停一下检查一下生成的trainval.txt生成的是不是对的 train_file=fopen('train.txt','w'); text_file=fopen('val.txt','w'); trainvalfile=fopen('trainval.txt','r'); num_train=sort(randperm(numoffile,floor(numoffile*train_percent))); %随机取出 train_percent的数据 num_test=setdiff(1:numoffile,num_train); %去掉num_train的数据编号就是num_test数据编号 i=1; %分割图像文件生成训练文件和测试文件 while ~feof(trainvalfile) tline=fgetl(trainvalfile); if ismember(i,num_train) fprintf(train_file,'%s\n',tline); %图片路径/图片名 图片所属类别编号(不需要加图片编号,txt会自动编号) else fprintf(text_file,'%s\n',tline); end i=i+1; end fclose(train_file); fclose(text_file); fclose(trainvalfile); fprintf('共有图片%d张!\n',numoffile); fprintf('Done!\n');
生成的val.txt文件如下:
生成的labels.txt文件如下:
(这里前面的编号是txt文档编辑器的编号,我们在制作txt文件时不需要加编号)
二、用creat_imagenet.sh把数据转换成LMDB或LEVELDB格式
将编译好的caffe文件夹中的examples/imagenet中的create_imagenet.sh复制到你需要的路径下,我这里是“lxq/caffe/models/bvlc_alexnet/stanfdog”,并对create_imagenet.sh文件做些修改,主要是路径的修改,还有就是我的图片大小都不一样,所以需要resize,将RESIZE=false改为RESIZE=true(这里是true而非True)
create_imagenet.sh
#!/usr/bin/env sh# Create the imagenet lmdb inputs# N.B. set the path to the imagenet train + val data dirsset -eEXAMPLE=lxq/caffe/models/bvlc_alexnet/stanfdog #生成的lmdb文件存放路径DATA=lxq/caffe/models/bvlc_alexnet/stanfdog #train.txt和val.txt存放路径TOOLS=lxq/caffe/build/tools #convert_imageset.cpp文件存放路径TRAIN_DATA_ROOT=/home/nielsen/caffe-new/data/Stanford-Dogs/ #图片存放路径(这里没有把train和val分开)VAL_DATA_ROOT=/home/nielsen/caffe-new/data/Stanford-Dogs/# Set RESIZE=true to resize the images to 256x256. Leave as false if images have# already been resized using another tool.RESIZE=trueif $RESIZE; then RESIZE_HEIGHT=227 RESIZE_WIDTH=227else RESIZE_HEIGHT=0 RESIZE_WIDTH=0fiif [ ! -d "$TRAIN_DATA_ROOT" ]; then echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT" echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \ "where the ImageNet training data is stored." exit 1fiif [ ! -d "$VAL_DATA_ROOT" ]; then echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT" echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \ "where the ImageNet validation data is stored." exit 1fiecho "Creating train lmdb..."GLOG_logtostderr=1 $TOOLS/convert_imageset \ --resize_height=$RESIZE_HEIGHT \ --resize_width=$RESIZE_WIDTH \ --shuffle \ #随机排序 $TRAIN_DATA_ROOT \ #原始图片路径 $DATA/train.txt \ #train.txt路径 $EXAMPLE/stanfdog_train_lmdb #生成的lmdb文件名及存放路径echo "Creating val lmdb..."GLOG_logtostderr=1 $TOOLS/convert_imageset \ --resize_height=$RESIZE_HEIGHT \ --resize_width=$RESIZE_WIDTH \ --shuffle \ $VAL_DATA_ROOT \ $DATA/val.txt \ $EXAMPLE/stanfdog_val_lmdbecho "Done."
(注意create_imagenet.sh中最好不要出现中文,哪怕我这里是注释了的中文,刚开始时我是用这个添加了注释的文件运行,结果出错,也不知道错在哪儿,后来把里面的中文删掉了重新运行还是出错,最后干脆又重新复制了个文件过来改好路径,运行就对啦,我想可能是添加的中文影响了文件结构还是怎么回事,总之尽量避免出现中文)
在终端输入:
./lxq/caffe/models/bvlc_alexnet/stanfdog/create_imagenet.sh
如图:
在我对应的文件路径下生成了stanfdog_train_lmdb 和stanfdog_val_lmdb 文件夹
三、生成训练图片的均值文件
将编译好的caffe文件夹中的examples/imagenet中的make_imagenet_mean.sh复制到你需要的路径下,我这里是“lxq/caffe/models/bvlc_alexnet/stanfdog”,并对make_imagenet_mean.sh中的路径做对应的修改
make_imagenet_mean.sh
#!/usr/bin/env sh# Compute the mean image from the imagenet training lmdb# N.B. this is available in data/ilsvrc12EXAMPLE=lxq/caffe/models/bvlc_alexnet/stanfdogDATA=lxq/caffe/models/bvlc_alexnet/stanfdogTOOLS=lxq/caffe/build/tools$TOOLS/compute_image_mean $EXAMPLE/stanfdog_train_lmdb \ $DATA/imagenet_mean.binaryprotoecho "Done."
在终端输入:
./lxq/caffe/models/bvlc_alexnet/stanfdog/make_imagenet_mean.sh
在lxq/caffe/models/bvlc_alexnet/stanfdog文件夹下生成文件imagenet_mean.binaryproto
四、下载基于ImageNet训练的AlexNet模型参数文件bvlc_alexnet.caffemodel。
这个可以在https://www.cnblogs.com/leoking01/p/7123154.html 上下载,里面还有很多其他模型
五、修改模型文件train_val_Alexnet.prototxt
1. 修改数据层mean_file路径(imagenet_mean.binaryproto文件的路径),数据存放路径(stanfdog_train_lmdb,stanfdog_val_lmdb文件路径),batch_size大小
2. 由于是基于ImageNet训练的AlexNet训练我们的数据,属于fine-tuning ,ImagNet数据集有1000类,原AlexNet的fc8有1000个输出,我们只有120类,所以这一层的输出个数要改为120,由于这一层参数与原网络不同需要重新训练,将这一层参数的学习效率适当调大,一般调大为原来的10倍,由于之前的模型的参数是通过各层的名称加载的,最后一层的名称需要修改,以告诉机器这一层参数不需要加载,随之后面的层次也要做相应的修改
3. 修改模型求解文件 train_val_Alexnet_solver.prototxt
关于上面的各个参数的说明:
4. 修改模型执行文件train_val_Alexnet.sh
#!/usr/bin/env shset -eTOOLS=./lxq/caffe/build/toolsMODEL=lxq/caffe/models/bvlc_alexnet/stanfdog#画出网络模型图./lxq/caffe/python/draw_net.py ./$MODEL/train_val_Alexnet.prototxt ./$MODEL/train_val_Alexnet.png#开始训练$TOOLS/caffe train \ --solver=$MODEL/train_val_Alexnet_solver.prototxt \ --weights=$MODEL/bvlc_alexnet.caffemodel 2>&1| tee $MODEL/stanfdog_Alexnet.log $@ #保存屏幕输出到日志
经过漫长的等待,训练完成后生成:
网络模型图train_val_Alexnet.png,网络模型参数快照stanfdog_Alexnet_iter_4000.caffemodel(即我们训练得到的模型),网络训练记录文件stanfdog_Alexnet_iter_4000.solverstate(以外中断时可直接用该文件接着训练),生成的log文件stanfdog_Alexnet.log(保存屏幕输出,方便以后分析和画图)
六、测试
修改stanfdog_deploy.prototxt文件,这个可以对照文件train_val_Alexnet.prototxt修改,主要是对网络模型的修改,去掉卷积层、全连接层的参数设置,还有就是最后一层需要softmax的输出。
编写test.sh执行测试
#!/usr/bin/env shset -eROOT=lxq/caffe/build/examplesMODEL=lxq/caffe/models/bvlc_alexnet/stanfdog./$ROOT/cpp_classification/classification.bin \$MODEL/stanfdog_deploy.prototxt \$MODEL/stanfdog_Alexnet_iter_4000.caffemodel \$MODEL/imagenet_mean.binaryproto \$MODEL/labels.txt \caffe-new/data/test_Stanford-Dogs/QQ截图20161224093349.jpg
主要是相应的路径一定要写对,这里对文件的命名一定要避免空格,因为看classification.cpp可以知道classification.bin是根据空格分隔参数的,如果文件中的命名有空格,classification.bin会认为输入了多余的参数而不能运行
在命令行输入:
./lxq/caffe/models/bvlc_alexnet/stanfdog/test.sh
即可得到softmax输出的前5个最大的概率所对应的类别
后记
我在这里训练的过程中,发现当迭代2000次的时候,正确率有69.46%,而且正确率变化很缓慢,到4000次的时候正确率是69.9%,这个其实在2000次的时候已经发现loss变化也基本没变化,如果我这个时候需要做调整,该怎么调整呢,如果中断训练的话,由于我的snapshot=4000,如果现在中断,我之前跑得结果岂不是都没有了,这种情况下该怎么办呢
- caffe用自己的数据训练模型,并测试输出图片类别
- Caffe训练、测试自己的图片数据
- caffe配置:自己训练模型并测试
- 用caffe训练测试自己的图片
- 用caffe训练测试自己的图片
- 使用CAFFE训练自己的数据集并单张图片测试的方法
- caffe实战之训练并测试自己的数据
- ubuntu14.04+caffe训练测试自己的图片数据
- caffe----训练自己的图片caffenet模型
- caffe训练自己的图片分类模型
- caffe:用自己的图像数据训练模型(图片分类)
- caffe:自己的数据训练模型 (四)
- 用caffe训练并测试自己收集的数据,踩了一堆坑
- caffe:用自己的图像数据训练模型
- Caffe windows 用自己的数据训练模型
- Caffe用训练好的模型测试图片
- caffe-2.0-(纯CPU完整流程)下载、编译caffe + 将自己的图片转为255*255+转为lmdb格式 + 训练并测试自己的数据
- caffe 训练测试自己的数据集
- MTK Battery系统
- websocket
- bad file descriptor
- Oracle数据库一体机助力零售走向互联网零售新模式
- MySQL索引类型总结和使用技巧以及注意事项
- caffe用自己的数据训练模型,并测试输出图片类别
- 端模式
- CentOS 7 设置默认进入图形界面或文本界面
- 多线程图片下载
- //Dijkstra算法大连理工大学数据结构上机第四章
- 修改、删除表内容,增加列、修改列、删除列
- 地鼠的困境(SSL_1333)
- 深度学习—加快梯度下降收敛速度(二):Monmentum、RMSprop、Adam
- 1333 地鼠的困境