利用caffe在Windows下实现图像识别

本系列文章主要介绍了在win10系统下caffe的安装编译,运用CPU和GPU完成简单的小项目,文章之间具有一定延续性。

step1:准备数据集

数据集是进行深度学习的第一步,在这里我们从以下五个链接中下载所需要的数据集:
animal
flower
plane
house
guitar

我们在原先的models文件夹下新建文件夹my_models_recognition,用于存放本文在实现图像识别过程中的相关文件。我们之前下载的五个压缩包包含animal、flower、plane、house和guitar五个类别。我们首先需要将其分成训练集和测试集两个部分,在这里,我们采用手工的方法来制作数据集。

首先分别在train和test文件夹下新建五个类别的文件夹,用于存放每个类别的训练集和测试集。
在这里插入图片描述
在这里,我们设定训练集的数目为500,测试集的数目为300,我们将每个分类的前500章图片剪切到train文件夹的相应类别下,用于作为训练集,剪切300张图片到test的相应文件夹下作为测试集。至此,我们已经完成了数据集的准备工作。

step2:制作标签

我们以“文件路径+标签”的形式对每个图像进行命名,在这里,如果我们继续采用手工操作对图像标签进行制作,这个过程需要耗费大量的时间。为此,我们在jupyter 中运行下列程序来帮助我们完成标签制作。在运行程序之前先新建labels文件夹用于存放产生的标签。

import os 

#定义Caffe根目录
caffe_root = ‘E:/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:
for root,dirs,files in os.walk(caffe_root+‘models/my_models_recognition/data/train/’+str(dir)): #遍历每一个文件夹中的文件
for file in files:
image_file = str(dir) + ‘\’ + str(file)
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 “成功生成文件列表”

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

运行程序,输出“成功生成文件列表”,打开labels文件夹,就可以在里面分别找到train和test的标签文件。在这里插入图片描述
至此,我们也已经完成了标签的制作过程。

step3:数据转换

由于我们的数据集中图片是png的形式,我们需要将其转化为LMDB的格式,新建lmdb文件夹用于存放生成的lmdb文件。

和之前我们讲述的方法一样,在这里我们运用convert_imageset.exe来完成格式转化。运行批处理文件如下,对训练集的图像进行格式转换并打乱图片顺序:

%格式转换的可执行文件%
%重新设定图像大小%
%打乱图片%
%转换格式%
%图片路径%
%图片标签%
%lmdb文件的输出路径%

E:\caffe-windows\Build\x64\Release\convert_imageset.exe ^
--resize_height=256 --resize_width=256 ^
--shuffle ^
--backend=“lmdb” ^
E:\caffe-windows\models\my_models_recognition\data\train\ ^
E:\caffe-windows\models\my_models_recognition\labels\train.txt ^
E:\caffe-windows\models\my_models_recognition\lmdb\train
pause

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

同理,运行如下程序修改测试集中的图片格式。

%格式转换的可执行文件%
%重新设定图像大小%
%打乱图片%
%转换格式%
%图片路径%
%图片标签%
%lmdb文件的输出路径%

E:\caffe-windows\Build\x64\Release\convert_imageset.exe ^
--resize_height=256 --resize_width=256 ^
--shuffle ^
--backend=“lmdb” ^
E:\caffe-windows\models\my_models_recognition\data\test\ ^
E:\caffe-windows\models\my_models_recognition\labels\test.txt ^
E:\caffe-windows\models\my_models_recognition\lmdb\test
pause

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在这里插入图片描述

step5:修改网络参数文件

在之前的文章中,我们使用过Googlenet,Googlenet适用于分类多,数据量大的情况,当数据集太小的时候容易出现过拟合现象(如本文只采用500个数据集),因此在这里我们使用caffenet来完成图像的分类。
在这里插入图片描述
把上述文件复制到my_models_recognition中,然后编辑网络参数文件
在这里,我们没有使用均值文件,因此将下列代码注释掉

#  transform_param {
#   mirror: true
#    crop_size: 227
#    mean_file: "data/ilsvrc12/imagenet_mean.binaryproto"
#  }
# mean pixel / channel-wise mean instead of mean image

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

同理,还有下列代码:

#  transform_param {
#    mirror: false
#    crop_size: 227
#    mean_file: "data/ilsvrc12/imagenet_mean.binaryproto"
#  }
# mean pixel / channel-wise mean instead of mean image

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

将第25行batch size改为100
将293和333行num_output改为512
373行中,因为这里我们只有五个类别,所以只需要5个输出即可,将1000改为5

step6:修改超参数文件

对超参数文件中的路径进行修改,最大迭代次数改为3000.,每500次迭代输出一次model,并新建文件夹model,用于存放训练得到的模型

net: "E:/caffe-windows/models/my_models_recognition/train_val.prototxt"
test_iter: 30
test_interval: 200
base_lr: 0.01
lr_policy: "step"
gamma: 0.1
stepsize: 1000
display: 50
max_iter: 3000
momentum: 0.9
weight_decay: 0.0005
snapshot: 500
snapshot_prefix: "E:/caffe-windows/models/my_models_recognition/model/"
solver_mode: GPU

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

