Caffe基础(三)- 使用Matlab接口、python接口、c++接口训练网络和预测

需要结合我之前的博客做参考,相关配置文件在文末有链接可以下载

1.使用Matlab接口训练自己的数据集(MATLAB2017b)

Caffe源码编译后将主目录下的matlab\+caffe\private\Release文件夹内的caffe_.mexw64拷贝至上一层文件夹内,即matlab\+caffe\private文件夹内

                                                     

                                

同时点击设置路径按钮选项,将主目录下的matlab文件夹路径添加至路径中

     

       

新建train.m文件,输入

clear;
clc;
caffe.reset_all;
caffe.set_mode_gpu();
gpu_id = 0;  % we will use the first gpu in this demo
caffe.set_device(gpu_id);
solver=caffe.Solver('.\data\mydata\solver.prototxt')
solver.solve()
close all;
hold on;
% iter_ = solver.iter();
% while iter_<10000
%     solver.step(1);%一步一步迭代
%     iter_ = solver.iter();    %得到迭代次数
%     loss=solver.net.blobs('loss').get_data();%取训练集的loss  
%     if iter_==1
%         loss_init = loss;
%     else if(mod(iter_,1)==0)  %每1次绘制一次损失
%         y_l=[loss_init loss];
%         x_l=[iter_-1, iter_];     
%         plot(x_l, y_l, 'r-');
%         drawnow
%         loss_init = loss;
%         end
%     end
% 
%     if mod(iter_, 100) == 0   %100次取一次accuray
%         accuracy=solver.test_nets.blobs('accuracy').get_data();%取验证集的accuracy       
%         if iter_/100 == 1
%             accuracy_init = accuracy;
%         else 
%             x_l=[iter_-100, iter_];
%             y_a=[accuracy_init accuracy];
%             plot(x_l, y_a,'g-');
%             drawnow
%             accuracy_init=accuracy;
%         end
%     end
% end

注释部分代码可以实现损失率及精度的输出,具体使用可见博客https://blog.csdn.net/u014114990/article/details/50502125/

点击train.m文件开始训练,文件中需要使用的文件均可以在我之前的博客中找到

2.使用Matlab接口预测一张图片(MATLAB2017b)

新建test_a_image.m,输入

clear;
clc;
caffe.reset_all;
caffe.set_mode_gpu();
gpu_id = 0;  % we will use the first gpu in this demo
caffe.set_device(gpu_id);
caffe.reset_all();

deploy = '.\data\mydata\deploy.prototxt';      %测试模型结构
caffe_model = '.\data\mydata\full_iter_6000.caffemodel.h5';     %训练好的模型
net = caffe.Net(deploy, caffe_model, 'test');     %三个参数,分别代表,测试结构,训练好的测试模型,test
im_data=imread('.\data\mydata\dog009.jpg');         %读入图像
%imshow(im_data);
input_data = {prepare_image(im_data)};  %准备数据,需要裁剪时裁剪数据
scores = net.forward(input_data); 

scores = scores{1};
scores = mean(scores, 2);  % take average scores over 10 crops

[~, maxlabel] = max(scores);
scores
maxlabel
figure;plot(scores);%画出得分情况
axis([0, 999, -0.1, 0.5]);%坐标轴范围
grid on %有网格
fid = fopen('.\data\mydata\synset_words.txt', 'r');
i=0;
while ~feof(fid)
    i=i+1;
    lin = fgetl(fid);
    lin = strtrim(lin);
    if(i==maxlabel)
        fprintf('the label of %d is %s\n',i,lin)
        break
    end
end

训练时有用到mean.binaryproto,所以预测是也需要每张图片去减下该mean图片,可以用prepare_image函数实现,代码如下:

function crops_data = prepare_image(im) 
% ———————————————————————— 
% caffe/matlab/+caffe/imagenet/ilsvrc_2012_mean.mat contains mean_data that 
% is already in W x H x C with BGR channels 
mean_data = caffe.io.read_mean('.\data\mydata\mean.binaryproto'); %读入均值文件 
crops_data = single(im) - mean_data; 

运行该文件,结果如下:

                                                                  

对比命令行预测该张图片方式,结果保持一致

同样此中用的配置文件可以参考我之前的博客

3.使用python接口训练自己的数据集

将主目录下的python/caffe文件夹内的文件复制到C:\Program Files\Anaconda3\Lib\site-packages文件夹下

                                                  

在主目录下新建train.py文件,

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import caffe
print(caffe.__version__)
caffe.set_mode_gpu()
caffe.set_device(0)

solver = caffe.SGDSolver('.\data\mydata\solver.prototxt')
solver.solve()

运行文件,训练自己构造的数据集

使用中如果出现pydot的报错问题时,可以尝试如下方法解决:

(1)命令 行下pip install graphviz

(2)安装graphviz-2.38.zip 链接:https://pan.baidu.com/s/126zoIOQdKeQKK9ocvFTsHw 
提取码:b5wf

安装完毕后,记得添加环境变量,添加完毕后重启下电脑

                                 

(3)在命令行方式下pip install pydotplus

4.使用python接口预测一张图片

