caffe学习笔记6-matlab接口总结

第一部分:用matlab接口操作网络,包括网络生成,数据读取及修改,存储caffeemodel,返回layer的类型
  1.设置网络:
    model = './models/bvlc_reference_caffenet/deploy.prototxt';
    weights ='./models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel';
  2.启动网络前,设置运行模式cpu/gpu,模式和设备的设置必须在创建一个net或solver之前。
    caffe.set_mode_cpu();
    caffe.set_mode_gpu();
    caffe.set_device(gpu_id); //使用 GPU,指定 GPU 的 ID 号
  3.创建网络:
    net = caffe.Net(model, weights, 'test'); % 创建网络并加载权值
    或者
    net = caffe.Net(model, 'test'); % 创建网络,但不加载权值
    net.copy_from(weights); % 加载权值
  4.你可以存取网络中任意的 blob。若希望用 1 来填充’data’这个 blob:
    net.blobs('data').set_data(ones(net.blobs('data').shape));
  5.若希望将 ‘data’这个blob中的所有值都乘以 10,Caffe使用单精度float型数据。如果你的数据不是单精度的,set_data会自动将数据转换为单精度。
    net.blobs('data').set_data(net.blobs('data').get_data() * 10);
  6.你可以访问每一层,对网络进行调整(surgery)。例如,将 conv1 的参数乘以 10:
    net.params('conv1', 1).set_data(net.params('conv1', 1).get_data() * 10); % 设置权值
    net.params('conv1', 2).set_data(net.params('conv1', 2).get_data() * 10); % 设置偏置
    或者,你也可以使用以下命令:
    net.layers('conv1').params(1).set_data(net.layers('conv1').params(1).get_data() * 10);
    net.layers('conv1').params(2).set_data(net.layers('conv1').params(2).get_data() * 10);
  7.保存刚刚修改的网络:
    net.save('my_net.caffemodel');
  8.得到 layer 的类型(返回一个 string):
    layer_type = net.layers('conv1').type;

  第二部分:网络的前向传导(forward)与后向传播(backward)
  1.Forward 可使用 net.forward 或者 net.forward_prefilled 函数。
    net.forward()传入包含了输入数据的 N-D arrays 形式的单元阵列(cell array),返回包含输出数据的单元阵列。  
    net.forward_prefilled()使用了 forward 过程中,input blobs(s)中已经存在的数据。
    如果没有输入就不会产生输出。
    在创建了类似 datmean_data = caffe.io.read_mean('./data/ilsvrc12/imagenet_mean.binaryproto');a = rand(net.blobs('data').shape);的输入数据后,可运行
    res = net.forward({data});
    prob = res{1};
    或者
    net.blobs('data').set_data(data);//先装载数据
    net.forward_prefilled();//再进行前向计算
    prob = net.blobs('prob').get_data();//计算之后再读取原块的数据
  2.Backward 用法相似,使用 net.backward()或者 net.backward_prefilled()
    用 get_diff()和 set_diff() 替换 get_data() 和 set_data()。
    在创建了类似 prob_diff = rand(net.blobs('prob').shape);产生输出blobs的梯度后,你可以运行:
    res = net.backward({prob_diff}); //先装载数据,在进行前向计算
    data_diff = res{1}; //计算之后返回数据
    或者
    net.blobs('prob').set_diff(prob_diff);//先装载数据
    net.backward_prefilled(); //反向计算
    data_diff = net.blobs('data').get_diff();//返回计算后的数据
    然而,上述的 backward 计算不能得到正确结果,因为 Caffe 认为它不需要 backward 计算(prob(accuracy)层不需要反向计算,还有data层也是)。
    为了得到正确的 backward 结果,你需要在网络 prototxt 文件中设置'force_backward: true' 。
  3.在完成前向和后向计算之后,你可以获得中间blobs的data和diff。例如,你可以在前向计算后获取pool5的特征。
    pool5_feat = net.blobs('pool5').get_data();//刚才上面第一部分是通过caffemodel来提取数据的,这里得到的是自己通过计算之后的特征(视觉层)
 
  第三部分:调整网络的形状
  1.假设一次性只在神经网络中放入一张(而不是十张)图像:
    net.blobs('data').reshape([227 227 3 1]); % 改造 blob 'data'
    net.reshape();
    这样,整个网络形状就会被调整。现在 net.blobs('prob').shape 应该为[1000 1]; //1表示批处理的个数
  
  第四部分:训练网络
  1.假设已经创建了 ImageNET Tutorial 的训练和验证的 lmdb 数据库。若要创建在 LSVRC2012 分类数据集上的 Solver 并进行训练:
    solver = caffe.Solver('./models/bvlc_reference_caffenet/solver.prototxt');//solver中含有网络的定义,而网络定义data中含有数据源
    训练时,使用以下命令:
    solver.solve();
    或者只训练 1000 iterations(以便在训练更多的 iterations 之前,你可以对网络做一些其它修改)
    solver.step(1000);
  2.来获取迭代数量:
    iter = solver.iter();
  3.获取训练/测试网络:
    train_net = solver.net;
    test_net = solver.test_nets(1);
  4.假设从一个snapshot中恢复网络训练:
    solver.restore('your_snapshot.solverstate');

  第五部分:输入和输出
  caffe.io 类提供了基础的输入函数 load_image 和 read_mean。
  1.读取 ILSVRC 2012的均值文件:
    mean_data = caffe.io.read_mean('./data/ilsvrc12/imagenet_mean.binaryproto');
  2.读取caffe例子图片,重新调整尺寸为[width, height],假设我们想要 width = 256;height = 256;
    记住caffe读取的图片,width 是第一维度,通道为 BGR,这与 Matlab 通常存储图片的方式不同。
    im_data = caffe.io.load_image('./examples/images/cat.jpg');
    im_data = imresize(im_data, [width, height]); % resize using Matlab's imresize
    im_data = im_data - mean_data;
    若不想使用 caffe.io.load_image,而想使用 Matlab 自带接口加载图像,你可以这样做:
    im_data = imread('./examples/images/cat.jpg'); % read image
    im_data = im_data(:, :, [3, 2, 1]); % 从 RGB 转换为 BGR
    im_data = permute(im_data, [2, 1, 3]); % 改变 width 与 height 位置
    im_data = single(im_data); % 转换为单精度
  3.在 caffe/matlab/hdf5creation 中展示了如何用 Matlab 读取与写入 HDF5数据,而 Matlab 自身在输出方面的功能十分强大:
  4.清除 Nets 和 Solvers
    Call caffe.reset_all() 清除你创建的所有 solvers或独立的 nets。
  
  第六部分:数据层
  Caffe 中数据流以 Blobs 进行传输。数据层将输入转换为 blob 加载数据,将 blob 转换为其他格式保存输出。
  均值消去、特征缩放等基本数据处理都在数据层进行配置。
  数据层加载 leveldb 或 lmdb 的数据库存储格式保证快速传输。
layer{ # 数据层
  name: data
  type: Data
  top: "data"     # 是数据本身:“data”的命名只是方便使用
  top: "label"    # 是数据标签:“label”的命名只是方便使用
  include {
    phase: TRAIN  # 表明这是在训练阶段才包括进去
  }
  data_param{ #数据库具体配置
              
        source: "lmdb文件夹路径"  # 数据库路径
        backend: LMDB             # 默认为LEVELDB (LMDB 支持并行读取)
        batch_size: 64            # 批量处理,提高效率
  }
  transform_param{

mirror: true
  crop_size: 227
  mean_file: "data/ilsvrc12/imagenet_mean.binaryproto"
        scale: 0.00390625 # 默认为1, 特征归一化系数,将范围为[0, 255]的 MNIST 数据归一化为[0, 1]
  }
}

------------------------------------------------------------------------------------------------------------------------------
matlab函数cat
问题:两个图像矩阵A=M*N*K1,B=M*N*K2,第三维K1,K2表示数量,matlab怎么快速实现他们在第三维数量上的叠加。
答:cat(3,A,B)
------------------------------------------------------------------------------------------------------------------------------
matlab函数meshgrid
问题:使用matlab怎么能够产生这样的一组数组呢?
x = 1,2,3,4
y = 5,6
产生一组点:
(1,5) (1,6)
(2,5) (2,6)
(3,5) (3,6)
(4,5) (4,6)
答案:
x = [1,2,3,4];
y = [5,6];
[X,Y] = meshgrid(x,y);
[X(:), Y(:)] 
-----------------------------------------------------------------------------------------------------------------------------------

