騙補者或被取消資質 新能源補貼新政欲出

中國新能源汽車騙補事件結果即將出爐。日前,國務院方已經就新能源汽車推廣應用督查報告作出批示,要求嚴肅懲處市場騙補行為,同時完善相關補貼制度。  
 
部分騙補車企或被取消資質 今年初,部分車企被爆造假資料,騙取中國國家財政補貼,形成了新能源汽車騙補產業鏈,引起外界一片譁然。隨後,工信部、財政部、科技部以及 發改委聯合發佈《關於開展新能源汽車推廣應用核查工作的通知》,通過自查與現場督查的方式,調查全部車輛生產企業以及新能源汽車運營企業(含公交、客運、專用車等)、租賃企業、企事業單位等新能源汽車用戶,全面核查財政資金使用及管理情況、新能源汽車生產與使用情況。   目前,中國界定騙補和違規謀補方式主要有三種,包括車輛未達到推廣標準甚至未生產,違規取得牌照騙取補貼;車輛符合規定,但賣給關聯企業而非終端使用者,未達到補貼條件提前謀取補貼;車輛賣給終端使用者,但在獲取補貼後大量閒置,造成財政資金嚴重浪費。   同時,根據車企的違規情節採取不同的措施,包括取消財政補貼資格,追回補貼資金、罰款、取消汽車生產資質,將問題車型從推薦車型目錄中剔除,等等。  
新一輪補貼政策即將推出 目前,按照中’國的補貼政策,新能源汽車補貼分為國家補貼和地方補貼兩大類,而大部分新能源汽車示範推廣城市的地方補貼標準與國家1:1配比。高額的政策性補貼,不僅成為了新能源生產企業的主要利潤來源,也是新能源汽車推廣的重要動力。   分析人士指出,打擊騙補為未來新能源車發展奠定較好的補貼環境基礎。而出臺更為完善的政策,將是新能源汽車未來可持續性發展的關鍵,才能讓大市場刺激強勢產品和讓優秀企業脫穎而出。   據悉,隨著騙補調查結果的出爐,新一輪的新能源補貼政策也將隨之出爐。  
文章來源:南方日報(中國大陸)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

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

目錄

博客: | |

權重初始化最佳實踐

書接上回,全0、常數、過大、過小的權重初始化都是不好的,那我們需要什麼樣的初始化?

  • 因為對權重\(w\)的大小和正負缺乏先驗,所以應初始化在0附近,但不能為全0或常數,所以要有一定的隨機性,即數學期望\(E(w)=0\)
  • 因為梯度消失和梯度爆炸,權重不易過大或過小,所以要對權重的方差\(Var(w)\)有所控制

  • 深度神經網絡的多層結構中,每個激活層的輸出對後面的層而言都是輸入,所以我們希望不同激活層輸出的方差相同,即\(Var(a^{[l]})=Var(a^{[l-1]})\),這也就意味不同激活層輸入的方差相同,即\(Var(z^{[l]})=Var(z^{[l-1]})\)
  • 如果忽略激活函數,前向傳播和反向傳播可以看成是權重矩陣(轉置)的連續相乘。數值太大,前向時可能陷入飽和區,反向時可能梯度爆炸,數值太小,反向時可能梯度消失。所以初始化時,權重的數值範圍(方差)應考慮到前向和後向兩個過程

權重的隨機初始化過程可以看成是從某個概率分佈隨機採樣的過程,常用的分佈有高斯分佈、均勻分佈等,對權重期望和方差的控制可轉化為概率分佈的參數控制,權重初始化問題也就變成了概率分佈的參數設置問題

在上回中,我們知道反向傳播過程同時受到權重矩陣和激活函數的影響,那麼,在激活函數不同以及每層超參數配置不同(輸入輸出數量)的情況下,權重初始化該做怎樣的適配?這裏,將各家的研究成果匯總如下,

其中,扇入\(fan\_in\)和扇出\(fan\_out\)分別為當前全連接層的輸入和輸出數量,更準確地說,1個輸出神經元與\(fan\_in\)個輸入神經元有連接(the number of connections feeding into the node),1個輸入神經元與\(fan\_out\)個輸出神經元有連接(the number of connections flowing out of the node),如下圖所示(來自),

對於卷積層而言,其權重為\(n\)\(c\times h \times w\)大小的卷積核,則一個輸出神經元與\(c\times h \times w\)個輸入神經元有連接,即\(fan\_in = c\times h \times w\),一個輸入神經元與\(n\times h \times w\)個輸出神經元有連接,即\(fan\_out=n\times h \times w\)

期望與方差的相關性質

接下來,首先回顧一下期望與方差計算的相關性質。

對於隨機變量\(X\),其方差可通過下式計算,
\[ Var(X) = E(X^2) – (E(X))^2 \]
若兩個隨機變量\(X\)\(Y\),它們相互獨立,則其協方差為0,
\[ Cov(X, Y) = 0 \]
進一步可得\(E(XY)=E(X)E(Y)\),推導如下,
\[ \begin{align} Cov(X, Y) &= E((X-E(X))(Y-E(Y))) \\ &= E(XY)-E(X)E(Y) =0 \end{align} \]
兩個獨立隨機變量和的方差,
\[ \begin{aligned} \operatorname{Var}(X+Y) &=E\left((X+Y)^{2}\right)-(E(X+Y))^{2} \\ &=E\left(X^{2}+Y^{2}+2 X Y\right)-(E(X)+E(Y))^{2} \\ &=\left(E\left(X^{2}\right)+E\left(Y^{2}\right)+2 E(X Y)\right)-\left((E(X))^{2}+(E(Y))^{2}+2 E(X) E(Y)\right) \\ &=\left(E\left(X^{2}\right)+E\left(Y^{2}\right)+2 E(X) E(Y)\right)-\left((E(X))^{2}+(E(Y))^{2}+2 E(X) E(Y)\right) \\ &=E\left(X^{2}\right)-(E(X))^{2}+E\left(Y^{2}\right)-(E(Y))^{2} \\ &=\operatorname{Var}(X)+\operatorname{Var}(Y) \end{aligned} \]
兩個獨立隨機變量積的方差,
\[ \begin{aligned} \operatorname{Var}(X Y) &=E\left((X Y)^{2}\right)-(E(X Y))^{2} \\ &=E\left(X^{2}\right) E\left(Y^{2}\right)-(E(X) E(Y))^{2} \\ &=\left(\operatorname{Var}(X)+(E(X))^{2}\right)\left(\operatorname{Var}(Y)+(E(Y))^{2}\right)-(E(X))^{2}(E(Y))^{2} \\ &=\operatorname{Var}(X) \operatorname{Var}(Y)+(E(X))^{2} \operatorname{Var}(Y)+\operatorname{Var}(X)(E(Y))^{2} \end{aligned} \]

