欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python?實現(xiàn)一個全連接的神經(jīng)網(wǎng)絡(luò)

 更新時間:2022年06月28日 11:03:32   作者:??zidea????  
這篇文章主要介紹了Python?實現(xiàn)一個全連接的神經(jīng)網(wǎng)絡(luò),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

前言

在這篇文章中,準(zhǔn)備用 Python 從頭開始實現(xiàn)一個全連接的神經(jīng)網(wǎng)絡(luò)。你可能會問,為什么需要自己實現(xiàn),有很多庫和框架可以為我們做這件事,比如 Tensorflow、Pytorch 等。這里只想說只有自己親手實現(xiàn)了,才是自己的。

想到今天自己從接觸到從事與神經(jīng)網(wǎng)絡(luò)相關(guān)工作已經(jīng)多少 2、3 年了,其中也嘗試用 tensorflow 或 pytorch 框架去實現(xiàn)一些經(jīng)典網(wǎng)絡(luò)。不過對于反向傳播背后機制還是比較模糊。

梯度

梯度是函數(shù)上升最快方向,最快的方向也就是說這個方向函數(shù)形狀很陡峭,那么也是函數(shù)下降最快的方向。

雖然關(guān)于一些理論、梯度消失和結(jié)點飽和可以輸出一個 1、2、3 但是深究還是沒有底氣,畢竟沒有自己動手去實現(xiàn)過一個反向傳播和完整訓(xùn)練過程。所以感覺還是浮在表面,知其所以然而。

因為最近有一段空閑時間、所以利用這段休息時間將要把這部分知識整理一下、深入了解了解

類型符號說明表達式維度
標(biāo)量n^LnL表示第 L 層神經(jīng)元的數(shù)量  
向量B^LBL表示第 L 層偏置 n^L \times 1nL×1
矩陣W^LWL表示第 L 層的權(quán)重 n^L \times n^LnL×nL
向量Z^LZL表示第 L 層輸入到激活函數(shù)的值Z^L=W^LA^{(L-1)} + B^LZL=WLA(L−1)+BLn^L \times 1nL×1
向量A^LAL表示第 L 層輸出值A^L = \sigma(Z^L)AL=σ(ZL)n^L \times 1nL×1

我們大家可能都了解訓(xùn)練神經(jīng)網(wǎng)絡(luò)的過程,就是更新網(wǎng)絡(luò)參數(shù),更新的方向是降低損失函數(shù)值。也就是將學(xué)習(xí)問題轉(zhuǎn)換為了一個優(yōu)化的問題。那么如何更新參數(shù)呢?我們需要計算參與訓(xùn)練參數(shù)相對于損失函數(shù)的導(dǎo)數(shù),然后求解梯度,然后使用梯度下降法來更新參數(shù),迭代這個過程,可以找到一個最佳的解決方案來最小化損失函數(shù)。

我們知道反向傳播主要就是用來結(jié)算損失函數(shù)相對于權(quán)重和偏置的導(dǎo)數(shù)

可能已經(jīng)聽到或讀到了,很多關(guān)于在網(wǎng)絡(luò)通過反向傳播來傳遞誤差的信息。然后根據(jù)神經(jīng)元的 w 和 b 對偏差貢獻的大小。也就是將誤差分配到每一個神經(jīng)元上。 但這里的誤差(error)是什么意思呢?這個誤差的確切的定義又是什么?答案是這些誤差是由每一層神經(jīng)網(wǎng)絡(luò)所貢獻的,而且某一層的誤差是后繼層誤差基礎(chǔ)上分?jǐn)偟?,網(wǎng)絡(luò)中第 層的誤差用來表示。

反向傳播是基于 4 個基本方程的,通過這些方程來計算誤差和損失函數(shù),這里將這 4 個方程一一列出

關(guān)于如何解讀這個 4 個方程,隨后想用一期分享來說明。

class NeuralNetwork(object):
  def __init__(self):
    pass
  def forward(self,x):
    # 返回前向傳播的 Z 也就是 w 和 b 線性組合,輸入激活函數(shù)前的值
    # 返回激活函數(shù)輸出值 A
    # z_s , a_s
    pass
  def backward(self,y,z_s,a_s):
    #返回前向傳播中學(xué)習(xí)參數(shù)的導(dǎo)數(shù) dw db
    pass
  def train(self,x,y,batch_size=10,epochs=100,lr=0.001):
    pass

