caffe训练自己的数据时准确率很好,但测试时很差是什么回事

Caffe 实例笔记 1 CaffeNet从训练到分类及可视化参数特征
这里是利用原文的网络设置tain_val prototxt和slover prototext,在models bvlc_reference_caffenet solver prototxt路径中,这里的训练和验证的网络基本一样用 include { phase: TRAIN } or include { phase: TEST }和来区分,其两点不同之处具体为
首先使用caffeNet训练数据集然后使用训练好的模型分类
1 使用caffeNet训练自己的数据集
主要参考:
官方网址:
数据集及第一部分参考网址:
主要步骤:
1. 准备数据集
2. 标记数据集
3. 创建lmdb格式的数据
4. 计算均值
5. 设置网络及求解器
6. 运行求解
由于imagenet的数据集太大,博主电脑显卡840m太弱,所以就选择了第二个网址中的数据集
,其训练集为1000张10类图片,验证集为200张图片,原作者已经整理好其标签放于对应的txt文件中,所以这里就省去上面的1-2步骤。
1.1 创建lmdb
使用对应的数据集创建lmdb:
这里使用 examples/imagenet/create_imagenet.sh,需要更改其路径和尺寸设置的选项,为了减小更改的数目,这里并没有自己新创建一个文件夹,而是直接使用了原来的imagenet的文件夹,而且将train.txt,val.txt都放置于/data/ilsvrc12中,
TRAIN_DATA_ROOT=/home/beatree/caffe-rc3/examples/imagenet/train/
VAL_DATA_ROOT=/home/beatree/caffe-rc3/examples/imagenet/val/
RESIZE=true
注意下面的地址的含义:
echo "Creating train lmdb..."
GLOG_logtostderr=1 $TOOLS/convert_imageset \
--resize_height=$RESIZE_HEIGHT \
--resize_width=$RESIZE_WIDTH \
--shuffle \
$TRAIN_DATA_ROOT \
$DATA/train.txt \
$EXAMPLE/ilsvrc12_train_lmdb
主要用了tools里的convert_imageset
1.2 计算均值
模型需要我们从每张图片减去均值,所以我们需要获得训练的均值,直接利用./examples/imagenet/make_imagenet_mean.sh创建均值文件binaryproto,如果之前创建了新的路径,这里同样需要修改sh文件里的路径。
这里的主要语句是
$TOOLS/compute_image_mean $EXAMPLE/ilsvrc12_train_lmdb \
$DATA/imagenet_mean.binaryproto
如果显示Check failed: size_in_datum == data_size () Incorrect data field size说明上一步的图片没有统一尺寸
1.3 设置网络及求解器
这里是利用原文的网络设置tain_val.prototxt和slover.prototext,在models/bvlc_reference_caffenet/solver.prototxt路径中,这里的训练和验证的网络基本一样用 include { phase: TRAIN } or include { phase: TEST }和来区分,其两点不同之处具体为:
transform_param {
mirror: true#不同1:训练集会randomly mirrors the input image
crop_size: 227
mean_file: "data/ilsvrc12/imagenet_mean.binaryproto"
data_param {
source: "examples/imagenet/ilsvrc12_train_lmdb"#不同2:来源不同
batch_size: 32#原文很大,显卡比较弱的会内存不足,这里改为了32,这里根据需要更改,验证集和训练集的设置也不一样
backend: LMDB
另外在输出层也有不同,训练时的loss需要用来进行反向传递,而val就不需要了。
solver.protxt的改动:
net: "/home/beatree/caffe-rc3/examples/imagenet/train_val.prototxt"#网络配置存放地址
test_iter: 4, 每个批次是50,一共200个
test_interval: 300 #每300次测试一次
base_lr: 0.01 #是基础学习率,因为数据量小,0.01 就会下降太快了,因此可以改成 0.001,这里博主没有改
lr_policy: "step" #lr可以变化
gamma: 0.1 #学习率变化的比率
stepsize: 300
display: 20 #20层显示一次
max_iter: 1200 一共迭代1200次
momentum: 0.9
weight_decay: 0.0005
snapshot: 600 #每600存一个状态
snapshot_prefix: "/home/beatree/caffe-rc3/examples/imagenet/"#状态存放地址
使用上面的配置训练,得到的结果准确率仅仅是0.2+,数据集的制作者迭代了12000次得到0.5的准确率
1.5.1杀掉正在运行的caffe进程:
ps -A#查看所有进程,及caffe的代码
kill -9 代码#杀掉caffe
1.5.2 查看gpu的使用情况
nvidia-sim -l
(NVIDIA System Management Interface)
1.5.3 查看时间使用情况
./build/tools/caffe time --model=models/bvlc_reference_caffenet/train_val.prototxt
我的时间使用情况
Average Forward pass: 3490.86 ms.
Average Backward pass: 5666.73 ms.
Average Forward-Backward: 9157.66 ms.
Total Time: 457883 ms.
1.5.4 恢复数据
如果我们在训练途中就停电或者有了其他的情况,我们可以通过之前保存的状态恢复数据,使用的时候直接添加&snapshot参数即可,如:
./build/tools/caffe train --solver=models/bvlc_reference_caffenet/solver.prototxt --snapshot=models/bvlc_reference_caffenet/caffenet_train_iter_10000.solverstate
这时候运行会从snapshot开始继续运行,如从第600迭代时运行:
2 使用pycaffe分类
2.1 import
首先载入环境:
environment: numpy for numerical routines, and matplotlib for plotting
import numpy as np
import matplotlib.pyplot as plt
# display plots in this notebook
%matplotlib inline#这里由于ipython启动时移除了 pylab 启动参数,所以需要使用这种格式查看,官网介绍http://ipython.org/ipython-doc/stable/interactive/reference.html#plotting-with-matplotlib:
#To start IPython with matplotlib support, use the --matplotlib switch. If IPython is already running, you can run the %matplotlib magic. If no arguments are given, IPython will automatically detect your choice of matplotlib backend. You can also request a specific backend with %matplotlib backend, where backend must be one of: &tk&, &qt&, &wx&, &gtk&, &osx&. In the web notebook and Qt console, &inline& is also a valid backend value, which produces static figures inlined inside the application window instead of matplotlib&s interactive figures that live in separate windows.
# set display defaults
#关于rcParams函数http://matplotlib.org/api/matplotlib_configuration_api.html#matplotlib.rcParams
plt.rcParams['figure.figsize'] = (10, 10)
# large images
plt.rcParams['image.interpolation'] = 'nearest'
# don't interpolate: show square pixels
plt.rcParams['image.cmap'] = 'gray'
# use grayscale output rather than a (potentially misleading) color heatmap
import caffe#如果没有设置好路径可能发现不了caffe,需要import sys cafe_root='你的路径',sys.path.insert(0,caffe_root+'python')之后再import caffe
下面下载模型,由于上面刚开始我们用的数据不是imagenet,现在我们直接下载一个模型,可能你的python中没有yaml,这里可以用pip安装(终端里):
sudo apt-get install python-pip
pip install pyyaml
cd #你的caffe root
./scripts/download_model_binary.py /home/beatree/caffe-rc3/model
/bvlc_reference_caffenet
#其他的网络路径如下:models/bvlc_alexnet
models/bvlc_reference_rcnn_ilsvrc13
models/bvlc_googlenet
model zoo的连接http://caffe.berkeleyvision.org/model_zoo.html,模型一共232m
2.2 模型载入
caffe.set_mode_cpu()#使用cpu模式
model_def='/home/beatree/caffe-rc3/models/bvlc_reference_caffenet/deploy.prototxt'
model_weights='/home/beatree/caffe-rc3/models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'
net=caffe.Net(model_def,
model_weights,
caffe.TEST)
mu=np.load('/home/beatree/caffe-rc3/python/caffe/imagenet/ilsvrc_2012_mean.npy')
mu=mu.mean(1).mean(1)
mu长成下面这个样子:
array([[[ 110.,
110., ...,
110.9342804 ,
110.5134201 ],
111., ...,
110.6951828 ],
[ 110.525177
111., ...,
得到bgr的均值
print 'mean-subtracted values:', zip('BGR', mu)
mean-subtracted values: [('B', 104.9), ('G', 116.67), ('R', 122.6)]
matplotlib加载的image是像素[0-1],图片的数据格式[weight,high,channels],RGB 而caffe加载的图片需要的是[0-255]像素,数据格式[channels,weight,high],BGR,那么就需要转换 ,这里用了 caffe.io.Transformer,可以使用help()来获得相关信息,他的功能有
preprocess(self, in_, data)
set_channel_swap(self, in_, order)
set_input_scale(self, in_, scale)
set_mean(self, in_, mean)
set_raw_scale(self, in_, scale)
set_transpose(self, in_, order)
# create transformer for the input called 'data'
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})#net.blobs['data'].data.shape=(10, 3, 227, 227)
transformer.set_transpose('data', (2,0,1))
# move image channels to outermost dimension第一个变成了channels
transformer.set_mean('data', mu)
# subtract the dataset-mean value in each channel
transformer.set_raw_scale('data', 255)
# rescale from [0, 1] to [0, 255]
transformer.set_channel_swap('data', (2,1,0))
# swap channels from RGB to BGR
2.3 cpu 分类
这里可以准备开始分类了,下面改变输入size的步骤也可以跳过,这里batchsize设置为50只是为了演示用,实际我们只对一张图片进行分类。
# set the size of the input (we can skip this if we're happy
# we can also change it later, e.g., for different batch sizes)
net.blobs['data'].reshape(50,
# batch size
# 3-channel (BGR) images
# image size is 227x227
image = caffe.io.load_image( 'path/to/images/cat.jpg')
transformed_image = transformer.preprocess('data', image)
plt.imshow(image)
得到一个可爱的小猫,接下来看一看模型是不是认为她是不是小猫vcD4NCjxwcmUgY2xhc3M9"brush:">
# copy the image data into the memory allocated for the net
net.blobs['data'].data[...] = transformed_image
### perform classification
output = net.forward()
output_prob = output['prob'][0]
# the output probability vector for the first image in the batch
print 'predicted class is:', output_prob.argmax(),output_prob[output_prob.argmax()]
得到结果:
predicted calss is 281 0.312436
也就是第281种最有可能,概率比重是0.312436
那么第231种是不是猫呢,让我们接着看
# load ImageNet labels
labels_file = caffe_root + 'data/ilsvrc12/synset_words.txt'#如果没有这个文件,须运行/data/ilsvrc12/get_ilsvrc_aux.sh
labels = np.loadtxt(labels_file, str, delimiter='\t')
print 'output label:', labels[output_prob.argmax()]
结果是answer is n tabby, tabby cat连花纹都判断对了。接下来让我们进一步观察判断的结果:
# 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])
得到的结果是:
[(0., 'n tabby, tabby cat'),#虎斑猫
(0.2379715, 'n tiger cat'),#虎猫
(0., 'n Egyptian cat'),#埃及猫
(0., 'n red fox, Vulpes vulpes'),#赤狐
(0., 'n lynx, catamount')]#猞猁,山猫
2.4 对比GPU
现在对比下GPU与CPU的性能表现
首先看看cpu每次(50 batch size)向前运行的时间:
%timeit net.forward()
%timeit能自动选择运行的次数 求平均运行时间,这里我的运行时间是1 loops, best of 3: 5.29 s per loop,官网的是1.42,差距
接下来看GPU的运行时间:
caffe.set_device(0)
caffe.set_mode_gpu()
net.forward()
%timeit net.forward()
1 loops, best of 3: 507 ms per loop(官网是70.2ms),慢了好多的说
2.5 查看中间输出
首先我们看下网络的结构及每层输出的shape,其形式应该是(batchsize,channeldim,height,weight)
# for each layer, show the output shape
for layer_name, blob in net.blobs.iteritems():
print layer_name + '\t' + str(blob.data.shape)
得到的结果如下:
(50, 3, 227, 227)
(50, 96, 55, 55)
(50, 96, 27, 27)
(50, 96, 27, 27)
(50, 256, 27, 27)
(50, 256, 13, 13)
(50, 256, 13, 13)
(50, 384, 13, 13)
(50, 384, 13, 13)
(50, 256, 13, 13)
(50, 256, 6, 6)
fc6 (50, 4096)
fc7 (50, 4096)
fc8 (50, 1000)
(50, 1000)
现在看其参数的样子,函数为net.params,其中weight的样子应该是(output_channels,input_channels,filter_height,flier_width), biases的形状只有一维(output_channels,)
for layer_name,parame in net.params.iteritems():
print layer_name+'\t'+str(param[0].shape),str(param[1].data.shape)#可以看出param里0为weight1为biase
(96, 3, 11, 11) (96,)#输入3通道,输出96通道
(256, 48, 5, 5) (256,)#为什么变成48了?看下方解释
(384, 256, 3, 3) (384,)#这里的输入没变
(384, 192, 3, 3) (384,)
(256, 192, 3, 3) (256,)
fc6 () (4096,)#*3
fc7 () (4096,)
fc8 () (1000,)
可以看出只有卷基层和全连接层有参数
既然后了各个参数我们就初步解读下caffenet:
首先第一层conv1其输出结果的变化
(图片来自博客)
这一步应该可以理解,其权重的形式为(96, 3, 11, 11)
但是第二层的卷积层为什么为(256, 48, 5, 5),因为这里多了一个group选项,在cs231n里没有提及,这里的group=2,把输入输出分为了两个组也就是输入变成了96/2=48,
全连接层fc6的数据流图:
这是一张特拉维夫大学的ppt
下面进行可视化操作,首先要定义一个函数方便以后调用,可视化各层参数和结果:
def vis_square(data):
"""Take an array of shape (n, height, width) or (n, height, width, 3)
and visualize each (height, width) thing in a grid of size approx. sqrt(n) by sqrt(n)"""
#输入为格式为数量,高,宽,(3),最终展示是在一个方形上
# normalize data for display
#首先将数据规则化
data = (data - data.min()) / (data.max() - data.min())
# force the number of filters to be square
n = int(np.ceil(np.sqrt(data.shape[0])))
#pad是补充的函数,paddign是每个纬度扩充的数量
padding = (((0, n ** 2 - data.shape[0]),
(0, 1), (0, 1))
# add some space between filters,间隔的大小
+ ((0, 0),) * (data.ndim - 3))
# don't pad the last dimension (if there is one)如果有3通道,要保持其不变
data = np.pad(data, padding, mode='constant', constant_values=0)
# pad with zero (black)这里该为了黑色,可以更容易看出最后一列中拓展的样子
# tile the filters into an image
data = data.reshape((n, n) + data.shape[1:]).transpose((0, 2, 1, 3) + tuple(range(4, data.ndim + 1)))
data = data.reshape((n * data.shape[1], n * data.shape[3]) + data.shape[4:])
plt.imshow(data)
plt.axis('off')
以conv1为例,探究如果reshape的
filters = net.params['conv1'][0].data
vis_square(filters.transpose(0, 2, 3, 1))
得到的结果
这里conv1的权重,原来的shape是(96, 3, 11, 11),其中输出为96层,每个filter的大小是11 11 3(注意后面的3噢),每个filter经过滑动窗口(卷积)得到一张output,一共得到96个。
首先进入vissquare之前要transpose&》(96,11,11,3)
输入vis_square得到的padding是(0,4),(0,1),(0,1),(0,0) 也就是经过padding之后变为(100,12,12,3),这时的12多出了一个边框,第一个reshape(10,10,12,12,3),相当于原来100个图片一排变为矩阵式排列,然后又经过transpose(0,2,1,3,4)—&(10,12,10,12,3)又经过第二个reshape(120,120,3)
下面展示第一层filter输出的特征:
feat = net.blobs['conv1'].data[0, :36]#原输出为(50,96,55,55),这里取第一幅图前36张
vis_square(feat)
如果取全部的96张会出现下面的情况:中间的分割线没有了,为什么呢?
用上面的方法也可以查看其他几层的输出。
对于全连接层的输出需要用直方图的形式:
feat = net.blobs['fc6'].data[0]
plt.subplot(2, 1, 1)
plt.plot(feat.flat)
plt.subplot(2, 1, 2)
_ = plt.hist(feat.flat[feat.flat & 0], bins=100)#bin统计某一个数段之间的数量
输出分类结果:
feat = net.blobs['prob'].data[0]
plt.figure(figsize=(15, 3))
plt.plot(feat.flat)
大体就是这样了,我们可以用自己的图片来分类看看结果
主要分类过程代码主要步骤:
1. 载入工具包
2. 设置显示设置
3. 设置求解其set_mode_cup()/gpu()
4. 载入模型 net=caffe.Net(,,caffe.TEST)
5. transformer(包括载入均值)
6. 设置分类输入size(batch size等)
7. 载入图片并转换(io.load_image(&path&), transformer.preprocesss)
8. net.blobs[&data&],data[…]=transformed_image
9. 向前计算output=net.forward
10. output_prob=output[&prob&][0]
11. 载入synset_words.txt(np.loadtxt(,,))
12. 分类结果输出 output_prob.argsort()[::-1][] ?????
13. 展示各层输出net.blobs.iteritems()
14. 展示各层参数net.params.iteritems()
15. 可视化注意pad和reshape,transpose的运用
16. net.params[&name&][0].data
17. net.blobs[&name&].data[0,:36]
18. net.blobs[&prob&].data[0]#每个图片都有不同的输出所以后面加了个【0】用mnist数据集训练好的caffe模型,用自己的手写图片进行测试,准确率很低。请问这是为什么? - 知乎13被浏览2472分享邀请回答2添加评论分享收藏感谢收起0添加评论分享收藏感谢收起查看更多回答caffe第二个比较经典的[小图片]识别例子CIFAR_10的运行,网络模型的详解
(一)CIFAR-10简述
CIFAR-10是什么?
Cifar-10是由Hinton的两个大弟子Alex Krizhevsky和Ilya Sutskever收集的一个用于普通物体识别的数据集。
CIFAR是由加拿大牵头投资的一个先进的科学项目研究所.Hinton和Bengio以及他的学生在2004年拿到了CIFAR项目投
资的少量资金.建立了神经计算和自适应感知项目.
这个项目集结了不少的科学家,生物学家,电气工程师,神经科学家,物理学家,心理学家,加速推动了DL的进程.
从这个阵容来看,DL和ML系列的数据挖掘分的已经很远了.DL强调的是自适应感知和人工智能,是计算机与神经科学交叉
的一个学科.而ML强调的是高速,大数据,统计数学分析,是计算机和数学的交叉.
(二)cifar-10数据集简介:
1---CIFAR-10(DataSet)这个数据集总共包含:60000张图片
1---图片size:32pixel*32pixel
2---图片深度:三通道RGB的彩色图片
2---这60000张图片:
1---共分为10类,具体的分类如下图所示:
2---60000张图片里面有:
1--50000张训练样本
2--10000张测试样本(验证Set)
1---CIFAR-10:是一个[普通物体]识别的数据集
2---因此,这个数据集和网络模型的最大特点就是:可以很容易的将[物体识别]迁移到其他普通的物体
3---而且可以将10分类问题扩展至100类物体的分类,甚至1000类和更多类的物体分类(当然,需要你们
有更多的GPU和DataSet)
4---注意的一点是:
这个示例中的数据集存在一个L
1---的numpy的数组中------10000张图片*每张图片的像素数组
2---单位是uint8s
3---3072存储了一个32*32的彩色图片(3*32*32==3*)
4---numpy的前1024位是RGB中的R分量像素值,中间的1024位是G分量的像素值,最后的1024是B分量
5---最后注意的一点是:
CIFAR-10这个例子只能用于[小图片]的分类,正如前面讲的Mnist示例,主要用于[手写数字的识别一样]
(三)CIFAR-10所使用的卷积神经CNN的网络模型
1---DL的两大核心:数据+模型,上面,我们比较详细的讲述了CIFAR-10所使用的数据集(DataSet),下面我们来
看看CIFAR-10所使用的网络Net模型吧
2---该模型在caffe中的描述配置文件为:cifar10_quick_train_test.prototxt
3---该文件所在的位置:/home/wei/caffe/examples/cifar10/cifar10_quick_train_test.prototxt,如下
4---该CNN-NET主要由:卷积层,POOLing层,非线性变换层,局部对比归一化线性分类器组成
#(四)CIFAR10示例的具体操作运行过程:
1--下载数据集
执行下面的命令:sudo sh ./data/cifar10/get_cifra10.sh
如下图所示:
下载过程如下所示:
下载成功之后,在/home/wei/data/cifar10/文件目录下会看到以下的二进制文件数据:
2--将刚才下载下来的[二进制数据集文件]转换成[caffe所识别的LMDB或者LevelDB格式的形式],并且计算
数据集的均值文件
1---数据格式的转化和计算均值所需要使用的所有的shell命令都被写在了一个shell脚本中,所以我们只需
要运行这个shell脚本就可以了,这个shell脚本在:/home/wei/examples/cifar10/文件夹下,名字为:
create_cifar10.sh
2--使用下面的命令:sudo sh ./examples/cifar10/create_cifar10.sh
3--下载成功之后,会在/home/wei/caffe/examplse/cifar10/目录下生成三个文件(如下图所示):
1--cifar10_train_lmdb--------训练样本数据集
2--cifar10_test_lmdb---------测试样本数据集
3--mean.binaryproto----------数据集的均值文件(用于减均值操作)
(五)训练和测试网络模型
在这个阶段,寻妖准备三个文件:
1---网络模型配置文件:cifar10_quick_train_test.prototxt
2---超参数配置文件solver:cifar10_quick_solver.prototxt
3---训练脚本文件:train_quick.sh
1--建立训练上面数据的网络模型,当然在这个例子中,caffe已经为我们创建好了,那就是/home/wei/caffe/examples/
cifar10/文件夹下面的:cifar10_quick_train_test.prototxt
2---配置参数设置solver文件,当然caffe也已经为我们准备好了,这个文件位于/home/wei/caffe/examples/cifar10/
文件夹下面的:cifar10_quick_solver.prototxt
3---编写训练模型的shell脚本文件:train_quick.sh
4---由于我使用的CPU没有GPU,所以还要改cifar10_quick_solver.prototxt配置文件的最后一项:将GPU改为CPU
准备好数据+模型+参数配置solver文件之后,执行下面的命令:
sudo ./examples/cifar10/train_quick.sh
训练的过程如下所示:
其中,每迭代100次,显示一次训练时的lr(learning rate)和loss(训练损失函数),每过500次,输出score 0(准确率)
训练完成后,训练好的模型参数存储在二进制protobuf格式的文件中,CIFAR10训练好的模型存储在:/home/wei/
caffe/examples/cifar10/文件夹低下,名字为:cifar10_quick_iter_5000
最后,总结一下训练一个网络用到的相关文件:
cifar10_quick_solver.prototxt:方案配置,用于配置迭代次数等信息,训练时直接调用caffe train指定这个文件,就会开始训练
cifar10_quick_train_test.prototxt:训练网络配置,用来设置训练用的网络,这个文件的名字会在solver.prototxt里指定
cifar10_quick_iter_4000.caffemodel.h5:训练出来的模型,后面就用这个模型来做分类
cifar10_quick_iter_4000.solverstate.h5:也是训练出来的,应该是用来中断后继续训练用的文件
cifar10_quick.prototxt:分类用的网络安全检查中...
请打开浏览器的javascript,然后刷新浏览器
< 浏览器安全检查中...
还剩 5 秒&}

我要回帖

更多关于 caffe输出测试准确率 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信