全連接層方差分析

對線性組合層+非線性激活層,計算如下所示,其中\(z_i^{[l-1]}\)\(l-1\)層第\(i\)個激活函數的輸入,\(a_i^{[l-1]}\)為其輸出,\(w_{ij}^{[l]}\)為第\(l\)層第\(i\)個輸出神經元與第\(j\)個輸入神經元連接的權重,\(b^{[l]}\)為偏置,計算方式如下
\[ \begin{align}a_i^{[l-1]} &= f(z_i^{[l-1]}) \\z_i^{[l]} &= \sum_{j=1}^{fan\_in} w_{ij}^{[l]} \ a_j^{[l-1]}+b^{[l]} \\a_i^{[l]} &= f(z_i^{[l]})\end{align} \]
在初始化階段,將每個權重以及每個輸入視為隨機變量,可做如下假設和推斷,

  • 網絡輸入的每個元素\(x_1,x_2,\dots\)獨立同分佈
  • 每層的權重隨機初始化,同層的權重\(w_{i1}, w_{i2}, \dots\)獨立同分佈,且期望\(E(w)=0\)
  • 每層的權重\(w\)和輸入\(a\)隨機初始化且相互獨立,所以兩者之積構成的隨機變量\(w_{i1}a_1, w_{i2}a_2, \dots\)亦相互獨立,且同分佈;
  • 根據上面的計算公式,同層的\(z_1, z_2, \dots\)獨立同分佈,同層的\(a_1, a_2, \dots\)也為獨立同分佈

需要注意的是,上面獨立同分佈的假設僅在初始化階段成立,當網絡開始訓練,根據反向傳播公式,權重更新后不再相互獨立。

在初始化階段,輸入\(a\)與輸出\(z\)方差間的關係如下,令\(b=0\)
\[ \begin{align} Var(z) &=Var(\sum_{j=1}^{fan\_in} w_{ij} \ a_j) \\ &= fan\_in \times (Var(wa)) \\ &= fan\_in \times (Var(w) \ Var(a) + E(w)^2 Var(a) + Var(w) E(a)^2) \\ &= fan\_in \times (Var(w) \ Var(a) + Var(w) E(a)^2) \end{align} \]

tanh下的初始化方法

若激活函數為線性恆等映射,即\(f(x)=x\),則\(a = z\),自然\(E(a)=E(z)\)\(Var(a) = Var(z)\)

因為網絡輸入的期望\(E(x)=0\),每層權重的期望\(E(w) = 0\),在前面相互獨立的假設下,根據公式\(E(XY)=E(X)E(Y)\),可知\(E(a)=E(z)=\sum E(wa)=\sum E(w)E(a)=0\)。由此可得,
\[ Var(a^{[l]}) = Var(z^{[l]}) = fan\_in \times Var(w) \times Var(a^{[l-1]}) \]
更進一步地,令\(n^{[l]}\)為第\(l\)層的輸出數量(\(fan\_out\)),則第\(l\)層的輸入數量($fan_in \()即前一層的輸出數量為\)n^{[l-1]}\(。第\)L$層輸出的方差為
\[ \begin{align} Var(a^{L}) = Var(z^{[L]}) &= n^{[L-1]} Var(w^{[L]}) Var(a^{[L-1]}) \\ &=\left[\prod_{l=1}^{L} n^{[l-1]} Var(w^{[l]})\right] {Var}(x) \end{align} \]
反向傳播時,需要將上式中的\(n^{[l-1]}\)替換為\(n^{[l]}\)(即\(fan\_in\)替換為\(fan\_out\)),同時將\(x\)替換為損失函數對網絡輸出的偏導。

所以,經過\(t\)層,前向傳播和反向傳播的方差,將分別放大或縮小
\[ \prod^{t} n^{[l-1]} Var(w^{[l]}) \\ \prod^{t} n^{[l]} Var(w^{[l]}) \]
為了避免梯度消失和梯度爆炸,最好保持這個係數為1。

需要注意的是,上面的結論是在激活函數為恆等映射的條件下得出的,而tanh激活函數在0附近可近似為恆等映射,即$tanh(x) \approx x $。

Lecun 1998

Lecun 1998年的paper ,在輸入Standardization以及採用tanh激活函數的情況下,令\(n^{[l-1]}Var(w^{[l]})=1\),即在初始化階段讓前向傳播過程每層方差保持不變,權重從如下高斯分佈採樣,其中第\(l\)層的\(fan\_in = n^{[l-1]}\)
\[ W \sim N(0, \frac{1}{fan\_in}) \]

Xavier 2010

在paper 中,Xavier和Bengio同時考慮了前向過程和反向過程,使用\(fan\_in\)\(fan\_out\)的平均數對方差進行歸一化,權重從如下高斯分佈中採樣,
\[ W \sim N(0, \frac{2}{fan\_in + fan\_out}) \]
同時文章中還提及了從均勻分佈中初始化的方法,因為均勻分佈的方差與分佈範圍的關係為
\[ Var(U(-n, n)) = \frac{n^2}{3} \]
若令\(Var(U(-n, n)) = \frac{2}{fan\_in + fan\_out}\),則有
\[ n = \frac{\sqrt{6}}{\sqrt{fan\_in + fan\_out}} \]
即權重也可從如下均勻分佈中採樣,
\[ W \sim U(-\frac{\sqrt{6}}{\sqrt{fan\_in + fan\_out}}, \frac{\sqrt{6}}{\sqrt{fan\_in + fan\_out}}) \]
在使用不同激活函數的情況下,是否使用Xavier初始化方法對test error的影響如下所示,圖例中帶\(N\)的表示使用Xavier初始化方法,Softsign一種為類tanh但是改善了飽和區的激活函數,圖中可以明顯看到tanh 和tanh N在test error上的差異。

論文還有更多訓練過程中的權重和梯度對比圖示,這裏不再貼出,具體可以參見論文。

ReLU/PReLU下的初始化方法

搬運一下上面的公式,
\[ Var(z)= fan\_in \times (Var(w) \ Var(a) + Var(w) E(a)^2) \]
因為激活函數tanh在0附近可近似為恆等映射,所以在初始化階段可以認為\(E(a) = 0\),但是對於ReLU激活函數,其輸出均大於等於0,不存在負數,所以\(E(a) = 0\)的假設不再成立。

