一、准备数据集 点击此处返回总目录
二、制作标签
三、将图片转换为LMDB格式
四、修改网络结构文件
五、修改超参数文件
六、训练模型
七、测试模型
一、准备数据集
1. 根据下面5个链接可以分别下到物种类别的图片。
animal类
下载地址: http://www.robots.ox.ac.uk/~vgg/data/pets/

flowers类
下载地址: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
2. 下载完之后,解压:

里面全是一些jpg的图片。
flowers //有1360张
plane //有1074张
guitar //有1030张
house //有1000张
image(animal) //有7393张
3. 在caffe-windows\models下,新建my_models_recognition目录,用来存放我们自己的模型。
在my_models_recognition中如下创建文件夹:
|---data //存放训练数据和测试数据
| |---train
| | |---animal
| | |---flower
| | |---plane
| | |---house
| | |---guitar
| |
| |---test
| |---animal
| |---flower
| |---plane
| |---house
| |---guitar
|
|---labels //存放标签
|
|
|---bat //存放脚本
|
|
|---lmdb //存放转换后的lmdb数据
|
|
|---model //训练后结果保存到这里
这些文件夹分别用来存储训练集和测试集、标签、脚本等。
4. 把这五个类的图片分成训练集和测试集。
训练集和测试集分别有多少图片呢?我们这里采用手工拷的方法。从解压的数据里面分别剪切出500张放入到训练集中;剪切300张分别放入到测试集中。即:
train
animal //500张
flower //500张
plane //500张
house //500张
guitar //500张
test
animal //300张
flower //300张
plane //300张
house //300张
guitar //300张
二、制作标签
使用程序写一个文本文件,将图片和标签对应。
//制作标签.py
# coding: utf-8
import os
#定义Caffe根目录
caffe_root = 'F:/deep_learning/Caffe/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: #animal
for root,dirs,files in os.walk(caffe_root+'models/my_models_recognition/data/train/'+str(dir)): #遍历每一个文件夹中的文件
for file in files: #cat1.jpg
image_file = str(dir) + '\\' + str(file) #animal\cat1.jpg
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.txt和test.txt文件:

三、将图片转换为LMDB格式
编写脚本进行转换。
//convert_train_lmdb.bat
%格式转换的可执行文件%
%重新设定图片的大小%
%打乱图片%
%转换格式%
%图片路径%
%图片标签%
%转换后的数据存放在此目录%
F:\deep_learning\Caffe\caffe-windows\Build\x64\Release\convert_imageset.exe ^
--resize_height=256 --resize_width=256 ^
--shuffle ^
--backend="lmdb" ^
F:\deep_learning\Caffe\caffe-windows\models\my_models_recognition\data\train\ ^
F:\deep_learning\Caffe\caffe-windows\models\my_models_recognition\labels\train.txt ^
F:\deep_learning\Caffe\caffe-windows\models\my_models_recognition\lmdb\train\
pause
|
注意:标红色的"\"不能省略。我之前省略了,结果产生的lmdb文件不对。
//convert_test_lmdb.bat
%格式转换的可执行文件%
%重新设定图片的大小%
%打乱图片%
%转换格式%
%图片路径%
%图片标签%
%转换后的数据存放在此目录%
F:\deep_learning\Caffe\caffe-windows\Build\x64\Release\convert_imageset.exe ^
--resize_height=256 --resize_width=256 ^
--shuffle ^
--backend="lmdb" ^
F:\deep_learning\Caffe\caffe-windows\models\my_models_recognition\data\test\ ^
F:\deep_learning\Caffe\caffe-windows\models\my_models_recognition\labels\test.txt ^
F:\deep_learning\Caffe\caffe-windows\models\my_models_recognition\lmdb\test\
pause
|
执行完后,可以看到在lmdb文件夹下生成了train目录和test目录,里面有lmdb文件。
四、修改网络结构文件
我们选择caffenet进行修改得到我们的网络。
将caffe-windows\models\bvlc_reference_caffenet下的train_val.prototxt修改,得到我们的网络文件。
1.

因为我们没有均值文件,所以将上面的注释掉,用下面的。因此改为:

解释一下:
crop_size:227 //图片转换为lmdb格式后,都转成了256*256的大小。这个参数的意思是,在训练的时候会从256*256的
图片里面随机 截取一个227*227的框。这样做的目的是可以增加训练集。
下面三个mean_value,可以替代均值文件,是个经验值。是通过大量图片求出来的一个均值。这样就不需要均值文件了。
mirror:true //图片是否要做镜像。也是为了增大数据集。
2. 同样,测试数据也进行修改:

3. 修改训练集和测试集的lmdb,batch_size的大小


4. 全连接层fc6层 有4096个神经元。对于我们现在这个模型来说可能太大了,很容易出现过拟合。改小一点。

5.同样fc7层也改成512个。
6. 之前是1000分类,现在改成5.

五、修改超参数文件
将caffe-windows\models\bvlc_reference_caffenet下的solver.prototxt修改,得到我们的网络文件。
net: "F:/deep_learning/Caffe/caffe-windows/models/my_models_recognition/train_val.prototxt"
test_iter: 30 //共1500个测试数据,每个批次50张图片。所以1500/50=30
test_interval: 200 //训练200次测试一次。
base_lr: 0.1 //学习率
lr_policy: "step"
gamma: 0.1
stepsize: 1000 //每1000步减少一点学习率
display: 50 //每50次显示一次
max_iter: 2000 //迭代多少次
momentum: 0.9
weight_decay: 0.0005
snapshot: 1000
snapshot_prefix: "F:/deep_learning/Caffe/caffe-windows/models/my_models_recognition/model"
solver_mode: CPU
type: "AdaDelta"
delta: le-6
|
六、训练模型
编写脚本训练
//train.bat
%train训练数据%
%超参数文件%
F:\deep_learning\Caffe\caffe-windows\Build\x64\Release\caffe.exe train ^
-solver=F:/deep_learning/Caffe/caffe-windows/models/my_models_recognition/solver.prototxt
pause
|
执行,很慢很慢~~~~
等我装完GPU版本的,再来放结果吧
七、测试模型
在caffe-windows\models\my_models_recognition下新建image文件夹。
从网上随便找几张图片,放入image下。


