1. 程式人生 > >“Xavier”初始化方法

“Xavier”初始化方法

為了使得網路中資訊更好的流動,每一層輸出的方差應該儘量相等。

基於這個目標,現在我們就去推導一下:每一層的權重應該滿足哪種條件。

文章先假設的是線性啟用函式,而且滿足0點處導數為1,即 
這裡寫圖片描述

現在我們先來分析一層卷積: 
這裡寫圖片描述 
其中ni表示輸入個數。

根據概率統計知識我們有下面的方差公式: 
這裡寫圖片描述

特別的,當我們假設輸入和權重都是0均值時(目前有了BN之後,這一點也較容易滿足),上式可以簡化為: 
這裡寫圖片描述

進一步假設輸入x和權重w獨立同分布,則有: 
這裡寫圖片描述

於是,為了保證輸入與輸出方差一致,則應該有: 
這裡寫圖片描述

對於一個多層的網路,某一層的方差可以用累積的形式表達: 
這裡寫圖片描述

特別的,反向傳播計算梯度時同樣具有類似的形式: 
這裡寫圖片描述

綜上,為了保證前向傳播和反向傳播時每一層的方差一致,應滿足:

這裡寫圖片描述

但是,實際當中輸入與輸出的個數往往不相等,於是為了均衡考量,最終我們的權重方差應滿足

——————————————————————————————————————— 
這裡寫圖片描述 
———————————————————————————————————————

學過概率統計的都知道 [a,b] 間的均勻分佈的方差為: 
這裡寫圖片描述

因此,Xavier初始化的實現就是下面的均勻分佈:

—————————————————————————————————————————— 
這裡寫圖片描述 
———————————————————————————————————————————

下面,我們來看一下caffe中具體是怎樣實現的,程式碼位於include/caffe/filler.hpp檔案中。

<code class="language-C++ hljs haskell has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-title" style="box-sizing: border-box;">template</span> <typename <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Dtype</span>>
<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">XavierFiller</span> : public <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Filler</span><<span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Dtype</span>> {
 public:
  explicit <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">XavierFiller</span><span class="hljs-container" style="box-sizing: border-box;">(<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">const</span> <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">FillerParameter</span>& <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">param</span>)</span>
      : <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Filler</span><<span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Dtype</span>><span class="hljs-container" style="box-sizing: border-box;">(<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">param</span>)</span> {}
  virtual void <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Fill</span><span class="hljs-container" style="box-sizing: border-box;">(<span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Blob</span><<span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Dtype</span>>* <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">blob</span>)</span> {
    <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">CHECK</span><span class="hljs-container" style="box-sizing: border-box;">(<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">blob</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">count</span>()</span>);
    int fan_in = blob->count<span class="hljs-container" style="box-sizing: border-box;">()</span> / blob->num<span class="hljs-container" style="box-sizing: border-box;">()</span>;
    int fan_out = blob->count<span class="hljs-container" style="box-sizing: border-box;">()</span> / blob->channels<span class="hljs-container" style="box-sizing: border-box;">()</span>;
    <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Dtype</span> n = fan_in;  // default to fan_in
    if <span class="hljs-container" style="box-sizing: border-box;">(<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">this</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">filler_param_</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">variance_norm</span>()</span> ==
        <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">FillerParameter_VarianceNorm_AVERAGE</span>) {
      n = <span class="hljs-container" style="box-sizing: border-box;">(<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">fan_in</span> + <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">fan_out</span>)</span> / <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Dtype</span><span class="hljs-container" style="box-sizing: border-box;">(2)</span>;
    } else if <span class="hljs-container" style="box-sizing: border-box;">(<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">this</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">filler_param_</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">variance_norm</span>()</span> ==
        <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">FillerParameter_VarianceNorm_FAN_OUT</span>) {
      n = fan_out;
    }
    <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Dtype</span> scale = sqrt<span class="hljs-container" style="box-sizing: border-box;">(<span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Dtype(3)</span> / <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">n</span>)</span>;
    caffe_rng_uniform<<span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Dtype</span>><span class="hljs-container" style="box-sizing: border-box;">(<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">blob</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">count</span>()</span>, -scale, scale,
        blob->mutable_cpu_data<span class="hljs-container" style="box-sizing: border-box;">()</span>);
    <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">CHECK_EQ</span><span class="hljs-container" style="box-sizing: border-box;">(<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">this</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">filler_param_</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">sparse</span>()</span>, -1)
         << "<span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Sparsity</span> not supported by this <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">Filler</span>.";
  }
};</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul>

由上面可以看出,caffe的Xavier實現有三種選擇

(1) 預設情況,方差只考慮輸入個數: 
這裡寫圖片描述

(2) FillerParameter_VarianceNorm_FAN_OUT,方差只考慮輸出個數: 
這裡寫圖片描述

(3) FillerParameter_VarianceNorm_AVERAGE,方差同時考慮輸入和輸出個數: 
這裡寫圖片描述

之所以預設只考慮輸入,我個人覺得是因為前向資訊的傳播更重要一些

相關推薦

深度學習-網路Xavier初始方法

參考: 深度學習-網路Xavier初始化方法 通過方差分析詳解最流行的Xavier權重初始化方法 在 Xavier Glorot 和 Yoshua Bengio 2010 年的論文 Understanding the difficulty of training deep feedf

Xavier初始方法

轉載出處: https://blog.csdn.net/shuzfan/article/details/51338178 “Xavier”初始化方法是一種很有效的神經網路初始化方法,使用xavier演算法自動確定給予輸入—輸出神經元數量的初始化規模,方法來源於2010年的一篇論文《Und

Xavier初始方法

為了使得網路中資訊更好的流動,每一層輸出的方差應該儘量相等。 基於這個目標,現在我們就去推導一下:每一層的權重應該滿足哪種條件。 文章先假設的是線性啟用函式,而且滿足0點處導數為1,即  現在我們先來分析一層卷積:   其中ni表示輸入個數。 根據概率統計知識我

深度學習——Xavier初始方法

為了使得網路中資訊更好的流動,每一層輸出的方差應該儘量相等。 基於這個目標,現在我們就去推導一下:每一層的權重應該滿足哪種條件。 文章先假設的是線性啟用函式,而且滿足0點處導數為1,即 現在我們先來分析一層卷積: 其中ni表示輸入個

權值初始方法Xavier與MSRA

首先介紹一下Xavier等初始化方法比直接用高斯分佈進行初始化W的優勢所在:  一般的神經網路在前向傳播時神經元輸出值的方差會不斷增大,而使用Xavier等方法理論上可以保證每層神經元輸入輸出方差一致。  這裡先介紹一個方差相乘的公式,以便理解Xavier: Xavie

深度學習中的Xavier初始和He Initialization(MSRA初始)、Tensorflow中如何選擇合適的初始方法?

Xavier初始化: 論文:Understanding the difficulty of training deep feedforward neural networks 論文地址:http://proceedings.mlr.press/v9/glorot10a/glorot10a

卷積神經網路(三):權值初始方法Xavier與MSRA

基礎知識 首先介紹一下Xavier等初始化方法比直接用高斯分佈進行初始化W的優勢所在: 一般的神經網路在前向傳播時神經元輸出值的方差會不斷增大,而使用Xavier等方法理論上可以保證每層神經元輸入輸出方差一致。 這裡先介紹一個方差相乘的公式,以便理解Xav

網路權重初始方法總結(下):Lecun、Xavier與He Kaiming

目錄 權重初始化最佳實踐 期望與方差的相關性質 全連線層方差分析 tanh下的初始化方法 Lecun 1998 Xavier 2010 ReL

c++中成員函數指針數組定義和初始方法

fun all turn bsp ati const 成員函數指針 溢出 cat 實際項目中經常遇到很多類似操作,比如命令碼對應執行函數等,對於此類操作,比較好的方式是使用const數組,將命令碼和操作函數綁定在一起,通過查表方式找到操作函數,並執行操作函數。這樣可以簡化代

委托初始方法實例

選中 this leg clas style erro controls 返回 cti string strBirthError = ""; foreach (DataRow dr in dtInfo.Row

Java String、string[]、List初始方法

arraylist list add java 執行 ring1 初始化塊 str 方法 String初始化:   1.String str = new String("string1");   2.String str = "string1"; String[]初始化:

spring mvc bean的初始方法優先級

優先 eth 初始化 接口 定義 str initial mvc 沒有 開始學spring mvc打卡!!! 經過測試得 實現了InitializingBean, DisposableBean接口的初始化方法和銷毀方法優先級最高,但是缺點是不能夠自定義方法名。 自定義的初始

在Action指定方法執行之前執行指定初始方法

再要初始化的Action中實現Preparable介面    格式 : 實現方法名(perpare)+初始化Action的方法名稱 public String saveOrUpdate() { if (role.getId() != null) { roleSer

【TP5.1】自定義初始方法

author:咔咔 wechat:fangkangfk   初始化方法 平時在做專案的時候會用到的初始化方法initialize()這個方法   我們可以檢視一下原始碼: 通過方法的追蹤,我們在controller這個類找到了這個方法 這也就是

OC學習篇之---類的初始方法和點語法的使用

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

結構體初始方法

三種方式都可以:   1 #include <stdio.h>   2 typedef struct {   3     int a;   4     int b;

容器的初始方法和上下文的獲取

上下 contex text ext ext1 bean resource factor 工程 在java工程中 一,容器的初始化 //1.通過ClassPathXmlApplicationContext來加載類路徑下的xml文件 ApplicationContext c

tf.get_variable 中變數初始函式和Xavier初始

當使用 tf.get_variable(name, shape=None, initializer=None) 來定義變數時,可以利用變數初始化函式來實現對 initializer 的賦值。 在神經網路中,最常權重賦值方式是 正態隨機賦值 和 Xavier賦值。 1. 變數初始

Python中子類呼叫父類的初始方法

轉自:https://blog.csdn.net/feishicheng/article/details/79596000 Python中子類呼叫父類的初始化方法 前言 python中進行面向物件程式設計,當在子類的例項中呼叫父類的屬性時,由於子類的__init__方法重寫了父類的__init_

Linux---python中的封裝(內建方法初始方法),繼承

面向物件中:哪一個物件呼叫的方法,self就是哪一個物件的引用 在類封裝的方法內部,self就表示當前呼叫方法的物件自己 呼叫方法時,程式設計師不需要傳遞self引數(但是定義的時候,第一個引數必須是self) 在方法內部:可以通過self.訪問物件的屬性 在方法內部: