淺析神經網絡 Neural Networks
大 廠 技 術 堅 持 周 更 精 選 好 文
目錄

前情概要
-
該主題分享的目的是:
-
不侷限於前端,拓展知識學習領域,不設邊界。
-
以下僅代表我個人學習總結,如有問題,虛心請教,並及時修正。
另外本次分享不會有大段大段代碼,主要是理解為什麼這麼做。
在開始分享主題之前,我們可以先思考下,不管你用什麼語言 (解釋類型語言 或 編譯類型語言),你寫一堆的字符串,一頓解析編譯後,從彙編語言再到最後的機器語言 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實現的線性模型。
https://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了。 ![]() |
小總結
我們再來回顧下剛才的代碼例子。

-
確認目標: 你此刻站在山頂⛰,規劃下山路徑(),想要下山()
-
在你沒有開始行動前,就已經得到了下山最不費力的方法(損失函數))
-
當你走每一步,會調整下山步伐α 和方向的規劃
-
(梯度下降)
-
不停的重複第三步,最後成功下山。
是不是看到這裏,發現模型的訓練,也沒有那麼難啦。
邏輯迴歸
在線性迴歸模型中,我們瞭解到了模型、損失函數、梯度下降的含義。
邏輯迴歸對我們理解NN 神經網絡有很大的幫助。
邏輯迴歸的現實意義是分類問題。eg: 預測用户是否喜歡該類視頻?預測該用户是男還是女?
例如我們預測該圖片是否是隻貓:cat2::
-
:cat2: 模型: 我們有 n個貓的特徵features (毛髮、眼睛、鼻子.... ),通過這些特徵來預測一個圖片是否是貓:cat2:。
-
預測的結果標識 / 邏輯迴歸:,有多大的概率。
-
從模型和預測的結果來看,已經不是線性模型可以覆蓋到的情況了。下面介紹下邏輯迴歸的模型。

模型
如果要實現上述例子,就需要明白邏輯迴歸的模型。
除了sigmoid,還有一些其他方法例如 relu tanh,在NN中被使用。

損失函數
邏輯迴歸和線性迴歸的損失函數是不同的。線性迴歸損失函數(平方損失函數) 是在在滿足 高斯分佈 / 正態分佈 [5] 的條件下推導得到的,而邏輯迴歸假設樣本滿足 伯努利分佈 [6] 。故需要重新定義損失函數。
損失函數為: (是從 最大似然估計 [7] 得來的)
簡單解釋下損失函數的含義:
-
對單一樣本
-
預測結果只有 是和不是 兩種情況,即或。
-
展開後為
y | 損失函數 | 損失函數 和 之間關係 |
---|---|---|
代入公式 => |
![]() |
|
代入公式 => |
![]() |
有了損失函數的定義後,和線性迴歸一樣的道理,我們需要計算出 損失函數最小的時候值。
梯度下降

邏輯迴歸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] ,以下為代碼片段。
-
加載數據、處理數據。省略代碼説明。
-
建立模型,定義向前傳播。
# 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
-
定義損失函數。
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
-
梯度下降,定義向後傳播。
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
-
訓練模型。(這只是一層模型,如果有很多層的話,詳看 兩層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: 對於一張試卷結構和標誌點等識別)。
參考資料
機器學習、深度學習和強化學習的關係和區別是什麼? - 知乎: https://www.zhihu.com/question/279973545/answer/588124593
DEEP REINFORCEMENT LEARNING.pdf: https://arxiv.org/pdf/1810.06339.pdf
代碼: https://github.com/Linjiayu6/Tensorflow.js-LinearRegression/blob/master/src/tensorflow.js
過往實驗例子: https://github.com/Linjiayu6/Machine-Learning-Practice/tree/master/Regression/logistic_regression
高斯分佈 / 正態分佈: https://zh.wikipedia.org/wiki/%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83
伯努利分佈: https://zh.wikipedia.org/wiki/%E4%BC%AF%E5%8A%AA%E5%88%A9%E5%88%86%E5%B8%83
最大似然估計: https://zhuanlan.zhihu.com/p/26614750
邏輯迴歸demo,感興趣可以去看看: https://github.com/Linjiayu6/Deep-Learning/blob/master/coursera/L1_Neural%20Networks%20and%20Deep%20Learning/W2__Logistic%20Regression%20demo.ipynb
學習資料: 3blue1brown-深度學習(英文搬運)_嗶哩嗶哩_bilibili: https://www.bilibili.com/video/BV1Et411779N?p=2
偏移量增加的意義: https://www.zhihu.com/question/68247574
代碼: 用NN識別一隻:cat2:: https://github.com/Linjiayu6/Deep-Learning/blob/master/coursera/L1_Neural%20Networks%20and%20Deep%20Learning/W2__Logistic%20Regression%20with%20a%20Neural%20Network%20mindset.ipynb
兩層NN demo: https://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
投遞鏈接: https://jobs.toutiao.com/s/dQ2dogm
- 使用 WebAssembly 打造定製 JS Runtime
- 前端也要懂算法,不會算法也能微調一個 NLP 預訓練模型
- 聯機遊戲原理入門即入土 -- 入門篇
- Plasmo Framework:次世代的瀏覽器插件開發框架
- 深入理解 Mocha 測試框架:從零實現一個 Mocha
- Single Source of Truth:XCode SwiftUI 的界面編輯的設計理念
- 深入理解 D3.js 可視化庫之力導向圖原理與實現
- 淺析神經網絡 Neural Networks
- Cutter - Web視頻剪輯工具原理淺析
- 你可能需要一個四捨五入的工具函數
- 淺析eslint原理
- 最小編譯器the-super-tiny-compiler
- Git存儲原理及部分實現
- 淺談短鏈的設計
- Web組件構建庫-Lit
- 使用Svelte開發Chrome Extension
- Web3.0開發入門
- vscode插件原理淺析與實戰
- 深入淺出 Web Audio API
- 探祕HTTPS