第一部分:Caffe 簡介
caffe是有伯克利視覺和學習中心(BVLC)開發。作者是伯克利博士賈楊清。
caffe是一個深度學習(deep learning)框架。其具有易讀、快速和模塊化思想。
第二部分:Caffe安裝與配置
2.1 配置環境:ubuntu 14.04LTS, 使用Homebrew進行安裝。暫不使用GPU,所以使用CPU-ONLY模式。不使用Python,所以沒有下關於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包管理式的操作系統,主要用於自動從互聯網的軟件倉庫中搜索、安裝、升級、卸載軟件或操作系統。
2.3 所需要的庫簡介:
2.3.1 snappy
Snappy 是一個 C++ 的用來壓縮和解壓縮的開發包。其目標不是最大限度壓縮或者兼容其他壓縮格式,而是旨在提供高速壓縮速度和合理的壓縮率。Snappy 比 zlib 更快,但文件相對要大 20% 到 100%。在 64位模式的 Core i7 處理器上,可達每秒 250~500兆的壓縮速度。
2.3.2 leveldb
Leveldb是一個google實現的非常高效的kv數據庫,目前的版本1.2能夠支持billion級別的數據量了。 在這個數量級別下還有着非常高的性能,主要歸功於它的良好的設計。特別是LSM算法.
2.3.3 gflags
gflags是google的一個開源的處理命令行參數的庫,使用c++開發,具備python接口,可以替代getopt。
gflags使用起來比getopt方便,但是不支持參數的簡寫。
2.3.4 glog
Google Glog 是一個C++語言的應用級日志記錄框架,提供了 C++ 風格的流操作和各種助手宏。
2.3.5 szip
szip是一個快速,優良,跨平台的開源數據壓縮程序。
2.3.6 lmdb
lmdb是openLDAP項目開發的嵌入式(作為一個庫嵌入到宿主程序)存儲引擎。
2.3.7 hdf5
Hierarchical Data Format(HDF),可以存儲不同類型的圖像和數碼數據的文件格式,並且可以在不同類型的機器上傳輸,同時還有統一處理這種文件格式的函數庫。大多數普通計算機都支持這種文件格式。
2.3.8 opencv
OpenCV的全稱是:Open Source Computer Vision Library。OpenCV是一個基於BSD許可(開源)發行的跨平台計算機視覺庫,可以運行在Linux、Windows、Android和Mac OS操作系統上。它輕量級而且高效——由一系列 C 函數和少量 C++ 類構成,同時提供了Python、Ruby、MATLAB等語言的接口,實現了圖像處理和計算機視覺方面的很多通用算法。
OpenCV用C++語言編寫,它的主要接口也是C++語言,但是依然保留了大量的C語言接口。該庫也有大量的Python, Java and MATLAB/OCTAVE (版本2.5)的接口。這些語言的API接口函數可以通過在線文檔獲得。如今也提供對於C#,Ch, Ruby的支持。
2.3.9 protobuf
protocolbuffer是google 的一種數據交換的格式,它獨立於語言,獨立於平台。google 提供了多種語言的實現:java、c#、c++、go 和 python,每一種實現都包含了相應語言的編譯器以及庫文件。由於它是一種二進制的格式,比使用 xml 進行數據交換快許多。可以把它用於分布式應用之間的數據通信或者異構環境下的數據交換。作為一種效率和兼容性都很優秀的二進制數據傳輸格式,可以用於諸如網絡傳輸、配置文件、數據存儲等諸多領域。
2.3.10 Boost
Boost庫是為C++語言標准庫提供擴展的一些C++程序庫的總稱。
第三部分 Caffe編譯
3 使用Make編譯Caffe
在caffe$的路徑下:
#caffe文件夾中默認含有一個示例Makefile,只要去復制修改這個文件就可以了
cp Makefile.config.example Makefile.config
然后打開Makefile.config進行修改,筆者這里沒有GPU,所以使用CPU-ONLY模式。所以反注釋掉了 CPU_ONLY := 1
make all
make test
make runtest
經過以上之后Caffe就算是編譯成功了!
第四部分 利用Caffe在MNIST數據集上進行LeNet訓練
4.1 MNIST簡介
MNISTs是一個手寫數字電子版的數據集,其包含60000張的訓練集,10000張的測試集,均為32*32格式。
4.2 LeNet簡介
LeNet是一個用來進行手寫數字分類的網絡,作者是Yann LeCun。具體可以查詢:
http://yann.lecun.com/exdb/publis/pdf/lecun-01a.pdf
在這里使用時把原方法中的sigmoid激活函數改成了ReLU激活函數。
4.3 數據集准備
下載所需要的數據並且轉換為所需的數據格式
cd $CAFFE_ROOT
./data/mnist/get_mnist.sh
./examples/mnist/creat_mnist.sh
4.4 MNIST網絡的定義
網絡定義在了lenet_train_test.prototxt中。Caffe中的模型都是以Google Protobuf方式定義的。
4.4.1 定義名字
name: "LeNet"
4.4.2 定義數據層
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通過協調Caffe中的Net的前向推斷計算和反向梯度計算,來對參數進行更新,從而達到減小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 訓練與測試模型
運行腳本,這個腳本已經寫了所有的訓練和測試
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.
這是解釋了網絡中的每一層都是如何工作的。
最終得到了如下信息:
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.
網絡迭代了10000次,最終accurary是0.9897,loss是0.0324599