[caffe笔记008]:使用matlab调试caffe中新加的层

参考自http://blog.csdn.net/qq_30040223/article/details/50300779

写在前面: caffe的底层是c++实现的,所以当自己添加层时自然可以用调试c++的方法进行调试。一方面调试c++需要调试器,另一方面c++调试的时候观测矩阵或者向量的数据不是很方便。由于caffe有比较好的matlab接口,采用matlab进行辅助调试也就成为了一个很好的选择。

1. 利用MATLAB进行调试流程

我们这边需要调试自己实现的SoftProposal层。编译通过而且编译了matlab的接口。

Step1:构建单层测试网络

第一步便是编写一个测试网络’test.prototxt’,具体如下:

name: "TEST"
input: "data"
input_dim: 1
input_dim: 512
input_dim: 40
input_dim: 30

force_backward: true

layer {
  name: "testlayer" type: "SoftProposal" bottom: "data" top: "testlayer" }
Step2:观测单层测试输出

接下来,打开Matlab,

编写.m文件如下:

addpath $CAFFE_ROOT/matlab
model = 'test.prototxt';
caffe.set_mode_cpu();
% 测试gpu代码时请用GPU模式
% caffe.set_mode_gpu();
% caffe.set_device(gpu_id);
net = caffe.Net(model, 'test');
% 生成data同纬度的数据,并填入'data'层的blobs
net.blobs('data').set_data(randn(net.blobs('data').shape));
% 前向过程
net.forward();
% 检查生成的"res"是否是期望的结果
res = net.blobs('testlayer').get_data();


% 后向过程
% diff为自己设置的梯度值,保证维度一致

net.blobs('testlayer').set_diff(diff);
net.backward();
% 检查生成的"data_diff"是否是期望的结果
data_diff = net.blobs('data').get_diff();

在matlab中可以分别观测层输出和层反向传播的值,以判断是否实现正确。

2. 一些调试技巧

2.1. 利用LOG(INFO)观测单个数值

在caffe的底层c++代码中可以用LOG(INFO)在linux的shell窗口中输出一些简单的变量。

观测新添加的层的一些常量参数是否配置成功

例如我们新建的SoftProposal层,该层有参数maxiteration,如果设置了这个参数就采用设置值,否则采用默认值20。

  if(soft_proposal_param.has_maxiteration()) 
    maxIteration_ = soft_proposal_param.maxiteration();
  else
    maxIteration_ = 20;
  LOG(INFO) << "maxIteration: " << maxIteration_;
观测一些中间结果

例如迭代优化时观测每次迭代终止条件的判定值。

 for (j = 0; j < maxIteration_; j++) {
     // proposalBuffer_data = transferMatrix_data * proposal_data - proposalBuffer_data;
     caffe_cpu_gemv<Dtype>(CblasNoTrans, N_, N_, 1.,
     transferMatrix_data, proposal_data, -1., proposalBuffer_data);

    float normDiff = sqrt(proposalBuffer_.sumsq_data());

    LOG(INFO) << "normDiff(" << j << "): " << normDiff;

    if (normDiff < tolerance_) break;
    // proposalBuffer_data = proposal_data + proposalBuffer_data;
     UpdateProposalKernel(N_, proposal_data, proposalBuffer_data, proposalBuffer_data, -1.0f);  
end
2.2. 利用Blob的存取观测矩阵或者向量的值
保存Blob到文件(底层c++代码中)。

保存Blob到文件可以采用如下代码保存到指定文件中。

#include "caffe/util/io.hpp" 

... ...

BlobProto sp;
proposal_.ToProto(&sp, false);// false只保存blob.data,ture则同时保存blob.data和blob.diff
WriteProtoToBinaryFile(sp, "proposal.blob"); //保存到proposal.blob文件中
从文件中读取Blob数据(matlab中)

matlab中读取blob文件可以通过read_mean函数来实现。

proposal = caffe.io.read_mean('proposal.blob'); //从proposal.blob文件中读入数据到proposal

读入之后就可以在matlab中方便的查看了。

2.3. 调试一些子函数

子函数的调试,其实是利用了第一部分调试层的方式,只不过把和需要观测的子函数的输出值放入到当前层的topblob中。

例如有子函数InitDistanceMetricKernel,作用是初始化Blob<Dtype> distanceMetric_这个成员变量。

// for page rank
template <typename Dtype>  
void SoftProposalLayer<Dtype>::InitDistanceMetricKernel(){
  Dtype* distanceMetric_data = distanceMetric_.mutable_cpu_data();  

  long nthreads = N_ * N_;
  for(long n=0;n<nthreads;n++)
  {
    const long q = n % width_; 
    const long p = (n / width_) % height_;
    const long j = (n / N_) % width_;
    const long i = n / N_ / width_;
    const long u = i * width_ + j;
    const long v = p * width_ + q;

    if (u >= v) {
        *(distanceMetric_data + n) = expf(((i - p) * (i - p) + (j - q) * (j - q)) / (-2 * factor_ * factor_));
        *(distanceMetric_data + v*N_ + u) = *(distanceMetric_data + n);
    }
  }   
}

我们需要观测初始化是否成功,那么在Forward_cpu

template <typename Dtype>   
void SoftProposalLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  Dtype* top_data = top[0]->mutable_cpu_data();

  InitDistanceMetricKernel();  
  const Dtype* distanceMetric_data = distanceMetric_.cpu_data();

  /*
  编写一节程序,将distanceMetric_data赋值到top_data当中
  */
}

当再次编译后执行第一部分的测试网络,就可以获得distanceMetric_的数据。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值