制作标签文件:
在caffe-windows\models\my_models_recognition\labels下创建label.txt文件。内容与train.txt下的顺序对应。0对应animal,1对应flower,2对应guitar,3对应house,4对应plane。
animal
flower
guitar
house
plane |
修改caffe-windows\models\bvlc_reference_caffenet下的deploy.prototxt文件,作为我们的模型文件。
deploy文件和网络结构文件很像,是在测试的时候用的。同时使用deploy文件和model来测试。deploy文件和网络结构文件最大的不同是没有数据层。
修改三个地方。



编写测试程序:
# 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 = 'F:/deep_learning/Caffe/caffe-windows/'
#网络结构描述文件
deploy_file = caffe_root+'models/my_models_recognition/deploy.prototxt'
#训练好的模型
model_file = caffe_root+'models/my_models_recognition/model/caffenet_train_iter_5000.caffemodel'
#gpu模式
#caffe.set_device(0) #有多个GPU的时候,可以设定使用哪个。不设的话就是第0个。
caffe.set_mode_gpu() #如果用CPU的话:caffe.set_mode_cpu()。什么也不写默认是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))
|
还有一个版本的测试程序,也可以:
# -*- coding: utf-8 -*-
import os
import caffe
import numpy as np
#定义Caffe根目录
caffe_root = 'F:/deep_learning/Caffe/caffe-windows/'
#deploy文件
deploy_file = caffe_root+'models/my_models_pubu/deploy.prototxt'
#训练好的模型
model_file = 'E:/data2/model/my_iter_40.caffemodel'
#gpu模式
#caffe.set_device(0) #有多个GPU的时候,可以设定使用哪个。不设的话就是第0个。
caffe.set_mode_cpu() #如果用CPU的话:caffe.set_mode_cpu()
net = caffe.Net(deploy_file,
model_file,
caffe.TEST) #use test mode(e.g. don't perform dropout)
#求均值.如果训练的时候进行了减均值的操作,测试的时候也要进行该操作。如果训练时没有减均值,这两句就不用写了。
mu = np.load('E:/data/mean_file/mean.npy') #导入.npy格式的均值文件。需要把mean.binaryproto转成mean.npy
mu = mu.mean(1).mean(1) # average over pixels to obtain the mean (BGR) pixel values
# print u'各个颜色通道的均值:', zip('BGR', mu) #可以打出来看看
#对输入的图片进行预处理操作。训练的时候做了预处理,测试的时候要做相同的预处理。
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape}) #只对data层做预处理的操作。
transformer.set_transpose('data', (2,0,1)) #将高*宽*通道,转换为通道*高*宽的格式。
#transformer.set_mean('data',mu) # np.load(mean_file).mean(1).mean(1)) #减去均值,前面训练模型时没有减均值,这儿就不用
transformer.set_raw_scale('data', 255) # 从[0, 1]缩放到[0,255]之间。python中将图片存储为[0,1],而caffe中将图片存储为[0, 255],所以需要一个转换
transformer.set_channel_swap('data', (2,1,0)) #交换通道,将图片由RGB变为BGR。
net.blobs['data'].reshape(1, #将输入图片格式转化为合适格式(与deploy文件相同)。batch_size
3, #3通道。
115,1206) #第三个参数:图片高度 第四个参数:图片宽度。不要搞反了。
image=caffe.io.load_image('E:/data/image/wurenji4.bmp') #加载图片
transformer_image = transformer.preprocess('data',image) #对图片执行上面的预处理操作,得到预处理后的图像。
net.blobs['data'].data[...] =transformer_image #blobs的数据层中的数据等于预处理后的图片
#到目前为止,deploy的数据层就有东西了。现在就开始跑网络了。
output = net.forward() #用网络前向传播跑一次。得到output。output中包含所有层,每一层的结果。
output_prob = output['prob'][0] #得到'prob'层的每一个类别的概率值。0代表batch中的第一张图片。
print 'predictd class is:',output_prob.argmax() #对所有的概率求最大值。
labels = np.loadtxt('E:/data/labels/labels.txt', str, delimiter='\t') #读取类别名称文件
print 'label is:',labels[output_prob.argmax()]
# sort top five predictions from softmax output
top_inds = output_prob.argsort()[::-1][:5] # reverse sort and take five largest items
print 'probabilities and labels:',zip(output_prob[top_inds], labels[top_inds])
|
其实这些测试文件都是根据官网的例子改的。可以看:caffe-windows\examples\00-classification.ipynb,有最详细最权威的解释。
也可以参考这些人的翻译:
https://www.cnblogs.com/TensorSense/p/7413307.html
https://nbviewer.jupyter.org/github/BVLC/caffe/blob/master/examples/00-classification.ipynb
https://blog.****.net/cfyzcc/article/details/51318200
运行程序:
结果:
等我装完GPU版本的,再补上吧。
如果使用GPU的版本,运行的时候,可能出现错误。可能是因为没有编译GPU版本的pycaffe。
|