前言

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


测试的结果如下:


这个测试结果是不准确的,像这种概率是根本无法在项目中应用。一般深度学习的库都要求样本量尽量在在1万个以上,但有时候我们的样本又达不到这个数量,什么办呢,这里就要用到别的用户的训练好的成熟的数据模型进行微调(fine-tuning),借用训练好的参数,可以更快的收敛,达到比原来样本小的时候训练效果要好一些。但使用的网络必须一样。
图像分类这块,caffe团队用ImageNet进行训练,迭代30多万次,训练出来一个model。这个model将图片分为1000类,应该是目前为止最好的图片分类model了,这里就会用caffe的官方模型来进行迁移学习。

一、数据准备

在data这个文件夹下新建立一个,把上次转换的数据,均值文件文件都移到到这个文件夹,然后把caffe的图像分类官方模型下载到当前文件夹,下载地址是:http://dl.caffe.berkeleyvision.org/bvlc_reference_caffenet.caffemodel。
当前文件夹所包含的文件如下图:

所有包含的文件,不能少,如果没有这些文件,可以往回看我之前写的博文,如何生成这几个文件的。
2.数据处理

二、更改代码

修改配置三个文件的,这里我贴出我的文件,路径是我电脑上的,可能参考,是于参数的说明,可能看上一个博文。
1.修改solever.prototxt文件

net: "E:/LIB/caffe-windows/data/fine_tuning/train_val.prototxt"
test_iter: 4
test_interval: 8
base_lr: 0.001
lr_policy: "step"
gamma: 0.1
stepsize: 160
display: 20
max_iter: 800
momentum: 0.9
weight_decay: 0.0005
snapshot: 5000
snapshot_prefix: "E:/LIB/caffe-windows/data/fine_tuning/train"
solver_mode: CPU

2.train_val.prototxt文件

name: "CaffeNet"
layer {name: "data"type: "Data"top: "data"top: "label"include {phase: TRAIN}transform_param {mirror: truecrop_size: 227mean_file: "data/fine_tuning/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/fine_tuning/train_leveldb" #转换文件路径batch_size: 60backend: LEVELDB #数据类型}
}
layer {name: "data"type: "Data"top: "data"top: "label"include {phase: TEST}transform_param {mirror: falsecrop_size: 227mean_file: "data/fine_tuning/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/fine_tuning/test_leveldb" #转换文件路径batch_size: 25backend: LEVELDB}
}
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-re"   #要改的位置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"
}

3.deploy.prototxt文件

name: "CaffeNet"
layer {name: "data"type: "Input"top: "data"input_param { shape: { dim: 10     #一批的数量(bach of image)dim: 3       #图像通道数量(channels 彩色图是3通道RGB)dim: 227  #图像的高度dim: 227  #图像的宽度} }
}
layer {name: "conv1"                  #层的名称type: "Convolution"      #层的类型bottom: "data"               #层的输入(对应上面的data)top: "conv1"                    #层的输出(对应的是本层卷积的结果)convolution_param {     #卷积的参数num_output: 96            #过滤器的个数,可以看做的是卷积和的个数吧kernel_size: 11         #卷积核的大小stride: 4                        #图像中的间隔多少进行卷积(一次窗口滑动的步长)}
}
layer {name: "relu1"type: "ReLU"bottom: "conv1"top: "conv1"
}
layer {name: "pool1"type: "Pooling"bottom: "conv1"top: "pool1"pooling_param {pool: MAX              #使用最大池化kernel_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"convolution_param {num_output: 256pad: 2              #边界处补2个行和2个列kernel_size: 5group: 2          #卷积分组}
}
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 {           #主要是LRN的三个主要的参数local_size: 5alpha: 0.0001beta: 0.75}
}
layer {name: "conv3"type: "Convolution"bottom: "norm2"top: "conv3"convolution_param {num_output: 384pad: 1kernel_size: 3}
}
layer {name: "relu3"type: "ReLU"bottom: "conv3"top: "conv3"
}
layer {name: "conv4"type: "Convolution"bottom: "conv3"top: "conv4"convolution_param {num_output: 384pad: 1kernel_size: 3group: 2}
}
layer {name: "relu4"type: "ReLU"bottom: "conv4"top: "conv4"
}
layer {name: "conv5"type: "Convolution"bottom: "conv4"top: "conv5"convolution_param {num_output: 256pad: 1                  #对图像进行补充像素的设置(在图像的高和宽进行补充)kernel_size: 3group: 2}
}
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"inner_product_param {num_output: 4096}
}
layer {name: "relu6"type: "ReLU"bottom: "fc6"top: "fc6"
}
layer {name: "drop6"type: "Dropout"bottom: "fc6"top: "fc6"dropout_param {dropout_ratio: 0.5   #使用的drop进行网络的参数的隐藏时的参数}
}
layer {name: "fc7"type: "InnerProduct"bottom: "fc6"top: "fc7"inner_product_param {num_output: 4096     #过滤器的个数(输出的个数)}
}
layer {name: "relu7"type: "ReLU"          #relu的激活函数bottom: "fc7"top: "fc7"
}
layer {name: "drop7"type: "Dropout"             #dropout将一部分的权重置零不参与运算bottom: "fc7"top: "fc7"dropout_param {dropout_ratio: 0.5}
}
layer {name: "fc8-re"             #要改的位置type: "InnerProduct"    #内积(全连接层)bottom: "fc7"top: "fc8"inner_product_param {num_output: 4            #输出的类别(要改成对应的)}
}
layer {name: "prob"type: "Softmax"                  #Softmax分类层bottom: "fc8"top: "prob"
}

三、开始训练

1.编写脚本train.bat

cd ../../
E:/LIB/caffe-windows/build/tools/Release/caffe.exe train --solver=data/fine_tuning/solver.prototxt --weights=data/fine_tuning/bvlc_reference_caffenet.caffemodel
pause

2.运行脚本

完成之后会多出两个文件,如下,代表训练成功。

四、测试数据

1.新建labels.txt文件,写上以下内容:

0 cat
1 dog
2 flower
3 cartoon

2.新建data_test.bat文件

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

保存,点击运行,还是测试文章开头的那张图像,我们来看看测试结果明显提高了.

后记

1.以上所有的图像分类的训练已经完成,之后就是如何在在项目中使用训练好的模型。
2.有兴趣讨论学习可以加群:487350510。

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

  1. Windows下Caffe的学习与应用(一)——训练自己的数据模型(GoogleNet)

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

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

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

  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进程与线程学习笔记(二)—— 线程结构体

    Windows进程与线程学习笔记(二)-- 线程结构体 线程结构体 ETHREAD +0x000 Tcb : _KTHREAD 练习 线程结构体 ETHREAD 描述: 每个windows线程在0环都 ...

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

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

  7. Windows下Libvirt Java API使用教程(二)- 接口使用说明

    介绍完libvirt Java API的部署工作: <Windows下Libvirt Java API使用教程(一)- 开发环境部署> 接下来我们就介绍一下接口的使用和代码样例. libv ...

  8. Windows 下 PHP 开发环境配置系列二(使用 MODx CMS)

    Windows 下 PHP 开发环境配置系列一(PHP+Apache+MySql; Zend Debugger+PDT) 软件的下载地址在系列一中有列出 1. 需安装软件 PHP:   php-5.2 ...

  9. windows下vue-cli及webpack 构建网站(二)导入bootstrap样式

    1.先安装好vue-cli,如果还没有安装好的可以参考:<windows下vue-cli及webpack 构建网站(一)环境安装> 2.安装好之后Vue的欢迎界面,我们要做个例子导入boo ...

最新文章

  1. Linux使用logrotate来切割日志文件
  2. matlab 双音多频 接收端检测到的号码,信号语音论文,关于基于MATLAB的双音多频信号识别相关参考文献资料-免费论文范文...
  3. CentOS 搭建Postfix+Dovecot简单邮件系统
  4. python+selenium笔记(一):元素定位方法
  5. 宏晶STC单片机使用STC-ISP串口烧录失败的解决方法及实例汇总 (Ver0.99.15)
  6. html仿ppt动画,jquery仿PPT幻灯片特效插件ppt.js
  7. DEV中右键菜单如何只在非空单元格上显示?
  8. 魔兽世界个人插件、宏、WA 使用记录
  9. [转]高品质开源工具Chloe.ORM:支持存储过程与Oracle
  10. 交换机设备登录账号权限1_h3c交换机设置用户权限
  11. .net\C#基于zxing的彩色、Logo二维码生成---随笔
  12. image-conversion 图片压缩,vue
  13. Math.js库的使用
  14. angular4 - 思维导图(xmind)
  15. 让div在屏幕中居中(水平居中+垂直居中)的几种方法
  16. HTML效果图谷歌打不开,关于谷歌浏览器打不开Axure原型的HTML问题解决
  17. 【详解】SPI中的极性CPOL和相位CPHA是什么以及如何设置
  18. 计算机组成原理基础(转载)
  19. 努比亚红魔5s9008救砖教程
  20. 加快Win7整体运行速度的12个小技巧

热门文章

  1. 读数据库遇到空就进行不下去_如何解决高并发场景下缓存+数据库双写不一致问题?...
  2. 第三讲、Linux常用命令
  3. Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version 错误解决
  4. 【c++】48.g++编译opencv、多线程
  5. 如何高效的学习掌握新技术
  6. 浅谈WeakHashMap
  7. 用JavaScript玩转计算机图形学(二)基本光源
  8. 数字图像处理:第十七章 纹理分析
  9. Machine Learning week 1 quiz: Linear Algebra
  10. 【OpenCV3】cv::Mat块访问与操作(ROI区域的选取)