我們都是神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)過程,也就是訓(xùn)練過程。主要分為兩個階段前向傳播后向傳播

  • 在前向傳播函數(shù)中,主要計算傳播的 Z 和 A,關(guān)于 Z 和 A 具體是什么請參見前面表格
  • 在反向傳播中計算可學(xué)習(xí)變量 w 和 b 的導(dǎo)數(shù)
  def __init__(self,layers = [2 , 10, 1], activations=['sigmoid', 'sigmoid']):
    assert(len(layers) == len(activations)+1)
    self.layers = layers
    self.activations = activations
    self.weights = []
    self.biases = []
    for i in range(len(layers)-1):
      self.weights.append(np.random.randn(layers[i+1], layers[i]))
      self.biases.append(np.random.randn(layers[i+1], 1))
  • layers 參數(shù)用于指定每一層神經(jīng)元的個數(shù)
  • activations 為每一層指定激活函數(shù),也就是

來簡單讀解一下代碼 assert(len(layers) == len(activations)+1)

for i in range(len(layers)-1):
  self.weights.append(np.random.randn(layers[i+1], layers[i]))
  self.biases.append(np.random.randn(layers[i+1], 1))

因為權(quán)重連接每一個層神經(jīng)元的 w 和 b ,也就兩兩層之間的方程,上面代碼是對

前向傳播

def feedforward(self, x):
  # 返回前向傳播的值
  a = np.copy(x)
  z_s = []
  a_s = [a]
  for i in range(len(self.weights)):
      activation_function = self.getActivationFunction(self.activations[i])
      z_s.append(self.weights[i].dot(a) + self.biases[i])
      a = activation_function(z_s[-1])
      a_s.append(a)
  return (z_s, a_s)

這里激活函數(shù),這個函數(shù)返回值是一個函數(shù),在 python 用 lambda 來返回一個函數(shù),這里簡答留下一個伏筆,隨后會對其進行修改。

  @staticmethod
  def getActivationFunction(name):
        if(name == 'sigmoid'):
            return lambda x : np.exp(x)/(1+np.exp(x))
        elif(name == 'linear'):
            return lambda x : x
        elif(name == 'relu'):
            def relu(x):
                y = np.copy(x)
                y[y<0] = 0
                return y
            return relu
        else:
            print('Unknown activation function. linear is used')
            return lambda x: x
[@staticmethod]
def getDerivitiveActivationFunction(name):
    if(name == 'sigmoid'):
        sig = lambda x : np.exp(x)/(1+np.exp(x))
        return lambda x :sig(x)*(1-sig(x))
    elif(name == 'linear'):
        return lambda x: 1
    elif(name == 'relu'):
        def relu_diff(x):
            y = np.copy(x)
            y[y>=0] = 1
            y[y<0] = 0
            return y
        return relu_diff
    else:
        print('Unknown activation function. linear is used')
        return lambda x: 1

反向傳播

這是本次分享重點

  def backpropagation(self,y, z_s, a_s):
      dw = []  # dC/dW
      db = []  # dC/dB
      deltas = [None] * len(self.weights)  # delta = dC/dZ 計算每一層的誤差
      # 最后一層誤差

      deltas[-1] = ((y-a_s[-1])*(self.getDerivitiveActivationFunction(self.activations[-1]))(z_s[-1]))
      # 反向傳播
      for i in reversed(range(len(deltas)-1)):
          deltas[i] = self.weights[i+1].T.dot(deltas[i+1])*(self.getDerivitiveActivationFunction(self.activations[i])(z_s[i]))
      #a= [print(d.shape) for d in deltas]
      batch_size = y.shape[1]
      db = [d.dot(np.ones((batch_size,1)))/float(batch_size) for d in deltas]
      dw = [d.dot(a_s[i].T)/float(batch_size) for i,d in enumerate(deltas)]
      # 返回權(quán)重(weight)矩陣 and 偏置向量(biases)
      return dw, db

首先計算最后一層誤差根據(jù) BP1 等式可以得到下面的式子

deltas[-1] = ((y-a_s[-1])*(self.getDerivitiveActivationFunction(self.activations[-1]))(z_s[-1]))

接下來基于上一層的 誤差來計算當(dāng)前層 

batch_size = y.shape[1]
db = [d.dot(np.ones((batch_size,1)))/float(batch_size) for d in deltas]
dw = [d.dot(a_s[i].T)/float(batch_size) for i,d in enumerate(deltas)]

開始訓(xùn)練

  def train(self, x, y, batch_size=10, epochs=100, lr = 0.01):
