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

cifar10的各层数据和参数可视化
先用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)) ##格式转换为(cannel,weight,high)
    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) #输入数据传给data层
    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)
    #conv1_data = net.blobs['conv1'].data #返回conv1层的数据,net.blobs['conv1'].data[0]返回conv1层的数据的第一张图片
    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。 测试无误!

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

阅读更多

没有更多推荐了,返回首页