Caffe学习系列(17):模型各层数据和参数可视化

转载自http://www.cnblogs.com/denny402

先用caffe对cifar10进行训练,将训练的结果模型进行保存,得到一个caffemodel,然后从测试图片中选出一张进行测试,并进行可视化。

In [1]:
#加载必要的库
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import sys,os,caffe
In [2]:
#设置当前目录,判断模型是否训练好
caffe_root = '/home/bnu/caffe/' 
sys.path.insert(0, caffe_root + 'python')
os.chdir(caffe_root)
if not os.path.isfile(caffe_root + 'examples/cifar10/cifar10_quick_iter_4000.caffemodel'):
    print("caffemodel is not exist...")
In [3]:
#利用提前训练好的模型,设置测试网络
caffe.set_mode_gpu()
net = caffe.Net(caffe_root + 'examples/cifar10/cifar10_quick.prototxt',
                caffe_root + 'examples/cifar10/cifar10_quick_iter_4000.caffemodel',
                caffe.TEST)
In [4]:
net.blobs['data'].data.shape
Out[4]:
(1, 3, 32, 32)
In [5]:
#加载测试图片,并显示
im = caffe.io.load_image('examples/images/32.jpg')
print im.shape
plt.imshow(im)
plt.axis('off')
 
(32, 32, 3)
Out[5]:
(-0.5, 31.5, 31.5, -0.5)
 
In [6]:
# 编写一个函数,将二进制的均值转换为python的均值
def convert_mean(binMean,npyMean):
    blob = caffe.proto.caffe_pb2.BlobProto()
    bin_mean = open(binMean, 'rb' ).read()
    blob.ParseFromString(bin_mean)
    arr = np.array( caffe.io.blobproto_to_array(blob) )
    npy_mean = arr[0]
    np.save(npyMean, npy_mean )
binMean=caffe_root+'examples/cifar10/mean.binaryproto'
npyMean=caffe_root+'examples/cifar10/mean.npy'
convert_mean(binMean,npyMean)
In [7]:
#将图片载入blob中,并减去均值
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
transformer.set_transpose('data', (2,0,1))
transformer.set_mean('data', np.load(npyMean).mean(1).mean(1)) # 减去均值
transformer.set_raw_scale('data', 255)  
transformer.set_channel_swap('data', (2,1,0))
net.blobs['data'].data[...] = transformer.preprocess('data',im)
inputData=net.blobs['data'].data
In [8]:
#显示减去均值前后的数据
plt.figure()
plt.subplot(1,2,1),plt.title("origin")
plt.imshow(im)
plt.axis('off')
plt.subplot(1,2,2),plt.title("subtract mean")
plt.imshow(transformer.deprocess('data', inputData[0]))
plt.axis('off')
Out[8]:
(-0.5, 31.5, 31.5, -0.5)
 
In [9]:
#运行测试模型,并显示各层数据信息
net.forward()
[(k, v.data.shape) for k, v in net.blobs.items()]
Out[9]:
[('data', (1, 3, 32, 32)),
 ('conv1', (1, 32, 32, 32)),
 ('pool1', (1, 32, 16, 16)),
 ('conv2', (1, 32, 16, 16)),
 ('pool2', (1, 32, 8, 8)),
 ('conv3', (1, 64, 8, 8)),
 ('pool3', (1, 64, 4, 4)),
 ('ip1', (1, 64)),
 ('ip2', (1, 10)),
 ('prob', (1, 10))]
In [10]:
#显示各层的参数信息
[(k, v[0].data.shape) for k, v in net.params.items()]
Out[10]:
[('conv1', (32, 3, 5, 5)),
 ('conv2', (32, 32, 5, 5)),
 ('conv3', (64, 32, 5, 5)),
 ('ip1', (64, 1024)),
 ('ip2', (10, 64))]
In [11]:
# 编写一个函数,用于显示各层数据
def show_data(data, padsize=1, padval=0):
    data -= data.min()
    data /= data.max()
    
    # force the number of filters to be square
    n = int(np.ceil(np.sqrt(data.shape[0])))
    padding = ((0, n ** 2 - data.shape[0]), (0, padsize), (0, padsize)) + ((0, 0),) * (data.ndim - 3)
    data = np.pad(data, padding, mode='constant', constant_values=(padval, padval))
    
    # 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.figure()
    plt.imshow(data,cmap='gray')
    plt.axis('off')
