1. 程式人生 > >Make your own neural network(Python神經網路程式設計)一

Make your own neural network(Python神經網路程式設計)一

  這本書應該算我第一本深度學習的程式碼入門書了吧,之前看阿里云云棲社和景略集智都有推薦這本書就去看了,

  成功建立了自己的第一個神經網路,也瞭解一些關於深度學習的內容,再加上這學期的概率論與數理統計的課,

  現在再來看李大大的機器學習課程,終於能看懂LogisticsRegression概率那部分公式!不至於像之前暑假看的那麼懵逼了。

  如果有大佬看了我的部落格發現錯誤。請一定要告訴我,畢竟我才學了1個月都不到,部落格是我強制自己去總結去反思的。有錯誤一定要告訴我啊!!!

  廢話不多說了,我整理了這本書中的內容,再加上一點我自己的收集,直接從第二章的Python實現開始寫,第一章內容穿插在裡面進行講解。我是用的是jupyter,具體安裝過程就不細說了。

  將神經網路寫成一個類,可以適用於各種場景,可以用來創景不同大小的網路,這本書寫的是一個三層神經網路,輸入層,隱藏層,輸出層

  大體框架就是

  ①初始化函式 -- 設定輸入層節點數,隱藏層節點數,輸出層節點數

  ②訓練 --學習給定訓練集的樣本,優化權重

  ③查詢--給定的輸入,輸出結果

  我分幾次部落格來寫吧。。。一次太長了。。。。

#神經網路類定義
class neuralNetwork:
    
    #初始化神經網路
    def __init__():
        pass
    
    #訓練神經網路
    def train():
        
pass #查詢神經網路的結果 def query(): pass

  首先先是①初始化神經網路

  我們需要設定的是輸入層節點數,隱藏層節點數,輸出層節點數,以及學習率(每一次迭代的步長),然後給到類裡面

  

 #初始化神經網路
    def __init__(self,inputnodes,hiddennodes,outputnodes,
                learningrate):
        #設定的是輸入層節點數,隱藏層節點數,輸出層節點數
        self.inodes = inputnodes
        self.hnodes 
= hiddennodes self.onodes = outputnodes #設定學習率 self.lr = learningrate pass

   然後初始化設定每層三個節點,看看是否執行成功。

#輸入層節點數,隱藏層節點數,輸出層節點數
input_nodes = 3
hidden_nodes = 3
output_nodes = 3

#learning rate is 0.3
learning_rate = 0.3

#例項化神經網路
n = neuralNetwork(input_nodes,hidden_nodes,output_nodes,
                 learning_rate)

  雖然沒實現任何功能,但是至少沒報錯。

  之後先來說說S閾值函式

  S閾值函式是什麼?幹什麼?怎麼用?

  神經網路模擬人的大腦的神經元的工作方式,神經元的工作方式是抑制輸入,直到輸入增強到一定的閾值就可以觸發輸出

,因為神經元不希望傳遞微小的噪聲訊號。有許多啟用函式可以使用,我們這裡使用最常用的S函式用單詞sigmoid表示,也叫邏輯函式。

  具體這個S函式怎麼來的,是從貝葉斯公式發展過來的,這裡就不細說了。

它是用來幹什麼的?是為了讓輸入的值和輸出的值不是線性的,為了後面的權重優化非線性誤差梯度。但是說到底還是為了模仿神經元的工作原理

它怎麼用?就是一個代入x得到y的簡單代數公式罷了。

 

  回到我們的主題。接下來就是神經網路的核心--權重的初始化了。

  神經網路中的權重是什麼?幹什麼?怎麼用?這三個問題先來說明一下。

  我先以一個兩層每層兩個節點的神經網路進行說明。

首先權重是什麼。一個神經網路會若干個輸入,第一層輸入層,只做輸入(重點)!

  權重就是賦予圖中綠線一定的數值,代表前一個節點的輸出的數值傳到後一個節點的輸入的佔比,權重最初是隨機出來的,之後要一點點調節,這個後面再說。

權重幹什麼?

  這張圖應該就能看出來權重的作用了,得到輸入值,各自和權重相乘然後求和,然後代入我們的S函式中得到一個值,就作為我們的輸出y

  假設給兩層神經網路隨機以下權重。是指前一層的第一個節點到下一層第一個節點的權重

   那麼第二層的節點1,的計算過程就是x = (1.0*0.9)+(0.5*0.3) = 1.05

  然後把x的值代入S函式中 y = 1/(1+e^1.05) = 0.7408

  到此,我們經歷了一個節點的全過程,但是很明顯這種枯燥乏味的活不適合人去做,我們需要計算機來幫我們做

  但是,每一個節點都有不同的權重,難道我們對每一個節點都要單獨敲一行程式碼嗎?

權重怎麼用?我們用矩陣來完成全部計算過程,計算機已經很好的和矩陣一起工作了,矩陣相乘的計算基礎也不多說了

  直接看看結果

  第一個矩陣就是權重矩陣,權重矩陣第一列是前一層第一個節點到下一層所有節點依次的權重。

  第二個矩陣就是輸入矩陣,必須是列向量,否則,你也乘不出來我們要的結果啊。

  右邊就是矩陣相乘的結果,也是一個列向量,從上到下依次代表下一層節點的輸入值

  然後把這個矩陣簡化一下就是,這樣不管矩陣裡面有2個還是200個,都能用這個公式表示

  最後就是把我們的輸入矩陣X,代入我們的S函式中,輸出矩陣O就是sigmoid(X)

 

  回到我們的程式之中,我們現在要處理三層每層三個神經網路的問題,但是精髓是不變的

  我們要隨機一個輸入層和隱藏層的權重矩陣,還要隨機一個隱藏層和輸出層的權重矩陣,取值是-1到+1

  這裡講解一下,為什麼要隨機呢,因為後面訓練要從不同的初始值找極值,來優化權重,所以我們不能在一棵樹上吊死。

  其次為什麼是-1到+1,可以看我們的S函式的圖,在<-1和>1的情況下都是斜率很小的,不適合後面優化權重,為了電腦不會跑宕機,就選-1到1。

  當然權重矩陣有一種經驗上的較好的取值方法,我最後再講,

  隨機數的生成我用numpy來實現

#初始化權重函式
        #初始化輸入層到隱藏層的權重矩陣
        self.wih = np.random.rand(self.hnodes,self.inodes)-0.5  #rand只出現0-1,所以-0.5為了能出現負數
        #初始化隱藏層到輸出層的權重矩陣
        self.who = np.random.rand(self.onodes,self.hnodes)-0.5

  特比說明一下權重矩陣的大小一定是(後一層的節點數X前一層的節點數),一列中每一行對應下一層的每一個節點,所以行數為下一層的節點數,

  可以看看前面那個權重矩陣的解釋自己感受一下那個feel。

  

至此我們的初始化快要完成了。時間不早了,後面的就下一次部落格寫了。附上我的程式碼

import numpy as np
#神經網路類定義
class neuralNetwork:
    
    #初始化神經網路
    def __init__(self,inputnodes,hiddennodes,outputnodes,
                learningrate):
        #設定的是輸入層節點數,隱藏層節點數,輸出層節點數
        self.inodes = inputnodes
        self.hnodes = hiddennodes
        self.onodes = outputnodes
        
        #設定學習率
        self.lr = learningrate
        
        #初始化權重函式
        #初始化輸入層到隱藏層的權重矩陣
        self.wih = np.random.rand(self.hnodes,self.inodes)-0.5  #-0.5為了能出現負數
        #初始化隱藏層到輸出層的權重矩陣
        self.who = np.random.rand(self.onodes,self.hnodes)-0.5
        
        pass
    
    #訓練神經網路
    def train():
        pass
    
    #查詢神經網路的結果
    def query():
        pass

#輸入層節點數,隱藏層節點數,輸出層節點數
input_nodes = 3
hidden_nodes = 3
output_nodes = 3

#learning rate is 0.3
learning_rate = 0.3

#例項化神經網路
n = neuralNetwork(input_nodes,hidden_nodes,output_nodes,
                 learning_rate)