Caffe学习 三 模型使用和特征提取

模型使用

使用caffe训练得到的模型进行测试,一般需要如下文件:
1.训练好的caffemodel模型

此处使用lenet_iter_10000.caffemodel。

2.测试网络deploy

可以对lenet_train_test.prototxt做修改。

主要修改的地方包括输入数据,最后的top,权值初始化,第一个卷积层名称不能和训练网络conv1同名。

也可以直接用下面代码生成,对应lenet.

# coding: utf8
from caffe import layers as L,params as P,to_proto
root='C:/Users/jj/Documents/caffe-windows/'
deploy=root+'examples/mnist/deploy.prototxt'    #文件保存路径

def create_deploy():
    #少了第一层,data层
    conv1=L.Convolution(bottom='data', kernel_size=5, stride=1,num_output=20, pad=0,weight_filler=dict(type='xavier'))
    pool1=L.Pooling(conv1, pool=P.Pooling.MAX, kernel_size=2, stride=2)
    conv2=L.Convolution(pool1, kernel_size=5, stride=1,num_output=50, pad=0,weight_filler=dict(type='xavier'))
    pool2=L.Pooling(conv2, pool=P.Pooling.MAX, kernel_size=2, stride=2)
    ip1=L.InnerProduct(pool2, num_output=500,weight_filler=dict(type='xavier'))
    relu1=L.ReLU(ip1, in_place=True)
    ip2 = L.InnerProduct(relu1, num_output=10,weight_filler=dict(type='xavier'))
    #最后没有accuracy层,但有一个Softmax层
    prob=L.Softmax(ip2)
    return to_proto(prob)
def write_deploy():
    with open(deploy, 'w') as f:
        f.write('name:"Lenet"
')
        f.write('input:"data"
')
        f.write('input_dim:1
')
        f.write('input_dim:3
')
        f.write('input_dim:28
')
        f.write('input_dim:28
')
        f.write(str(create_deploy()))
if __name__ == '__main__':
    write_deploy()

3.均值文件

Caffe的C++接口用到的均值文件为binaryproto类型,python接口均值文件为npy类型。

使用python需要将compute_image_mean.exe生成的mean.binaryproto转换成mean.npy。

SET GLOG_logtostderr=1
Buildx64Releasecompute_image_mean.exe examples/mnist/mnist_train_lmdb examples/mnist/number.binaryproto
pause
# coding: utf8
import numpy as np
import caffe

caffe_root = 'C:/Users/jj/Documents/caffe-windows/'  # 路径
MEAN_PROTO_PATH = (caffe_root+'examples/mnist/number.binaryproto' )             # 待转换的pb格式图像均值文件路径
MEAN_NPY_PATH = (caffe_root+'examples/mnist/number_mean.npy')                         # 转换后的numpy格式图像均值文件路径

blob = caffe.proto.caffe_pb2.BlobProto()           # 创建protobuf blob
data = open(MEAN_PROTO_PATH, 'rb' ).read()         # 读入mean.binaryproto文件内容
blob.ParseFromString(data)                         # 解析文件内容到blob

array = np.array(caffe.io.blobproto_to_array(blob))# 将blob中的均值转换成numpy格式,array的shape (mean_number,channel, hight, width)
mean_npy = array[0]                                # 一个array中可以有多组均值存在,故需要通过下标选择其中一组均值
np.save(MEAN_NPY_PATH ,mean_npy)

由于训练中实际并没有用到均值文件,可以直接生成全为0的或者不用。

import numpy as np
n=np.zeros((28,28,1),dtype=np.float32)
np.save('number.npy',n)

4.测试图片

随便截的一张图。

也可以用数据生成(28*28),对尺寸没有要求。

import numpy as np
from PIL import Image
import cPickle


f=open('mnist.pkl','rb')
a,b,c=cPickle.load(f)
r=a[0][10]
g=np.reshape(r,(28,28))
g=g*255
g=np.array(g)
x=Image.fromarray(g)
if x.mode != 'RGB':
    x = x.convert('RGB')
x.save('n.jpg')

特征提取

教程来自http://nbviewer.jupyter.org/github/BVLC/caffe/blob/master/examples/00-classification.ipynb

根据网页中的教程,略作修改。

下面代码分两部分,分类无误可以再进行特征提取。

# set up Python environment: numpy for numerical routines, and matplotlib for plotting
import numpy as np
import matplotlib.pyplot as plt

GPU=1

# display plots in this notebook
# set display defaults
plt.rcParams['figure.figsize'] = (10, 10)        # large images
plt.rcParams['image.interpolation'] = 'nearest'  # don't interpolate: show square pixels
plt.rcParams['image.cmap'] = 'gray'  # use grayscale output rather than a (potentially misleading) color heatmap

# The caffe module needs to be on the Python path;
#  we'll add it here explicitly.
import sys
caffe_root = 'C:/Users/jj/Documents/caffe-windows/'  # this file should be run from {caffe_root}/examples (otherwise change this line)
# sys.path.insert(0, caffe_root + 'python')   #  no need for win.

import caffe
# If you get "No module named _caffe", either you have not built pycaffe or you have the wrong path.
import os
if os.path.isfile(caffe_root + 'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'):
    print 'CaffeNet found.'
else:
    print 'Downloading pre-trained CaffeNet model...'
    #../scripts/download_model_binary.py ../models/bvlc_reference_caffenet
if GPU:
    caffe.set_device(0)  # if we have multiple GPUs, pick the first one
    caffe.set_mode_gpu()
else:
    caffe.set_mode_cpu()

model_def = caffe_root + 'examples/mnist/deploy.prototxt'    #  deploy.prototxt'  lenet_train_test_d2.prototxt
model_weights = caffe_root + 'examples/mnist/lenet_iter_10000.caffemodel'

net = caffe.Net(model_def,      # defines the structure of the model
                model_weights,  # contains the trained weights
                caffe.TEST)     # use test mode (e.g., don't perform dropout)

# load the mean ImageNet image (as distributed with Caffe) for subtraction
#mu = np.load(caffe_root + 'examples/mnist/m.npy')
#mu = mu.mean(1).mean(1)  # average over pixels to obtain the mean (BGR) pixel values
# print 'mean-subtracted values:', zip('BGR', mu)

# create transformer for the input called 'data'
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})

transformer.set_transpose('data', (2,0,1))  # move image channels to outermost dimension
#transformer.set_mean('data', mu)            # subtract the dataset-mean value in each channel
transformer.set_raw_scale('data', 255)      # rescale from [0, 1] to [0, 255]
#transformer.set_channel_swap('data', (2,1,0))  # swap channels from RGB to BGR

# set the size of the input (we can skip this if we're happy
#  with the default; we can also change it later, e.g., for different batch sizes)
#  net.blobs['data'].reshape(50,        # batch size
#                          1,         # 3-channel (BGR) images
#                          227, 227)  # image size is 227x227

image = caffe.io.load_image(caffe_root + 'examples/images/8.jpg',color=False)
transformed_image = transformer.preprocess('data', image)
plt.imshow(image[:,:,0])   # 28,28,1 to 28,28  [,'gray'] already set
plt.show()

# copy the image data into the memory allocated for the net
net.blobs['data'].data[...] = transformed_image

### perform classification
output = net.forward()

output_prob = output['Softmax1'][0]  # the output probability vector for the first image in the batch
print 'predicted class is:', output_prob.argmax()

if 1 :
    # load ImageNet labels
    labels_file = caffe_root + 'data/mnist/mnist_words.txt'
    if not os.path.exists(labels_file):
        print 0
        # !../ data / ilsvrc12 / get_ilsvrc_aux.sh

    labels = np.loadtxt(labels_file, str, delimiter='	')

    print 'output label:', labels[output_prob.argmax()]

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

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



    # for each layer, show the output shape
    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 + '	' + str(param[0].data.shape), str(param[1].data.shape)


    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)

        # 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:])

        if len(data.shape)==3:
            plt.imshow(data[:,:,0])
        else:
            plt.imshow(data)
        plt.axis('off')
        plt.show()

    # the parameters are a list of [weights, biases]
    filters = net.params['Convolution1'][0].data
    vis_square(filters.transpose(0, 2, 3, 1))

    feat = net.blobs['Convolution1'].data[0, :36]
    vis_square(feat)

    feat = net.blobs['Pooling1'].data[0]
    vis_square(feat)

    feat = net.blobs['InnerProduct1'].data[0]
    plt.subplot(2, 1, 1)
    plt.plot(feat.flat)
    plt.subplot(2, 1, 2)
    _ = plt.hist(feat.flat[feat.flat > 0], bins=100)
    feat = net.blobs['Softmax1'].data[0]
    plt.figure(figsize=(15, 3))
    plt.plot(feat.flat)
    plt.show()

原文地址:https://www.cnblogs.com/qw12/p/6257854.html