在主目录下新建test_a_image.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import numpy as np
import cv2
from glob import glob
import caffe
import multiprocessing

net = caffe.Net('.\data\mydata\deploy.prototxt','.\data\mydata\iter_6000.caffemodel.h5', caffe.TEST)
MEAN_PROTO_PATH = '.\data\mydata\mean.binaryproto'        # 待转换的pb格式图像均值文件路径
MEAN_NPY_PATH = '.\data\mydata\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中可以有多组均值存在,故需要通过下标选择其中一组均值
print(mean_npy.shape)
print(net.blobs['data'].data.shape)
#np.save(MEAN_NPY_PATH ,mean_npy)

transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
f1= np.load('.\data\mydata\mean.npy')
transformer.set_mean('data',f1.mean(1).mean(1))

transformer.set_transpose('data', (2, 0, 1))
im = caffe.io.load_image('.\data\mydata\dog009.jpg')
im1 = cv2.imread('.\data\mydata\dog009.jpg')
im2 = im1/255

net.blobs['data'].data[...] = transformer.preprocess('data', im)
out = net.forward()
print(out)

names = []
with open('.\data\mydata\synset_words.txt', 'r+') as f:
    for l in f.readlines():
        names.append(l.split(' ')[0].strip())
print(names)
prob = net.blobs['prob'].data[0].flatten()
print('prob: ', prob)
print('class: ', names[np.argmax(prob)])




gender_net = caffe.Classifier('.\data\mydata\deploy.prototxt', '.\data\mydata\iter_6000.caffemodel.h5')
output = gender_net.predict([im1],oversample = False)
print("caffe.classifier: ",output)
#top_k = net.blobs['prob'].data[0].flatten().argsort()[-1:-6:-1]
#for i in np.arange(top_k.size):
#    print(top_k[i])

运行该文件,结果如下:

(3, 121, 121)
(1, 3, 121, 121)
{'prob': array([[0.5013305 , 0.49866948]], dtype=float32)}
['cat', 'dog']
prob:  [0.5013305  0.49866948]
class:  cat

代码中最后的三句话:

gender_net = caffe.Classifier('.\data\mydata\deploy.prototxt', '.\data\mydata\iter_6000.caffemodel.h5')
output = gender_net.predict([im1],oversample = False)
print("caffe.classifier: ",output)

也可以用于预测一张图片,结果为:

caffe.classifier:  [[0.50133055 0.49866948]]

预测结果和matlab、命令行方式预测结果保持一致

以上对应的M文件及py文件见 链接:https://pan.baidu.com/s/1KtCyg76fQS4k5SROaQ8PcA 
提取码:zkjo

5.打印caffe的网络结构

在主目录下的python文件夹中存在draw_net.py文件,同时在该目录下我放入前面训练mnist数据集用到的lenet_train_test.prototxt文件,该文件实现了Lenet-5结构。

打开命令行语句,cd到该目录下,输入如下语句:

打印出来的网络结构如下:

 

                         

6.可以使用python文件来生成 prototxt 文件,可以参考博客https://blog.csdn.net/renhanchi/article/details/76472554

7.使用c++接口训练网络和预测图片

前面博客通过命令行方式训练网络结构,是使用caffe.exe后跟选项参数方式进行,caffe.exe可以由caffe.bin生成,所以可以借鉴caffe.bin工程来做训练

              

预测图片时使用classification.exe后跟参数进行,该exe由classification工程生成,所以可以参考此工程

              

 

 

8.使用tensorBoard来展示图,张量

代码段如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author:Icecream.Shao
# 在sess之前,计算图需要构建完成,才能对变量进行正确的初始化。详细的知识感觉自己也不是很懂。
# 。。。反正就记住了,在使用Sess启动计算图之前,一定要构建完整的计算图,不能在会话里面
# 再补充计算图。
import tensorflow as tf
import numpy as np
def f1(xx):
    w1=tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1),name="w1")
    return tf.matmul(xx, w1)

def f2(aa):
    w2=tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1),name="w2")
    return tf.matmul(aa, w2)


x=tf.placeholder(tf.float32,shape=[None,2],name="x")
#y=tf.placeholder(tf.float32,shape=[None,1],name="y")
a=f1(x)
y=f2(a)
init=tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)
    tmp=np.array([[0.7,0.9]])
    print(sess.run(y,feed_dict={x:tmp}))
    tf.identity(y,"y")
    writer = tf.summary.FileWriter('D://tensorflow-log//test_tensorboard3', tf.get_default_graph())
    writer.close()

在tensorflow-log的上一级目录,即D盘根部录下,新建.cmd文件,文件内内容为:
tensorboard --logdir=D://tensorflow-log --host=127.0.0.1

运行该cmd文件,出现

                         

然后在浏览器里输入http://localhost:6006

                           

9.目前主要还是通过prototxt文件构造网络结构,也有碰到用python直接写出网络结构的情况。

这一段时间整理了下tensorflow、keras、caffe的框架和一些基础代码实现方式,后续的精力会放在常用网络结构的了解,和一些经典的classification、detection、segmentation算法研读上面,过程中加强这些框架工具的使用。

 

 

Guess you like

Origin blog.csdn.net/jiugeshao/article/details/104090183