但是,我們可以進一步推導得到,
\[ \begin{align} Var(z) &= fan\_in \times (Var(w) \ Var(a) + Var(w) E(a)^2) \\ &= fan\_in \times (Var(w) (E(a^2) – E(a)^2)+Var(w)E(a)^2) \\ &= fan\_in \times Var(w) \times E(a^2) \end{align} \]

He 2015 for ReLU

對於某個具體的層\(l\)則有,
\[ Var(z^{[l]}) = fan\_in \times Var(w^{[l]}) \times E((a^{[l-1]})^2) \]
如果假定\(w{[l-1]}\)來自某個關於原點對稱的分佈,因為\(E(w^{[l-1]}) = 0\),且\(b^{[l-1]} = 0\),則可以認為\(z^{[l-1]}\)分佈的期望為0,且關於原點0對稱。

對於一個關於原點0對稱的分佈,經過ReLU后,僅保留大於0的部分,則有
\[ \begin{align}Var(x) &= \int_{-\infty}^{+\infty}(x-0)^2 p(x) dx \\&= 2 \int_{0}^{+\infty}x^2 p(x) dx \\&= 2 E(\max(0, x)^2)\end{align} \]
所以,上式可進一步得出,
\[ \begin {align}Var(z^{[l]}) &= fan\_in \times Var(w^{[l]}) \times E((a^{[l-1]})^2) \\&= \frac{1}{2} \times fan\_in \times Var(w^{[l]}) \times Var(z^{[l-1]}) \end{align} \]
類似地,需要放縮係數為1,即
\[ \frac{1}{2} \times fan\_in \times Var(w^{[l]}) = 1 \\ Var(w) = \frac{2}{fan\_in} \]
即從前向傳播考慮,每層的權重初始化為
\[ W \sim N(0, \frac{2}{fan\_in}) \]
同理,從後向傳播考慮,每層的權重初始化為
\[ W \sim N(0, \frac{2}{fan\_out}) \]
文中提到,單獨使用上面兩个中的哪一個都可以,因為當網絡結構確定之後,兩者對方差的放縮係數之比為常數,即每層扇入扇出之比的連乘,解釋如下,

使用Xavier和He初始化,在激活函數為ReLU的情況下,test error下降對比如下,22層的網絡,He的初始化下降更快,30層的網絡,Xavier不下降,但是He正常下降。

He 2015 for PReLU

對於PReLU激活函數,負向部分為\(f(x) = ax\),如下右所示,

對於PReLU,求取\(E((a^{[l-1]})^2)\)可對正向和負向部分分別積分,不難得出,
\[ \frac{1}{2} (1 + a^2) \times fan\_in \times Var(w^{[l]}) = 1 \\Var(w) = \frac{2}{(1 + a^2) fan\_in} \\W \sim N(0, \frac{2}{(1 + a^2) fan\_in}) \\W \sim N(0, \frac{2}{(1 + a^2) fan\_out}) \]

caffe中的實現

儘管He在paper中說單獨使用\(fan\_in\)\(fan\_out\)哪個都可以,但是,在Caffe的實現中,還是提供了兩者平均值的方式,如下所示,當然默認是使用\(fan\_in\)

小結

至此,對深度神經網絡權重初始化方法的介紹已告一段落。雖然因為BN層的提出,權重初始化可能已不再那麼緊要。但是,對經典權重初始化方法經過一番剖析后,相信對神經網絡運行機制的理解也會更加深刻。

以上。

參考

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

【編程題與分析題】Javascript 之繼承的多種實現方式和優缺點總結

[!NOTE]
能熟練掌握每種繼承方式的手寫實現,並知道該繼承實現方式的優缺點。

原型鏈繼承

    function Parent() {
      this.name = 'zhangsan';
      this.children = ['A', 'B', 'C'];
    }
    Parent.prototype.getName = function() {
      console.log(this.name);
    }
    
    function Child() {
      
    }
    Child.prototype = new Parent();
    var child = new Child();
    console.log(child.getName());

[!NOTE]
主要問題:
1. 引用類型的屬性被所有實例共享(this.children.push(‘name’))
2. 在創建Child的實例的時候,不能向Parent傳參

借用構造函數(經典繼承)

    function Parent(age) {
      this.names = ['zhangsan', 'lisi'];
      this.age = age;
      
      this.getName = function() {
        return this.names;
      }
      
      this.getAge = function() {
        return this.age;
      }
    }
    
    function Child(age) {
      Parent.call(this, age);
    }
    var child = new Child(18);
    child.names.push('haha');
    console.log(child.names);
    
    var child2 = new Child(20);
    child2.names.push('yaya');
    console.log(child2.names);

[!NOTE]
優點:
1. 避免了引用類型的屬性被所有實例共享
2. 可以直接在Child中向Parent傳參
缺點:
方法都在構造函數中定義了,每次創建實例都會創建一遍方法

組合繼承(原型鏈繼承和經典繼承雙劍合璧)

    /**
    * 父類構造函數
    * @param name
    * @constructor
    */
    function Parent(name) {
      this.name = name;
      this.colors = ['red', 'green', 'blue'];
    }
    
    Parent.prototype.getName = function() {
      console.log(this.name);
    }
    
    // child
    function Child(name, age) {
      Parent.call(this, name);
      this.age = age;
    }
    
    Child.prototype = new Parent();
    // 校正child的構造函數
    Child.prototype.constructor = Child;
    
    // 創建實例
    var child1 = new Child('zhangsan', 18);
    child1.colors.push('orange');
    console.log(child1.name, child1.age, child1.colors);    // zhangsan 18 (4) ["red", "green", "blue", "orange"]
    
    var child2 = new Child('lisi', 28);
    console.log(child2.name, child2.age, child2.colors);    // lisi 28 (3) ["red", "green", "blue"]

[!NOTE]
優點: 融合了原型鏈繼承和構造函數的優點,是Javascript中最常用的繼承模式

—— 高級繼承的實現

原型式繼承

    function createObj(o) {
      function F(){};
      // 關鍵:將傳入的對象作為創建對象的原型
      F.prototype = o;
      return new F();
    }
    
    // test
    var person = {
        name: 'zhangsan',
        friends: ['lisi', 'wangwu']
    }
    var person1 = createObj(person);
    var person2 = createObj(person);
    
    person1.name = 'wangdachui';
    console.log(person1.name, person2.name);  // wangdachui, zhangsan
    
    person1.friends.push('songxiaobao');
    console.log(person2.friends);       // lisi wangwu songxiaobao

