淺析神經網路 Neural Networks

語言: CN / TW / HK

       

目錄

前情概要

  • 該主題分享的目的是:

    • 不侷限於前端,拓展知識學習領域,不設邊界。

    • 以下僅代表我個人學習總結,如有問題,虛心請教,並及時修正。

另外本次分享不會有大段大段程式碼,主要是理解為什麼這麼做。

在開始分享主題之前,我們可以先思考下,不管你用什麼語言 (解釋型別語言 或 編譯型別語言),你寫一堆的字串,一頓解析編譯後,從組合語言再到最後的機器語言 0 / 1,即是CPU"認識"的。CPU用來計算和控制計算機系統的一套指令的集合。電路實現這種運算。運算又是規則。以上,每一個步驟的描述都是為了應對日益複雜的問題,不斷抽象的過程。

不管我們怎麼抽象,都離不開計算,計算又離不開數學(利用抽象和邏輯能力) 。我們今天主題跟抽象、計算、數學這幾個詞,是很有關係的。

回到本次分享的主題,人工智慧又是什麼?簡單的說是有海量資料 -> 歸納出規則 -> 解決問題。

Artificial intelligence is intelligence demonstrated by machines.

你會想這跟智慧沒啥關係啊 ~ 我個人理解智慧是玄學,那人工智慧是什麼?

任正非說: 人工智慧是統計學。

統計學: 是應用數學的一個分支,主要通過利用概率論建立數學模型,收集所觀察系統的資料,進行量化的分析、總結,並進而進行推斷和預測,為相關決策提供依據和參考。

Statistics is the study and manipulation of data , including ways to gather, review, analyze, and draw conclusions from data.

人工智慧包括機器學習,例如線性迴歸、邏輯迴歸、貝葉斯模型、NN等。通過某個模型結構,基於訓練資料,得出相應關係的概率。深度學習又是機器學習的一個分支,是基於NN神經網路為基本架構的拓展,常見的CNN(影象處理)、RNN(語音識別)等。

概念上就不做過多解釋了,我直接上參考的結論吧。

參考:

  • 機器學習、深度學習和強化學習的關係和區別是什麼? - 知乎 [1]

  • DEEP REINFORCEMENT LEARNING.pdf [2]

  • 機器學習:一切通過優化方法挖掘資料中規律的學科。

  • 深度學習:一切運用了神經網路作為引數結構進行優化的機器學習演算法。

  • 強化學習:不僅能利用現有資料,還可以通過對環境的探索獲得新資料,並利用新資料迴圈往復地更新迭代現有模型的機器學習演算法。

  • 深度強化學習:一切運用了神經網路作為引數結構進行優化的強化學習演算法。

前情概要的小總結: 應對海量資料,我們需要通過一些方法 (工具? 抽象能力?計算?演算法、數學?...),俗稱AI,來幫助我們解決問題。

迴歸模型

線性迴歸

例子 :chestnut:

我們先通過一個簡單的例子,來看基於tensorflow.js實現的線性模型。

http://linjiayu6.github.io/Tensorflow.js-LinearRegression/

首先,在螢幕上點幾個離散點。

一直點選【模型訓練】,我們希望得到訓練好的線性模型 (y = ax + b),其中a,b是需要我們通過幾個點訓練出的值。

最後得出: Y = 1.040215015411377 X + 0.33632710576057434。

  • 看到這裡你會問,這怎麼實現?我們來看看 程式碼 [3]

    • 確認模型 y = ax + b

    • x, y 資料需要處理成矩陣,叫做x特徵值,y是實際結果值。

    • a,b 是需要我們通過某種方法預測出來的值。

    • 訓練模型 涉及 損失函式、梯度下降等。

    • 得到訓練好的模型。

import * as tf from '@tensorflow/tfjs'

window.a = tf.variable(tf.scalar(Math.random()))
window.b = tf.variable(tf.scalar(Math.random()))

// 建立模型 y = ax + b
const model = (xs, a, b) => xs.mul(a).add(b)

// 1. training, y值
const training = ({ points, trainTimes }) => {
for (var i = 0; i < trainTimes; i++) {
const learningRate = 0.1 // 學習率
const optimizer = tf.train.sgd(learningRate); // 隨機梯度下降
const ys = tf.tensor1d(points.map(points => points.y)) // 樣本y值
// loss(訓練好的模型y'值 - 樣本y值)的損失到最小。
optimizer.minimize(() => loss(predict(points.map((points) => points.x)), ys));
}
}

// 2. predict, x值輸入, 線性方程 y = ax + b
const predict = x => {
return tf.tidy(() => {
const xs = tf.tensor1d(x)
const predictYs = model(xs, window.a, window.b)
return predictYs
})
}

// 3. 評價過程, 也是損失函式: 均方差 求出最小的
const loss = (predictYs, ys) => predictYs.sub(ys).square().mean()
export default {
training, predict
}

我們使用了一些資料,通過TensorFlow.js一些方法的呼叫,得到了一條和這幾個點擬合程度較好的線性模型。為了探究具體的實現,詳看一下幾個概念。

損失函式

損失函式是用來評估模型的好壞,即模型預測值和真實值的誤差, 損失越小, 模型越好。We measure the "accuracy" of our hypothesis function by using a cost function

平方誤差函式 廣泛應用在 迴歸的問題 square error function is commonly used for "regression" problems

目標是: 所有橘色線(讓黑色點和紅色點之間的線),即預測結果和實際結果間的誤差最小。

損失函式: 用於度量建模誤差的,為了得到誤差的最小值。統計學中通常使用平方誤差方法。

統計學中的平方誤差(損失)函式

  • 係數是為了後續在梯度下降中便於求解使用的。導數會抵消掉

梯度下降

梯度下降還會涉及到 特徵值縮放、均值歸一化處理等。這裡也不做過多擴充套件。

  • 好處是: 每個特性向量值均縮放到一個區間內,梯度下降速度會更快。

想象你在山頂上了,需要下山,有很多條道兒可以走。

  • 如果你步伐邁的太大,意味著你可能會很快下山,但也有可能走太多的彎路,花費更多時間。

  • 如果你步伐邁的太小,意味著你可能不能很快下山,但也可能會在過程中找到最佳下山路徑,用了最少時間。

簡單的例子,帶你瞭解梯度下降

過往實驗例子 [4] 訓練模型不會以一個固定值來訓練,會開始步子大些,後續逐漸變小。

該例子通過影象直觀說明學習率(步伐多大)對模型的影響 (eg: 收斂、欠擬合)。

梯度下降目的: 用來求解損失函式的最小值的方法。得到區域性最優解的方法。

幫您簡單回憶一下,什麼是導數呢?導數是微小的變化量。

線性迴歸模型
目標是 下山
損失函式表示 下山如何費力最小
梯度下降(Repeat) 具體細節:
步子邁多大
每次朝著哪個方向走經過不停的調整步伐和下山的方向,最後成功下山,並以最小費力方式。

Repeat until converage
以上結論,計算推導過程。高數知識只要知道複合函式求導就ok了。

小總結

我們再來回顧下剛才的程式碼例子。

  1. 確認目標: 你此刻站在山頂⛰,規劃下山路徑(),想要下山()

  2. 在你沒有開始行動前,就已經得到了下山最不費力的方法(損失函式))

  3. 當你走每一步,會調整下山步伐α 和方向的規劃

    1. (梯度下降)

  4. 不停的重複第三步,最後成功下山。

是不是看到這裡,發現模型的訓練,也沒有那麼難啦。

邏輯迴歸

線上性迴歸模型中,我們瞭解到了模型、損失函式、梯度下降的含義。

邏輯迴歸對我們理解NN 神經網路有很大的幫助。

邏輯迴歸的現實意義是分類問題。eg: 預測使用者是否喜歡該類視訊?預測該使用者是男還是女?

例如我們預測該圖片是否是隻貓:cat2::

  • :cat2: 模型: 我們有 n個貓的特徵features (毛髮、眼睛、鼻子.... ),通過這些特徵來預測一個圖片是否是貓:cat2:。

  • 預測的結果標識 / 邏輯迴歸:,有多大的概率。

    • 從模型和預測的結果來看,已經不是線性模型可以覆蓋到的情況了。下面介紹下邏輯迴歸的模型。

模型

如果要實現上述例子,就需要明白邏輯迴歸的模型。

除了sigmoid,還有一些其他方法例如 relu tanh,在NN中被使用。

損失函式

邏輯迴歸和線性迴歸的損失函式是不同的。線性迴歸損失函式(平方損失函式) 是在在滿足 高斯分佈 / 正態分佈 [5] 的條件下推導得到的,而邏輯迴歸假設樣本滿足 伯努利分佈 [6] 。故需要重新定義損失函式。

損失函式為: (是從 最大似然估計 [7] 得來的)

簡單解釋下損失函式的含義:

  • 對單一樣本

  • 預測結果只有 是和不是 兩種情況,即或。

    • 展開後為

y 損失函式 損失函式 之間關係
代入公式
=>
當預測值,誤差為0。反之隨著變小誤差變大。
代入公式
=>
當預測值,誤差為0。反之隨著變大誤差變大。

有了損失函式的定義後,和線性迴歸一樣的道理,我們需要計算出 損失函式最小的時候值。

梯度下降

邏輯迴歸demo,感興趣可以去看看 [8] ,跟線性迴歸的套路是一樣的,建立模型,定義好損失函式,訓練資料不停對模型進行訓練處理,最後得到訓練好的模型。