plt.rcParams['figure.figsize'] = (8, 8)
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'
In [12]:
#显示第一个卷积层的输出数据和权值(filter)
show_data(net.blobs['conv1'].data[0])
print net.blobs['conv1'].data.shape
show_data(net.params['conv1'][0].data.reshape(32*3,5,5))
print net.params['conv1'][0].data.shape
 
(1, 32, 32, 32)
(32, 3, 5, 5)
 
 
In [13]:
#显示第一次pooling后的输出数据
show_data(net.blobs['pool1'].data[0])
net.blobs['pool1'].data.shape
Out[13]:
(1, 32, 16, 16)
 
In [14]:
#显示第二次卷积后的输出数据以及相应的权值(filter)
show_data(net.blobs['conv2'].data[0],padval=0.5)
print net.blobs['conv2'].data.shape
show_data(net.params['conv2'][0].data.reshape(32**2,5,5))
print net.params['conv2'][0].data.shape
 
(1, 32, 16, 16)
(32, 32, 5, 5)
 
 
In [15]:
#显示第三次卷积后的输出数据以及相应的权值(filter),取前1024个进行显示
show_data(net.blobs['conv3'].data[0],padval=0.5)
print net.blobs['conv3'].data.shape
show_data(net.params['conv3'][0].data.reshape(64*32,5,5)[:1024])
print net.params['conv3'][0].data.shape
 
(1, 64, 8, 8)
(64, 32, 5, 5)
 
 
In [16]:
#显示第三次池化后的输出数据
show_data(net.blobs['pool3'].data[0],padval=0.2)
print net.blobs['pool3'].data.shape
 
(1, 64, 4, 4)
 
In [17]:
# 最后一层输入属于某个类的概率
feat = net.blobs['prob'].data[0]
print feat
plt.plot(feat.flat)
 
[  5.21440245e-03   1.58397834e-05   3.71246301e-02   2.28459597e-01
   1.08315737e-03   7.17785358e-01   1.91939052e-03   7.67927198e-03
   6.13298907e-04   1.05107691e-04]
Out[17]:
[<matplotlib.lines.Line2D at 0x7f3d882b00d0>]
 
 

从输入的结果和图示来看,最大的概率是7.17785358e-01,属于第5类(标号从0开始)。与cifar10中的10种类型名称进行对比:

airplane、automobile、bird、cat、deer、dog、frog、horse、ship、truck

根据测试结果,判断为dog。 测试无误!




进行12步的时候出现:
/Library/Python/2.7/site-packages/ipykernel/__main__.py:4: RuntimeWarning: invalid value encountered in divide
然后data数据没有得到,图是空白,请问楼主这是为什么啊?
  
#2楼   2016-04-27 15:13 |  swoyows   
Out [8]:得到的两张图original和subtract mean应该是一样的吧~
  
#3楼   2016-05-06 12:58 |  weichang88688   
您好,我想得到每层输出的数据,而不对其进行可视化,代码如何进行修改呢谢谢
  
#4楼 [ 楼主2016-05-07 10:51 |  denny402   
@ weichang88688
卷积层的输出数据就是net.blobs['conv1'].data[0],用一个变量保存起来就可以了
c1=net.blobs['conv1'].data[0]
  
#5楼   2016-05-20 20:47 |  yale524   
太感谢博主了 至少我大部分可以看得懂 学习学习
  
#6楼   2016-05-23 10:26 |  dddeee   
楼主你好,我输入图像是灰度图,想要可视化,In[7]中报错,channel swap needs to have the same number of dimensions as the input channels.请问楼主如何改代码呢?
  
