前言#
一開始我是拒絕的,因為不知道從何寫起。還是強迫自己去做了這件事,希望自己在寫的過程收穫滿滿。
一、Blob 簡介#
如果把一個網絡結構 Net 比作一座大廈的話,那麼層 Layer 就是每一層樓,而 Blob 就是磚。
Net 中,每一層 Layer 之間數據傳遞就是以 Blob 形式傳遞的,包括正向的原始數據 data 和反向的梯度信息 diff。它是一個四維數組,(Num,Channels,Height,Width),
也可以寫成 (n, k, h, w)。
以一張三通道 480640 的圖片為例子,如果轉為 Blob 格式的數據,那麼這個 Blob 大小為 (13480640)。
如果結合 caffe 來看的話,N 的大小是和每一 Batch 大小相同的。K 是和每一層的 output 輸出大小相同的。H 和 W 就是每一層輸出特徵圖的尺寸。注意哦,有些博客講對於一個比方有 1024 輸出和 77 卷積核的 Convolution 層,如果 batch 為 1,
那麼輸出 Blob 是(1,1024,7,7) 。 這個絕對是錯的啊!!! 輸出的 H 和 W 是上一層的 H 和 W 經過 77 卷積核卷積運算過後的大小。
舉個例子,上一層輸出是(32,512,14,14),也就是說上一層輸出特徵圖大小是 1414。當前層輸出數量 (卷積核數量) 規定是 1024,卷積核 55,步長 1,padding 為 0。那麼輸出結果特徵圖大小應該是 (14-5)/1
-
1 = 10 * (14-5)/1 +1 = 10,所以輸出 Blob 大小為(32,1024,10,10)。
二、Layer 簡介#
Layer 應該是 Caffe 的基本計算單元。Layer 使得 Net 很有層次性,讓我們很直觀的看到計算進行的順序和上下關係。
跟蓋樓一致,數據是自下而上的計算傳輸。bottom 為輸入口,top 為輸出口。
Layer 的一些派生類:
1. Vision Layer:負責處理視覺圖像,輸入輸出都是圖像。
**
**
1.1.Convolution 卷積層 :核心層。
lr_mult:學習率係數,當前層的學習率是根據 solver.prototxt 中 base_lr 學習率與此參數的乘積。如果有兩個這個參數,
那麼第二個對應偏置項的學習率。一般偏置項學習率是權值學習率的兩倍。
num_oupput: 卷積核數量,也就是輸出 N 的數量。
kernel_size: 卷積核大小。如果寬高不等,可以用 kernel_h 和 kernel_w 設置。
stride: 卷積核步長,默認為 1。也可以用 stride_h 和 stride_w 設置。
pad: 邊緣擴張,默認為 0。也可以用 pad_h 和 pad_w 設置。如果設置 pad=(kernel_sizie-1)/2,那麼卷積後的寬高不變。
weight_filler: 權值初始化方式。默認是 "constant",全為 0。現在普遍用 "xavier",也有用 "gaussian" 的。
bias_filler: 偏置項初始化方式。一般設置為 "constant",全為 0。
group: 分組,默認為 1 組。
卷積層輸出特徵圖寬高計算公式:輸出寬高 = (輸入寬高 + 2*pad - kernel_size)/stride + 1
1.2.Pooling 池化層:降採樣層 , 縮小數據大小。
kernel_sizie: 池化核大小
pool: 池化方式,有 MAX, AVE, STOCHASTIC。計算方式是在池化核大小的矩陣內選最大或計算平均數作為當前連接的輸出。
pad: 邊緣擴張。
stride: 步長
1.3.Local Response Normalization (LRN) 局部區域歸一化 : 側抑制,在 AlexNet 和 GoogLeNet 中有用到。
local_size: 默認 5,如果是跨通道歸一化,那麼表示通道數。如果是在一個通道內歸一化,則表示處理區域寬高。
alpha: 默認 1,公式中參數。
beta: 默認 5,公式中參數。
norm_region: 默認為 ACROSS_CHANNELS,表示在相鄰的通道間求和歸一化。WITHIN_CHANNEL 表示在一個通道內求和歸一化。
歸一化公式:分子為每一個數,分母為
1.4.im2col 層: 將一個大矩陣,重疊的劃分為多個子矩陣,對一個子矩陣序列化成向量,然後得到另外一個矩陣。
在 caffe 中,卷積運算就是先對數據進行 im2col 操作,再進行內積運算 (inner product)。這樣做比原始的卷積才做速度更快。
1.5.Batch Normalization (BatchNorm) 層: 歸一化,0 均值,單位方差,應用在 resnet。
早期都使用白化處理數據,常用的是 PCA 白化。就是先對數據進行 PCA 處理,然後在進行方差歸一化。
但是白化需要計算協方差矩陣和求逆等操作,計算量很大,並且在反向傳播的時候不一定可導。
理想情況是對整個數據集進行 Norm 處理,但這不現實。
所以提出了 Batch Norm,用一個 Batch 的均值和方差作為對整個數據集均值和方差的估計。
BN 算法流程如下:
有一個參數:
batch_norm_param {
use_global_stats: false
}
這個參數默認為 false,作用是使用當前 batch 數據的均值和方差做歸一化,
如果設置為 true,則會使用所有數據的均值和方差做歸一化。 ** 這裡留一個疑問,我猜測應該是累積以往所有數據的均值和方差。 **
** ** 在訓練階段,這個參數使用缺省設置,就是 false。否則模型不收斂。 **
**
在檢測階段,這個參數使用 true。否則準確率很低。
2. Loss Layers 損失層:用於計算損失值,根據損失值反向傳播求梯度更新參數。
**** 有 Softmax (SoftmaxWithLoss), Sum-of-Squares/Euclidean (EuclideanLoss),
Hinge/Margin(HingeLoss), Sigmoid Cross-Entropy(SigmoidCrossEntropyLoss),
Infogain(InfogainLoss), Top-k
2.1.SoftmaxWithLoss
Softmax 是一個分類器,輸出概率 (likelihood),是 Logistic Regression 的一種推廣,邏輯回歸只能用於二分類,
Softmax 可以用於多分類。
在 Softmax 輸出概率和已知類別的基礎上做交叉熵計算,可以求得當前類別的 loss。
3. Activation/Neuron Layer 激活層:運算為同址計算 (in-place computation,
返回值覆蓋原值而不佔用新內存)
**
**
3.1.Sigmoid
沒有額外參數。將輸入變量映射到 [0,1] 之間,可以用作分類器。求導容易。但是,初始化結果會對 sigmoid 的輸出產生很大影響。
如果初始化過大或者過小,梯度會接近 0,使參數掛掉。並且 sigmoid 函數的輸出並沒有 0 均值。
公式: y = 1/(1 + e ^ -x)
層類型: Sigmoid
3.2.TanH/Hyperbolic Tangent
雙曲正切函數數據變換,在形狀上與 Sigmoid 十分接近。將輸入變量映射到 [-1,1] 之間,求導容易,輸出期望為 0,
所以在一定程度上 TanH 比 Sigmoid 要好一點。與 Sigmoid 有共同的缺點,就是對初始化敏感,參數過大或者過小都會使梯度接近 0。
公式: y = (e ^ x - e ^ -x) / (e ^ x + e ^ -x)
層類型: ThanH
3.3.ReLU/Rectified-Linear and Leaky-ReLU
ReLU 是現在使用最多的激活函數,收斂快,易求導。標準 ReLU 將負數都變為 0,在會影響數據表現。Leaky-ReLU 設定一個參數,
讓負數輸入乘以這個參數,在一定程度上保護了數據的表現。
標準 ReLU 公式: y = max (0, x)
Leaky-ReLU 公式: y = max (x*negative_slope, x)
層類型: ReLU
3.4.Absolute Value
求每個輸入數據的絕對值。
公式: y = Abs (x)
層類型: AbsVal
3.5.Power
對輸入數據進行幂運算。
power: 默認為 1
scale: 默認為 1
shift: 默認為 0
公式: y = (shift + scale * x) ^ power
層類型
3.6.BNLL
Binomial Normal Log Likelihood
公式: y = log (1 + exp (x))
層類型: BNLL
4. Data Layer 數據層:網絡的最底層,主要實現數據格式的轉換。
**** 高效率: LevelDB, LMDB, 內存。低效率: hdf5, 圖片格式
層類型: Data
include 設置是 TEST 階段還是 TRAIN 階段。
transform_param 負責數據的預處理
根據輸入來源不同,data_param 參數不同。
4.1. transform_param
scale: 0.00390625 = 1/255, 將輸入數據歸一化。
mean_file_size: binaryproto 均值文件路徑
mean_value: 重複三次,分別是三通道的均值。ImageNet 常用均值為 {104, 117, 123}。
crop_size: 圖片縮放尺寸
下面的處理在 TRAIN 階段使用。
mirror: 0 或 1, true 或 false。鏡像處理。
4.2. 數據來自於 LevelDB 或者 LMDB 數據庫
層類型
data_param 參數:
source: 包含數據庫的目錄路徑。
batch_size: 批處理數量
backend: LevelDB 或者 LMDB,默認是前者。
4.3. 數據來自於內存
層類型: MemoryData
memory_data_param 參數:
batch_size: 批數量
channels: 通道數
height: 高度
width: 寬度
4.4. 數據來自於 hdf5
層類型: HDF5Data
hdf5_data_param 參數:
source: 路徑
batch_size: 批數量
4.5. 數據來自於圖片
層類型: ImageData
image_data_param 參數:
source: 一個文本文件的路徑,每一行是一張圖片的路徑和標籤
root_folder: 路徑,和上面 txt 文件中路徑組合為圖片的完整路徑。
batch_size: 批數量
shuffle: 隨機打亂。默認為 false
new_height, new_width: 如果設置,則 resize 圖片
4.6. 數據來自於 Windows
層類型: WindowData
window_data_param 參數:
source: 一個文本文件的路徑
batch_size: 批數量
5. Common Layers
Inner Product(InnerProduct), Accuracy(Accuracy), Splitting(Split),
Flattening(Flatten), Reshape(Reshape), Concatenation(Concat), Slicing(Slice),
Elementwise(Eltwise), Argmax(ArgMax), Mean-Variance Normalization(MVN)
5.1. Inner Product 全連接層
輸出維度為 (n, k, 1, 1)
層類型: InnerProduct
lr_mult: 學習率係數
num_output: 即為 k
weight_filler: 權值初始化方式。默認為 "constant",全為 0,一般設置成 "xavier" 或者 "gaussian"
bias_filler: 偏置項初始化方式,一般設置為 "constant",全為 0。
bias_term: 是否使用偏置項,默認為 true。
5.2. Accuracy
輸出分類結果的精確度,只有在 TEST 階段才有,需要加入 include 參數。
層類型: Accuracy
5.3. Dropout
用於防止過擬合,隨機讓某些層節點權值不失效。
dropout_ratio: 失效節點百分比
5.4. Concatenation
輸入數據的拼接
層類型: Concat
axis: (n, k, h, w) 的索引,表示拼接該通道。
5.5. Slicing
輸入數據的拆分,與 Concatenation 功能相反。
層類型: Slice
axis: 作用參照上面。
slice_point: 此參數個數必須比 top 數量少一個。第一個參數表示第一個拆分出來的數據的數量,以此類推。
最後一個數據的數量等於總數量減去前面所有參數的結果。
以上內容,部分參考自: http://www.cnblogs.com/denny402/category/759199.html