Caffe:利用训练好的模型进行分类

    以大神训练好的模型为基础,利用自己的数据进行了finetune之后,下一步就可以真正使用模型来进行分类操作了。具体步骤如下:

    1. 编辑分类网络的配置文件deploy.prototxt

    deploy文件是真正使用模型时候用的,其结构与train_val.prototxt基本上是一样的,只是输入和输出模块有区别。因此,可以直接把train_val.prototxt拷贝一份,改名为deploy.prototxt,并对其进行编辑:

    (1)输入模块

    把其中的data层删除(一般有两个,一个用于train,一个用于test),新增一个Input层,一般参数如下:

layer{
  name: "data"
  type: "Input"
  top: "data"
  input_param{
    shape: { dim: 1 dim: 3 dim: 227 dim: 227}
  }
}

    需要注意的是,top参数要和后面的cov1的bottom一样,才能把网络连接上;其次,shape是输入的图片的shape,可以在调用caffe的代码中进行修改。

    (2)输出模块

    删除Accuracy层和SoftmaxWithLoss层,新建一个Softmax层,一般参数如下:

layer {
  name: "prob"
  type: "Softmax"
  bottom: "fc8"
  top: "prob"
}

    其中,bottom参数为上面的网络中最后一层的top(一般为全连接层)

    2.图片信息预处理

    在输入到网络之前,需要对图片进行预处理,如减去均值等。具体步骤如下:

    (1)转换均值文件格式

    因为训练时生成的mean文件是通过caffe自带的工具生成的,是C++使用的格式,使用python接口使用caffe需要先将其转化为npy格式。脚本代码如下:

path =  '/Users/Coder/caffe/examples/my_file/'
blob = caffe.proto.caffe_pb2.BlobProto()
data = open(path + 'mean.binaryproto' , 'rb' ).read()
blob.ParseFromString(data)
arr = np.array( caffe.io.blobproto_to_array(blob) )
out = arr[0]
np.save(path + 'mean.npy' , out )

    (2)图片格式化    

    python中读入的图片与caffe中需要的并不一致,因此需要进行格式化

mu = np.load(my_path + 'mean.npy')
mu = mu.mean(1).mean(1)

transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape}) #shape要与net中data的shape一致
transformer.set_transpose('data', (2, 0, 1)) #caffe.io.load_image读取jpg图片时,第三维是channel,需要把channel换到第一维
transformer.set_mean('data', mu) #减去均值
transformer.set_raw_scale('data', 255) #python中将图片存储为[0, 1],而caffe中将图片存储为[0, 255],所以需要一个转换
transformer.set_channel_swap('data', (2, 1, 0)) #python的图片是RGB格式,而caffe中的是BGR格式,需要进行转置

    3. 加载模型,进行分类

    加载模型的网络和训练好的参数,把图片输入,进行分类

    加载模型:

my_path = '/Users/Coder/caffe/examples/my_file/'
caffe.set_mode_cpu() #如果只使用CPU,需要这一行,如果使用GPU,则设为GPU
model_def = my_path + 'deploy.prototxt'   #模型配置文件
model_weights = my_path + 'minemodel/solver_iter_200.caffemodel' #训练好的参数
net = caffe.Net(model_def, model_weights, caffe.TEST)

    输入图片,执行分类:

img = caffe.io.load_image('/Users/Coder/caffe/data/re/test/409.jpg') #加载图片,进行预处理
transformed_img = transformer.preprocess('data', img)

net.blobs['data'].reshape(1, 3, 227, 227) # 修改net的data的格式,使之与输入匹配(可以修改第一个参数,进行批处理)
net.blobs['data'].data[...] = transformed_img #输入
output = net.forward() #分类

output_prob = output['prob'][0] #读取分类结果
print 'predicted class is: ', output_prob.argmax() 


    

猜你喜欢

转载自blog.csdn.net/xiezongsheng1990/article/details/80643937
今日推荐