使用自己设计的网络训练自己的图像识别模型

一、准备数据集                                                                                                                          点击此处返回总目录

二、制作标签

三、将图片转换为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.csdn.net/cfyzcc/article/details/51318200

 

运行程序:

 

 

 

 

结果:

等我装完GPU版本的,再补上吧。

 

 

如果使用GPU的版本,运行的时候,可能出现错误。可能是因为没有编译GPU版本的pycaffe。