[!WARNING]
缺點:
對於引用類型的屬性值始終都會共享相應的值,和原型鏈繼承一樣

寄生式繼承

    // 創建一個用於封裝繼承過程的函數,這個函數在內部以某種形式來增強對象
    function createObj(o) {
      var clone = Object.create(o);
      clone.sayName = function() {
        console.log('say HelloWorld');
      }
      return clone;
    }

[!WARNING]
缺點:與借用構造函數模式一樣,每次創建對象都會創建一遍方法

寄生組合式繼承

基礎版本

    function Parent(name) {
      this.name = name;
      this.colors = ['red', 'green', 'blue'];
    }
    
    Parent.prototype.getName = function() {
      console.log(this, name);
    }
    
    function Child(name, age) {
      Parent.call(this, name);
      this.age = age;
    }
    
    // test1:
    // 1. 設置子類實例的時候會調用父類的構造函數
    Child.prototype = new Parent();
    // 2. 創建子類實例的時候也會調用父類的構造函數
    var child1 = new Child('zhangsan', 18);   // Parent.call(this, name);
    
    
    // 思考:如何減少父類構造函數的調用次數呢?
    var F = function(){};
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    
    // 思考:下面的這一句話可以嗎?
    /* 分析:因為此時Child.prototype和Parent.prototype此時指向的是同一個對象,
            因此部分數據相當於此時是共享的(引用)。
            比如此時增加 Child.prototype.testProp = 1; 
            同時會影響 Parent.prototype 的屬性的。
          如果不模擬,直接上 es5 的話應該是下面這樣吧
          Child.prototype = Object.create(Parent.prototype);*/
    Child.prototype = Parent.prototype;
    
    // 上面的三句話可以簡化為下面的一句話
    Child.prototype = Object.create(Parent.prototype);
    
    
    
    // test2:
    var child2 = new Child('lisi', 24);

優化版本

    // 自封裝一個繼承的方法
    function object(o) {
      // 下面的三句話實際上就是類似於:var o = Object.create(o.prototype)
      function F(){};
      F.prototype = o.prototype;
      return new F();
    }
    
    function prototype(child, parent) {
      var prototype = object(parent.prototype);
      // 維護原型對象prototype裏面的constructor屬性
      prototype.constructor = child;
      child.prototype = prototype;
    }
    
    // 調用的時候
    prototype(Child, Parent)

創建對象的方法

  • 字面量創建
  • 構造函數創建
  • Object.create()
var o1 = {name: 'value'};
var o2 = new Object({name: 'value'});

var M = function() {this.name = 'o3'};
var o3 = new M();

var P = {name: 'o4'};
var o4 = Object.create(P)

原型

  • JavaScript 的所有對象中都包含了一個 __proto__ 內部屬性,這個屬性所對應的就是該對象的原型
  • JavaScript 的函數對象,除了原型 __proto__ 之外,還預置了 prototype 屬性
  • 當函數對象作為構造函數創建實例時,該 prototype 屬性值將被作為實例對象的原型 __proto__

原型鏈

任何一個實例對象通過原型鏈可以找到它對應的原型對象,原型對象上面!

的實例和方法都是實例所共享的。

一個對象在查找以一個方法或屬性時,他會先在自己的對象上去找,找不到時,他會沿着原型鏈依次向上查找。

注意: 函數才有prototype,實例對象只有有__proto__, 而函數有的__proto__是因為函數是Function的實例對象

instanceof原理

判斷實例對象的__proto__屬性與構造函數的prototype是不是用一個引用。如果不是,他會沿着對象的__proto__向上查找的,直到頂端Object。

判斷對象是哪個類的直接實例

使用對象.construcor直接可判斷

構造函數,new時發生了什麼?

   var obj  = {}; 
   obj.__proto__ = Base.prototype;
   Base.call(obj);  
  1. 創建一個新的對象 obj;
  2. 將這個空對象的__proto__成員指向了Base函數對象prototype成員對象
  3. Base函數對象的this指針替換成obj, 相當於執行了Base.call(obj);
  4. 如果構造函數显示的返回一個對象,那麼則這個實例為這個返回的對象。 否則返回這個新創建的對象

類的聲明

// 普通寫法
function Animal() {
  this.name = 'name'
}

// ES6
class Animal2 {
  constructor () {
    this.name = 'name';
  }
}

繼承

借用構造函數法

在構造函數中 使用Parent.call(this)的方法繼承父類屬性。

原理: 將子類的this使用父類的構造函數跑一遍

缺點: Parent原型鏈上的屬性和方法並不會被子類繼承

function Parent() {
  this.name = 'parent'
}

function Child() {
  Parent.call(this);
  this.type = 'child'
}

原型鏈實現繼承

原理:把子類的prototype(原型對象)直接設置為父類的實例

缺點:因為子類只進行一次原型更改,所以子類的所有實例保存的是同一個父類的值。
當子類對象上進行值修改時,如果是修改的原始類型的值,那麼會在實例上新建這樣一個值;
但如果是引用類型的話,他就會去修改子類上唯一一個父類實例裏面的這個引用類型,這會影響所有子類實例

function Parent() {
  this.name = 'parent'
  this.arr = [1,2,3]
}

function Child() {
  this.type = 'child'
}

Child.prototype = new Parent();
var c1 = new Child();
var c2 = new Child();
c1.__proto__ === c2.__proto__

組合繼承方式

組合構造函數中使用call繼承和原型鏈繼承。

原理: 子類構造函數中使用Parent.call(this);的方式可以繼承寫在父類構造函數中this上綁定的各屬性和方法;
使用Child.prototype = new Parent()的方式可以繼承掛在在父類原型上的各屬性和方法

缺點: 父類構造函數在子類構造函數中執行了一次,在子類綁定原型時又執行了一次

function Parent() {
  this.name = 'parent'
  this.arr = [1,2,3]
}

function Child() {
  Parent.call(this);
  this.type = 'child'
}

Child.prototype = new Parent();

組合繼承方式 優化1:

因為這時父類構造函數的方法已經被執行過了,只需要關心原型鏈上的屬性和方法了

Child.prototype = Parent.prototype;

缺點:

  • 因為原型上有一個屬性為constructor,此時直接使用父類的prototype的話那麼會導致 實例的constructor為Parent,即不能區分這個實例對象是Child的實例還是父類的實例對象。
  • 子類不可直接在prototype上添加屬性和方法,因為會影響父類的原型

