1.准备数据集,下面是一些图片数据下载网址:
animal:
http://www.robots.ox.ac.uk/~vgg/data/pets/
flower:
http://www.robots.ox.ac.uk/~vgg/data/flowers/
plane:
http://www.robots.ox.ac.uk/~vgg/data/airplanes_side/airplanes_side.tar
house:
http://www.robots.ox.ac.uk/~vgg/data/houses/houses.tar
guitar:
http://www.robots.ox.ac.uk/~vgg/data/guitars/guitars.tar
将这些图片数据划分为训练集和测试集
新建文件夹
我这里各选500张作为训练集,剪切到对应的文件夹。
各选300张作为测试集,剪切到对应的文件夹。
2.制作标签
比如把animal标记为第0类,flower标记为第1类,guitar第2类,house第3类,plane第4类
格式:“文件路径+标签”
制作标签程序如下:
import os
#定义caffe根目录
caffe_root='E:/graduate_student/deep_learning/caffe/new_Win_caffe/document/1/caffe-windows/caffe-windows'
#制作测试标签数据
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 "成功生成文件列表"
得到标签文件:
3.数据转换
将图片转换为lmdb格式
新建批处理文件:
%格式转换的可执行文件%
%重新设定图片的大小%
%打乱图片%
%转换格式%
%图片路径%
%图片标签%
%lmdb文件的输出路径%
E:\graduate_student\deep_learning\caffe\new_Win_caffe\document\1\caffe-windows\caffe-windows\Build\x64\Release\convert_imageset.exe ^
--resize_height=256 --resize_width=256 ^
--shuffle ^
--backend="lmdb" ^
E:\graduate_student\deep_learning\caffe\new_Win_caffe\document\1\caffe-windows\caffe-windows\models\my_models_recognition\data\test\ ^
E:\graduate_student\deep_learning\caffe\new_Win_caffe\document\1\caffe-windows\caffe-windows\models\my_models_recognition\labels\test.txt ^
E:\graduate_student\deep_learning\caffe\new_Win_caffe\document\1\caffe-windows\caffe-windows\models\my_models_recognition\lmdb\test\ %ttest文件不需要提取创建%
pause
运行bat文件,分别将tes和train文件转换为lmdb格式
得到文件:
4.修改网络模型文件 train_val.prototxt
我们用caffenet训练模型。
(1)
不用均值文件,然后把lmdb文件路径改下:
(2) 把训练集的batch_size改成100
(3)把两个全连接层神经元数量从4096改为512
dropout层是为了抵抗过拟合现象,每次迭代只有一半的神经元工作。
(4) 然后把输出类别从1000改成5:
修改完成。
5.修改超参数文件 solver.prototxt
把参数test_iter改为:测试集总图片数1500除以批次50=30
test_interval改为200,即训练200次测试一次
学习率从0.01改为0.1。
stepsize改为1000,意思是每1000步减小一次学习率
max_iter改为5000, 最大迭代5000次,此处样本较少,不需要太多迭代次数。
然后设置保存路径。
(第1次训练完发现准确率不高,于是第2次训练的时候把优化策略改了,另注意model文件夹后要加斜杠):
6.训练模型
新建批处理文件。
%train训练数据%
%超参数文件%
E:\graduate_student\deep_learning\caffe\new_Win_caffe\document\1\caffe-windows\caffe-windows\Build\x64\Release\caffe.exe train ^
-solver=E:/graduate_student/deep_learning/caffe/new_Win_caffe/document/1/caffe-windows/caffe-windows/models/my_models_recognition/solver.prototxt
pause
运行。
我这里1060显卡大概运行了十多分钟。
得到以下文件:
7.测试模型
准备图片:
我这里从之前下好的5个类别图片的文件夹里每个拿两张图片。
做标签文件:
修改deploy文件(因为测试用到deploy文件)
把两个全连接层神经元数量改成512,把输出改成5
代码:
# coding: utf-8
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:/graduate_student/deep_learning/caffe/new_Win_caffe/document/1/caffe-windows/caffe-windows/'
#网络结构描述文件
deploy_file = caffe_root+'models/my_models_recognition/deploy.prototxt'
#训练好的模型
model_file = caffe_root+'models/my_models_recognition/model/model_iter_5000.caffemodel'
#gpu模式
#caffe.set_device(0)
caffe.set_mode_gpu()
#定义网络模型
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))