caffe中Blob和Net最基本的操作

首先,查看相关的结构体的定义

Net:
Net类的数据结构
  构造函数(从NetPatameter构造或者从net.prototxt中构造),初始化函数,NetParameter;
  前向传播,反向传播
  Net的读取与保存(序列化)
  返回Blobs, Layers的名称,是否需要反向传播,权值和相关参数等
  查找当前网络是否包含指定名称的Blob,Layer
初始化Init()
  构建所有的Layer:CreateLayer(param.layer(layer_id));
  确定Layer的输入Blob和输出Blob,从而将各个layer通过Bolb连接起来
  调用Layer->Setup函数
  初始化各层权值Blob
 
前向传播Forward
  net->ForwardFromTo调用相应层的layer_[i]->Forward(bottom_vecs_[i],top_vecs_[i])
Blob:
Blob用于存储4维数据。4个维度分别为(num,channel,height,width).
public:
  构造函数
  Reshape,打印Bolob的shape,获取某一维度的尺寸,根据n计算偏移量,Blob中的元素数目
  获取指定位置的data或diff,获取cpu_data或cpu_diff
  Blob的序列化或反序列化
protected:
  指向data_,diff_的指针
  形状信息shape_
  存放有效元素数目的信息count_,Blob的容量信息capacity_.
 
src/caffe.blob.cpp
  Reshape(),变维函数
  构造函数
  获得cpu_data,cpu_diff,gpu_data,gpu_diff的指针
  共享另一个Blob的data,diff指针
  Update来更新网络中的参数(data = data-diff)
  Blob的序列化与反序列化

Blob的基础功能有:定义一个Blob,打印Blob的shape,重定义该Blob的shape(Blob的大小可以不一致),修改和获取Blob在各个位置的参数值

#include <vector>
#include <iostream>
#include <caffe/blob.hpp>
using namespace caffe;
using namespace std;
int main(void)
{
  Blob<float> a;#定义一个Blob
  cout<<"Size : "<< a.shape_string()<<endl;#获取该Blob的size
  a.Reshape(1, 2, 3, 4);#Reshape该Blob
  cout<<"Size : "<< a.shape_string()<<endl;
  
#修改Blob指定位置元素的值
  float * p = a.mutable_cpu_data();
  for(int i = 0; i < a.count(); i++)
  {
    p[i] = i;
  }
#获取病打印Blob各个元素的值
  for(int u = 0; u < a.num(); u++)
  {
    for(int v = 0; v < a.channels(); v++)
    {
      for(int w = 0; w < a.height(); w++)
      {
        for(int x = 0; x < a.width(); x++)
        {
          cout<<"a["<<u<<"]["<<v<<"]["<<w<<"]["<<x<<"] = "<< a.data_at(u, v, w, x)<<endl;
        }
      }
    }
  }

  

  return 0;
}

Blob的进阶功能有:修改Blob的diff,根据data=data-diff来更新Blob

 

Net的基本功能有:读取xxx.prototxt文件来设置网络,获取并修改Net的权值(如W,b,即训练参数),读取和设置网络的输入,前向传播后读取网络的输出

#include <caffe/caffe.hpp>
#include <algorithm>
#include <iosfwd>
#include <memory>
#include <string>
#include <utility>
#include <vector>


using namespace caffe;  // NOLINT(build/namespaces)
using std::string;



int main(int argc, char** argv) {


 //从model_file(xxx.prototxt)中初始化网络结构
shared_ptr<Net<float> > net_;
net_.reset(new Net<float>("./net.prototxt", TEST));
//设置网络的权重参数,如使用训练好的网络来初始化网络参数,或自己手动设置网络权重所在的Blob
//由于我们的网络只有一层卷积,一层卷积只有两个网络参数,第一个是W(num_output,num_input,height,width),第二个是b(num_output)
const vector<shared_ptr<Blob<float> > >& net_params = net_->params();
std::cout<<net_params.size()<<std::endl;#表示有多少个网络参数(多少个W+多少个b)
const vector<int>& shape = net_params[0]->shape();#得到第一个网络参数W的Blob
std::cout<<shape.size()<<std::endl;#打印W的维度,4维
std::cout<<shape[0] <<shape[1] <<shape[2]<<shape[3]<<std::endl;#打印W各个维度(num_output,num_input,height,width)
float *p = net_params[0]->mutable_cpu_data();#获取和设置W所在的Blob
for(int i =0;i<net_params[0]->count();i++)
{
    p[i]=i%2==0?1:1;
}
for(int u =0;u<net_params[0]->channels();u++)
{
    for(int v =0;v<net_params[0]->height();v++)
    {
        for(int w =0;w<net_params[0]->width();w++)
        {
            std::cout<<net_params[0]->data_at(0,u,v,w)<<std::endl;
        }
    }
}


//设置网络的输入Blob
//  获取和设置输入Blob
Blob<float>* input_layer = net_->input_blobs()[0];//输入Blob可能有多个,[0]表示获取第一个Blob
float *p2 = input_layer->mutable_cpu_data();
int num_channels_ = input_layer->channels();
for(int i2 =0;i2<input_layer->count();i2++)
{
    p2[i2]=(i2%2==0)?2:5;
}
for(int u =0;u<input_layer->channels();u++)
{
    for(int v =0;v<input_layer->height();v++)
    {
        for(int w =0;w<input_layer->width();w++)
        {
            std::cout<<"input_layer"<<u<<v<<w<<" "<<input_layer->data_at(0,u,v,w)<<std::endl;
        }
    }
}

#网络执行前向传播并得到输出Blob
net_->Forward();

Blob<float>* out_layer = net_->output_blobs()[0];
float *p4 = out_layer->mutable_cpu_data();
for (int x =0;x<out_layer->num();x++)
{
    for(int u =0;u<out_layer->channels();u++)
    {
        for(int v =0;v<out_layer->height();v++)
        {
            for(int w =0;w<out_layer->width();w++)
            {
                std::cout<<"out_layer"<<x<<u<<v<<w<<" "<<out_layer->data_at(x,u,v,w)<<std::endl;
            }
        }
    }
}

}
  

用于创建网络模型的xxx.prototxt

1.数据输入层
不指定数据,指定数据的维度
input: "data"
input_dim: 1
input_dim: 1
input_dim: 10
input_dim: 10

图像语义分割的输入,需要自己创建DenseImageData层
layer {
  name: "ImageData1"
  type: "DenseImageData"
  top: "ImageData1"
  top: "ImageData2"
  dense_image_data_param {
    source: "/media/mlxuan/LinuxH/project/SegNet/SegNet-Tutorial-master/CamVid/train.txt"
    batch_size: 1
	shuffle: true
  }
}

图像分类的输入


其他


2.卷积层

layer {
  name: "Convolution1"
  type: "Convolution"
  bottom: "data"
  top: "Convolution1"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 1
    pad: 0
    kernel_size: 3
    stride: 1
    dilation: 1
    weight_filler {
      type: "msra"
    }
    bias_filler {
      type: "constant"
    }
  }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值