Caffe实战之Python接口系列(一)Classification_Visualization

引言

记录学习官网的例程中的一些重要语句,遇到的问题等,内容分散,建议顺序查看。
主要是调用Caffe的Python接口
源文件就在{caffe_root}/examples中,安装sudo pip install jupyter打开即可运行,初学者最好是放在它指定的目录,如,否则要改很多路径。
注:eaxmples是用jupyter notebook写的,部分Cell中出现了一些特殊的用法:
1. 感叹号‘!’:用于执行系统命令,如 !pwd
2. 百分号‘%’:用法太多,如 %matplotlib inline 显示绘图窗口 详见Jupyter Notebook Viewer

目录

图像分类和卷积核可视化

用一个预训练模型进行即时识别并通过访问网络接口来可视化特征和逐层参数。

加载网络并设置输入预处理

  • 设置模式CPU or GPU(如果是多GPU,可指定设备号):
    caffe.set_mode_cpu() or caffe.set_device(0);caffe.set_mode_gpu()

  • 加载Caffe网络模型:net = caffe.Net(model_def, model_weights, caffe.TEST)

  • 输入数据预处理的配置(独立于Caffe的其他部分,可以用任何惯用的方法)
    1. 对输入数据’data’创建一个transformer:transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
    2. 设置输入预处理参数
      • innermost dimension 到outermost dimension,即HxWxC-> CxHxW.:transformer.set_transpose('data', (2,0,1))
      • 每个通道减去图像均值:transformer.set_mean('data', mu)
      • 从[0, 1]区间映射回[0, 255]:transformer.set_raw_scale('data', 255)
      • 改变输入图像的通道顺序RGB->BGR:transformer.set_channel_swap('data', (2,1,0))

分类单张图片

  1. 设置输入大小:net.blobs['data'].reshape(50,3,227,227)
  2. 利用Caffe加载一张图片并执行我们前面设置的数据预处理

    image = caffe.io.load_image(caffe_root + 'examples/images/cat.jpg')
    transformed_image = transformer.preprocess('data', image)
  3. 复制图片数据到网络分配的内存中:net.blobs['data'].data[...] = transformed_image
  4. 执行一次前向预测:output = net.forward()
  5. 输出结果的处理:

    从输出中取出一个batch的第一幅图像的概率向量:output_prob = output['prob'][0]
    取出一幅图像概率向量中最大值对应的索引,对应到数据集的标签列表,可找到对应类别。

查看中间输出

  1. 先查看网络结构(activation and parameter shapes)

    
    # 每一层输出数据shape,(batch_size, channel_dim, height, width)
    
    for layer_name, blob in net.blobs.iteritems():
        print layer_name + '\t' + str(blob.data.shape)
    
    # 查看卷积核参数shape,(output_channels, input_channels, filter_height, filter_width)
    
    for layer_name, param in net.params.iteritems():
        print layer_name + '\t' + str(param[0].data.shape), str(param[1].data.shape)
  2. 定义辅助显示函数,用于可视化

    def vis_square(data):
        """Take an array of shape (n, height, width) or (n, height, width, 3)
           and visualize each (height, width) thing in a grid of size approx. sqrt(n) by sqrt(n)"""
    
        # normalize data for display 归一化
        data = (data - data.min()) / (data.max() - data.min())
    
        # 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, 1), (0, 1))                 # add some space between filters 填充图片的底部和右侧,隔离开来。
                   + ((0, 0),) * (data.ndim - 3))  # don't pad the last dimension (if there is one) 一个图片/核的各通道间不需要填充
        data = np.pad(data, padding, mode='constant', constant_values=1)  # pad with ones (white) 对整个大数组进行填充,padding对应四个维度的前后分别填多少个
    
        # 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:]) #reshape为正常图片格式
    
    
        plt.imshow(data); plt.axis('off')
  3. 绘制图像

    
    # the parameters are a list of [weights, biases] 可视化卷积核
    
    filters = net.params['conv1'][0].data
    vis_square(filters.transpose(0, 2, 3, 1)) # 注意需要对通道顺序进行转置
    
    # 可视化各层输出数据
    
    feat = net.blobs['conv1'].data[0, :36]
    vis_square(feat)
  4. 绘制全连接层的输出值

    feat = net.blobs['fc6'].data[0]
    plt.subplot(2, 1, 1)
    plt.plot(feat.flat) # np.flat 为数组一维迭代器
    plt.subplot(2, 1, 2)
    _ = plt.hist(feat.flat[feat.flat > 0], bins=100) # (大于零)的直方图,bins为柱数
  5. 绘制最终概率输出

    feat = net.blobs['prob'].data[0]
    plt.figure(figsize=(15, 3))
    plt.plot(feat.flat)

尝试自己的图片

# download an image
my_image_url = "..."  # paste your URL here
# for example:
# my_image_url = "https://upload.wikimedia.org/wikipedia/commons/b/be/Orang_Utan%2C_Semenggok_Forest_Reserve%2C_Sarawak%2C_Borneo%2C_Malaysia.JPG"
!wget -O image.jpg $my_image_url

# transform it and copy it into the net
image = caffe.io.load_image('image.jpg')
net.blobs['data'].data[...] = transformer.preprocess('data', image)

# perform classification
net.forward()

# obtain the output probabilities
output_prob = net.blobs['prob'].data[0]

# sort top five predictions from softmax output
top_inds = output_prob.argsort()[::-1][:5]

plt.imshow(image)

print 'probabilities and labels:'
zip(output_prob[top_inds], labels[top_inds])

下一篇:Caffe实战之Python接口系列(二)Learning-LeNet

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值