小總結

邏輯迴歸模型

2.   Sigmoid Function

3.  值在[0, 1]

目標是
損失函式
梯度下降
Repeat until converage
-  以上結論,計算推導過程。高數知識只要知道複合函式求導就ok了。

我們大致瞭解了線性和邏輯迴歸的模型,也理解了損失函式和梯度下降的意義。

但面對著日益複雜的情況,如此簡單的模型是無法滿足現實情況的。尤其當特徵值很多的時候,即對計算是非常大的負荷。例如我們對一張圖片進行預測是否是車,如果該圖片畫素是100*100 *3, 即有3w個特徵值,這顯然對計算來說是很不合理的。

這也就是為什麼,我們需要神經網路NN,以及CNN、RNN 等這些更復雜的模型。

神經網路

學習資料: 3blue1brown-深度學習(英文搬運)_嗶哩嗶哩_bilibili [9]

什麼是神經網路

生物上的神經元,有輸入和輸出層,輸入層接受其他神經元的資訊,輸出層以電脈衝的形式發給其他神經元。

當 大腦在思考的時候,一枚可愛的神經元在幹什麼? 每個樹突收到其他神經元發出的刺激脈衝後,當這些刺激脈衝疊加後,達到一定的強度閾值,就會產生動作電位,並沿著軸突發送電訊號。故以此來不停的傳遞。

該過程可類比於有很多條水管(樹突),水管粗細不一,故輸入的流速也不一樣,開始放水(訊號),當水桶裡水足夠多並達到閾值的時候 (啟用),會從右側軸突流出來。流出的水會再次流向下一個水桶。

來源: 來自google搜尋圖

Neural Networks: 演算法來模擬人的大腦。本質還是構建模型,並通過數學運算得到預測結果。人認識某個動物是大熊貓是一樣的,我們對熊貓的特徵認知,例如大熊貓只有黑白色、只在四川、只吃竹子等等。故對NN模型的訓練道理是一樣的。

NN 神經網路是最基本的的演算法模型,像深度學習的CNN 卷積神經網路對影象的處理;RNN 迴圈神經網路對語言模型的研究等等,各種複雜的模型,都是基於NN拓展的。

神經網路模型

層:

  • 1個輸入層: Input Layer。eg: 圖上輸入層有3個特徵值。

  • N隱藏層: Hidden Layers。eg: 圖上有兩個隱藏層。

  • 1個輸出層: Output Layer。eg: 對某個結果的預測。

每一層都有很多個神經元 Neuron。對於一個神經元的結構如下:

一個神經元的模型

說明:

  • 特徵值 features:

  • 權重值 weights:每個神經元連線的線 (概念也可以理解為)

  • 偏移量 bias: 偏移量增加的意義 [10]

  • 啟用函式 activation function 例如常見的sigmoid、tanh、Relu方法

一個神經元內部計算:

是不是也不難看懂,其實每一個小的神經元,類似一個邏輯迴歸。

通常對於啟用函式 activation function,如圖上使用 sigmoid的使用,會使用Relu。

正向傳播

建立模型,定義每層的結構,並以此往後傳遞。

簡單的理解是: 將多個邏輯迴歸模型組合在一起。

我們建立一個簡單的NN模型,只有一個hidden layer,會有2個預測結果的輸出。

Eg: (只是個例子說明) 該模型是預測是貓還是狗,X 特徵值代表 毛髮、眼睛、鼻子、嘴巴,輸出層會判斷貓還是狗的概率更大些。

針對已經建立的模型,像邏輯迴歸一樣,明確每一個神經元連線的資訊。

例如 按照我們上面對一個神經元模型的建立,建立每個神經元的公式。

以下為了理解 啟用函式 activation function用了 sigmoid function

正向傳播: 沿著從輸入層到輸出層,依次計算,並存儲神經網路的中間變數。

此時,我們的目標值是每一層的 W 和 b。

反向傳播

按照我們迴歸模型的套路是,在已經建立好的模型基礎上,評估損失函式。

其實理解了邏輯迴歸的損失函式,不難理解這個公式。

我們暫不去看正則化的處理 (正則化我的理解是: 向模型加入某些規則,加入先驗,縮小解空間,減小求出錯誤解的可能性)。NN損失函式的定義非常的明確,是每個分類的損失函式加和。

反向傳播演算法的目的是: 計算每一層的引數 w b 對總損失函式的影響。

Repeat until converage

例子 :chestnut:

程式碼: 用NN識別一隻:cat2: [11] ,以下為程式碼片段。

  1. 載入資料、處理資料。省略程式碼說明。

  2. 建立模型,定義向前傳播。

 # Sigmoid
def sigmoid (z):
return 1 / ( 1 + np . exp(-z))
# Sigmoid Derivatives
def sigmoid_derivatives (a):
return a * (1 - a)


def forward_propagation (W, b, X):
# W, B: 一列為一組資料
Z = np . dot(W . T, X) + b
A = sigmoid(Z)
return A
  1. 定義損失函式。

def loss_function (y, a):
# one sample
return -y * np . log(a) - (1 - y) * np . log(1 - a)

def Loss_Fn (Y, A):
# all samples (1, 209)
m = Y . shape[1]
# log(0)會遇到報錯情況
epsilon = 1e-5
J = (1 / m) * np . sum(-Y * np . log(A + epsilon) - (1 - Y) * np . log(1 - A + epsilon))
return J
  1. 梯度下降,定義向後傳播。

def backward_propagation (Y, A, X):
# eg: A: 1 * m, Y: 1 * m X: 3 * m
m = A . shape[1]
dL_dZ = A - Y

dL_dW = (1 / m) * np . dot(X, (A - Y) . T)
dL_dB = (1 / m) * np . sum(A - Y)

return dL_dW, dL_dB
  1. 訓練模型。(這只是一層模型,如果有很多層的話,詳看 兩層NN demo [12] )。

def train (X, Y, alpha, iterations):
# ......
# hyperparameters
# alpha = 0.005
# iterations = 2000

# 1. Initializing parameters - 目標
W, b = initialize_parameters(input_nums, output_nums)
J_arr = []

# 4. iterations: 2,3,4
for i in range(iterations): # 不停訓練
# 2. Forward Propagation 向前傳播
A = forward_propagation(W, b, X)

# 3. Backward Propagation 向後傳播,梯度下降
dL_dW, dL_dB = backward_propagation(Y, A, X)
W -= alpha * dL_dW # 類似下山步伐和方向
b -= alpha * dL_dB # 類似下山步伐和方向

return W, b, J_arr

總結

上述,我只是簡單介紹了一點有關NN模型的基礎知識,實際上有關神經網路的知識還很多。本次分享的初衷是通過一些對模型基礎的理解 + TensorFlow.js,前端同學也可以玩玩機器學習。

在我們的業務場景裡,常見演算法對業務賦能的場景,例如在出讀閱卷中的影象識別 (eg: 對於一張試卷結構和標誌點等識別)。

參考資料

[1]

機器學習、深度學習和強化學習的關係和區別是什麼? - 知乎: http://www.zhihu.com/question/279973545/answer/588124593

[2]

DEEP REINFORCEMENT LEARNING.pdf: http://arxiv.org/pdf/1810.06339.pdf

[3]

程式碼: http://github.com/Linjiayu6/Tensorflow.js-LinearRegression/blob/master/src/tensorflow.js

[4]

過往實驗例子: http://github.com/Linjiayu6/Machine-Learning-Practice/tree/master/Regression/logistic_regression

[5]

高斯分佈 / 正態分佈: http://zh.wikipedia.org/wiki/%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83

[6]

伯努利分佈: http://zh.wikipedia.org/wiki/%E4%BC%AF%E5%8A%AA%E5%88%A9%E5%88%86%E5%B8%83

[7]

最大似然估計: http://zhuanlan.zhihu.com/p/26614750

[8]

邏輯迴歸demo,感興趣可以去看看: http://github.com/Linjiayu6/Deep-Learning/blob/master/coursera/L1_Neural%20Networks%20and%20Deep%20Learning/W2__Logistic%20Regression%20demo.ipynb

[9]

學習資料: 3blue1brown-深度學習(英文搬運)_嗶哩嗶哩_bilibili: http://www.bilibili.com/video/BV1Et411779N?p=2

[10]

偏移量增加的意義: http://www.zhihu.com/question/68247574

[11]

程式碼: 用NN識別一隻:cat2:: http://github.com/Linjiayu6/Deep-Learning/blob/master/coursera/L1_Neural%20Networks%20and%20Deep%20Learning/W2__Logistic%20Regression%20with%20a%20Neural%20Network%20mindset.ipynb

[12]

兩層NN demo: http://github.com/Linjiayu6/Deep-Learning/blob/master/coursera/L1_Neural%20Networks%20and%20Deep%20Learning/W5__2-Layer__Deep%20Neural%20Network%20for%20Image%20Classification%20-%20Application.ipynb

- END -

:heart: 謝謝支援

以上便是本次分享的全部內容,希望對你有所幫助^_^

喜歡的話別忘了 分享、點贊、收藏 三連哦~。

歡迎關注公眾號 ELab團隊 收貨大廠一手好文章~

位元組跳動校/社招內推碼: W7HD8A6

投遞連結: http://jobs.toutiao.com/s/dQ2dogm