前言

之前有用OpenCv的SUFT特征提取和SVM、BOW做过按图像里的内容进行分类的相关项目,耗时长,准确率又不是很高,各种优化之后准确率也只有百分七十到八十,所以一直想用caffe试试。

一、系统环境

1.windows 7 64位
之前一直在linux下(Ubuntu 16.04 64位)使用过caffe,然后也有在win7 32位试过,能编译,但是在训练过程中出现各种小问题,所有就换64位系统,在训练没有遇到什么问题。
2.Anaconda3
安装Anaconda3尽量装3.4,这样就不用再把python的版本降到3.5。
3.caffe CPU
caffe我使用的是CPU版本。

二、数据收集与处理

1.收集数据
图像数据是从ZOL壁纸网站下载,里面有分类好的壁纸,可以整个系列下载。下载之后新建文件夹放同类型的图像,我收集了四个类型的然后手工分类放到相关的文件夹里,每个种类收集了差不多150张图像。

比如我这里把动漫人物放到这个文件夹下:

2.更改文件名
但下载下来的文件的文件名很混乱,所以要更改成与文件夹对应的文件名,方便之后训练使用,编写python脚本更改整个文件夹的文件名,每个类型的文件夹运行一次
rename.ipynb

import os
def rename(): path="E:/caffe/4/" #文件路径ex = 4filelist = os.listdir(path) #该文件夹下的所有文件count = 0for file in filelist: #遍历所有文件 包括文件夹Olddir = os.path.join(path,file)#原来文件夹的路径if os.path.isdir(Olddir):#如果是文件夹,则跳过continuefilename = os.path.splitext(file)[0]  #文件名filetype = ".jpg"#os.path.splitext(file)[1]   文件扩展名p = str(count).zfill(3)Newdir = os.path.join(path,str(ex)+p+filetype) #新的文件路径os.rename(Olddir,Newdir) #重命名count += 1
rename()

得到统一递增的文件名,文件名前缀是当前的文件夹名,生成训练文件名列表是以文件名前缀打上标签。

3.统一图像大小
下载下来的图像文件大小有很多用类型的,编写python脚本把每个文件夹下的图像改成统一大小的像素的,该脚本把所有图像改成宽384和高256的图像。
resize.ipynb

from PIL import Image
import glob, os
w,h = 384,256 #更改成的分辨率
def timage():for files in glob.glob('E:/caffe/5/*.jpg'): #原文件路径filepath,filename = os.path.split(files)filterame,exts = os.path.splitext(filename)opfile = r'E:/caffe/data/5/' #保存的文件路径if (os.path.isdir(opfile)==False):os.mkdir(opfile)im=Image.open(files)im_ss=im.resize((int(w), int(h)))try:im_ss.save(opfile+filterame+'.jpg')except:print (filterame)os.remove(opfile+filterame+'.jpg')if __name__=='__main__':timage()

4.可以从这里下载我分好类的正样本和测试样本,下载地址:https://download.csdn.net/download/matt45m/11044661

三、准备训练

1.创建数据文件夹
(1)在caffe-windows/data路径下创建一个自己存放数据的文件夹,这里起名为classify,在classify创建两个文件夹,分别为train和test,如下图:

(2)把要训练的图像文件放到train文件夹下,这里每个类别选了120张照片放进来,剩下的图像放到test文件夹里面,如下图:
(3)test文件夹里放着测试用的图像,如下图:

2.得到数据集文件名列表
(1)编写python代码,得到train与test文件夹下的文件列表并标记
getFileNameList.ipynb

import osif __name__ == "__main__":data_dir = 'E:/LIB/caffe-windows/data/classify/test/' #要遍历的文件夹fid = open("E:/LIB/caffe-windows/data/classify/test.txt","w")  #保存的文件列表files = os.listdir(data_dir)index = 0for ii, file in enumerate(files,1):fid.write("{0}{1} {2}\n".format("",file, int(file[0])-2))index = index + 1if index%100 == 0:print("{0} images processed!".format(index))print("All images processed!")fid.close()

运行之后在classify文件夹生成两个train.txt和test.txt

(2)得到的train.txt和test.txt文件内容如下:
test.txt的一部分内容,后面数字为类型标记

train.txt的内容,后面数字为类型标记

四、转换数据

在caffe-windows/data/classify文件夹下编写脚本,把图像数据改成Leveldb格式
data_convention.bat

E:/LIB/caffe-windows/build/tools/Release/convert_imageset.exe --shuffle --resize_height=256 --resize_width=256 --shuffle --backend=leveldb E:/LIB/caffe-windows/data/classify/train/ E:/LIB/caffe-windows/data/classify/train.txt E:/LIB/caffe-windows/data/classify/train_leveldb
E:/LIB/caffe-windows/build/tools/Release/convert_imageset.exe --shuffle --resize_height=256 --resize_width=256 --shuffle --backend=leveldb E:/LIB/caffe-windows/data/classify/test/ E:/LIB/caffe-windows/data/classify/test.txt E:/LIB/caffe-windows/data/classify/test_leveldb
pause

其中resize_height和resize_width表示将原图像更改为相应的大小,这里改成256是因为选取的网络(ImageNet)的要求,shuffle是将数据随机打乱的意思,backend表示将数据转换的格式,这里选择Leveldb。
出现下面的窗口代表转换成功

注:Caffe生成的数据分为2种格式:Lmdb和Leveldb,它们都是键/值对(Key/Value Pair)嵌入式数据库管理系统编程库。lmdb的内存消耗是leveldb的1.1倍,但是lmdb的速度比leveldb快10%至15%,更重要的是lmdb允许多种训练模型同时读取同一组数据集。因此之后lmdb取代了leveldb成为Caffe默认的数据集生成格式。但上面还是使用Leveldb数据类型。
2.运行之后在caffe-windows/data/classify生成两个文件夹,test_leveldb和train_leveldb两个文件夹:
test_leveldb文件夹下内容

train_leveldb文件夹下内容

五、生成均值文件

在caffe-windows/data/classify文件夹下编写脚本,点击运行,生成均值文件
data_mean.bat

E:/LIB/caffe-windows/build/tools/Release/compute_image_mean.exe E:/LIB/caffe-windows/data/classify/train_leveldb --backend=leveldb E:/LIB/caffe-windows/data/classify/train_mean.binaryproto
E:/LIB/caffe-windows/build/tools/Release/compute_image_mean.exe E:/LIB/caffe-windows/data/classify/test_leveldb --backend=leveldb E:/LIB/caffe-windows/data/classify/test_mean.binaryproto
pause

其中backend的参数要与上面转换时的格式保持一致,运行完成后,会在caffe-windows/data/classify文件夹下生成train_mean.binaryproto和test_mean.binaryproto文件
出现以下窗口代表生成成功

在caffe-windows/data/classify生成两个均值文件,如下:

六、训练数据

1.将caffe-windows/models/bvlc_reference_caffenet文件夹下的deploy.prototxt、solver.prototxt和train_val.prototxt拷贝到caffe-windows/data/classify下。
bvlc_reference_caffenet文件夹:

复制到classify文件夹下:

2.更改solver.prototxt

#训练样本为480张图像,batch_size = 60,480 / 60 = 8 那么test_interval(测试间隔)的值要大于或者等于8,即处理完一次所有的训练数据后,才去进行测试.
#如果想训练100代,max_iter 则最大迭代次数为800。
#测试数据为100张图像,batch_size = 25,100 / 25 = 4 那么test_interval(测试间隔)的值要大于或者等于4,即需要4次才能完整的测试一次。
#stepsize(学习率变化规律)置为随着迭代次数的增加,慢慢变低。总共迭代800次,我们将变化5次,所以stepsize设置为800/5=160,即每迭代160次,就要降低一次学习率。
net: "data/classify/train_val.prototxt"                       #训练或者测试配置文件
test_iter:4                                                     #完成一次测试需要的迭代次数
test_interval: 8                                                #测试间隔
base_lr: 0.001                                                  #基础学习率
lr_policy: "step"                                                     #学习率变化规律
gamma: 0.1                                                              #学习率变化指数
stepsize: 160                                                           #学习率变化频率 (stepsize不能太小,如果太小会导致学习率再后来越来越小,达不到充分收敛的效果)
display: 20                                                             #屏幕显示间隔
max_iter: 800                                                           #最大迭代次数
momentum: 0.9                                                       #动量
weight_decay: 0.0005                                                #权重衰减
snapshot: 5000                                                      #保存模型间隔
snapshot_prefix: "data/classify/caffenet_train"       #保存模型的前缀
solver_mode: CPU                                                    #使用GPU或者CPU

