利用caffe 训练训练siamese网络时,有训练出很好结果的吗

利用GPU和Caffe训练神经网络
发表于 07:53|
来源www.joyofdata.de|
作者Raffael Vogler
摘要:本文为利用GPU和Caffe训练神经网络的实战教程,介绍了根据Kaggle的“奥托集团产品分类挑战赛”的数据进行训练一种多层前馈网络模型的方法,如何将模型应用于新数据,以及如何将网络图和训练权值可视化。
【编者按】本文为利用GPU和Caffe训练神经网络的实战教程,介绍了根据Kaggle的“奥托集团产品分类挑战赛”的数据进行训练一种多层前馈网络模型的方法,如何将模型应用于新数据,以及如何将网络图和训练权值可视化。Caffe是由发起的一个开源深度学习框架,它允许你利用你的GPU训练神经网络。相对于其他的深度学习框架如Theano或Torch等,Caffe不需要你自己编写算法程序,你只需要通过配置文件来指定网络。显然,这种做法比自己编写所有程序更加节省时间,也将你限制在一定的框架范围内。不过,在大多数情况下,这没有太大的问题,因为Caffe提供的框架相当强大,并且不断进步。这篇文章的主题由一种多层前馈网络组成。该模型将根据Kaggle的“”的数据进行训练。我们还关注将模型应用于新数据,以及如何将网络图(network graph)和训练得到的权值可视化。限于篇幅,本文不会解释所有的细节。另外,简单的代码比一千多字的话更有说服力。相对于对照来程序化细节,本文将着重描述观念以及一些我遇到的绊脚石。设置如果你还没有把Caffe安装在你的系统上,我建议在一个允许GPU处理的EC2实例上工作,例如g2.2xlarge实例。有关如何使用EC2工作的介绍可以查看,设置Caffe及其准备工作可以参考。对于使用Caffe,我也建议你在你的实例上安装IPython
Notebook——在可以找到教程。定义模型和元参数一个模型及其应用的训练至少需要三个配置文件。这些配置文件的格式遵循界面描述语言,称为协议缓冲区()。它表面上类似于JSON,但却又显著不同,实际上应该在需要进行验证(通过自定义模式的方式——像Caffe的这样)和序列化的数据文档中取代它。为了训练,你必须有一个prototxt文件保持训练的元参数()以及一个模型用于定义网络图形()——以非周期和定向的方式连接各层。需要注意的是,数据从底部流向到顶部时伴随着关于怎样指定层的顺序。这里的示例网络有五个层次:数据层(一个用于训练,一个用于测试)内积层(权值Ⅰ)ReLUs(隐含层)内积层(权值Ⅱ)输出层(用于分类的Soft Max)&A,Soft Max层给出损失&B,准确性层——允许我们看到网络如何在训练的同时提升。以下从model_train_test.prototxt的摘录显示层(4)和(5A):[...]
name: "ip2"
type: "InnerProduct"
bottom: "ip1"
top: "ip2"
inner_product_param {
num_output: 9
weight_filler {
type: "xavier"
bias_filler {
type: "constant"
name: "accuracy"
type: "Accuracy"
bottom: "ip2"
bottom: "label"
top: "accuracy"
phase: TEST
[...]第三个prototxt文件()指定应用于它的网络。在这种情况下,它与训练规范大体上是一致的——但它缺乏数据层(因为我们不从产品的数据源中读取数据)并且Soft Max层不会产生损耗值但有分类的可能。另外,准确性层现在已经没有了。还要注意的是,我们现在在开始指定输入尺寸(如预期:1,93,1,1)——它是肯定混乱的,所有四个尺寸被称为input_dim,只有顺序定义哪个是哪个,并没有指定明确的背景。支持的数据源这是开始尝试使用Caffe时要克服的首要心理障碍之一。它不像使用一些CSV来提供Caffe可执行的方式那样简单。实际上,对于没有图像的数据,你有三种选择。LMDB(闪电内存映射数据库)LevelDBHDF5格式HDF5可能是最容易使用的,因为你只需要采用HDF5格式把数据集存储到文件中。LMDB和LevelDB是数据库,所以你必须按照他们的协议。HDF5格式存储数据集的大小会被内存限制,这就是为什么我抛弃它的原因。LMDB和LevelDB之间的选择是相当随便的——从我掠过的资源来看,LMDB似乎更强大,速度更快,更成熟。然后从GitHub来看,LevelDB的维护似乎更积极,也具有较大的Google和StackOverflow的足迹。Blobs和DatumsCaffe内部使用一个叫做Blobs的数据结构进行工作,它用于正向传递数据和反向渐变。这是一个四维数组,其四个维度被称为:N或batch_size通道高度宽度这与我们有关,因为在把它存储到LMDB之前我们必须按照结构塑造我们的案例——从它被送到Caffe的地方。图像的形状是直观的,一批次64个按规定的100×200 RGB像素的图像将最终作为形阵列(64,3,200,100)。对于一批64个特征矢量,每个长度93的Blob的形状为(64,93,1,1)。在将数据加载到LMDB时,你可以看到个别案例或特征向量存储在Datum的对象上。整型数据被存储在(字节串格式)data中,浮点型数据存储在float_data中。一开始我犯错将浮点型数据分配到data中,从而导致该模型不学习任何东西。在将Datum存储到LMDB之前,你需要将对象序列化成一个字节的字符串表示。总结对我来说,掌握Caffe是一个令人惊讶的非线性体验。也就是说,要深刻理解这个系统,还没有任何的切入点和持续的学习路径。让Caffe对你发挥作用的有效信息,分布在很多不同的,,以及。这就是为什么我花时间撰写本教程及相关的代码。在我将学到的知识总结形成文本之后,我自己都要从头读一下。我认为Caffe有一个光明的未来——只要添加新的功能,它将不仅仅是水平的增长,而且会垂直的重构和改善所有用户的体验。这绝对是高性能深度学习的好工具。如果你想要做图像处理和卷积神经网络,我建议你看看,它会为你提供一个舒适的GUI来实现目标。原文链接:(翻译/王玮 责编/周建丁)
推荐阅读相关主题:
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章7868人阅读
caffe(5)
step 1.&&&&&&首先,确保caffe已经正确安装,并且make runtest基本通过。
step 2.&&&&&&准备训练集:
& & & &&在训练之前,要准备训练需要的训练集,为了验证训练的效果,最好也准备一定数量的测试集。由于caffe的数据集的输入是leveldb格式,因此在训练前需要将输入转为相应格式。
& & & &&在caffe_root/example 文件夹中,提供了一些例子,cifar10与imagenet均是将图片形式数据库转换为leveldb格式,mnist则是将其本身的数据集转换为leveldb格式。这就要求我们需要把自己的数据集转换成leveldb格式,需要自己编写程序实现。下面以jpg格式图片为例说明。
在此,假设数据库本身是以图片形式给出,并且给出了label或者同一类别的图片已经分类。这样我们就可以通过imagenet例子中给出的create_imagenet.sh 对我们自己的数据库进行转换,要求数据集图片格式为jpg,以下为具体操作步骤:
& & & &&A.若数据集已经给出label则忽略此步骤。图片按照类别装在不同文件夹下的情况,自己编写mklabel.sh命令,对图片进行处理并标明label。具体操作参照mklabel.sh 程序说明。
&pre name=&code& class=&plain&&mklabel.sh
#----------------------------------------------------
#文件存放形式为
# dir/subdir1/files...
# dir/subdir2/files...
# dir/subdir3/files...
# dir/subdirX/files...
#1.$ sh mklabel.dir 为目标文件夹名称
#2.$ chmod a+x mklabel.sh ;然后可以直接用文件名运行
#3.默认label信息显示在终端,请使用转向符'&'生成文本,例:
$ sh ./mklabel.sh
data/faces94/male
& label.txt
#4.确保文件夹下除了图片不含其他文件(若含有则需自行添加判断语句)
#-----------------------------------------------------
DIR=~/codes/mklabel.sh
#命令位置(无用)
#label起始编号(为数字,根据自己需要修改)
#保留的测试集大小
if test $# -eq 0;then #无参数,默认为当前文件夹下,label=1
$DIR . 0 $label
if test $# -eq 1;then #仅有位置参数,默认testnum=0,label=1
$DIR $1 0 $label
if test $# -eq 2;then #两个参数时,label=1
$DIR $1 $2 $label
testnum=$2
#每个类别保留测试集大小
#自定义label起始
#转到目标文件夹
if test $testnum -ne 0;then
mkdir &testdata& #建立测试集
for i in * ; do
exist=`expr &$i& != &testdata&`
if test -d $i && test $exist -eq 1;then #文件夹存在
#echo 'DIR:' $i
#进入文件夹
for j in *
if test $num -gt $then
num=`expr $num + 1`
#回到上层目录
if test $testnum -eq 0;then
mv $i ./testdata
label=`expr $label + 1`
#计算label
& & & &&B.修改create_imagenet.sh 文件,使其中的图片源地址与标明label的txt文件对应到自己数据库的相应文件。其中的convert_imageset.cpp 函数的参数依次为图片文件夹位置,label.txt文本文件,目标数据集名称,是否随机存储图片与label(即打乱图片数据的读入顺序)。
若你所使用的数据集不是通过图片形式给出,为了方便,可以根据leveldb数据的存储格式,自己编写程序转换数据集。
& & & &&C.多通道图片需要用到meanfile,通过example/imagenet文件夹下的shell函数make_imagenet_mean.sh,更改相应函数,很轻松的得到binaryproto文件,在训练时可能需要用到。
step 3.&&&&&&使用自己的数据进行训练:
& & & &&以最简单的mnist网络为例,因为数据集的不同则需要更改的参数也不同。在训练前最好在example下新建个文件夹命名为数据集的名称,然后把mnist下的5个文件:
&&&&&&& lenet.prototxt
&&&&&&& lenet_solver.prototxt
&&&&&&& lenet_train.prototxt
&&&&&&& lenet_test.prototxt
&&&&&&& train_lenet.sh
& & & 复制到新文件夹下,以上5个文件为必需的文件。按顺序对以上文件进行修改,在忽略网络结构的情况下,需要修改的有:
& & & &&a.&&&&&&lenet.prototxt:
input_dim: 64
input_dim: 1
input_dim: 28
input_dim: 28
& & & &&分别为一次导入的图片个数,channel,heigth ,width。
& & & & & & & & & & & 倒数第二层,即输入给softmax层数据的那层,其中的num_output需要更改为实际图片的label数,即图片类别数。否则在进行训练时,会出现错误。
& & & & & & & & & & & & & & & & & &
& & & &&b.&&&&&&lenet_solver.prototxt:
& & & &如果之前文件名没改的话则不需要更改以上两项,否则改为对应文件。其他参数根据实际需要更改。
& & & &&c.&&&&&&lenet_train.prototxt:
& & & & 需要把data层的数据源文件替换为自己的数据。
& & & & & & &&
& & & &&在训练多通道图片时,此处最好需要有一个meanfile参数。例如cifar10
& & & &num_output参数参照lenet.prototxt修改。
& & & &&d.&&&&&&lenet_test.prototxt:
& & & &&参照lenet_train.prototxt 进行相应修改。
& & & &&e.&&&&&&train_lenet.sh:
& & & & &lenet_solver.prototxt文件名未更改的话则不需要进行改动。
step 4.&&&&&&使用自己的model进行分类:
& & & &&Reference:&
& & & & &假设之前的所有步骤已经成功,并且已经训练出正确率还行的model,则现在就可以使用model对图片进行分类。
& & & &&a.&&&&&&首先确保已经正确安装了pythonwrapper,以及caffe_root/python/文件夹下requirements.txt文件中所需要的组件。
& & & &&b.&&&&&&另外,还需要meanfile的npy文件。即需要把数据对应的binaryproto文件转换到npy文件。Caffe_root/python/caffe/io.cpp文件中已经给了对应的API。
& & & &&具体参照:
& & & &&需要对blobproto_to_array 进行修改,得到blobproto_to_array2.
& & & &&即删去了blob.num 项。
& & & &&通过调用此API进行处理,具体python函数如下:
& & & &&convert_bproto_to_npy.py
#!/usr/bin/python
import numpy as np
from caffe.io import blobproto_to_array2
from caffe.proto import caffe_pb2
blob = caffe_pb2.BlobProto()
filename = './imagenet_mean.binaryproto'
data = open(filename, &rb&).read()
blob.ParseFromString(data)
nparray =blobproto_to_array2(blob)
f = file(&mean.npy&,&wb&)
np.save(f,nparray)
& & & &&c.&&&&&&按照demo步骤进行分类:
& & & &&代码的主要部分参照
& & & &&classify.py
& & & &&classifymap.py
& & & &&输出部分的说明
& & & &&1)&&&&&Classify.py
& & & &&输出的是prediction[0],一维数组,以imagenet为例就是大小为1000的数组,每个值对应概率大小。
& & & &&处理部分代码:
preDict = {}
for i in xrange(len(prediction[0])):
preDict[prediction[0][i]] = i
for i in xrange(5):
val = sorted(preDict.keys())[-i -1]
print(&%d %f %s& %(preDict[val], val * 100, linecache.getline(SYNSET, preDict[val])))
& & & &&把数组的值和索引对应到字典中,值作为键,把数组值进行排序,再用前五个作为键,找出索引值,也就是对应的类别。
为了能够直观地显示数字所代表的类别名,需要输出synset_words.txt文件中对应行数的内容。这里用的是linecache.getline()函数,需要
& & & &&import caffe
& & & &&为了修改方便,把synset_words.txt的路径设为变量
& & & &&SYNSET = '../../data/ilsvrc12/synset_words.txt'
& & & &&(序号概率值(百分比)对应种类)
& & & & 2)&&&&&Classifymap.py
& & & &&输出的是
& & & & & & & & & & &outMat =out['prob'][0].argmax(axis=0)
是一个二维矩阵,8*8大小,每个值对应的都是一种类别,出现的越多代表概率越高。
& & & &&处理部分代码:
h1, w1 = np.shape(outMat)
outList = list(np.reshape(outMat,h1 * w1))
#print(outList)
outSet = set(outList)
outdict = {}
for x in outSet:
outdict[outList.count(x)]=x
appear = outdict.keys()
applen = len(appear)
if len &= 5:
for i in xrange(applen):
print('%d %d: %s'%(outdict[appear[-(i+1)]], appear[-(i+1)],linecache.getline(SYNSET,outdict[appear[-(i+1)]])))
for i in xrange(5):
print('%d %d: %s'%(outdict[appear[-(i+1)]], appear[-(i+1)], linecache.getline(SYNSET,outdict[appear[-(i+1)]])))
& & & &&和上面的文件大致思路相同。但是需要先把矩阵展开成一维列表,用set()变成集合,也就是去掉重复元素,再一一对应到字典中,然后通过count()找到每个值在矩阵中出现的次数,进行排序即可。
& & & &&(序号出现次数对应种类)
& & & &&3) &源代码:
& & & &&Classiy.py
import numpy as np
import matplotlib.pyplot as plt
import pylab
import caffe
caffe_root = '../'
MODEL_FILE = '../imagenet/imagenet_deploy.prototxt'
PRETRAINED = '../imagenet/caffe_reference_imagenet_model'
IMAGE_FILE = '../images/cat.jpg'
#net = caffe.Classifier(MODEL_FILE, PRETRAINED, mean_file = caffe_root + '../python/caffe/imagenet/ilsvrc_2012_mean.npy', channel_swap = (2,1,0), input_scale = 255)
net = caffe.Classifier(MODEL_FILE, PRETRAINED, mean_file = caffe_root + 'mean2.npy', channel_swap = (2,1,0), input_scale = 255)
net.set_phase_test()
net.set_mode_gpu()
input_image = caffe.io.load_image(IMAGE_FILE)
pylab.ion()
plt.imshow(input_image)
#pylab.show()
prediction = net.predict([input_image])
print 'prediction shape:', prediction[0].shape
#print(prediction[0])
plt.plot(prediction[0])
#pylab.show()
preDict = {}
preList = list(prediction[0])
for i in preList:
preDict[preList[i]] = i
preLen = len(preList)
for i in xrange(5):
print('%d %d: %s' %(preDict[preDict.keys[-(i+1)]], preDict.values[-(i+1)], linecache.getline(SYNSET,preDict.values[-(i+1)])))
classifymap.py
import caffe
import matplotlib.pyplot as plt
import pylab
import numpy as np
import linecache
IMAGE_FILE ='../images/dog.jpg'
SYNSET = '../../data/ilsvrc12/synset_words.txt'
# Load the original network and extract the fully-connected layers' parameters.
net = caffe.Net('../imagenet/imagenet_deploy.prototxt', '../imagenet/caffe_reference_imagenet_model')
params = ['fc6', 'fc7', 'fc8']
# fc_params = {name: (weights, biases)}
fc_params = {pr: (net.params[pr][0].data, net.params[pr][1].data) for pr in params}
#for fc in params:
#print '{} weights are {} dimensional and biases are {} dimensional'.format(fc, fc_params[fc][0].shape, fc_params[fc][1].shape)
# Load the fully-convolutional network to transplant the parameters.
net_full_conv = caffe.Net('../imagenet/imagenet_full_conv.prototxt', '../imagenet/caffe_reference_imagenet_model')
params_full_conv = ['fc6-conv', 'fc7-conv', 'fc8-conv']
# conv_params = {name: (weights, biases)}
conv_params = {pr: (net_full_conv.params[pr][0].data, net_full_conv.params[pr][1].data) for pr in params_full_conv}
#for conv in params_full_conv:
#print '{} weights are {} dimensional and biases are {} dimensional'.format(conv, conv_params[conv][0].shape, conv_params[conv][1].shape)
for pr, pr_conv in zip(params, params_full_conv):
conv_params[pr_conv][1][...] = fc_params[pr][1]
for pr, pr_conv in zip(params, params_full_conv):
out, in_, h, w = conv_params[pr_conv][0].shape
W = fc_params[pr][0].reshape((out, in_, h, w))
conv_params[pr_conv][0][...] = W
# net_full_conv.save('../imagenet/caffe_imagenet_full_conv')
# load input and configure preprocessing
im = caffe.io.load_image(IMAGE_FILE)
plt.imshow(im)
#pylab.show()
net_full_conv.set_mean('data', '../../python/caffe/imagenet/ilsvrc_2012_mean.npy')
net_full_conv.set_channel_swap('data', (2,1,0))
net_full_conv.set_input_scale('data', 255.0)
# make classification map by forward pass and show top prediction index per location
out = net_full_conv.forward_all(data=np.asarray([net_full_conv.preprocess('data', im)]))
outMat = out['prob'][0].argmax(axis=0)
h1, w1 = np.shape(outMat)
outList = list(np.reshape(outMat,h1 * w1))
#print(outList)
outSet = set(outList)
outdict = {}
for x in outSet:
outdict[outList.count(x)]=x
appear = outdict.keys()
applen = len(appear)
if len &= 5:
for i in xrange(applen):
print('%d %d: %s' %(outdict[appear[-(i+1)]], appear[-(i+1)], linecache.getline(SYNSET,outdict[appear[-(i+1)]])))
for i in xrange(5):
print('%d %d: %s' %(outdict[appear[-(i+1)]], appear[-(i+1)], linecache.getline(SYNSET,outdict[appear[-(i+1)]])))
在训练之前,要准备训练需要的训练集,为了验证训练的效果,最好也准备一定数量的测试集。由于caffe的数据集的输入是leveldb格式,因此在训练前需要将输入转为相应格式。
在caffe_root/example 文件夹中,提供了一些例子,cifar10与imagenet均是将图片形式数据库转换为leveldb格式,mnist则是将其本身的数据集转换为leveldb格式。这就要求我们需要把自己的数据集转换成leveldb格式,需要自己编写程序实现。下面以jpg格式图片为例说明。
在此,假设数据库本身是以图片形式给出,并且给出了label或者同一类别的图片已经分类。这样我们就可以通过imagenet例子中给出的create_imagenet.sh 对我们自己的数据库进行转换,要求数据集图片格式为jpg,以下为具体操作步骤:
A.若数据集已经给出label则忽略此步骤。图片按照类别装在不同文件夹下的情况,自己编写mklabel.sh命令,对图片进行处理并标明label。具体操作参照mklabel.sh 程序说明。
&pre name=&code& class=&plain&&mklabel.sh
#----------------------------------------------------
#文件存放形式为
# dir/subdir1/files...
# dir/subdir2/files...
# dir/subdir3/files...
# dir/subdirX/files...
#1.$ sh mklabel.dir 为目标文件夹名称
#2.$ chmod a+x mklabel.sh ;然后可以直接用文件名运行
#3.默认label信息显示在终端,请使用转向符'&'生成文本,例:
$ sh ./mklabel.sh
data/faces94/male
& label.txt
#4.确保文件夹下除了图片不含其他文件(若含有则需自行添加判断语句)
#-----------------------------------------------------
DIR=~/codes/mklabel.sh
#命令位置(无用)
#label起始编号(为数字,根据自己需要修改)
#保留的测试集大小
if test $# -eq 0;then #无参数,默认为当前文件夹下,label=1
$DIR . 0 $label
if test $# -eq 1;then #仅有位置参数,默认testnum=0,label=1
$DIR $1 0 $label
if test $# -eq 2;then #两个参数时,label=1
$DIR $1 $2 $label
testnum=$2
#每个类别保留测试集大小
#自定义label起始
#转到目标文件夹
if test $testnum -ne 0;then
mkdir &testdata& #建立测试集
for i in * ; do
exist=`expr &$i& != &testdata&`
if test -d $i && test $exist -eq 1;then #文件夹存在
#echo 'DIR:' $i
#进入文件夹
for j in *
if test $num -gt $then
num=`expr $num + 1`
#回到上层目录
if test $testnum -eq 0;then
mv $i ./testdata
label=`expr $label + 1`
#计算label
B.修改create_imagenet.sh 文件,使其中的图片源地址与标明label的txt文件对应到自己数据库的相应文件。其中的convert_imageset.cpp 函数的参数依次为图片文件夹位置,label.txt文本文件,目标数据集名称,是否随机存储图片与label(即打乱图片数据的读入顺序)。
若你所使用的数据集不是通过图片形式给出,为了方便,可以根据leveldb数据的存储格式,自己编写程序转换数据集。
C.多通道图片需要用到meanfile,通过example/imagenet文件夹下的shell函数make_imagenet_mean.sh,更改相应函数,很轻松的得到binaryproto文件,在训练时可能需要用到。
step 3.&&&&&&使用自己的数据进行训练:
以最简单的mnist网络为例,因为数据集的不同则需要更改的参数也不同。在训练前最好在example下新建个文件夹命名为数据集的名称,然后把mnist下的5个文件:
&&&&&&& lenet.prototxt
&&&&&&& lenet_solver.prototxt
&&&&&&& lenet_train.prototxt
&&&&&&& lenet_test.prototxt
&&&&&&& train_lenet.sh
& & & 复制到新文件夹下,以上5个文件为必需的文件。按顺序对以上文件进行修改,在忽略网络结构的情况下,需要修改的有:
a.&&&&&&lenet.prototxt:
input_dim: 64
input_dim: 1
input_dim: 28
input_dim: 28
分别为一次导入的图片个数,channel,heigth ,width。
& & & & & & & & & & & 倒数第二层,即输入给softmax层数据的那层,其中的num_output需要更改为实际图片的label数,即图片类别数。否则在进行训练时,会出现错误。
& & & & & & & & & & & & & & & & & &
b.&&&&&&lenet_solver.prototxt:
& & & &如果之前文件名没改的话则不需要更改以上两项,否则改为对应文件。其他参数根据实际需要更改。
c.&&&&&&lenet_train.prototxt:
& & & & 需要把data层的数据源文件替换为自己的数据。
& & & & & & &&
& & & &&在训练多通道图片时,此处最好需要有一个meanfile参数。例如cifar10
& & & &num_output参数参照lenet.prototxt修改。
d.&&&&&&lenet_test.prototxt:
& & & &&参照lenet_train.prototxt 进行相应修改。
e.&&&&&&train_lenet.sh:
& & & & &lenet_solver.prototxt文件名未更改的话则不需要进行改动。
step 4.&&&&&&使用自己的model进行分类:
& & & &&Reference:
& & & & &假设之前的所有步骤已经成功,并且已经训练出正确率还行的model,则现在就可以使用model对图片进行分类。
& & & &&a.&&&&&&首先确保已经正确安装了pythonwrapper,以及caffe_root/python/文件夹下requirements.txt文件中所需要的组件。
& & & &&b.&&&&&&另外,还需要meanfile的npy文件。即需要把数据对应的binaryproto文件转换到npy文件。Caffe_root/python/caffe/io.cpp文件中已经给了对应的API。
& & & &&具体参照:
& & & &&需要对blobproto_to_array 进行修改,得到blobproto_to_array2.
& & & &&即删去了blob.num 项。
& & & &&通过调用此API进行处理,具体python函数如下:
& & & &&convert_bproto_to_npy.py
#!/usr/bin/python
import numpy as np
from caffe.io import blobproto_to_array2
from caffe.proto import caffe_pb2
blob = caffe_pb2.BlobProto()
filename = './imagenet_mean.binaryproto'
data = open(filename, &rb&).read()
blob.ParseFromString(data)
nparray =blobproto_to_array2(blob)
f = file(&mean.npy&,&wb&)
np.save(f,nparray)
& & & &&c.&&&&&&按照demo步骤进行分类:
& & & &&代码的主要部分参照
& & & &&classify.py
& & & &&classifymap.py
& & & &&输出部分的说明
& & & &&1)&&&&&Classify.py
& & & &&输出的是prediction[0],一维数组,以imagenet为例就是大小为1000的数组,每个值对应概率大小。
& & & &&处理部分代码:
preDict = {}
for i in xrange(len(prediction[0])):
preDict[prediction[0][i]] = i
for i in xrange(5):
val = sorted(preDict.keys())[-i -1]
print(&%d %f %s& %(preDict[val], val * 100, linecache.getline(SYNSET, preDict[val])))
& & & &&把数组的值和索引对应到字典中,值作为键,把数组值进行排序,再用前五个作为键,找出索引值,也就是对应的类别。
为了能够直观地显示数字所代表的类别名,需要输出synset_words.txt文件中对应行数的内容。这里用的是linecache.getline()函数,需要
& & & &&import caffe
& & & &&为了修改方便,把synset_words.txt的路径设为变量
& & & &&SYNSET = '../../data/ilsvrc12/synset_words.txt'
& & & &&(序号概率值(百分比)对应种类)
& & & & 2)&&&&&Classifymap.py
& & & &&输出的是
& & & & & & & & & & &outMat =out['prob'][0].argmax(axis=0)
是一个二维矩阵,8*8大小,每个值对应的都是一种类别,出现的越多代表概率越高。
& & & &&处理部分代码:
h1, w1 = np.shape(outMat)
outList = list(np.reshape(outMat,h1 * w1))
#print(outList)
outSet = set(outList)
outdict = {}
for x in outSet:
outdict[outList.count(x)]=x
appear = outdict.keys()
applen = len(appear)
if len &= 5:
for i in xrange(applen):
print('%d %d: %s'%(outdict[appear[-(i+1)]], appear[-(i+1)],linecache.getline(SYNSET,outdict[appear[-(i+1)]])))
for i in xrange(5):
print('%d %d: %s'%(outdict[appear[-(i+1)]], appear[-(i+1)], linecache.getline(SYNSET,outdict[appear[-(i+1)]])))
& & & &&和上面的文件大致思路相同。但是需要先把矩阵展开成一维列表,用set()变成集合,也就是去掉重复元素,再一一对应到字典中,然后通过count()找到每个值在矩阵中出现的次数,进行排序即可。
(序号出现次数对应种类)
3) &源代码:
Classiy.py
import numpy as np
import matplotlib.pyplot as plt
import pylab
import caffe
caffe_root = '../'
MODEL_FILE = '../imagenet/imagenet_deploy.prototxt'
PRETRAINED = '../imagenet/caffe_reference_imagenet_model'
IMAGE_FILE = '../images/cat.jpg'
#net = caffe.Classifier(MODEL_FILE, PRETRAINED, mean_file = caffe_root + '../python/caffe/imagenet/ilsvrc_2012_mean.npy', channel_swap = (2,1,0), input_scale = 255)
net = caffe.Classifier(MODEL_FILE, PRETRAINED, mean_file = caffe_root + 'mean2.npy', channel_swap = (2,1,0), input_scale = 255)
net.set_phase_test()
net.set_mode_gpu()
input_image = caffe.io.load_image(IMAGE_FILE)
pylab.ion()
plt.imshow(input_image)
#pylab.show()
prediction = net.predict([input_image])
print 'prediction shape:', prediction[0].shape
#print(prediction[0])
plt.plot(prediction[0])
#pylab.show()
preDict = {}
preList = list(prediction[0])
for i in preList:
preDict[preList[i]] = i
preLen = len(preList)
for i in xrange(5):
print('%d %d: %s' %(preDict[preDict.keys[-(i+1)]], preDict.values[-(i+1)], linecache.getline(SYNSET,preDict.values[-(i+1)])))
classifymap.py
import caffe
import matplotlib.pyplot as plt
import pylab
import numpy as np
import linecache
IMAGE_FILE ='../images/dog.jpg'
SYNSET = '../../data/ilsvrc12/synset_words.txt'
# Load the original network and extract the fully-connected layers' parameters.
net = caffe.Net('../imagenet/imagenet_deploy.prototxt', '../imagenet/caffe_reference_imagenet_model')
params = ['fc6', 'fc7', 'fc8']
# fc_params = {name: (weights, biases)}
fc_params = {pr: (net.params[pr][0].data, net.params[pr][1].data) for pr in params}
#for fc in params:
#print '{} weights are {} dimensional and biases are {} dimensional'.format(fc, fc_params[fc][0].shape, fc_params[fc][1].shape)
# Load the fully-convolutional network to transplant the parameters.
net_full_conv = caffe.Net('../imagenet/imagenet_full_conv.prototxt', '../imagenet/caffe_reference_imagenet_model')
params_full_conv = ['fc6-conv', 'fc7-conv', 'fc8-conv']
# conv_params = {name: (weights, biases)}
conv_params = {pr: (net_full_conv.params[pr][0].data, net_full_conv.params[pr][1].data) for pr in params_full_conv}
#for conv in params_full_conv:
#print '{} weights are {} dimensional and biases are {} dimensional'.format(conv, conv_params[conv][0].shape, conv_params[conv][1].shape)
for pr, pr_conv in zip(params, params_full_conv):
conv_params[pr_conv][1][...] = fc_params[pr][1]
for pr, pr_conv in zip(params, params_full_conv):
out, in_, h, w = conv_params[pr_conv][0].shape
W = fc_params[pr][0].reshape((out, in_, h, w))
conv_params[pr_conv][0][...] = W
# net_full_conv.save('../imagenet/caffe_imagenet_full_conv')
# load input and configure preprocessing
im = caffe.io.load_image(IMAGE_FILE)
plt.imshow(im)
#pylab.show()
net_full_conv.set_mean('data', '../../python/caffe/imagenet/ilsvrc_2012_mean.npy')
net_full_conv.set_channel_swap('data', (2,1,0))
net_full_conv.set_input_scale('data', 255.0)
# make classification map by forward pass and show top prediction index per location
out = net_full_conv.forward_all(data=np.asarray([net_full_conv.preprocess('data', im)]))
outMat = out['prob'][0].argmax(axis=0)
h1, w1 = np.shape(outMat)
outList = list(np.reshape(outMat,h1 * w1))
#print(outList)
outSet = set(outList)
outdict = {}
for x in outSet:
outdict[outList.count(x)]=x
appear = outdict.keys()
applen = len(appear)
if len &= 5:
for i in xrange(applen):
print('%d %d: %s' %(outdict[appear[-(i+1)]], appear[-(i+1)], linecache.getline(SYNSET,outdict[appear[-(i+1)]])))
for i in xrange(5):
print('%d %d: %s' %(outdict[appear[-(i+1)]], appear[-(i+1)], linecache.getline(SYNSET,outdict[appear[-(i+1)]])))
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:13552次
排名:千里之外
评论:12条
(1)(1)(1)(4)

我要回帖

更多关于 siamese网络 训练数据 的文章

 

随机推荐