入門神經網絡

準備工作

讀懂這篇文章,需要你有以下方面的知識

  • 如何求導數
  • 基本的矩陣乘法

如果有下列知識就更好了

  • 懂一點機器學習的知識,比如線性迴歸
  • 知道什麼是 感知機(perceptron)

有任何沒看懂的部分,歡迎留言,信不信我半小時內秒回。

一個巨簡單的神經網絡(A Deadly Simple NN)

如果你對神經網絡(neural network)感興趣或者關注過相關的文章,那下圖中的這個模型想必你不會感覺很陌生。

入門神經網絡

一個人工神經網絡模型

不過這個可能對於初學者有點不太友好?那看看下面這個簡化版的

入門神經網絡

一個無隱層的神經網絡

圖裡的這些東西,咱們一個一個的捋一遍。每個藍色的圓代表一個神經元(neuron)。每個方塊代表一個運算,比如 + 代表求和。上圖中最左邊的三個神經元組成了輸入層(input layer),包含一個 h 的神經元組成了輸出層(output layer),並且這一層只有這一個神經元。

入門神經網絡

輸出層神經元的輸入值

對於生物學意義上的神經元來說,通常存在一個閾值(threshold)來使其達到興奮的狀態,也就是被激活。在我們所討論的神經網絡中,我們的神經元將會通過輸入值和激活函數(activation function)計算一個輸出值。激活函數最值得稱讚的一點就是它可以是任何類型的函數,包括但不限於躍階函數,多項式函數或者 sigmoid 函數。h 是輸出神經元的輸入值,結合激活函數,輸出神經元會輸出 f(h) 計算的結果 y,也就是整個神經網絡的輸出值。

如果你選擇 f(h) = h 作為你的激活函數,那麼你的神經網絡輸出結果將會是下圖中的這個公式,這裡 y = f(h)

入門神經網絡

神經網絡的輸出

如果你覺得這看起來是一個線性迴歸的模型,那就對了。如果你的激活函數是連續可導的,那麼(通常情況下)你就可以使用一個叫做 梯度下降(gradient descent) 的方法來訓練你的網絡。不過這理解起來要稍微麻煩一點,在我們深入到訓練的步驟之前,我們先來編寫一個很簡單的程序來了解神經網絡作出預測的過程。我們將使用 sigmoid 函數作為激活函數, Python 作為編程語言。預測的這個過程是一種前饋(feedforward)的計算,僅僅有這一部分的神經網絡是不能學習的(例如,通過反向傳播(backpropagation)),但我們稍後再關注訓練學習的部分。

入門神經網絡

Sigmoid 函數

import numpy as np

def sigmoid(x):
# sigmoid function
return 1/(1 + np.exp(-x))

inputs = np.array([0.7, -0.3])
weights = np.array([0.1, 0.8])
bias = -0.1

# calculate the output
output = sigmoid(np.dot(weights, inputs) + bias)

print('Output:')
print(output)

第一個單隱層神經網絡(Your First 2-Layer NN)

注:單隱層,即為包括一個隱層,一個輸出層的神經網絡,輸入層和輸出層因為是必須的,所以不計數。

現在你已經基本知道了一個神經網絡是怎麼計算預測結果的。在現實生活中,我們面臨的預測問題往往十分複雜,這樣簡單的網絡結構可能遠遠不夠。這裡我們要引入一個新的概念,隱層(hidden layer)

入門神經網絡

一個擁有三個輸入層神經元,兩個隱層神經元和一個輸出層神經元的神經網絡

在第一部分那個簡單的網絡模型中,我們的權重(weight)是一個向量。但是對於多數神經網絡來說,其實權重將會是一個如下圖一樣的矩陣。

入門神經網絡

三個輸入層神經元和兩個隱層神經元的權重矩陣

結合第一部分的理解和上面單隱層神經網的模型,你也許已經知道怎麼通過這個模型計算 h1 的具體數值了。我們給出一個簡單的公式定義

入門神經網絡

計算隱層神經元輸入值的公式

對於我們所關注的這個單隱層模型來說,它是下面這樣的

入門神經網絡

計算隱層輸入值的矩陣乘法

注意!!:上圖中的權重下角標已經更改為矩陣的表達方式,並不是和單隱層神經網絡圖中的下角標所對應的。因為在矩陣的表達方法中,是用行/列的順序來標註的。所以如果用示意圖中的方法標註的話,會造成一些誤會。

入門神經網絡

用先前神經網絡模型圖中的下角標所標註的矩陣

記住,上圖中的這個計算過程使用的並非是矩陣使用的角標,但這個和我們上面單隱層神經網絡的示意圖中的標註是一致的。

結合上面所學的知識,我們可以快速構建一個單隱層神經網絡的前饋(即預測)過程了。我們仍然使用 sigmoid 函數作為我們的激活函數(並且在之後很長時間都會用這個函數)。

待辦事項:

  • 計算隱層的輸入值
  • 計算隱層的輸出值
  • 計算輸出層的輸出值
  • 計算輸出層的輸出值
import numpy as np

def sigmoid(x):
# sigmoid function
return 1/(1+np.exp(-x))

# 神經網絡各層神經元數量
N_input = 3
N_hidden = 2
N_output = 1

np.random.seed(42)
# Make some fake data
X = np.random.randn(4)

# 生成輸入層到隱層/隱層到輸出層權重
weights_in_hidden = np.random.normal(0, scale=0.1, size=(N_input, N_hidden))
weights_hidden_out = np.random.normal(0, scale=0.1, size=(N_hidden, N_output))

# 計算隱層的輸入值/輸出值
hidden_layer_in = np.dot(X, weights_in_hidden)
hidden_layer_out = sigmoid(hidden_layer_in)

print('Hidden-layer Output:')
print(hidden_layer_out)

# 計算輸出層的輸入值/輸出值
output_layer_in = np.dot(hidden_layer_out, weights_hidden_out)
output_layer_out = sigmoid(output_layer_in)

print('Output-layer Output:')
print(output_layer_out)
  • All formulas are generated by HostMath
  • Some figures are taken from the Udacity deep learning course
  • 【模式識別】多層感知器 MLP
  • CS224d:
    TensorFlow Tutorial
  • CS231n Winter 2016 Lecture 4 Backpropagation, Neural Networks


分享到:


相關文章: