實戰篇中,人臉識別模型的搭建看似非常複雜,其實都是由一些常用的神經網絡層搭建而來,只要我們明白了這些網絡層,搭建一個模型就不再困難了
神經網絡搭建的方式有2種:順序模型和函數式API
計算機視覺常用的神經網絡層:全連接層、二維卷積層、池化層、BN層、dropout層、flaten層
下面我們分別介紹他們
全連接層
全連接層的每一個節點都和上一層所有的節點相連,從而把之前提取到的特徵綜合起來。如下圖所示:
- 圖中的圓圈稱爲神經單元
- Layer1:稱爲輸入層
- layer4:稱爲輸出層
- Layer2、layer3:稱爲隱藏層
- 、、:爲輸入特徵
- 、、:爲輸入值X經過激活函數後的值
- W:爲輸入特徵對應的權值,初始化後,通過反向傳播修正它的值
- Z : 爲a與W之間點乘的結果,比如圖中的 = + +
keras調用代碼
Dense(units = 4,activation = 'relu')
- units :是一個正數,表示輸出空間的維度
- activation:激活函數,默認不使用激活函數,即線性激活,輸入與輸出相同
- use_bias:布爾型變量,代表該層是否使用偏置向量
- kernel_initializer:kernel權值矩陣的初始化器
- bias_initializer:偏置向量的初始化器
- kernel_regularizer:運用到kernel的正則化函數
- bias_regularizer:運用到偏置向量的正則化函數
- activity_regularizer:運用到輸出結果的正則化函數
- kernel_constraint:運用到kernel權值矩陣的約束函數
- bias_constraint:運用到偏置向量的約束函數
總結
其實看得出,全連接層的參數非常多,參數量也非常大,從而導致計算量非常大,早期的神經網絡是隻有全連接的,比如我們將一張320*320的圖片傳入全連接,輸入層的神經單元就有102400個,而且將每一個像素當做特徵值輸入,也十分容易出現過擬合現象。
二維卷積
在深度學習之前的人臉識別,大都採用Haar特徵,Haar特徵是通過不同模板來對圖片進行特徵提取,最後篩選出比較具有代表性的特徵再使用強分類器進行分類。這個Haar特徵對特徵的提取方式,讓我感覺像是卷積的雛形。卷積相對模塊來說,它可以根據反向傳播來糾正自己的“模板”中的數值,讓提取特徵更加有效。
工作方式
如下圖:黃色的卷積核(黃色)對圖片(綠色)從左到右,從上到下進行掃描並點乘,提取出右邊(粉紅)的特徵圖(feature map)。
特點
- 卷積層中使用參數共享可以來控制參數的數量,因此用卷積來替代前期的全連接,參數量更少
- 相對於全連接,可以減少過擬合現象
- 二維卷積掃描方式有“valid”和“same”2種,“same”掃描前會填充數據,以至於掃描後的特徵圖長寬相對於原圖不會減少
- 卷積尺寸一般都不大,常用的有1x1、3x3、7x7、9x9,其中3X3最常用
- 常用的集合函數是:ReLU
keras代碼
kears.layers.Conv2D(filters,kernel_size,strides=(1,1),padding='valid',data_format = None,dilation_rate=(1,1),activation = None,use_bias = true,kernel_initializer = 'glorot_uniform',bias_initializer='zeros',kernel_regularizer=None,bias_regularizer=None,activity_regularizer = None,kernel_constraint=None,bias_constraint=None)
- filters :卷積核的個數,即卷積操作後輸出空間的維度
- kernel_size:可以是整數也可以是一個元祖,表示卷積窗口的寬度和高度
- strides:可以是一個整數也可以是一個元祖,表面卷積沿寬度和高度方向的步長,即卷積操作每一步移動的步長
- padding:只能爲“valid”或者“same”,設置圖像在卷積過程中邊界像素如何填充。
- data_format:可以設置爲“channels_last”(默認)或“channels_first”二者之一,表示輸入中維度的順序。
- dilation_rate:可以是一個整數,也可以是一個元祖,指定膨脹卷積的膨脹率。
- activation:卷積層要使用的激活函數。默認不激活,輸入輸出相同,即f(x) = x
- use_bias:布爾型變量,代表該層是否使用偏置向量
- kernel_initializer:偏置向量的初始化器
- bias_initializer:偏置向量的初始化器
- kernel_regularizer:運用到kernel的正則化函數
- bias_regularizer:運用到偏置向量的正則化函數
- activity_regularizer:運用到輸出層(他的激活值)的正則化函數
- kernel_constraint:運用到kernel權值矩陣的約束函數
- bias_constraint:運用到偏置向量的約束函數
池化層
池化層也稱爲抽樣層,他的掃描方式和卷積相似,計算的方式不再是掃描框與被掃描的區域點乘,池化運算方法有以下3種:
- 均值池化:提取被掃描區域中有所值的均值
- 隨機池化:提取被掃描區域中的任意一個值
- 最大池化:提取被掃描區域中值最大的一個(最常用的)。
優點
- 可以壓縮數據,改善結果,是神經網絡不容易發生過擬合 。
- 和卷積層一起使用,有效的減少數據量,起到了降採樣的作用,相當於對卷積後進一步的特徵提取與壓縮。
keras代碼(MaxPooling2D)
MaxPooling2D(pool_size=(2,2),strides=None,padding='valid',data_format = None)
- pool_size:池化的窗口,可以是整數或者元祖,整數的話,表示長寬一樣
- strides:可以是整數、元祖或者None,默認值None代表與pool_size相同
- padding:取值爲爲“valid”或者“same”
- data_format:可以設置爲“channels_last”(默認)或“channels_first”二者之一,表示輸入中維度的順序。“channels_first”表示顏色通道在最前面,(3,64,64)。“channels_last”則相反
另外:平均池化:AveragePooling2D
全局池化
全局池化與普通池化的區別在於,全局池化不需要池化窗口在輸入數據上進行滑動採樣,也就是說池化過程的輸入是前一個卷積層輸出得到的特徵圖,
- 包含全局平均池化、全局最大池化。
- 全局平均池化替代全連接層,減少卷積神經網絡中的參數(GoogleNet 結合了全局平均池化層,所以全連接層總參數還不到700萬)
- 替代全連接層,同時不需要dropout層
- 全局平均池化層更有意義且容易解釋其內在原理
缺點
- 全局平均池化網絡收斂速度會相對較慢
代碼
keras.layers.GlobalAveragePooling2D(data_fromat=None)/GlobalMaxPooling2D(data_format=None)
- 對輸入特徵的一種線性計算過程
BN層
Batch Normalization層,稱爲批量標準化層。這是一種優化深度學習神經網絡的方式,我們常將它夾雜在各層之間,對數據進行歸一化處理,比如:min-max標準化、Z-score等。
- 對數據標準化可以提高網絡的訓練速度。
- 可以解決Internal Covariate Shift現象
- 讓數據滿足IID獨立同分布
- 對訓練中的每一批次的數據進行處理,使其平均值接近0,標準差接近1.
Internal Covariate Shift
google稱爲ICS現象
深度神經網絡涉及到很多層的疊加,而每一層的參數更新會導致上層的輸入數據分佈發生變化,通過層層疊加,高層的輸入分佈變化會非常劇烈,這就使得高層需要不斷去重新適應底層的參數更新。爲了訓好模型,我們需要非常謹慎地去設定學習率、初始化權重、以及儘可能細緻的參數更新策略。
IID獨立同分布
IID獨立同分布假設就是假設訓練數據與測試數據是滿足相同分佈的,那麼通過訓練數據獲得的模型能夠在測試集上獲得較好的效果
keras代碼
keras.layers.BatchNormalization(axis=-1,momentum=0.99,epsilon=0.11,center=True,scale=True,beta_initializer='zeros',gamma_initializer='ones',moving_mean_initializer='zeros',moving_variance_initializer='ones',beta_regularizer=None,gamma_regularizer=None,beta_constraint=None,gamma_constraint=None)
- axis:需要標準化的軸,一般是特徵軸。例如在data_format='channels_first’的Conv2D層的後面。將BN層的axis參數設置爲1
- momentum:超參數,移動均值和移動方差的動量值
- epsilon:正則化的超參數,這是一個很小的浮動數值,用以避免在除法的過程中除數爲零。
- center:如果爲True,把β的偏移量加到標準化的張量上;如果爲False,則忽略。
- scale:縮放,如果爲True,乘以γ;如果爲False,則不使用。當下一層爲線性層時。這個參數可以被禁用,因爲縮放將由下一層完成
- beta_initializer:β權重初始化方法。
- gamma_initializer:γ權重的初始化方法。
- moving_mean_initializer:移動均值的初始化方法。
- moving_variance_initializer:移動方差的初始化方法。
- beta_regularizer:可選的β權重的正則化方法。
- gamma_regularizer:可選的γ正則化方法。
- beta_constraint:可選的β的權重的約束方法
- gamma_constraint:可選的γ權重的約束方法
dropout層
dropout層的作用是爲了解決參數量過大帶來的過擬合現象,所以的它的原理是,對每一個全連接層,按照一定的概率將其中的神經網絡單元暫時從網絡中隨機丟棄。從而簡化了神經網絡結構,如下圖所示:
- 左圖是未droput的神經網絡,右圖是droput的神經網絡
- dropout層是隨機選擇丟棄的,且每次丟棄的都不一樣
- 我們可以設置丟棄的比例
- 丟棄的方式是:將全連接的輸入單元按照比例隨機的設置爲0
keras代碼
keras.layers.Dropout(rate,noise_shape = None,seed = None)
- rete:0-1 的浮點數,指定需要斷開連接的比例
- noise_shape:表示將與輸入數據相乘的二進制dropout掩層的形狀,一般默認即可。
- seed:生成隨機數的隨機數種子數。
flatten層
將輸入數據展平,他不會影響數據的大小,一般我們將它放在卷積層和全連接層中間,起到轉換數據的作用。因爲卷積層輸出的數據是一個多維張量(一般是二維),Flatten層將其轉換爲向量序列的形式,如下如所示:
keras代碼
keras.layers.Flatten(data_format = None)
- data_format:一般默認即可,不需要修改
總結
好了,常用的而神經網絡層就這些了,此時你再去看實戰篇中的模型搭建,就會覺得簡單很多了