Caffe从入门到精通09

来源:互联网 发布:进口软件涉及的税种 编辑:程序博客网 时间:2024/05/16 02:34

【用训练好的模型,测试自己的一张图片并实现参数可视化——以MNIST数据集为例】

1.数据准备

1.1获取mnist数据集中的某一张图片(自己照的图片也可),将其转换为单通道格式,图片大小28*28,这里已经给大家准备了制作好的10张图片。点击链接,下载图片集

如下图所示:


tips:通过“位深度”的值可以判断是否为单通道,单通道的位深度为“8”,三通道的位深度为“24”。(R,G,B)

1.2 新建标签文档label.txt,内容为:标签值与标签名称的对应(中间用一个空格隔开),如下图所示:


1.3 将准备好的图片9.jpg和新建的label.txt放到caffe-master/data/mnist/的目录下,如下图所示:


1.4 在caffe-master/examples/mnist/文件目录下新建deploy.prototxt文件,其内容如下所示:

name: "LeNet"layer {  name: "data"  type: "Input"  top: "data"  input_param { shape: { dim: 1 dim: 1 dim: 28 dim: 28 } }}layer {  name: "conv1"  type: "Convolution"  bottom: "data"  top: "conv1"  param {    lr_mult: 1  }  param {    lr_mult: 2  }  convolution_param {    num_output: 20    kernel_size: 5    stride: 1    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"    }  }}layer {  name: "pool1"  type: "Pooling"  bottom: "conv1"  top: "pool1"  pooling_param {    pool: MAX    kernel_size: 2    stride: 2  }}layer {  name: "conv2"  type: "Convolution"  bottom: "pool1"  top: "conv2"  param {    lr_mult: 1  }  param {    lr_mult: 2  }  convolution_param {    num_output: 50    kernel_size: 5    stride: 1    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"    }  }}layer {  name: "pool2"  type: "Pooling"  bottom: "conv2"  top: "pool2"  pooling_param {    pool: MAX    kernel_size: 2    stride: 2  }}layer {  name: "ip1"  type: "InnerProduct"  bottom: "pool2"  top: "ip1"  param {    lr_mult: 1  }  param {    lr_mult: 2  }  inner_product_param {    num_output: 500    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"    }  }}layer {  name: "relu1"  type: "ReLU"  bottom: "ip1"  top: "ip1"}layer {  name: "ip2"  type: "InnerProduct"  bottom: "ip1"  top: "ip2"  param {    lr_mult: 1  }  param {    lr_mult: 2  }  inner_product_param {    num_output: 10    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"    }  }}layer {  name: "prob"  type: "Softmax"  bottom: "ip2"  top: "prob"}

1.5 在python开发环境下,进行基本设置

# -*- coding: utf-8 -*-import matplotlib.pyplot as pltimport osimport caffeimport numpy as np#设置显示面板的显示样式plt.rcParams['figure.figsize'] = (8, 8) #宽幅图像plt.rcParams['image.interpolation'] = 'nearest' #最邻近内插算法plt.rcParams['image.cmap'] = 'gray' #显示为灰度图像,否则将以“热力图”的彩图显示

2.Caffe模型配置

#定义caffe的根目录caffe_root='E:/DL/caffe-master/'#加载caffe的根目录os.chdir(caffe_root)#设置caffe为cpu配置caffe.set_mode_cpu()#网络模型架构文件model_def='examples/mnist/deploy.prototxt'#网络模型参数文件model_weights='examples/mnist/lenet_iter_1000.caffemodel'#根据两个配置文件加载网络,并使用“测试”模式net=caffe.Net(model_def,model_weights,caffe.TEST)
其中lenet._iter_1000.caffemodel就是之前已经训练好并保存下来的网络模型


3.图片维度配置