注意:這個時候instanseof是可以判斷出實例為Child的實例的,因為instanceof的原理是沿着對象的__proto__判斷是否有一個原型是等於該構造函數的原型的。這裏把Child的原型直接設置為了父類的原型,那麼: 實例.__proto__ === Child.prototype === Child.prototype

組合繼承方式 優化2 – 添加中間對象【最通用版本】:

function Parent() {
  this.name = 'parent'
  this.arr = [1,2,3]
}

function Child() {
  Parent.call(this);
  this.type = 'child'
}

Child.prototype = Object.create(Parent.prototype); //提供__proto__
Child.prototype.constrctor = Child;

Object.create()方法創建一個新對象,使用現有的對象來提供新創建的對象的__proto__

創建JS對象的多種方式總結

工廠模式

 
    /**
    * 工廠模式創建對象
    * @param name
    * @return {Object}
    */
    function createPerson(name){
        var o = new Object();
        o.name = name;
        o.getName = function() {
          console.log(this.name);
        }
        return o;
    }
    var person = createPerson('zhangsan');
    console.log(person.__proto__ === Object.prototype); // true

缺點:無法識別當前的對象,因為創建的所有對象實例都指向的是同一個原型

構造函數模式

構造函數創建對象基礎版本

    /**
    * 使用構造函數的方式來創建對象
    * @param name
    * @constructor
    */
    function Person(name) {
      this.name = name;
      this.getName = function() {
        console.log(this.name)
      }
    }
    var person = new Person('lisi');
    console.log(person.__proto__ === Person.prototype)

優點:實例剋識別偽一個特定的類型
缺點:每次創建實例對象的時候,每個方法都會被創建一次

構造函數模式優化

    function Person(name) {
      this.name = name;
      this.getName = getName;
    }
    
    function getName() {
      console.log(this.name);
    }
    
    var person = new Person('zhangsan');
    console.log(person.__proto__ === Person.prototype);

優點:解決了每個方法都要被重新創建的問題
缺點:不合乎代碼規範……

原型模式

原型模式基礎版

    function Person(name) {
      
    }
    Person.prototype.name = 'lisi';
    Person.prototype.getName = function() {
      console.log(this.name);
    }
    var person = new Person();
    console.log(Person.prototype.constructor)       // Person

優點:方法不會被重新創建
缺點:1. 所有的屬性和方法所有的實例上面都是共享的;2. 不能初始化參數

原型模式優化版本一

    function Person(name) {
      
    }
    Person.prototype = {
        name: 'lisi',
        getName: function() {
          console.log(this.name);
        }
    }
    var person = new Person();
    console.log(Person.prototype.constructor)       // Object
    console.log(person.constructor == person.__proto__.constructor) // true

優點:封裝性好了一些
缺點:重寫了Person的原型prototype屬性,丟失了原始的prototype上的constructor屬性

原型模式優化版本二

    function Person(name) {
      
    }
    Person.prototype = {
        constructor: Person,
        name: 'lisi',
        getName: function() {
          console.log(this.name)
        }
    }
    var person = new Person();

優點:實例可以通過constructor屬性找到所屬的構造函數
缺點:所有的屬性和方法都共享,而且不能初始化參數

組合模式

    function Person(name) {
      this.name = name;
    }
    Person.prototype = {
        constructor: Person,
        getName: function() {
          console.log(this.name)
        }
    }
    var person = new Person('zhangsan');

優點:基本符合預期,屬性私有,方法共享,是目前使用最廣泛的方式
缺點:方法和屬性沒有寫在一起,封裝性不是太好

動態原型模式

    // 第一種創建思路:
    function Person(name) {
       this.name = name;
       if (typeof this.getName !== 'function') {
           Person.prototype.getName = function() {
             console.log(this.name);
           }
       }
    }
    var person = new Person();

    // 第二種創建的思路:使用對象字面量重寫原型上的方法
    function Person(name) {
      this.name = name;
      if (typeof this.getName !== 'function') {
          Person.prototype = {
              constructor: Person,
              getName: function() {
                console.log(this.name)
              }
          }
          return new Person(name);
      }
    }
    
    var person1 = new Person('zhangsan');
    var person2 = new Person('lisi');
    console.log(person1.getName());
    console.log(person2.getName());
    

寄生構造函數模式

    /**
    * 寄生構造函數模式
    * @param name
    * @return {Object}
    * @constructor
    */
   function Person(name){
        var o = new Object();
        o.name = name;
        o.getName = function() {
          console.log(this.name)
        }
        return o;
   }
   var person = new Person('zhangsan');
   console.log(person instanceof Person);   // false
   console.log(person instanceof Object);   // true
   
   
   // 使用寄生-構造函數-模式來創建一個自定義的數組
   /**
    * 特殊數組的構造器
    * @constructor
    */
   function SpecialArray() {
     var values = new Array();
     /*for (var i = 0, len = arguments.length; i < len; i++) {
         values.push(arguments[i]);
     }*/
     // 開始添加數據(可以直接使用apply的方式來優化代碼)
     values.push.apply(values, arguments);
     
     // 新增的方法
     values.toPipedString = function(){
         return this.join('|');
     }
     
     return values;
   }
   
   // 使用new來創建對象
   var colors1 = new SpecialArray('red1', 'green1', 'blue1');
   // 不使用new來創建對象
   var colors2 = SpecialArray('red2', 'green2', 'blue2');
   
   console.log(colors1, colors1.toPipedString());
   console.log(colors2, colors2.toPipedString());

穩妥構造函數模式

    /**
    * 穩妥的創建對象的方式
    * @param name
    * @return {number}
    * @constructor
    */
    function Person(name){
        var o = new Object();
        o.sayName = function() {
           // 這裡有點類似於在一個函數裏面使用外部的變量
           // 這裏直接輸出的是name
          console.log(name);
        }
        return o;
    }
    var person =  Person('lisi');
    person.sayName();
    person.name = 'zhangsan';
    person.sayName();
    console.log(person instanceof Person);      // false
    console.log(person instanceof Object);      // false

[!NOTE]
與寄生的模式的不同點:1. 新創建的實例方法不引用this 2.不使用new操作符調用構造函數
優點:最適合一些安全的環境中使用
缺點:和工廠模式一樣,是無法識別對象的所屬類型的

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

比亞迪新能源車上海補貼將腰斬 銷量已現大滑坡

兩個月前,比亞迪在上海失去了兩萬元(人民幣,下同)地方補貼,兩個月後,又將失去5000元補貼,仍然在手的只剩5000元, 昨(25)天,比亞迪確認,已經接到上海有關部門的通知,比亞迪新能源汽車在滬補貼將減半,並將成為受補貼「按量退坡」影響的首家新能源汽車企業。  
 
銷量沖4萬,福兮禍兮   在上海收穫了4萬的銷量,對於比亞迪來說,是福,也是禍。   上海市新能源汽車推進辦透露,2014年以來,比亞迪品牌新能源乘用車在上海累計銷量距離4萬輛僅一步之遙。按照相關政策,如累計銷量達到4萬輛以上,上海市地方補貼將降至每輛5000元,較目前減半。部分消費者因擔心比亞迪新能源汽車實際購車價提高而轉向享受更高補貼的其他品牌新能源汽車。  
公司是否貼補看市場反應   從6月份開始,比亞迪為了挽救主力車型「秦」在上海市場的銷量,採取廠家和經銷商聯合補貼1.4萬元,以補齊無法拿到政府1.4萬元額外補貼的差價。不過,比亞迪6月初的補貼政策7月底即將到期,到期後,比亞迪是否會出臺力度更大的補貼,挽回價格上的不利?昨天,比亞迪公關部相關人士透露,目前還在商討,具體的市場政策要看市場反應。  
今年上海銷量已現大滑坡   上海補貼退坡已導致比亞迪在上海市場一蹶不振。今年以來,比亞迪銷量呈現直線下滑,市場份額也被上汽取代。去年上海的插電混動市場上,比亞迪幾乎是一家獨大,在上海的銷量超越大本營深圳。而今年4月以後,隨著上海插電式混動汽車准入技術門檻的提高,比亞迪的表現疲軟。   上海的疲態拖累比亞迪「秦」全國銷量大跌,今年上半年“秦”僅賣出9404輛,不足萬輛的成績相較其去年同期的1.6萬輛,同比大跌42.9%。另一款新能源車型「秦」EV也只賣出1725輛。 

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

高通、Lear簽署電動車無線充電授權協議

手機晶片公司美國高通,與汽車座椅與電子系統供應商Lear簽訂了電動汽車無線充電(wireless electric vehicle charging,WEVC)授權協議。Lear將在高通授權下,將高通的Halo WEVC技術應用於旗下產品,以支援PHEV、EV製造商與無線充電基礎設施公司推動WEVC的商業應用。高通將提供技術與工程支援。

高通與Lear正與多家車廠合作推動WEVC生產計畫。高通副總裁暨無線充電部門總經理Steve Pazol表示,Lear能研發多樣化的WEVC系統,包括多線圈、螺絲館、循環系統等,足以滿足眾多客戶的多種需求。與Lear的合作,也將推動高通Halo技術的商業化,並進一步使WEVC技術走向實用市場。

Lear將無線充電技術視為新的市場契機,並表示無線充電技術將有助客戶擬定策略、搶進現有與未來的新車市場。Lear正在向高通取得全面的技術轉讓組合,希望研發出兼具技術與商業性的WEVC系統,以支援後續各種進階款的WEVC系統設計。

(圖片來源:高通Halo技術專頁截圖)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

全球電動車市場加溫 鋰電池原料價格飆漲

根據 《日本經濟新聞》 的報導,由於全世界快速發展環保電動車產業的緣故,使得電動車中重要的零組件-鋰電池,其主要的元素稀有金屬 「鋰」,1 年來的國際價格急劇上漲,僅短短1 年的時間,「鋰」 的價格就暴漲3 倍。不但,使得全球主要供應商開啟新產線,以滿足市場的需求之外,預估供給不足的情況也將持續到2019 至2020 年後。

報導中指出,稀有金屬 「鋰」 被廣泛用於生産環保車的充電電池。由於全球性的電動環保車增産,因此針對環保車電池的需求急劇增加。隨著國際 「鋰」 價格的高漲,包括以生產電動環保車電池為主的日本市場,其國內交易價格也呈上漲態勢。

報導中分析,從「鋰」的消費量觀察,中國佔全球市場的40% ,為世界最大需求國。這也使得中國國內的 「鋰」 現貨價格成為國際價格指標之一。這一現貨價格在2016 年初小幅下跌之後就一路大漲,到7 月中旬的價格為1 噸人民幣12.9 萬元左右(折合新台幣約61.43 萬元),達到1 年前價格的3 倍。

至於,中國的 「鋰」 需求量的快速增加,則是反映了中國為了改善日益嚴重的空氣污染,正加快普及純電動汽車 (EV) 和插電式混合動力車 (PHV) 的趨勢。除了消費者購買電動環保車可獲得政府補貼之外,政府還積極推廣搭載鋰電池公共汽車,這使得中國車載電池需要的 「鋰」 採購量因此大幅增加。

而除了中國之外,美國電動車廠商特斯拉 (TESLA) 的需求成長,也是 「鋰」 價格高漲的原因之一。日前,TESLA 預定於2017 年供貨的 「Model3」 電動車預售熱絡,造成鋰電池供應不足的情況。目前,為TESLA 供應車載電池的松下 (Panasonic) ,日前決定提前啟動與TESLA 在美國設立的車載電池工廠生産,計劃在2016 年底前啟動量産。

目前,「鋰」 供不應求的狀況,也使得 「鋰」 的主要供應商智利的SQM 、美國FMC 、美國雅保化工 (Albemarle) ,以及一部分中國企業開始計劃今後在北美和澳大利亞等地新設生産線。不過,即使如此,仍有不少業界人士認為,供給不足的狀況也將持續到2019 至2020 年。

根據統計,2015 年全球的「鋰」(以碳酸鋰來換算)總需求為17 萬噸。其中,鋰電池的生產需求6 萬噸。預計到2020 年時,全球總需求將提高至28 萬噸,而針對鋰電池的生產需求,將增加到16.5 萬噸。

根據日本獨立行政法人 「石油天然氣金屬礦物資源機構」(JOGMEC) 統計,在電池成本中,「鋰」 僅佔不到10% 。因此,對最終産品價格的影響有限。在日本國內,目前鋰電池的主要材料廠商尚未能徹底將原料價格的上漲轉嫁到産品價格中。不過,除鋰電池以外的工業用途,「鋰」 目前也正陷入短缺的情況。未來的價格波動,恐將在所難免。

(本文授權轉載自《》──〈〉)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

Gogoro 騎進柏林,與Bosch子公司共推租賃服務

來自台灣的智慧雙輪交通工具品牌Gogoro再下一城,宣布與德國Bosch集團旗下的新創品牌Coup合作,於德國柏林展開Gogoro電動機車Smartscooter™的租賃服務,正式進軍歐洲。