Matlab 的标号从 1 开始,且以列(column)为主,则 blob 通常的 4 个维度在 Matlab,中用 [width, height, channels, num]表示, width 是第一维。

-----------------------------------------------------------------------------------------------------------------------------------

   tic和toc用来记录matlab命令执行的时间。
   tic用来保存当前时间,而后使用toc来记录程序完成时间。
   两者往往结合使用,用法如下:
   tic
   operations
   toc
   显示时间单位:秒
-----------------------------------------------------------------------------------------------------------------------------------
   matlab启动前(临时设置变量) 每次启动的都加载用 ~/.bashrc ,查看变量用echo $LD_LIBRARY_PATH
  $ export LD_LIBRARY_PATH=/opt/intel/mkl/lib/intel64:/usr/local/cuda7.5/lib64(:为分割号)
  $ export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6
   matlab启动后 (startup.m)放在caffe文件夹下,运行一下就可以了
   addpath(genpath(pwd));
   fprintf('caffe startup\n');
   或者手敲命令
   addpath('~/caffe-master');//只用添加主文件夹 或者 addpath ./matlab
   help caffe 可测试路径是否添加成功

-----------------------------------------------------------------------------------------------------------------------------------
画图

figure;plot(scores);
axis([0, 999, -0.1, 0.5]);
grid on

或文件夹下使用gnuplot进行画图:
gnuplot plot-p-at-k.gnuplot

-----------------------------------------------------------------------------------------------------------------------------------

matlab 图片集转成.mat格式,便于检索后根据索引号来显示对应的图片
%文件夹下图片按顺序全部转为mat
image_folder_path = '/home/nielsen/caffe-master/data/image1000test200/train/';
ext = '*.jpg';
dis = dir([image_folder_path ext]);
nms = {dis.name};
my_images = cell(length(nms),1);%
for k = 1:length(nms)
    nm = [image_folder_path nms{k}];   % 注意要加上路径
    my_images{k} = imread(nm);
end
save('train_images.mat','my_images');


%显示图片
clc;
clear all;
load train_images.mat
p1 = my_images{2};
imshow(p1);


-----------------------------------------------------------------------------------
%用于显示检索结果的图片的显示
%x_one_distance.mat 存储的是top距离
%y_one_index 存储的是top图片的索引-----
%z_one_label 存储的是标签(类别号)
%假设显示前k个最接近的图片,使用matlab读取这k个原图片并顺序显示
k = 20;
load x_one_distance.mat %内部x_distance
load y_one_index.mat     %内部y_index
load z_one_label.mat       %内部z_label
load train_images.mat     %内部my_images
%load y_index.mat
imgs = cell(1,k);
%y_index = y_index(:,2); %批量时候的检索
for i=1:k
  img_index = y_index(i);
  imgs{i} = my_images{img_index};
  subplot(4,5,i); %以4行5列显示
  imshow(imgs{i});
end

-----------------------------------------------------------------------------------

%用路径显示图片
train = importdata('/home/nielsen/caffe-new/data/cifar10/train_pairwised.txt'); %数据库标签,取第二列的标签data = train.data;
train_path = train.textdata;%提路径
train_label = train.data;%提标签
index = y_index(1:k,:);%取出前k行的索引
path = train_path(index,:);
label = train_label(index,:);
for i=1:k
  subplot(4,5,i); %以4行5列显示
  imshow(path{i});
  title(label(i));
end

你可能感兴趣的:(caffe)