乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      神經網絡-全連接層(1)

       高教幫 2019-03-12

      接下來聊一聊現(xiàn)在大熱的神經網絡。最近這幾年深度學習發(fā)展十分迅速,感覺已經占據了整個機器學習的“半壁江山”。各大會議也是被深度學習占據,引領了一波潮流。深度學習中目前最火熱的兩大類是卷積神經網絡(CNN)和遞歸神經網絡(RNN),就從這兩個模型開始聊起。

      當然,這兩個模型所涉及到概念內容實在太多,要寫的東西也比較多,所以為了能把事情講得更清楚,這里從一些基本概念聊起,大神們不要覺得無聊啊……

      今天扯的是全連接層,也是神經網絡中的重要組成部分。關于神經網絡是怎么發(fā)明出來的這里就不說了。全連接層一般由兩個部分組成,為了后面的公式能夠更加清楚的表述,以下的變量名中上標表示所在的層,下標表示一個向量或矩陣內的行列號:


      • 線性部分:主要做線性轉換,輸入用X表示,輸出用Z表示

      • 非線性部分:那當然是做非線性變換了,輸入用線性部分的輸出Z表示,輸出用X表示。

      線性部分

      線性部分做了什么事情呢?簡單來說就是對輸入數(shù)據做不同角度的分析,得出該角度下對整體輸入數(shù)據的判斷。

      這么說有點抽象,舉一個實際點的例子,就拿CNN的入門case——MNIST舉例。MNIST的例子在此不多說了,它是一個手寫數(shù)字的識別項目,輸入是一張28*28的二值圖,輸出是0-9這是個數(shù)字,這里假設我們采用完全全連接的模型,那么我們的輸入就是28*28=784個像素點。數(shù)據顯示到屏幕上大概是這個樣子:

      對于我們來說,這個像素點都太過于抽象了,我們無法判斷這些像素點的取值和最終識別的關系:

      他們是正相關還是負相關?

      很顯然,像素點之間是存在相關關系的,這個關系具體是什么我們后面再說,但存在關系這件事是板上釘釘?shù)摹K灾唤o每一個像素點一個權重是解決不了問題的,我們需要多組權重。

      我們可以:

      1)在第一組權重中給第一個像素一個正數(shù),第二個也是正數(shù),

      2)在第二組權重中給第一個像素負數(shù),而第二個還是正數(shù)……

      這樣,我們相當于從多個角度對輸入數(shù)據進行分析匯總,得到了多個輸出結果,也就是對數(shù)據的多種評價。

      非線性部分

      非線性部分有一些“套路”函數(shù),這里只說下其中的一個經典函數(shù)——sigmoid。它的函數(shù)形式如下所示:

      這個函數(shù)的輸入正是我們上一步線性部分的輸出z,此時z取值范圍在,經過了這個函數(shù)就變成了。

      那非線性部分為什么要做這個函數(shù)轉換呢?以我的粗淺理解,其中的一個作用就是作數(shù)據的歸一化。不管前面的線性部分做了怎樣的工作,到了非線性這里,所有的數(shù)值將被限制在一個范圍內,這樣后面的網絡層如果要基于前面層的數(shù)據繼續(xù)計算,這個數(shù)值就相對可控了。不然如果每一層的數(shù)值大小都不一樣,有的范圍在(0,1),有的在(0,10000),做優(yōu)化的時候優(yōu)化步長的設定就會有麻煩。

      另外一個作用,就是打破之前的線性映射關系。如果全連接層沒有非線性部分,只有線性部分,我們在模型中疊加多層神經網絡是沒有意義的,我們假設有一個2層全連接神經網絡,其中沒有非線性層,那么對于第一層有:

      這個長得很復雜的函數(shù)的范圍是(-1,1)??梢钥闯?,它的函數(shù)范圍和前面的sigmoid不同,它是有正有負的,而sigmoid是全為正的。

      神經網絡的模樣

      實際上對于只有一層且只有一個輸出的神經網絡,如果它的非線性部分還使用sigmoid函數(shù),那么它的形式和邏輯斯特回歸(logistic regression)是一樣的。所以可以想象神經網絡模型從概念上來看比邏輯斯特回歸要復雜。那么它的復雜的樣子是什么樣呢?下面給出一段全連接層的代碼,開始做實驗:

      class FC:
         def __init__(self, in_num, out_num, lr = 0.01):
             self._in_num = in_num
             self._out_num = out_num
             self.w = np.random.randn(out_num, in_num) * 10
             self.b = np.zeros(out_num)
         def _sigmoid(self, in_data):
             return 1 / (1 + np.exp(-in_data))
         def forward(self, in_data):
             return self._sigmoid(np.dot(self.w, in_data) + self.b)

      從代碼上看東西并不多嘛,注意到我們會對參數(shù)中的w進行隨機初始化,有時我們會讓老天隨機一個神經網絡給我們,我們也可以看看隨機大帝的旨意。

      為了方便可視化,這里只做輸入為2,輸出為1的數(shù)據。好了,先來看1號選手:

      x = np.linspace(-10,10,100)
      y = np.linspace(-10,10,100)
      X, Y = np.meshgrid(x,y)
      X_f = X.flatten()
      Y_f = Y.flatten()
      data = zip(X_f, Y_f)


      fc = FC(2, 1)
      Z1 = np.array([fc.forward(d) for d in data])
      Z1 = Z1.reshape((100,100))
      draw3D(X, Y, Z1)

      定睛一看這其實就是一個標準的Logistic Regression。他的圖像如下所示:

      經過多次隨機測試,基本上它都是這個形狀,只不過隨著權重隨機的數(shù)值變化,這個“臺階”對旋轉到不同的方向,但歸根結底還是一個臺階。

      這也說明1層神經網絡是沒有出路的,它本質上還是個線性分類器的實力,那么小伙伴還給它加一層吧:

      fc = FC(2, 3)
      fc.w = np.array([[0.4, 0.6],[0.3,0.7],[0.2,0.8]])
      fc.b = np.array([0.5,0.5,0.5])

      fc2 = FC(3, 1)
      fc2.w = np.array([0.3, 0.2, 0.1])
      fc2.b = np.array([0.5])

      Z1 = np.array([fc.forward(d) for d in data])
      Z2 = np.array([fc2.forward(d) for d in Z1])
      Z2 = Z2.reshape((100,100))

      draw3D(X, Y, Z2)

      這次我們暫時不用隨機權重,而是自己設置了幾個數(shù)值,可以看出,參數(shù)設置得很用心。兩層全都是正數(shù)……,那么圖像呢?

      看上去比之前的臺階“柔軟”了一些,但歸根結底還是很像一個臺階……好吧,那我們加點負權重,讓我們從兩個方面分析輸入數(shù)據:

      fc = FC(2, 3)
      fc.w = np.array([[-0.4, 1.6],[-0.3,0.7],[0.2,-0.8]])
      fc.b = np.array([-0.5,0.5,0.5])

      fc2 = FC(3, 1)
      fc2.w = np.array([-3, 2, -1])
      fc2.b = np.array([0.5])

      Z1 = np.array([fc.forward(d) for d in data])
      Z2 = np.array([fc2.forward(d) for d in Z1])
      Z2 = Z2.reshape((100,100))

      draw3D(X, Y, Z2)

      趕緊上圖:

      加了負權重后,看上去終于不那么像臺階了,這時候2層神經網絡的非線性能力開始顯現(xiàn)出來了。下面把權重交給隨機大帝:

      fc = FC(2, 100)
      fc2 = FC(100, 1)

      Z1 = np.array([fc.forward(d) for d in data])
      Z2 = np.array([fc2.forward(d) for d in Z1])
      Z2 = Z2.reshape((100,100))
      draw3D(X, Y, Z2,(75,80))

      上圖:

      這時候的非線性已經非常明顯了,我們不妨繼續(xù)加幾層看看DNN的厲害:

      fc = FC(2, 10)
      fc2 = FC(10, 20)
      fc3 = FC(20, 40)
      fc4 = FC(40, 80)
      fc5 = FC(80, 1)

      Z1 = np.array([fc.forward(d) for d in data])
      Z2 = np.array([fc2.forward(d) for d in Z1])
      Z3 = np.array([fc3.forward(d) for d in Z2])
      Z4 = np.array([fc4.forward(d) for d in Z3])
      Z5 = np.array([fc5.forward(d) for d in Z4])
      Z5 = Z5.reshape((100,100))
      draw3D(X, Y, Z5,(75,80))

      這個圖看上去又復雜了許多……

      從上面的實驗中可以看出,層數(shù)越高,非線性的“能力”確實越強,腦洞開得也越大。

      知道了他的厲害,下回我們將詳細聊下它的求解方法——反向傳播(Back Propagation)。

      文章代碼可以在hsmyy/zhihuzhuanlan (http://link.zhihu.com/?target=https%3A//github.com/hsmyy/zhihuzhuanlan/blob/master/FCLayer.ipynb)找到

        本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多