Gogoro 執行長暨共同創辦人陸學森表示:「Gogoro 與德國BOSCH 集團有一個共同的願景:希望透過COUP 雙輪共享服務提供城市一種更進化的移動方式。」

他指出,選擇以柏林作為歐洲首站的原因,不僅是因為柏林是全球最進步、創新的代表性城市之一,也是因為柏林對機車的依賴度高。透過Coup服務平台,柏林消費者只要年滿21歲、或擁有機車駕照,下載APP後就能騎乘Gogoro電動機車。租用Gogoro電動機車的價格是每30分鐘3歐元,全日租賃則為20歐元。Gogoro初步規劃設置200輛智慧雙輪機車於柏林,並將其最高速度設定為時速45公里,以符合市區騎乘的安全性。

銷售破萬,推回娘家活動

除了成功進軍海外市場之外,Gogoro也宣布台灣市場銷售創下佳績。今年七月,Gogoro智慧雙輪機車在台灣共售出1,300輛,累計車主突破10,000人。為感謝破萬車主的支持,Gogoro從8月4日至9月30日止舉辦車主回娘家活動,只要在Gogoro網路或實體商店消費周邊產品,一律享九折優惠。

陸學森感謝車主與經營團隊的支持,表示:「隨著台灣市場成功達到車主破萬的里程碑,我們也順利的走向國際進軍歐洲,這一切都要歸功於所有車主、員工與夥伴的支持,Gogoro 才能有今天的成績。」

在過去一年間,Gogoro所有車主的總騎乘公里數已接近2,000萬公里,省下85萬公升的汽油、減排1,634公噸的二氧化碳排放。目前Gogoro在全台共有225座GoStation電池交換站,分別位於桃園以北與台中、彰化,每天服務超過7,000顆電池進行交換。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

電動車供應鏈需求強,台達電、貿聯-KY忙翻

美國電動車廠商特斯拉(Tesla)、德國BMW接連提高電動車零組件的訂單,使中上游供應鏈廠商忙著接單。台灣台達電、貿聯-KY等特斯拉供貨廠商表示接單狀況良好,而台達電也透露可望與BMW達成供貨合約。

《經濟日報》報導,各國積極發展電動車,帶動了電動車產業鏈的興盛。台達電已通過歐、美、日、中等地的電動車認證標準,目前已有歐美合作廠商,未來在電動車業界的發展可期。由於台達電將於第三季起出貨北美油電混和車所需的零組件,因此台達電第三季的獲利十分看好。

在與特斯拉的合作方面,台達電一直都是Model S、Model X的電力控制系統、電池管理系統的供應商。針對特斯拉所提高的訂單需求,據了解,特斯拉已要求台達電備妥目前三至五倍的產能。另一家台系上游廠商貿聯-KY也接訂單忙翻天。

而在與BMW的合作方面,BMW將在泰國投資20億泰銖興建電動車用電池工廠,最快在2017年中動工。報導指出,台達電已與BMW達成共識,未來將為BMW供應電源控制系統,主要市場為東協。

台達電董事長海英俊曾於法說會上表示,汽車產業對台達電而言十分重要,也看好未來汽車相關應用的發展。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

特斯拉新款電動汽車比Model 3便宜1萬美金

今年4月1日,特斯拉正式發佈旗下第四款純電動汽車——Model 3,此舉引爆了全球的電動汽車愛好者。不過,特斯拉似乎並沒打算將Model 3設定為自己的“國民車”,據悉,其未來的生產規劃中還有一款更“國民化”的車型。  
  有知情人士透露,特斯拉的“國民車”是一款A級車,售價將比Model 3還低1萬美元,僅2.5萬美元,約合人民幣16.65萬元。不過雖然價格有所下降,但因電池技術不斷提高,成本不斷下降,該款車型的續航里程將仍在300km以上。   該人士還介紹,此款“國民車”應該在2018年左右向全球公佈,2020年交付。屆時,特斯拉將在中國完成國產化,所以中國消費者未來購買該款車型可享受與美國相同的售價。   文章來源:EV世紀

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

[ch02-00] 反向傳播與梯度下降的通俗解釋

系列博客,原文在筆者所維護的github上:,
點擊star加星不要吝嗇,星越多筆者越努力。

第2章 神經網絡中的三個基本概念

2.0 通俗地理解三大概念

這三大概念是:反向傳播,梯度下降,損失函數。

神經網絡訓練的最基本的思想就是:先“猜”一個結果,我們叫預測結果a,看看這個預測結果和事先標記好的訓練集中的真實結果y之間的差距,然後調整策略,再試一次,這一次就不是“猜”了,而是有依據地向正確的方向靠近。如此反覆多次,一直到預測結果和真實結果之間相差無幾,亦即|a-y|->0,就結束訓練。

在神經網絡訓練中,我們把“猜”叫做初始化,可以隨機,也可以根據以前的經驗給定初始值。即使是“猜”,也是有技術含量的。

這三個概念是前後緊密相連的,講到一個,肯定會牽涉到另外一個。但由於損失函數篇幅較大,我們將在下一章中再詳細介紹。

下面我們舉幾個例子來直觀的說明下這三個概念。

2.0.1 例一:猜數

甲乙兩個人玩兒猜數的遊戲,数字的範圍是[1,50]:

甲:我猜5

乙:太小了

甲:50

乙:有點兒大

甲:30

乙:小了

……

在這個遊戲里:

  • 目的:猜到乙心中的数字;
  • 初始化:甲猜5;
  • 前向計算:甲每次猜的新数字;
  • 損失函數:乙在根據甲猜的數來和自己心中想的數做比較,得出“大了”或“小了”的結論;
  • 反向傳播:乙告訴甲“小了”、“大了”;
  • 梯度下降:甲根據乙的反饋中的含義自行調整下一輪的猜測值。

這裏的損失函數是什麼呢?就是“太小了”,“有點兒大”,很不精確!這個“所謂的”損失函數給出了兩個信息:

  1. 方向:大了或小了
  2. 程度:“太”,“有點兒”,但是很模糊

2.0.2 例二:黑盒子

假設有一個黑盒子如圖2-1。

圖2-1 黑盒子

我們只能看到輸入和輸出的數值,看不到裏面的樣子,當輸入1時,輸出2.334,然後黑盒子有個信息显示:我需要輸出值是4。然後我們試了試輸入2,結果輸出5.332,一下子比4大了很多。那麼我們第一次的損失值是\(2.334-4=-1.666\),而二次的損失值是\(5.332-4=1.332\)

這裏,我們的損失函數就是一個簡單的減法,用實際值減去目標值,但是它可以告訴你兩個信息:1)方向,是大了還是小了;2)差值,是0.1還是1.1。這樣就給了我們下一次猜的依據。

  • 目的:猜到一個輸入值,使得黑盒子的輸出是4
  • 初始化:輸入1
  • 前向計算:黑盒子內部的數學邏輯
  • 損失函數:在輸出端,用輸出值減4
  • 反向傳播:告訴猜數的人差值,包括正負號和值
  • 梯度下降:在輸入端,根據正負號和值,確定下一次的猜測值,goto前向計算

2.0.3 例三:打靶

小明拿了一支步槍,射擊100米外的靶子。這支步槍沒有準星,或者是準星有問題,或者是小明眼神兒不好看不清靶子,或者是霧很大,或者風很大,或者由於木星的影響而側向引力場異常……反正就是遇到各種干擾因素。

第一次試槍后,拉回靶子一看,彈着點偏左了,於是在第二次試槍時,小明就會有意識地向右側偏幾毫米,再看靶子上的彈着點,如此反覆幾次,小明就會掌握這支步槍的脾氣了。圖2-2显示了小明的5次試槍過程。

圖2-2 打靶的彈着點記錄

在有監督的學習中,需要衡量神經網絡輸出和所預期的輸出之間的差異大小。這種誤差函數需要能夠反映出當前網絡輸出和實際結果之間一種量化之後的不一致程度,也就是說函數值越大,反映出模型預測的結果越不準確。

這個例子中,小明預期的目標是全部命中靶子的中心,最外圈是1分,之後越向靶子中心分數是2,3,4分,正中靶心可以得10分。

  • 每次試槍彈着點和靶心之間的差距就叫做誤差,可以用一個誤差函數來表示,比如差距的絕對值,如圖中的紅色線。
  • 一共試槍5次,就是迭代/訓練了5次的過程 。
  • 每次試槍后,把靶子拉回來看彈着點,然後調整下一次的射擊角度的過程,叫做反向傳播。注意,把靶子拉回來看和跑到靶子前面去看有本質的區別,後者容易有生命危險,因為還有別的射擊者。一個不恰當的比喻是,在數學概念中,人跑到靶子前面去看,叫做正向微分;把靶子拉回來看,叫做反向微分。
  • 每次調整角度的數值和方向,叫做梯度。比如向右側調整1毫米,或者向左下方調整2毫米。如圖中的綠色矢量線。

上圖是每次單發點射,所以每次訓練樣本的個數是1。在實際的神經網絡訓練中,通常需要多個樣本,做批量訓練,以避免單個樣本本身採樣時帶來的誤差。在本例中,多個樣本可以描述為連發射擊,假設一次可以連打3發子彈,每次的離散程度都類似,如圖2-3所示。

圖2-3 連發彈着點記錄

  • 如果每次3發子彈連發,這3發子彈的彈着點和靶心之間的差距之和再除以3,叫做損失,可以用損失函數來表示。

那小明每次射擊結果和目標之間的差距是多少呢?在這個例子裏面,用得分來衡量的話,就是說小明得到的反饋結果從差9分,到差8分,到差2分,到差1分,到差0分,這就是用一種量化的結果來表示小明的射擊結果和目標之間差距的方式。也就是誤差函數的作用。因為是一次只有一個樣本,所以這裏採用的是誤差函數的稱呼。如果一次有多個樣本,就要叫做損失函數了。

其實射擊還不這麼簡單,如果是遠距離狙擊,還要考慮空氣阻力和風速,在神經網絡里,空氣阻力和風速可以對應到隱藏層的概念上。

在這個例子中:

  • 目的:打中靶心;
  • 初始化:隨便打一槍,能上靶就行,但是要記住當時的步槍的姿態;
  • 前向計算:讓子彈飛一會兒,擊中靶子;
  • 損失函數:環數,偏離角度;
  • 反向傳播:把靶子拉回來看;
  • 梯度下降:根據本次的偏差,調整步槍的射擊角度,goto前向計算。

損失函數的描述是這樣的:

  1. 1環,偏左上45度;
  2. 6環,偏左上15度;
  3. 7環,偏左;
  4. 8環,偏左下15度;
  5. 10環。

這裏的損失函數也有兩個信息:

  1. 距離;
  2. 方向。

所以,梯度,是個矢量! 它應該即告訴我們方向,又告訴我們數值。

2.0.4 黑盒子的真正玩兒法

以上三個例子比較簡單,容易理解,我們把黑盒子再請出來:黑盒子這件事真正的意義並不是猜測當輸入是多少時輸出會是4。它的實際意義是:我們要破解這個黑盒子!於是,我們會有如下破解流程:

  1. 記錄下所有輸入值和輸出值,如表2-1。

表2-1 樣本數據表

樣本ID 輸入(特徵值) 輸出(標籤)
1 1 2.21
2 1.1 2.431
3 1.2 2.652
4 2 4.42
  1. 搭建一個神經網絡,給出初始權重值,我們先假設這個黑盒子的邏輯是:\(z=x + x^2\)
  2. 輸入1,根據\(z=x + x^2\)得到輸出為2,而實際的輸出值是2.21,則誤差值為\(2-2.21=-0.21\),小了;
  3. 調整權重值,比如\(z=1.5x+x^2\),再輸入1.1,得到的輸出為2.86,實際輸出為2.431,則誤差值為\(2.86-2.431=0.429\),大了;
  4. 調整權重值,比如\(z=1.2x+x^2\)再輸入1.2……
  5. 調整權重值,再輸入2……
  6. 所有樣本遍歷一遍,計算平均的損失函數值;
  7. 依此類推,重複3,4,5,6過程,直到損失函數值小於一個指標,比如0.001,我們就可以認為網絡訓練完畢,黑盒子“破解”了,實際是被複制了,因為神經網絡並不能得到黑盒子里的真實函數體,而只是近似模擬。

從上面的過程可以看出,如果誤差值是正數,我們就把權重降低一些;如果誤差值為負數,則升高權重。

2.0.5 總結

簡單總結一下反向傳播與梯度下降的基本工作原理:

  1. 初始化;
  2. 正向計算;
  3. 損失函數為我們提供了計算損失的方法;
  4. 梯度下降是在損失函數基礎上向著損失最小的點靠近而指引了網絡權重調整的方向;
  5. 反向傳播把損失值反向傳給神經網絡的每一層,讓每一層都根據損失值反向調整權重;
  6. goto 2,直到精度足夠好(比如損失函數值小於0.001)。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整