本系列文章主要介绍了在win10系统下caffe的安装编译,运用CPU和GPU完成简单的小项目,文章之间具有一定延续性。
数据集是进行深度学习的第一步,在这里我们从以下五个链接中下载所需要的数据集: animal flower plane house guitar
我们在原先的models文件夹下新建文件夹my_models_recognition,用于存放本文在实现图像识别过程中的相关文件。我们之前下载的五个压缩包包含animal、flower、plane、house和guitar五个类别。我们首先需要将其分成训练集和测试集两个部分,在这里,我们采用手工的方法来制作数据集。
首先分别在train和test文件夹下新建五个类别的文件夹,用于存放每个类别的训练集和测试集。 在这里,我们设定训练集的数目为500,测试集的数目为300,我们将每个分类的前500章图片剪切到train文件夹的相应类别下,用于作为训练集,剪切300张图片到test的相应文件夹下作为测试集。至此,我们已经完成了数据集的准备工作。
我们以“文件路径+标签”的形式对每个图像进行命名,在这里,如果我们继续采用手工操作对图像标签进行制作,这个过程需要耗费大量的时间。为此,我们在jupyter 中运行下列程序来帮助我们完成标签制作。在运行程序之前先新建labels文件夹用于存放产生的标签。
import os #定义Caffe根目录 caffe_root = 'E:/caffe-windows/' #制作训练标签数据 i = 0 #标签 with open(caffe_root + 'models/my_models_recognition/labels/train.txt','w') as train_txt: for root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/data/train/'): #遍历文件夹 for dir in dirs: for root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/data/train/'+str(dir)): #遍历每一个文件夹中的文件 for file in files: image_file = str(dir) + '\\' + str(file) label = image_file + ' ' + str(i) + '\n' #文件路径+空格+标签编号+换行 train_txt.writelines(label) #写入标签文件中 i+=1 #编号加1 #制作测试标签数据 i=0 #标签 with open(caffe_root + 'models/my_models_recognition/labels/test.txt','w') as test_txt: for root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/data/test/'): #遍历文件夹 for dir in dirs: for root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/data/test/'+str(dir)): #遍历每一个文件夹中的文件 for file in files: image_file = str(dir) + '\\' + str(file) label = image_file + ' ' + str(i) + '\n' #文件路径+空格+标签编号+换行 test_txt.writelines(label) #写入标签文件中 i+=1#编号加1 print "成功生成文件列表"运行程序,输出“成功生成文件列表”,打开labels文件夹,就可以在里面分别找到train和test的标签文件。 至此,我们也已经完成了标签的制作过程。
由于我们的数据集中图片是png的形式,我们需要将其转化为LMDB的格式,新建lmdb文件夹用于存放生成的lmdb文件。
和之前我们讲述的方法一样,在这里我们运用convert_imageset.exe来完成格式转化。运行批处理文件如下,对训练集的图像进行格式转换并打乱图片顺序:
%格式转换的可执行文件% %重新设定图像大小% %打乱图片% %转换格式% %图片路径% %图片标签% %lmdb文件的输出路径% E:\caffe-windows\Build\x64\Release\convert_imageset.exe ^ --resize_height=256 --resize_width=256 ^ --shuffle ^ --backend="lmdb" ^ E:\caffe-windows\models\my_models_recognition\data\train\ ^ E:\caffe-windows\models\my_models_recognition\labels\train.txt ^ E:\caffe-windows\models\my_models_recognition\lmdb\train\ pause同理,运行如下程序修改测试集中的图片格式。
%格式转换的可执行文件% %重新设定图像大小% %打乱图片% %转换格式% %图片路径% %图片标签% %lmdb文件的输出路径% E:\caffe-windows\Build\x64\Release\convert_imageset.exe ^ --resize_height=256 --resize_width=256 ^ --shuffle ^ --backend="lmdb" ^ E:\caffe-windows\models\my_models_recognition\data\test\ ^ E:\caffe-windows\models\my_models_recognition\labels\test.txt ^ E:\caffe-windows\models\my_models_recognition\lmdb\test\ pause在之前的文章中,我们使用过Googlenet,Googlenet适用于分类多,数据量大的情况,当数据集太小的时候容易出现过拟合现象(如本文只采用500个数据集),因此在这里我们使用caffenet来完成图像的分类。 把上述文件复制到my_models_recognition中,然后编辑网络参数文件 在这里,我们没有使用均值文件,因此将下列代码注释掉
# transform_param { # mirror: true # crop_size: 227 # mean_file: "data/ilsvrc12/imagenet_mean.binaryproto" # } # mean pixel / channel-wise mean instead of mean image同理,还有下列代码:
# transform_param { # mirror: false # crop_size: 227 # mean_file: "data/ilsvrc12/imagenet_mean.binaryproto" # } # mean pixel / channel-wise mean instead of mean image将第25行batch size改为100 将293和333行num_output改为512 373行中,因为这里我们只有五个类别,所以只需要5个输出即可,将1000改为5
对超参数文件中的路径进行修改,最大迭代次数改为3000.,每500次迭代输出一次model,并新建文件夹model,用于存放训练得到的模型
net: "E:/caffe-windows/models/my_models_recognition/train_val.prototxt" test_iter: 30 test_interval: 200 base_lr: 0.01 lr_policy: "step" gamma: 0.1 stepsize: 1000 display: 50 max_iter: 3000 momentum: 0.9 weight_decay: 0.0005 snapshot: 500 snapshot_prefix: "E:/caffe-windows/models/my_models_recognition/model/" solver_mode: GPU新建label文件,在里面放置物体的类别
虽然在之前我们已经修改了网络结构文件,但是在测试过程中我们使用的是deploy Prototxt文件,因此我们对其进行同样的修改:
181行和157行输出改为512,第205行改为5.
运行批处理文件如下:
%train训练数据% %超参数文件% E:\caffe-windows\Build\x64\Release\caffe.exe train ^ -solver=E:/caffe-windows/models/my_models_recognition/solver.prototxt ^ pause(第一次进行训练的时候是设置没5次迭代输出一次结构,第二次训练改为500次训练输出一次结构,因此前面有那些第五次第十次之类,忽略即可)
新建image文件夹,将我们要测试的图片放置在其中:
在jupyter中运行如下代码:
import caffe import numpy as np import matplotlib.pyplot as plt import os import PIL from PIL import Image import sys #定义Caffe根目录 caffe_root = 'E:/caffe-windows/' #网络结构描述文件 deploy_file = caffe_root+'models/my_models_recognition/deploy.prototxt' #训练好的模型 model_file = caffe_root+'models/my_models_recognition/model/_iter_3000.caffemodel' #gpu模式 #caffe.set_device(0) caffe.set_mode_cpu() #定义网络模型 net = caffe.Classifier(deploy_file, #调用deploy文件 model_file, #调用模型文件 channel_swap=(2,1,0), #caffe中图片是BGR格式,而原始格式是RGB,所以要转化 raw_scale=255, #python中将图片存储为[0, 1],而caffe中将图片存储为[0, 255],所以需要一个转换 image_dims=(227, 227)) #输入模型的图片要是227*227的图片 #分类标签文件 imagenet_labels_filename = caffe_root +'models/my_models_recognition/labels/label.txt' #载入分类标签文件 labels = np.loadtxt(imagenet_labels_filename, str) #对目标路径中的图像,遍历并分类 for root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/image/'): for file in files: #加载要分类的图片 image_file = os.path.join(root,file) input_image = caffe.io.load_image(image_file) #打印图片路径及名称 image_path = os.path.join(root,file) print(image_path) #显示图片 img=Image.open(image_path) plt.imshow(img) plt.axis('off') plt.show() #预测图片类别 prediction = net.predict([input_image]) print 'predicted class:',prediction[0].argmax() # 输出概率最大的前5个预测结果 top_k = prediction[0].argsort()[::-1] for node_id in top_k: #获取分类名称 human_string = labels[node_id] #获取该分类的置信度 score = prediction[0][node_id] print('%s (score = %.5f)' % (human_string, score))运行代码即可输出分类结果,我们发现模型的识别准确率非常高