#7楼 [ 楼主2016-05-23 13:10 |  denny402   
@ dddeee
这个例子用的是cifar10模型,要求输入的是三通道彩色图片。你可以将灰度图像变为彩色图像输入。
将 im = caffe.io.load_image('examples/images/32.jpg') 这行代码改为:
from PIL import Image
im=np.array(Image.open(examples/images/32.jpg').convert('RGB'))
  
#8楼   2016-05-23 14:56 |  dddeee   
@ denny402
我用的模型是按你前边的教博客用自己的数据训练的,也是用灰度图训练出来的模型,所以不知道In[7]中那几行应该怎样设置?
  
#9楼   2016-08-15 16:56 |  Evence   
@ swoyows
they're different. The second is substracted picture, you can see every pixcel while input cat from example/images/
  
#10楼   2016-08-15 17:01 |  Evence   
@ Zoe_only
The same problem......Do you solve it?
  
#11楼   2016-08-17 15:26 |  trs-breeze   
博主@denny402,您好:
对于每一层的输出,第一列是设置的num_output,后两列卷积的维度
请问下边输出中的每一行的第二列是什么参数呢,它与group参数有什么关系?

Out[10]: [ ('conv1', (32, 3, 5, 5)),
('conv2', (32, 32, 5, 5)),
('conv3', (64, 32, 5, 5)),
('ip1', (64, 1024)),
('ip2', (10, 64))]
  
#12楼   2016-10-26 21:36 |  kamo   
@ denny402
博主您好,我只要添上这行代码net.forward(),,运行就会有错,The kernel appears to have died. It will restart automatically.但是不加这句,输出数据显示不出来,最后一层的概率也算不出来,我该怎么解决,希望楼主抽空看一下我的问题。
  
#13楼   2016-11-25 09:22 |  linry   
博住,怎么可视化自己的数据训练的网络,我的总是报错,但是我用caffe自带例子就不报错?这个要求有什么文件吗?
  
#14楼   2016-12-09 19:30 |  hxdhxd   
为啥我运行第三步总是这么提示:The kernel appears to have died. It will restart automatically.劳烦您抽空解答 @denny402
  
#15楼 [ 楼主2016-12-11 13:33 |  denny402   
@ hxdhxd
出现这个问题一般是配置文件有问题。仔细检查一下这个地方:net = caffe.Net(caffe_root + 'examples/cifar10/cifar10_quick.prototxt',
  
#16楼   2017-01-20 13:51 |  durcan   
楼主你好,我按照您的步骤在显示数据阶段,显示的是空白的小格,我用的测试图片是caffe中的那张cat.jpg的图像。这是什么原因呢?
  
#17楼   2017-02-23 17:40 |  Jenny威5   
你好,我在执行In [12]步后出现的都是一样的空白,我的仅cpu,这是配置问题还是其他的?求赐教
  
#18楼   2017-03-03 09:28 |  东哥犀利啊   
@ Jenny威5
出现空白说明你的图没有加载到blob里,你可以print net.blobs['conv1'].data[0],你的情况输出应该都是0,具体看一下
In 7 里
net.blobs['data'].data[...] = transformer.preprocess('data',im) 这句前后,这里是把图像加载到blob里
  
#19楼   2017-04-14 17:29 |  EchoAmor   
@ dddeee
你好, 我做的显著性检测,也是要测试一张图片,label是灰度图,你的问题解决了吗,能不能交流一下
  
#20楼   2017-06-15 09:51 |  Andy*   
@ kamo
你的这个问题解决了吗?我现在也遇到了和你同样的问题
  
#21楼   2017-06-15 09:55 |  Andy*   
@ hxdhxd
我也遇到了这个问题,您解决了吗
  
#22楼   2017-06-15 10:42 |  Andy*   
问题:只要添上这行代码net.forward(),,运行就会有错,The kernel appears to have died. It will restart automatically.
已解决!!
方法:
本节博客中有一句写的是
caffe.set_mode_gpu()
我caffe编译设置的是cpu模式
把这句改成
caffe.set_mode_cpu()
就好使了
  
#23楼   2017-08-09 19:52 |  成名在望   
@ Andy*
@kamo
感谢,遇到了同样的问题,解决了,没有用GPU真的是各种坑啊
  
#24楼   2017-08-18 09:54 |  北海盗   
博主你好。
请问最后输出的那副图和对应的10个输出的概率值有什么关系?
从你实验展示出来的图和你最后输出的10个概率数据并不能对号入座,(你的第一个概率值是5.21440245e-03,而图中x轴上的0号对应的y值只是0.0几)。。
我按照你的代码,得到的图示和输出的概率值也不匹配,所以我就有个疑问:图示的曲线表示什么?
  
#25楼   2017-12-03 17:25 |  ZaneYang   
你好 请问:
feat = net.blobs['prob'].data[0]
KeyError Traceback (most recent call last)
<ipython-input-31-57e23f682ee2> in <module>()
----> 1 feat = net.blobs['prob'].data[0]

KeyError: 'prob'
是什么原因

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值