#数据初始化#新建caffe数据转换器trainsformer=caffe.io.Transformer({'data':net.blobs['data'].data.shape})#python读取图片格式为H*W*K, 需转化为K*H*Wtrainsformer.set_transpose('data',(2,0,1))
#加载图片,自动转换为3通道的灰度图,这三个通道完全一样image=caffe.io.load_image('data/mnist/9.jpg')#将图片放入数据转换器,变换维度transformed_image=trainsformer.preprocess('data',image)#将(3,28,28)转换成(1,1,28,28),若n>1,则网络会自动增广到设置的数量nnet.blobs['data'].data[...]=transformed_image.reshape(1,3,28,28)[:,0].reshape(1,1,28,28)#驱动图片在网络中前向传播output=net.forward()
注意:caffe.io.load_image()函数会自动将任何输入的图片转换为3通道的图片(28,28,3),只不过对于单通道的图片而言,这三个通道的图片是完全一样的。首先通过transformer数据转换器转换为(3,28,28),再用reshape函数最终转换为与deploy.prototxt的输入格式一致的(1,1,28,28)

4.输出预测值与网络内的张量形态

#此时网络中只有一张图片,获得该图片的概率值output_prob=output['prob'][0]#将最大的概率值输出到控制台print output_prob.argmax()#加载标签文件目录label_file=caffe_root+'data/mnist/label.txt'#加载标签labels=np.loadtxt(label_file,str,delimiter=' ')#获取标签值实际对应的标签名称print 'output label:',labels[output_prob.argmax()][1]#输出测试图片经过各层时的张量形态for layer_name,blob in net.blobs.iteritems():    print layer_name+' '+str(blob.data.shape)#输出各层参数的张量形态for layer_name,param in net.params.iteritems():    print layer_name+'\t'+str(param[0].data.shape)+str(param[1].data.shape)
其结果如下图所示:



5.网络中的测试图片可视化

#定义python中的可视化面板def vis_square(data):    #获得shape为(n,height,width)或(n,height,width,3)的序列,并将每一个图片均匀地显示在网格界面中    #正则化数据    data=(data-data.min())/(data.max()-data.min())    #根据图片的数量绘制正方形的布局网格    n=int(np.ceil(np.sqrt(data.shape[0])))    #为每一个小的显示窗口绘制边框    padding=(((0,n**2-data.shape[0]),(0,1),(0,1))+((0,0),)*(data.ndim-3))    #边框的颜色为白色    data=np.pad(data,padding,mode='constant',constant_values=1)    #将图片用小的窗口显示    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')    plt.show()#参数可视化#由于通道数是1,所以只能用(n,height,width)这样的参数形式,只有3通道才可以用(n,height,width,3)的参数形式#data的shape是(n,c,h,w),通过[:,0]取所有行(第一维度下)的第0个(第二个维度下的,即第0个通道)的数据,
#之后shape变为(n,h,w)#获取第一层卷积核的数据filters=net.params['conv1'][0].data[:,0]#这里的data[n],中的n表示batch中的某一幅图feat=net.blobs['con1'].data[0]#可视化卷积核参数vis_square(filters)
显示结果如下图所示:



将vis_square中的参数filters改为feat后,即可显示测试图片在经过第一个卷积层之后的效果:


不难想出,将“conv1”改为“conv2“、“pool1”后,将会获得对应的层的数据值,这里不再赘述。

注意:[:,0]的方法,是python对张量处理比较常用的降维处理技巧,应该熟练掌握!

   reshape、transpose同样也是python中对张量处理常用的变维技巧,应熟练掌握!

6.Softmax概率输出图表可视化

feat=net.blobs['prob'].data[0]plt.figure(figsize=(10,5))plt.plot(feat.flat)plt.show()
其结果如下图所示:



可以直观地看出,根据我们输入的这张测试图片(如下图所示),模型网络作出了较为准确的识别,识别为“9”的概率最大,而且也存在着识别成“4”的偏向,符合我们人眼的直观视觉!


实战经验总结:

1.要学会对张量维度的处理技巧,这在深度学习网络模型中至关重要!

原创粉丝点击