元旦假期已经开始了,今天是17年最后一天,连续两天独自一人在实验室学习,其实也并没有什么了不起,平常心,宠辱不惊。
相对于tensorflow里边的tensor同等地位,caffe的blob就是数据存储和流动的单元。这也是为什么和很多教材里一样,称之为房屋的砖块,是构成整个架构的基本元素。
看了书和一些技术博客,写了个简单的例子,跑跑感受一些,如何使用blob,blob的功能作用。
#include<vector>
#include<iostream>
#include<caffe\blob.hpp>
#include<caffe\util\io.hpp>//专门针对ToProto和FromProto加入的。
using namespace caffe;
using namespace std;
int main()
{
Blob<float> a;
cout << "size: " << a.shape_string() << endl;
a.Reshape(1, 2, 3, 4);//这里可以表示一张图片,2个通道,3为高度,4为宽度。
cout << "size: " << a.shape_string() << endl;
float * p = a.mutable_cpu_data();//带mutable_开头的函数意味着可以对返回的指针内容进行更改,
//而不带mutable_开头的返回const 指针,不能对其指针的内容进行修改。
float * q = a.mutable_cpu_diff();
for(int i =0;i!=a.count();i++)
{
p[i] = i;
q[i] = a.count() - i - 1;
}
a.Update();//负责了线性代数库的调用,实现的功能是blob里面的data部分减去diff部分,权值更新。
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 y = 0; y<a.width(); y++)
{
cout << "a[" << u << "][" << v << "][" << w << "][" << y << "]" << a.data_at(u,v,w,y)<<endl;
}
}
}
}
cout << "ASUM= " << a.asum_data() << endl;//L1范数
cout << "SUMSQ= " << a.sumsq_data() << endl;//L2范数
/*
将Blob的值保存到磁盘,使用了Blob对象的TOPROTO FROMPROTO函数。
需要先申请一个BlobProto对象来接受blob对象。
*/
BlobProto bp;
a.ToProto(&bp, true);//将a的data 和 diff 一起写入 bp;
WriteProtoToBinaryFile(bp, "a.blob");//把bp写入磁盘文件a.blob。
BlobProto bp2;
ReadProtoFromBinaryFileOrDie("a.blob", &bp2);//把a.blob文件内容写入bp2;即读取磁盘
Blob<float> f;
f.FromProto(bp2, true);//将内容拷贝至f。
for (int u = 0; u<f.num(); u++)
{
for (int v = 0; v<f.channels(); v++)
{
for (int w = 0; w<f.height(); w++)
{
for (int y = 0; y<f.width(); y++)
{
cout << "a[" << u << "][" << v << "][" << w << "][" << y << "]" << f.data_at(u, v, w, y) << endl;
}
}
}
}
return 0;
}
一些关键注释都保存在代码里,这样容易理解。其实写出来并不一定可以运行。这里有以下几点需要注意:
1 我在windows下进行了caffe的配置,vs2015无GPU 版本,新建项目之后需要对项目属性进行以下四个方面的配置。
A。VC++的包含目录,主要是相关的头文件,需要加进来哪些,不说了
B。VC++库目录,一些lib文件加入进来
C。C/C++ (编译器的一些配置)可以在命令行下加入一些linux下手动写入的编译选项。
D。链接器-》常规,一些lib文件比如编译好的caffe-bulid-lib下的lib文件。还有caffe的第三方依赖库文件
E。链接器-》输入,把编译的时候无法解析的外部命令的所在的一些lib文件的名字,放到这里。即寻找这些lib文件。
编译完成之后,并不代表可以运行,还需要很多dll文件,这些大部分在第三方依赖库中。找到他们复制到当前项目exe文件所在目录即可。
相关如下图: