LevelDB库
它是google实现的一个非常高效的Key-Value数据库。它是单进程的服务,性能非常高。它只是一个C/C++编程语言的库,不包含网络服务封装。caffe主要使用该数据库来存储传入训练的图片数据与label。
LMDB库
它是个和levelDB类似的key/value存储库,是由OpenLDAP项目的Symas开发的。使用内存映射文件,因此读取的性能跟内存数据库一样,其大小受限于虚拟地址空间的大小。caffe主要使用该数据库来存储传入训练的图片数据与label。
ProtoBuf库
GoogleProtocol Buffer(简称ProtoBuf),它是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或RPC数据交换格式。可用于通信协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。要使用ProtoBuf库,首先需要自己编写一个.proto文件,定义我们程序中需要处理的结构化数据,例如在caffe中文件”/src/caffe/proto/caffe.proto”中就定义了传入程序的一些网络参数,这些参数定义在“solver.prototxt”文件中。
具体用法可见:::http://www.jb51.cc/article/p-gzhwswrv-ben.html
HDF(Hierarchical Data Format)
HDF是一种为存储和处理大容量科学数据而设计的文件格式及相应的库文件。它可以存储不同类型的图像和数码数据的文件格式,并且可以在不同类型的机器上传输,同时还有统一处理这种文件格式的函数库。当前最流行的版本是HDF5,HDF5是分层式数据管理结构。HDF5只有两种基本结构,组(group)和数据集(dataset)。组,包含0个或多个HDF5对象以及支持元数据(Metadata)的一个群组结构。数据集,数据元素的一个多维数组以及支持元数据。
GFlags库
它是google的一个开源的处理命令行参数的库,使用C++开发,可以替代getopt函数。GFlags与getopt函数不同,在GFlags中,标记的定义分散在源代码中,不需要列举在一个地方。
GLog库
它是一个应用程序的日志库,提供基于C++风格的流的日志API,以及各种辅助的宏。它的使用方式与C++的stream操作类似。
CUDA
NVIDIA公司推出的基于NVIDIA显卡的GPU计算接口,使GPU能够解决复杂的计算问题。
Blas库
基础线性代数子程序库,里面拥有大量已经编写好的关于线性代数运算的程序。caffe中在/src/caffe/util/Math_functions.cpp文件中多次调用库中函数实现矩阵运算。
BOOST库
它是一个可移植、跨平台,提供源代码的C++库,作为标准库的后备。Caffe中主要用到了boost库的以下几个类。
boost::thread
它是在 boost/thread.hpp 里定义的,用来创建一个新线程的类。
他创建新线程的方式可以用下述代码来解释::::
#include@H_404_45@ <@H_404_45@boost/thread@H_404_45@.@H_404_45@hpp>@H_404_45@
#include@H_404_45@ <@H_404_45@iostream>@H_404_45@
void@H_404_45@ wait(int seconds)
{
boost::this_thread@H_404_45@::sleep@H_404_45@(boost::posix_time@H_404_45@::seconds@H_404_45@(seconds));
}
void@H_404_45@ thread@H_404_45@()
{
for (int i =@H_404_45@ 0@H_404_45@; i <@H_404_45@ 5@H_404_45@; ++@H_404_45@i)
{
wait(1@H_404_45@);
std::cout@H_404_45@ <<@H_404_45@ i <<@H_404_45@ std::endl@H_404_45@;
}
}
int main()
{
boost::thread@H_404_45@ t(thread@H_404_45@);
t.@H_404_45@join@H_404_45@();
}
新建线程里执行的那个函数的名称被传递到 boost::thread 的构造函数。 一旦上述示例中的变量t 被创建,该thread() 函数就在其所在线程中被立即执行。 同时在 main() 里也并发地执行该 thread() 。
为了防止程序终止,就需要对新建线程调用 join() 方法。 join() 方法是一个阻塞调用:它可以暂停当前线程,直到调用 join() 的线程运行结束。 这就使得main() 函数一直会等待到 thread() 运行结束。
boost::mutex
它是boost库中的互斥对象,他用来实现多线程同步。 互斥的基本原则是当一个特定的线程拥有资源的时候防止其他线程夺取其所有权。 一旦释放,其他的线程可以取得所有权。 这将导致线程等待至另一个线程完成处理一些操作,从而相应地释放互斥对象的所有权。具体的实现方式见下述代码:::
#include@H_404_45@ <@H_404_45@boost/thread@H_404_45@.@H_404_45@hpp>@H_404_45@
#include@H_404_45@ <@H_404_45@iostream>@H_404_45@
void@H_404_45@ wait(int seconds)
{
boost::this_thread@H_404_45@::sleep@H_404_45@(boost::posix_time@H_404_45@::seconds@H_404_45@(seconds));
}
boost::mutex@H_404_45@ mutex;
void@H_404_45@ thread@H_404_45@()
{
for (int i =@H_404_45@ 0@H_404_45@; i <@H_404_45@ 5@H_404_45@; ++@H_404_45@i)
{
wait(1@H_404_45@);
mutex.@H_404_45@lock();
std::cout@H_404_45@ <<@H_404_45@ "Thread "@H_404_45@ <<@H_404_45@ boost::this_thread@H_404_45@::get_id@H_404_45@() <<@H_404_45@ ": "@H_404_45@ <<@H_404_45@ i <<@H_404_45@ std::endl@H_404_45@;
mutex.@H_404_45@unlock();
}
}
int main()
{
boost::thread@H_404_45@ t1(thread@H_404_45@);
boost::thread@H_404_45@ t2(thread@H_404_45@);
t1.@H_404_45@join@H_404_45@();
t2.@H_404_45@join@H_404_45@();
}
上面的示例使用一个类型为 boost::mutex 的 mutex 全局互斥对象。thread() 函数获取此对象的所有权才在 for 循环内使用lock() 方法写入到标准输出流的。 一旦信息被写入,使用 unlock() 方法释放所有权。
main() 创建两个线程,同时执行 thread ()函数。 利用 for 循环,每个线程数到5,用一个迭代器写一条消息到标准输出流。 不幸的是,标准输出流是一个全局性的被所有线程共享的对象。 该标准不提供任何保证std::cout 可以安全地从多个线程访问。 因此,访问标准输出流必须同步:在任何时候,只有一个线程可以访问 std::cout。
boost::posix_time
定义了一系列格式化输出当前系统的时间的类。
boost::python
用于实现Python和C++对象的无缝接口和混合编程。这里有实现python与C++对象导入的实例:http://www.cppblog.com/zhaoyg/archive/2011/06/01/147885.html
boost::split
分割字符串,例如caffe中如下代码:::
std@H_404_45@::vector@H_404_45@<std@H_404_45@::string@H_404_45@>@H_404_45@ blob_names;
boost::split(blob_names,extract_feature_blob_names,boost::is_any_of(","@H_404_45@));
将extract_feature_blob_names字符串以逗号“,”来分割,分割得到的每个字符串放到blob_names的字符串容器中。
boost::shared_ptr
可以共享对象所有权的智能指针,使用它可以不需要考虑内存释放的问题。具体使用方法见:http://www.cnblogs.com/TianFang/archive/2008/09/19/1294521.html