# update weights and biases based on the output
      for e in range(epochs): 
          i=0
          while(i<len(y)):
              x_batch = x[i:i+batch_size]
              y_batch = y[i:i+batch_size]
              i = i+batch_size
              z_s, a_s = self.feedforward(x_batch)
              dw, db = self.backpropagation(y_batch, z_s, a_s)
              self.weights = [w+lr*dweight for w,dweight in  zip(self.weights, dw)]
              self.biases = [w+lr*dbias for w,dbias in  zip(self.biases, db)]
              # print("loss = {}".format(np.linalg.norm(a_s[-1]-y_batch) ))

到此這篇關(guān)于Python 實現(xiàn)一個全連接的神經(jīng)網(wǎng)絡(luò)的文章就介紹到這了,更多相關(guān)Python 全連接神經(jīng)網(wǎng)絡(luò)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python使用xslt提取網(wǎng)頁數(shù)據(jù)的方法

    python使用xslt提取網(wǎng)頁數(shù)據(jù)的方法

    這篇文章主要為大家詳細(xì)介紹了Python使用xslt提取網(wǎng)頁數(shù)據(jù)的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • Python爬蟲之PhantomJS和handless的使用詳解

    Python爬蟲之PhantomJS和handless的使用詳解

    這篇文章主要介紹了Python爬蟲之PhantomJS和handless的使用詳解,PhantomJS是一個基于Webkit的headless瀏覽器,它會把網(wǎng)站加載到內(nèi)存并使用webkit來編譯解釋執(zhí)行頁面上的JavaScript代碼,由于不進行css和gui渲染、不展示圖形界面,需要的朋友可以參考下
    2023-09-09
  • Python語言實現(xiàn)百度語音識別API的使用實例

    Python語言實現(xiàn)百度語音識別API的使用實例

    這篇文章主要介紹了Python語言實現(xiàn)百度語音識別API的使用實例,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • Python批量獲取并保存手機號歸屬地和運營商的示例

    Python批量獲取并保存手機號歸屬地和運營商的示例

    這篇文章主要介紹了Python批量獲取并保存手機號的歸屬地和運營商的示例,幫助大家更好的利用python處理數(shù)據(jù),感興趣的朋友可以了解下
    2020-10-10
  • 教你用Python3+mysql8.0搭建Django框架

    教你用Python3+mysql8.0搭建Django框架

    發(fā)現(xiàn)有很多小伙伴還不知道如何搭建Django框架,今天特地整理了本篇文章,基于Python3和mysql8.0,文中有非常詳細(xì)的步驟教程,對小伙伴很有幫助,需要的朋友可以參考下
    2021-05-05
  • python中g(shù)et和post有什么區(qū)別

    python中g(shù)et和post有什么區(qū)別

    在本篇內(nèi)容里小編給大家分享的是關(guān)于python中g(shù)et和post有什么區(qū)別的相關(guān)內(nèi)容,需要的朋友們參考下吧。
    2020-06-06
  • 淺析python字符串前加r、f、u、l 的區(qū)別

    淺析python字符串前加r、f、u、l 的區(qū)別

    這篇文章主要介紹了淺析python字符串前加r、f、u、l 的區(qū)別,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • 一篇文章帶你了解kali局域網(wǎng)攻擊

    一篇文章帶你了解kali局域網(wǎng)攻擊

    這篇文章主要給大家介紹了kali的局域網(wǎng)攻擊,小編覺得這篇文章還是不錯的,使用起來也是非常方便的,需要的朋友可以參考下
    2021-08-08
  • 一文搞懂Python的hasattr()、getattr()、setattr()?函數(shù)用法

    一文搞懂Python的hasattr()、getattr()、setattr()?函數(shù)用法

    python中的getattr()、setattr()、hasattr()函數(shù)均是對類屬性或方法的操作,其中g(shù)etattr()用于獲取類或?qū)嵗兄付ǚ椒ǐ@取屬性的值,setattr()用于設(shè)置類或?qū)嵗袑傩曰蚍椒?hasattr()用于判斷類或?qū)嵗惺欠翊嬖谥付ǖ膶傩曰蚍椒?本文通過例子給大家詳解,一起看看吧
    2022-04-04
  • 使用Python對Csv文件操作實例代碼

    使用Python對Csv文件操作實例代碼

    這篇文章主要介紹了使用Python對Csv文件操作實例代碼,非常具有實用價值,需要的朋友可以參考下
    2017-05-05

最新評論