caffe可视化各个层
caffe的配置文件prototxt与模型.model文件,这是可视化要用的两个文件.
2..model文件
这个可以用别人优化好的,也可以用自己微调的
可视化过程使用jupyter notebook
一.加载网络
import numpy as np
import matplotlib.pyplot as plt
import os
import caffe
import sys
import pickle
import cv2
%matplotlib inline
最后一行的matplotlib inline 要加上 不然画图时候会出问题
root='.../net/'
import sys
sys.path.insert(0,root+'python')
import caffe
import cv2
root的路径可以是绝对路径也可以是相对路径.
deploy = root+'deploy.prototxt';caffe_model = root+'bvlc_reference_caffenet.caffemodel'
print(deploy)
#打印出路径,以防出错,在win里面路径用\,linux用/
net = caffe.Net(deploy,caffe_model,caffe.TEST)#deploy是测试,所有caffe.Test模式,训练模式:caffe.TRAIN
net.blobs['data'].data.shape
二.测试网络是否可行
#加载测试图片,并显示
im = caffe.io.load_image('_net/1.jpg')
print im.shape
plt.imshow(im)
plt.axis('off')
三.可视化:(单张图片输入模型)
#将图片载入blob中,
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
transformer.set_transpose('data', (2,0,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
#运行测试模型,并显示各层数据信息(blob)
net.forward()
[(k, v.data.shape) for k, v in net.blobs.items()]
[('data', (1, 3, 227, 227)),
('conv1', (1, 96, 55, 55)),
('pool1', (1, 96, 27, 27)),
('norm1', (1, 96, 27, 27)),
('conv2', (1, 256, 27, 27)),
('pool2', (1, 256, 13, 13)),
('norm2', (1, 256, 13, 13)),
('conv3', (1, 384, 13, 13)),
('conv4', (1, 384, 13, 13)),
('conv5', (1, 256, 13, 13)),
('pool5', (1, 256, 6, 6)),
('fc6', (1, 4096)),
('fc7', (1, 4096)),
('fc8', (1, 1000)),
('prob', (1, 1000))]
#显示各层的参数信息(params)
[(k, v[0].data.shape) for k, v in net.params.items()]
[('conv1', (96, 3, 11, 11)),
('conv2', (256, 48, 5, 5)),
('conv3', (384, 256, 3, 3)),
('conv4', (384, 192, 3, 3)),
('conv5', (256, 192, 3, 3)),
('fc6', (4096, 9216)),
('fc7', (4096, 4096)),
('fc8', (1000, 4096))]
# 编写一个函数,用于显示各层数据
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' #最后三行不影响结果 可以注释掉
#显示第二次卷积后的输出数据以及相应的权值(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(256*48,5,5)) #这个reshape后面大小要改,根据网络blobs的大小
print net.params['conv2'][0].data.shape
#显示pooling后的输出数据
feat = net.blobs['pool1'].data[0]
show_data(feat)
feat = net.blobs['pool2'].data[0]
show_data(feat)
#显示第三次卷积后的输出数据以及相应的权值(filter),取前100个进行显示(数量太多看不清,可以先选择部分显示)
show_data(net.blobs['conv3'].data[0][1:100],padval=0.5)
print net.blobs['conv3'].data.shape
show_data(net.params['conv3'][0].data.reshape(384*256,3,3)[:100])
print net.params['conv3'][0].data.shape
feat = net.blobs['fc7'].data[0]
plt.subplot(2, 1, 1)
plt.plot(feat.flat)
plt.subplot(2, 1, 2)
_ = plt.hist(feat.flat[feat.flat > 0], bins=350)
plt.savefig('fc7.jpg')
print feat
feat = net.blobs['net1_fc8'].data[0]
fig, axes = plt.subplots(figsize=(10,6)) #长宽
plt.subplot(1, 1, 1)
plt.plot(feat.flat)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12) #刻度尺寸
plt.xlim((0, 100)) #也可写成plt.xlim(-5, 5) #横坐标范围
#plt.axis('auto')
plt.xlabel('Output Size',fontsize=12) #字体尺寸
plt.ylabel('Value',fontsize=12)
plt.rc('font',family='Times New Roman')
#fig, axes = plt.subplots(figsize=(12,3))
plt.savefig('1.jpg')
plt.savefig('2.png')
#一些问题:
1.采用别人的网络模型,记得要核对好网络名称,
http://ethereon.github.io/netscope/#/editor
这个网址可以把prototxt丢进去,然后shift+enter可以得出模型的网络
一定要核对好,当出现ignore source layer时候,基本上就是名称不对
2.对于灰度图与彩色图,只是通道的关系,不影响结果,当然,也可以转换下,之前有博客有说明.
#新手上路,多多指点