反向傳播 - 神經網路的核心

反向傳播的目標是優化權重,以便神經網路可以學習如何正確地將任意輸入對映到輸出。

每一層都有自己的一組權重,必須調整這些權重,以便能夠準確預測給定輸入的正確輸出。

反向傳播的高階概述如下:

  1. 正向傳遞 - 輸入轉換為某些輸出。在每一層,使用輸入和權重之間的點積計算啟用,然後將結果與偏差相加。最後,該值通過啟用函式傳遞,以啟用該層,該層將成為下一層的輸入。
  2. 在最後一層中,將輸出與對應於該輸入的實際標籤進行比較,並計算錯誤。通常,它是均方誤差。
  3. 向後傳遞 - 將步驟 2 中計算的誤差傳播回內層,並調整所有層的權重以解決此錯誤。

1.權重初始化

權重初始化的簡化示例如下所示:

layers = [784, 64, 10] 
weights = np.array([(np.random.randn(y, x) * np.sqrt(2.0 / (x + y))) for x, y in zip(layers[:-1], layers[1:])])
biases = np.array([np.zeros((y, 1)) for y in layers[1:]])
  • 隱藏層 1 具有尺寸[64,784]的重量和尺寸 64 的偏差。

  • 輸出層具有維度[10,64]的權重和維度的偏差

你可能想知道在上面的程式碼中初始化權重時發生了什麼。這稱為 Xavier 初始化,它比隨機初始化權重矩陣更好一步。是的,初始化確實很重要。根據你的初始化,你可能能夠在梯度下降期間找到更好的區域性最小值(反向傳播是梯度下降的美化版本)。

2.前往通行證

activation = x
hidden_activations = [np.reshape(x, (len(x), 1))]
z_list = []

for w, b in zip(self.weights, self.biases):    
    z = np.dot(w, np.reshape(activation, (len(activation), 1))) + b
    z_list.append(z)
    activation = relu(z)
    hidden_activations.append(activation)

t = hidden_activations[-1] 
hidden_activations[-1] = np.exp(t) / np.sum(np.exp(t))

該程式碼執行上述轉換。hidden_activations[-1] 包含 softmax 概率 - 所有類的預測,其總和為 1.如果我們預測數字,則輸出將是維度 10 的概率向量,其總和為 1。

3.後退通行證

weight_gradients = [np.zeros(w.shape) for w in self.weights]
bias_gradients = [np.zeros(b.shape) for b in self.biases]

delta = (hidden_activations[-1] - y) * (z_list[-1] > 0) # relu derivative
weight_gradients[-1] = np.dot(delta, hidden_activations[-2].T)
bias_gradients[-1] = delta

for l in range(2, self.num_layers):
    z = z_list[-l]
    delta = np.dot(self.weights[-l + 1].T, delta) * (z > 0) # relu derivative
    weight_gradients[-l] = np.dot(delta, hidden_activations[-l - 1].T)
    bias_gradients[-l] = delta

前兩行初始化漸變。計算這些梯度,並將用於稍後更新權重和偏差。

接下來的 3 行通過從目標中減去預測來計算誤差。然後將錯誤反饋傳播到內層。

現在,仔細跟蹤迴圈的工作。第 2 行和第 3 行將錯誤從 layer[i] 轉換為 layer[i - 1]。跟蹤乘以矩陣的形狀以理解。

4.重量/引數更新

for i in xrange(len(self.weights)):
    self.weights[i] += -self.learning_rate * weight_gradients[i]
    self.biases[i] += -self.learning_rate * bias_gradients[i] 

self.learning_rate 指定網路學習的速率。你不希望它學得太快,因為它可能不會收斂。平穩下降有利於找到一個好的最小值。通常,0.010.1 之間的比率被認為是好的。