您的位置:首页 > 编程语言 > MATLAB

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

2017-03-05 10:59 274 查看
第一部分:用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
相关文章推荐