3.更改train_val
对trian_val文件进行修改,更改source路径,batch_size,backend和mean_file,其中batch_size看计算机的配置,计算机配置较高,可以设大一点,训练的结果准确率会有些提升。

name: "CaffeNet"
layer {name: "data"type: "Data"top: "data"            #输出数据top: "label"     #输出标签include {phase: TRAIN  #训练阶段}transform_param {mirror: true #映射是否开启crop_size: 227   #图的尺寸mean_file: "data/classifyCPP/train_mean.binaryproto" #均值文件路径}
# mean pixel / channel-wise mean instead of mean image
#  transform_param {
#    crop_size: 227
#    mean_value: 104
#    mean_value: 117
#    mean_value: 123
#    mirror: true
#  }data_param {source: "data/classifyCPP/train_lmdb" #训练集的lmdb数据路径batch_size: 60     #每一批的大小backend: leveldb         #数据格式leveldb}
}
layer {name: "data"type: "Data"top: "data"top: "label"include {phase: TEST  #测试阶段}transform_param {mirror: false            #映射是否开启crop_size: 227       #测试图的尺寸mean_file: "data/classifyCPP/test_mean.binaryproto"    #测试集的均值文件}
# mean pixel / channel-wise mean instead of mean image
#  transform_param {
#    crop_size: 227
#    mean_value: 104
#    mean_value: 117
#    mean_value: 123
#    mirror: false
#  }data_param {source: "data/classifyCPP/test_lmdb"  #测试集的lmdb数据路径batch_size: 25     #测试图像个数backend: LMDB}
}
layer {name: "conv1"type: "Convolution"bottom: "data"top: "conv1"param {lr_mult: 1decay_mult: 1}param {lr_mult: 2decay_mult: 0}convolution_param {num_output: 96kernel_size: 11stride: 4weight_filler {type: "gaussian"std: 0.01}bias_filler {type: "constant"value: 0}}
}
layer {name: "relu1"type: "ReLU"bottom: "conv1"top: "conv1"
}
layer {name: "pool1"type: "Pooling"bottom: "conv1"top: "pool1"pooling_param {pool: MAXkernel_size: 3stride: 2}
}
layer {name: "norm1"type: "LRN"bottom: "pool1"top: "norm1"lrn_param {local_size: 5alpha: 0.0001beta: 0.75}
}
layer {name: "conv2"type: "Convolution"bottom: "norm1"top: "conv2"param {lr_mult: 1decay_mult: 1}param {lr_mult: 2decay_mult: 0}convolution_param {num_output: 256pad: 2kernel_size: 5group: 2weight_filler {type: "gaussian"std: 0.01}bias_filler {type: "constant"value: 1}}
}
layer {name: "relu2"type: "ReLU"bottom: "conv2"top: "conv2"
}
layer {name: "pool2"type: "Pooling"bottom: "conv2"top: "pool2"pooling_param {pool: MAXkernel_size: 3stride: 2}
}
layer {name: "norm2"type: "LRN"bottom: "pool2"top: "norm2"lrn_param {local_size: 5alpha: 0.0001beta: 0.75}
}
layer {name: "conv3"type: "Convolution"bottom: "norm2"top: "conv3"param {lr_mult: 1decay_mult: 1}param {lr_mult: 2decay_mult: 0}convolution_param {num_output: 384pad: 1kernel_size: 3weight_filler {type: "gaussian"std: 0.01}bias_filler {type: "constant"value: 0}}
}
layer {name: "relu3"type: "ReLU"bottom: "conv3"top: "conv3"
}
layer {name: "conv4"type: "Convolution"bottom: "conv3"top: "conv4"param {lr_mult: 1decay_mult: 1}param {lr_mult: 2decay_mult: 0}convolution_param {num_output: 384pad: 1kernel_size: 3group: 2weight_filler {type: "gaussian"std: 0.01}bias_filler {type: "constant"value: 1}}
}
layer {name: "relu4"type: "ReLU"bottom: "conv4"top: "conv4"
}
layer {name: "conv5"type: "Convolution"bottom: "conv4"top: "conv5"param {lr_mult: 1decay_mult: 1}param {lr_mult: 2decay_mult: 0}convolution_param {num_output: 256pad: 1kernel_size: 3group: 2weight_filler {type: "gaussian"std: 0.01}bias_filler {type: "constant"value: 1}}
}
layer {name: "relu5"type: "ReLU"bottom: "conv5"top: "conv5"
}
layer {name: "pool5"type: "Pooling"bottom: "conv5"top: "pool5"pooling_param {pool: MAXkernel_size: 3stride: 2}
}
layer {name: "fc6"type: "InnerProduct"bottom: "pool5"top: "fc6"param {lr_mult: 1decay_mult: 1}param {lr_mult: 2decay_mult: 0}inner_product_param {num_output: 4096weight_filler {type: "gaussian"std: 0.005}bias_filler {type: "constant"value: 1}}
}
layer {name: "relu6"type: "ReLU"bottom: "fc6"top: "fc6"
}
layer {name: "drop6"type: "Dropout"bottom: "fc6"top: "fc6"dropout_param {dropout_ratio: 0.5}
}
layer {name: "fc7"type: "InnerProduct"bottom: "fc6"top: "fc7"param {lr_mult: 1decay_mult: 1}param {lr_mult: 2decay_mult: 0}inner_product_param {num_output: 4096weight_filler {type: "gaussian"std: 0.005}bias_filler {type: "constant"value: 1}}
}
layer {name: "relu7"type: "ReLU"bottom: "fc7"top: "fc7"
}
layer {name: "drop7"type: "Dropout"bottom: "fc7"top: "fc7"dropout_param {dropout_ratio: 0.5}
}
layer {name: "fc8"type: "InnerProduct"bottom: "fc7"top: "fc8"param {lr_mult: 1decay_mult: 1}param {lr_mult: 2decay_mult: 0}inner_product_param {num_output: 4               #训练的种类weight_filler {type: "gaussian"std: 0.01}bias_filler {type: "constant"value: 0}}
}
layer {name: "accuracy"type: "Accuracy"bottom: "fc8"bottom: "label"top: "accuracy"include {phase: TEST}
}
layer {name: "loss"type: "SoftmaxWithLoss"bottom: "fc8"bottom: "label"top: "loss"
}

4.编写训练脚本
trainSc.bat

cd ../../
"E:/LIB/caffe-windows/build/tools/Release/caffe.exe" train --solver=data/classify/solver.prototxt
pause

点击运行

等待运行结束,在classify会多出两个训练好的模型

所有训练完成,之后就是如何测试和使用模型。
七.测试模型
1.修改caffe-windows/data/classify/deploy.prototxt文件,训练是4个类型的数据,那么这里要改成4,注意看行数,不要改前面。

2.编写脚本data_test.bat,运行classification.exe,如果报错,手动查找classification.exe这个文件,脚本里改成它所在的位置,运行。

E:\LIB\caffe-windows\build\examples\cpp_classification\Release\classification.exe ..\..\data\classifyCPP\deploy.prototxt ..\..\data\classifyCPP\caffenet_train_iter_800.caffemodel ..\..\data\classifyCPP\test_mean.binaryproto ..\..\data\classifyCPP\labels.txt ..\..\data\classifyCPP\test\5136.jpg
pause

3.运行结果,有些特征类似的图像还是不能很好的判断,这个要去更改相关配置,重新训练。
(1)测试图像

运行结果:

(2)测试图像

运行结果:

(3)测试图像

运行结果:

这个结果是判断错误的。

后记:

1.以上只是训练成模型的部分,是于如何在win7下编译caffe的办法,现在没有时间去整理,如果有需要问的可以私信我一起探讨。
2.关于python的几个脚本,不熟悉python的,也可用C++实现,C++要使用boost库读取文件操作相对简单一些。
3.之后有时间会写caffe的fine tuning和使用opnecv调用caffe训练好的模型。
4.有兴趣讨论学习可以加群:487350510。

Windows下Caffe的学习与应用(一)——训练自己的数据模型(GoogleNet)相关推荐

  1. Windows下Caffe的学习与应用(三)——使用OpenCV3调用自己训练好的Caffe模型进行图像分类

    前言 前面的博文中,我试了如何使用caffe训练得到想要的模型与其如何使用别人成熟的模型微调优化自己训练的模型,那么得到训练好的模型之后如何在自己的项目中呢,我这里使用opencv的DNN模块调用ca ...

  2. Windows下Caffe的学习与应用(二)——优化自己训练的模型(fine-tuning)

    前言 在前面的博文中,我们也看到,在进行训练的样本比较少,每个种类的样本只有120张,迭代次数为100代,训练得到的模型在测试那些特征不那么明显图像时,准确率达不到我们想要的效果.如果下图: 测试的结 ...

  3. caffe学习日记--lesson4:windows下caffe DEMO (mnist and cifar10)

    caffe学习日记--lesson4:windows下caffe DEMO (mnist and cifar10) 1.下载数据 mnist官网:http://yann.lecun.com/exdb/ ...

  4. 【Caffe】Windows下caffe安装详解

    学习windows下caffe的相关开发.同时也在安装完后及时进行总结,希望这篇博文可以帮助到大家! 需要准备的文件: 1,VS2013(必选),这个不再赘述 2,Windows版的caffe,BVL ...

  5. windows下caffe+CPUOnly实现MNIST手写分类

    工具下载 微软官方移植的Caffe:https://github.com/Microsoft/caffe 对属性表的操作 需要把实例属性表的后缀改成vs可用的.props 打开同一个文件夹下的Caff ...

  6. 【caffe】windows下caffe+vs2013+python2.7+cuda8.0+cmake3.8编译与配置

    项目的需要,终究还是用到了深度学习,Caffe无疑是我这种菜鸟最好的入门平台,然鹅,事情并没有想象的那么简单!!!单是编译caffe的库就已经把我折腾得灰头土脸了,搜了很多caffe的编译教程,一步一 ...

  7. windows下的docker学习

    一.为什么学 每学一个东西,我们肯定是基于某个需求去学习的,众所周知,软件开发最麻烦的是环境配置,开发好好的,部署出问题就很难受,所以为了确保开发.测试.部署环境一致,且高效的部署所以选择了容器技术而 ...

  8. windows下C语言学习--在两台电脑之间传文件

    客户端client.c #define _CRT_SECURE_NO_WARNINGS #define _WINSOCK_DEPRECATED_NO_WARNINGS #include<stdi ...

  9. Ubuntu下caffe:用自己的图片训练并测试AlexNet模型

    目录 1.准备图片 2. 将 图片路径写入txt 参考 这篇文章 3.转换格式 还是参考这篇文章 4.训练模型 参考这篇 参考这篇 参考这篇 5.测试模型 看过这篇转换均值文件 看过这篇 ------ ...

最新文章

  1. 快速人体姿态估计:CVPR2019论文阅读
  2. python下什么版本-python版本有什么不同
  3. shell脚本字符串截取
  4. 新人如何快速上手项目管理
  5. 博客订阅代码de制作
  6. Android利用soap WSDL与Webservice通信
  7. mysql io队列_网易视频云经验分享MYSQL 5.5 的IO控制
  8. MTK:文件操作接口详解
  9. c语言进度条窗口,【C语言】进度条实现
  10. 如何定义一个类对象并用next()的方法使用_python零基础必读--可迭代对象、迭代器与生成器...
  11. python 读xml_python读取xml文件
  12. Git 下载与安装教程
  13. appium+python实现手势密码
  14. linux ubuntu 安装odb,Ubuntu 使用C++ ORM框架--ODB
  15. cnpm : 无法加载文件 C:\Users\AppData\Roaming\npm\cnpm.ps1,因为在此系统上禁止运行脚本。的解决方案之一
  16. 挂载移动硬盘到ubuntu server
  17. 手把手教你搭建一个你自己的语音合成系统
  18. centos7 查看本地ip地址
  19. 笔记本电池“衰老”了怎么办?
  20. html5获取我的位置并在百度地图上显示

热门文章

  1. swift中的@objc
  2. .ajax done参数,困惑jQuery .ajax .done()函数
  3. win10 linux ssh自动启动,win10子系统 wsl开机启动ssh服务
  4. C/C++经典程序训练3---模拟计算器_JAVA
  5. WPF messagebox生命周期的探讨
  6. Caffe学习记录:Cifar-10 自定义网络训练记录
  7. JQuery 总结(3) jQuery 各种事件
  8. TCP 滑动窗口协议
  9. 深度学习Deep Learning 相关库简介
  10. python 文件和路径操作函数小结