第一部分:Caffe 簡介
caffe是有伯克利視覺和學(xué)習(xí)中心(BVLC)開發(fā)雳攘。作者是伯克利博士賈楊清。
caffe是一個深度學(xué)習(xí)(deep learning)框架绍哎。其具有易讀来农、快速和模塊化思想。
第二部分:Caffe安裝與配置
2.1 配置環(huán)境:ubuntu 14.04LTS崇堰, 使用Homebrew進(jìn)行安裝沃于。暫不使用GPU,所以使用CPU-ONLY模式海诲。不使用Python繁莹,所以沒有下關(guān)于Python的任何支持庫。
2.2 支持庫
2.2.1 利用Homebrew 安裝所需要的庫特幔,其中包括:boost snappy leveldb protobuf gflags glog szip lmdb homebrew/science/opencv
sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial-dev protobuf-compiler
sudo apt-get install --no-install-recommends libboost-all-dev
sudo apt-get install libatlas-base-dev
sudo apt-get install libgflags-dev libgoogle-glog-dev liblmdb-dev
2.2.2:apt-get 簡介:
apt-get是一條linux命令咨演,適用于deb包管理式的操作系統(tǒng),主要用于自動從互聯(lián)網(wǎng)的軟件倉庫中搜索蚯斯、安裝薄风、升級饵较、卸載軟件或操作系統(tǒng)。
2.3 所需要的庫簡介:
2.3.1 snappy
Snappy 是一個 C++ 的用來壓縮和解壓縮的開發(fā)包遭赂。其目標(biāo)不是最大限度壓縮或者兼容其他壓縮格式循诉,而是旨在提供高速壓縮速度和合理的壓縮率。Snappy 比 zlib 更快撇他,但文件相對要大 20% 到 100%茄猫。在 64位模式的 Core i7 處理器上,可達(dá)每秒 250~500兆的壓縮速度困肩。
2.3.2 leveldb
Leveldb是一個google實(shí)現(xiàn)的非常高效的kv數(shù)據(jù)庫划纽,目前的版本1.2能夠支持billion級別的數(shù)據(jù)量了。 在這個數(shù)量級別下還有著非常高的性能锌畸,主要?dú)w功于它的良好的設(shè)計勇劣。特別是LSM算法.
2.3.3 gflags
gflags是google的一個開源的處理命令行參數(shù)的庫,使用c++開發(fā)蹋绽,具備python接口芭毙,可以替代getopt。
gflags使用起來比getopt方便卸耘,但是不支持參數(shù)的簡寫退敦。
2.3.4 glog
Google Glog 是一個C++語言的應(yīng)用級日志記錄框架,提供了 C++ 風(fēng)格的流操作和各種助手宏蚣抗。
2.3.5 szip
szip是一個快速侈百,優(yōu)良,跨平臺的開源數(shù)據(jù)壓縮程序翰铡。
2.3.6 lmdb
lmdb是openLDAP項(xiàng)目開發(fā)的嵌入式(作為一個庫嵌入到宿主程序)存儲引擎钝域。
2.3.7 hdf5
Hierarchical Data Format(HDF),可以存儲不同類型的圖像和數(shù)碼數(shù)據(jù)的文件格式锭魔,并且可以在不同類型的機(jī)器上傳輸例证,同時還有統(tǒng)一處理這種文件格式的函數(shù)庫。大多數(shù)普通計算機(jī)都支持這種文件格式迷捧。
2.3.8 opencv
OpenCV的全稱是:Open Source Computer Vision Library织咧。OpenCV是一個基于BSD許可(開源)發(fā)行的跨平臺計算機(jī)視覺庫,可以運(yùn)行在Linux漠秋、Windows笙蒙、Android和Mac OS操作系統(tǒng)上。它輕量級而且高效——由一系列 C 函數(shù)和少量 C++ 類構(gòu)成庆锦,同時提供了Python捅位、Ruby、MATLAB等語言的接口,實(shí)現(xiàn)了圖像處理和計算機(jī)視覺方面的很多通用算法艇搀。
OpenCV用C++語言編寫尿扯,它的主要接口也是C++語言,但是依然保留了大量的C語言接口焰雕。該庫也有大量的Python, Java and MATLAB/OCTAVE (版本2.5)的接口姜胖。這些語言的API接口函數(shù)可以通過在線文檔獲得。如今也提供對于C#,Ch, Ruby的支持淀散。
2.3.9 protobuf
protocolbuffer是google 的一種數(shù)據(jù)交換的格式,它獨(dú)立于語言蚜锨,獨(dú)立于平臺档插。google 提供了多種語言的實(shí)現(xiàn):java、c#亚再、c++郭膛、go 和 python,每一種實(shí)現(xiàn)都包含了相應(yīng)語言的編譯器以及庫文件氛悬。由于它是一種二進(jìn)制的格式则剃,比使用 xml 進(jìn)行數(shù)據(jù)交換快許多∪缤保可以把它用于分布式應(yīng)用之間的數(shù)據(jù)通信或者異構(gòu)環(huán)境下的數(shù)據(jù)交換棍现。作為一種效率和兼容性都很優(yōu)秀的二進(jìn)制數(shù)據(jù)傳輸格式,可以用于諸如網(wǎng)絡(luò)傳輸镜遣、配置文件己肮、數(shù)據(jù)存儲等諸多領(lǐng)域。
2.3.10 Boost
Boost庫是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱悲关。
第三部分 Caffe編譯
3 使用Make編譯Caffe
在caffe$的路徑下:
#caffe文件夾中默認(rèn)含有一個示例Makefile谎僻,只要去復(fù)制修改這個文件就可以了
cp Makefile.config.example Makefile.config
然后打開Makefile.config進(jìn)行修改,筆者這里沒有GPU寓辱,所以使用CPU-ONLY模式艘绍。所以反注釋掉了 CPU_ONLY := 1
make all
make test
make runtest
經(jīng)過以上之后Caffe就算是編譯成功了!
第四部分 利用Caffe在MNIST數(shù)據(jù)集上進(jìn)行LeNet訓(xùn)練
4.1 MNIST簡介
MNISTs是一個手寫數(shù)字電子版的數(shù)據(jù)集秫筏,其包含60000張的訓(xùn)練集诱鞠,10000張的測試集,均為32*32格式跳昼。
4.2 LeNet簡介
LeNet是一個用來進(jìn)行手寫數(shù)字分類的網(wǎng)絡(luò)般甲,作者是Yann LeCun。具體可以查詢:
http://yann.lecun.com/exdb/publis/pdf/lecun-01a.pdf
在這里使用時把原方法中的sigmoid激活函數(shù)改成了ReLU激活函數(shù)鹅颊。
4.3 數(shù)據(jù)集準(zhǔn)備
下載所需要的數(shù)據(jù)并且轉(zhuǎn)換為所需的數(shù)據(jù)格式
cd $CAFFE_ROOT
./data/mnist/get_mnist.sh
./examples/mnist/creat_mnist.sh
4.4 MNIST網(wǎng)絡(luò)的定義
網(wǎng)絡(luò)定義在了lenet_train_test.prototxt中敷存。Caffe中的模型都是以Google Protobuf方式定義的。
4.4.1 定義名字
name: "LeNet"
4.4.2 定義數(shù)據(jù)層
layer {
?name: "mnist"
?type: "Data"
?transform_param {
? ?scale: 0.00390625
?}
?data_param {
? ?source: "mnist_train_lmdb"
? ?backend: LMDB
? ?batch_size: 64
?}
?top: "data"
?top: "label"
}
4.4.2 定義卷積層
layer {
?name: "conv1"
?type: "Convolution"
?param { lr_mult: 1 }
?param { lr_mult: 2 }
?convolution_param {
? ?num_output: 20
? ?kernel_size: 5
? ?stride: 1
? ?weight_filler {
? ? ?type: "xavier"
? ?}
? ?bias_filler {
? ? ?type: "constant"
? ?}
?}
?bottom: "data"
?top: "conv1"
}
4.4.3 定義池化層
layer {
?name: "pool1"
?type: "Pooling"
?pooling_param {
? ?kernel_size: 2
? ?stride: 2
? ?pool: MAX
?}
?bottom: "conv1"
?top: "pool1"
}
4.4.4 定義全連接層
layer {
?name: "ip1"
?type: "InnerProduct"
?param { lr_mult: 1 }
?param { lr_mult: 2 }
?inner_product_param {
? ?num_output: 500
? ?weight_filler {
? ? ?type: "xavier"
? ?}
? ?bias_filler {
? ? ?type: "constant"
? ?}
?}
?bottom: "pool2"
?top: "ip1"
}
4.4.5 定義ReLU層
layer {
?name: "ip2"
?type: "InnerProduct"
?param { lr_mult: 1 }
?param { lr_mult: 2 }
?inner_product_param {
? ?num_output: 10
? ?weight_filler {
? ? ?type: "xavier"
? ?}
? ?bias_filler {
? ? ?type: "constant"
? ?}
?}
?bottom: "ip1"
?top: "ip2"
}
4.4.6 定義損失層
layer {
?name: "loss"
?type: "SoftmaxWithLoss"
?bottom: "ip2"
?bottom: "label"
}
4.5 定義Solver
4.5.1 Solver簡介
Solver通過協(xié)調(diào)Caffe中的Net的前向推斷計算和反向梯度計算,來對參數(shù)進(jìn)行更新锚烦,從而達(dá)到減小loss的目的
4.5.2 定義MNIST Solver
定義在$CAFFE_ROOT/examples/mnist/lenet_solver.prototxt:
# The train/test net protocol buffer definition
net: "examples/mnist/lenet_train_test.prototxt"
# test_iter specifies how many forward passes the test should carry out.
# In the case of MNIST, we have test batch size 100 and 100 test iterations,
# covering the full 10,000 testing images.
test_iter: 100
# Carry out testing every 500 training iterations.
test_interval: 500
# The base learning rate, momentum and the weight decay of the network.
base_lr: 0.01
momentum: 0.9
weight_decay: 0.0005
# The learning rate policy
lr_policy: "inv"
gamma: 0.0001
power: 0.75
# Display every 100 iterations
display: 100
# The maximum number of iterations
max_iter: 10000
# snapshot intermediate results
snapshot: 5000
snapshot_prefix: "examples/mnist/lenet"
# solver mode: CPU or GPU
solver_mode: GPU
4.6 訓(xùn)練與測試模型
運(yùn)行腳本,這個腳本已經(jīng)寫了所有的訓(xùn)練和測試
cd $CAFFE_ROOT
./examples/mnist/train_lenet.sh
屏幕上閃過類似于如下的信息:
I1203 net.cpp:66] Creating Layer conv1
I1203 net.cpp:76] conv1 <- data
I1203 net.cpp:101] conv1 -> conv1
I1203 net.cpp:116] Top shape: 20 24 24
I1203 net.cpp:127] conv1 needs backward computation.
這是解釋了網(wǎng)絡(luò)中的每一層都是如何工作的觅闽。
最終得到了如下信息:
I1203 solver.cpp:84] Testing net
I1203 solver.cpp:111] Test score #0: 0.9897
I1203 solver.cpp:111] Test score #1: 0.0324599
I1203 solver.cpp:126] Snapshotting to lenet_iter_10000
I1203 solver.cpp:133] Snapshotting solver state to lenet_iter_10000.solverstate
I1203 solver.cpp:78] Optimization Done.
網(wǎng)絡(luò)迭代了10000次,最終accurary是0.9897,loss是0.0324599