step7:准备标签

新建label文件,在里面放置物体的类别
在这里插入图片描述

step8:修改deploy Prototxt文件

虽然在之前我们已经修改了网络结构文件,但是在测试过程中我们使用的是deploy Prototxt文件,因此我们对其进行同样的修改:

181行和157行输出改为512,第205行改为5.

step9:模型运行

运行批处理文件如下:

%train训练数据%
%超参数文件%

E:\caffe-windows\Build\x64\Release\caffe.exe train ^
-solver=E:/caffe-windows/models/my_models_recognition/solver.prototxt ^
pause

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
(第一次进行训练的时候是设置没5次迭代输出一次结构,第二次训练改为500次训练输出一次结构,因此前面有那些第五次第十次之类,忽略即可)

step10:准备测试图片

新建image文件夹,将我们要测试的图片放置在其中:
在这里插入图片描述

step11:模型测试

在jupyter中运行如下代码:

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:/caffe-windows/’
#网络结构描述文件
deploy_file = caffe_root+‘models/my_models_recognition/deploy.prototxt’
#训练好的模型
model_file = caffe_root+‘models/my_models_recognition/model/_iter_3000.caffemodel’

#gpu模式
#caffe.set_device(0)
caffe.set_mode_cpu()

#定义网络模型
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)

    <span class="token comment">#打印图片路径及名称</span>
    image_path <span class="token operator">=</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>root<span class="token punctuation">,</span><span class="token builtin">file</span><span class="token punctuation">)</span>
    <span class="token keyword">print</span><span class="token punctuation">(</span>image_path<span class="token punctuation">)</span>
    
    <span class="token comment">#显示图片</span>
    img<span class="token operator">=</span>Image<span class="token punctuation">.</span><span class="token builtin">open</span><span class="token punctuation">(</span>image_path<span class="token punctuation">)</span>
    plt<span class="token punctuation">.</span>imshow<span class="token punctuation">(</span>img<span class="token punctuation">)</span>
    plt<span class="token punctuation">.</span>axis<span class="token punctuation">(</span><span class="token string">'off'</span><span class="token punctuation">)</span>
    plt<span class="token punctuation">.</span>show<span class="token punctuation">(</span><span class="token punctuation">)</span>
    
    <span class="token comment">#预测图片类别</span>
    prediction <span class="token operator">=</span> net<span class="token punctuation">.</span>predict<span class="token punctuation">(</span><span class="token punctuation">[</span>input_image<span class="token punctuation">]</span><span class="token punctuation">)</span>
    <span class="token keyword">print</span> <span class="token string">'predicted class:'</span><span class="token punctuation">,</span>prediction<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>argmax<span class="token punctuation">(</span><span class="token punctuation">)</span>

    <span class="token comment"># 输出概率最大的前5个预测结果</span>
    top_k <span class="token operator">=</span> prediction<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>argsort<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span>
    <span class="token keyword">for</span> node_id <span class="token keyword">in</span> top_k<span class="token punctuation">:</span>     
        <span class="token comment">#获取分类名称</span>
        human_string <span class="token operator">=</span> labels<span class="token punctuation">[</span>node_id<span class="token punctuation">]</span>
        <span class="token comment">#获取该分类的置信度</span>
        score <span class="token operator">=</span> prediction<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">[</span>node_id<span class="token punctuation">]</span>
        <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">'%s (score = %.5f)'</span> <span class="token operator">%</span> <span class="token punctuation">(</span>human_string<span class="token punctuation">,</span> score<span class="token punctuation">)</span><span class="token punctuation">)</span>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

运行代码即可输出分类结果,我们发现模型的识别准确率非常高
在这里插入图片描述

        </div>
					<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-2b43bc2447.css" rel="stylesheet">
            </div>
								
				<script>
					(function(){
						function setArticleH(btnReadmore,posi){
							var winH = $(window).height();
							var articleBox = $("div.article_content");
							var artH = articleBox.height();
							if(artH > winH*posi){
								articleBox.css({
									'height':winH*posi+'px',
									'overflow':'hidden'
								})
								btnReadmore.click(function(){
									if(typeof window.localStorage === "object" && typeof window.csdn.anonymousUserLimit === "object"){
										if(!window.csdn.anonymousUserLimit.judgment()){
											window.csdn.anonymousUserLimit.Jumplogin();
											return false;
										}else if(!currentUserName){
											window.csdn.anonymousUserLimit.updata();
										}
									}
									
									articleBox.removeAttr("style");
									$(this).parent().remove();
								})
							}else{
								btnReadmore.parent().remove();
							}
						}
						var btnReadmore = $("#btn-readmore");
						if(btnReadmore.length>0){
							if(currentUserName){
								setArticleH(btnReadmore,3);
							}else{
								setArticleH(btnReadmore,1.2);
							}
						}
					})()
				</script>
				</article>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值