http://www.jianshu.com/p/bfabcc47cb4d
http://iamtrask.github.io/2015/07/12/basic-python-network/
AlphaGo在人機大戰中戰勝李世乭讓深度學習這個名詞在大眾口中廣為傳播,深度學習的強大,也讓其增加了一層神秘色彩,似乎這是名校博士才能理解的算法。雖然相關的論文自己也無法看懂,然而,在網絡查閱了無數資料之后,才發現如果不去糾結理論的證明,只關心結論的話,神經網絡算法也并非高不可攀。
在查閱資料的過程中,有幸看到iamtrask的一篇文章A Neural Network in 11 lines of Python (Part 1),文章拋棄推理,直接從結論出發,用簡單的Python實現了一個簡易的神經網絡算法,對于像我這樣數學基礎一般的初學者,具有很大的啟發作用。本文主要參考這篇文章,并加入自己的理解,試圖以易于理解的方式闡述其思路,如果有表述不當的地方,您可以參考原文,或者參考其中文翻譯。
什么是神經網絡算法
在解釋什么是神經網絡之前,我們先明確幾個機器學習中的術語:特征,樣本,監督學習
樣本:可以用于學習的個體,我們可以獲得這些個體的其某些信息,并且我們已知這些個體的類別
特征:同一屬性在不同個體所體現出來的特點,在神經網絡中,特征應該是易于提取的
監督學習:根據樣本中個體的特征以及類別,然后創建我們的判定規則,并依靠這些調查所得信息,調整我們的規則,使得規則的預測結果盡可能接近我們的樣本,這樣,我們利用這個規則和新個體的特征信息,來判定其所屬分類
舉個例子,我們想要構建一套性別識別算法,而我們能夠獲得的特征信息只有三種:這個人不是長頭發;衣服顏色是紅色;身高是否超過了178cm。那以一個正常成年人的思維,我們應該采用什么策略來判斷這個人的性別呢?
我想大部分人都會采用和我一樣的策略:依據我們平時的經驗,一個人如果留長頭發,很大可能這個人是女的,而一個人穿紅色衣服,很難判斷其性別,一個人身高超過175cm,在中國人里面可能都屬于偏高的,而依據我們的經驗,男性的平均身高要大于女性,所以單純通過身高這個信息,我們推斷這個人是男性的可能性較大。
以上推測過程中,我們對每一個條件的推斷都基于一個詞,經驗,這里的經驗就是我們長期以來觀察身邊的人的特征所留下的記憶。而我們的推測結果主要用了一個詞匯,可能性,其代表基于某條已知信息推測出某個未知結論的概率。
科學家將我們的思維方法歸納為信息在神經元之間的傳導過程,這些神經元每一個都處理及簡單的信息,但是通過無數個神經元之間錯綜復雜的連接傳導,使得我們的大腦能夠處理及其復雜的信息。神經網絡算法就是對我們大腦思維方式的抽象,比如在上面的例子中,我們將每一個特征,輸入到一個神經元,這些接受輸入的神經元構成了第一層神經網絡,也叫做輸入層,我們的目標是判斷一個人的性別,是男是女分屬于兩個不同類別,我們將其抽象為一個神經元,這個神經元構成神經網絡的輸出層,每一個特征(輸入層神經元),都有到分類(輸出層神經元)的連接,也就是從特征轉化為分類的概率(權重),通過綜合各個連接的權重,傳送到輸出神經元。
人工神經網絡模型
以上便是神經網絡算法最簡單的模型,神經網絡算法的學習過程中,首先隨機初始化各層神經元之間的連接權重(上文中的可能性),然后輸入樣本進行預測,根據預測的誤差,調整神經網絡中的權重,完成這個過程之后,我們的神經網絡就訓練好了。所以,神經網絡訓練的結果,就是得到各個連接的權重(經驗),這樣,一旦有新的數據輸入神經網絡的時候,就能推測出其分類了。
神經網絡算法實例
問題定義
還是用上面的預測性別的例子,現在將其數學化,假設在一群人中,我們只能獲得每個人的三個特征:
特征1:長發(1)還是短發(0)
特征2:衣服顏色是紅色(1)還是不是紅色(0)
特征3:身高大于178cm(1)還是不超過178(0)
假設我們只知道其中四個人的性別(男:0,女:1),我們需要依據這四個人的三個特征以及性別訓練一個神經網絡,用于預測一個人的性別。樣本信息如下:
頭發 衣服 身高 性別
0 0 1 0
1 1 1 1
1 0 1 1
0 1 1 0
下面我們先實現最簡單的單層神經網絡。我們用X表示輸入的特征向量,由于每個樣本有三個特征,一共有四個樣本,所以我們定義一個4X3的矩陣,每一行代表一個樣本,如下代碼所示。其中,NumPy是Python語言的一個擴充程序庫。支持高級大量的維度數組與矩陣運算,此外也針對數組運算提供大量的數學函數庫。
#import numpy
import numpy as np
# input dataset
X = np.array([ [0,0,1],
[0,1,1],
[1,0,1],
[1,1,1] ])
而四個樣本對應輸出(分類結果)我們用一個1X4的矩陣表示。“.T” 為轉置函數,轉置后變成了4X1的矩陣。同我們的輸入一致,每一行是一個訓練實例,而每一列(僅有一列)對應一個輸出節點。因此,這個網絡還有三個輸入和一個輸出。代碼如下所示:
# output dataset
y = np.array([[0,0,1,1]]).T
訓練開始之前,我們先要初始化神經網絡的權重,由于輸入層有三個神經元,而輸出結果只有一個神經元,所以權重矩陣為3X1。由于一般初始化權重是隨機選擇的,因此要為隨機數設定產生的種子,如下第一行代碼所示。這樣可以使每次訓練開始時,得到的訓練隨機數都是一致的。這樣便于觀察策略變動是如何影響網絡訓練的,消除初始權重的影響。
對于第二行代碼,這里由于我們要將隨機初始化的權重矩陣均值設定為 0 (至于權重矩陣的初始化,大家有興趣的話,請查看相關資料)。因此使用第二行代碼來計算syn0(第一層網絡間的權重矩陣),如下所示:
# seed random numbers to make calculation
# deterministic (just a good practice)
np.random.seed(1)
# initialize weights randomly with mean 0
syn0 = 2*np.random.random((3,1)) - 1
為了將輸出的權重歸一化,定義一個sigmoid函數,其定義為:
sigmoid函數可以用以下Python代碼實現,其中,deriv參數表示是否計算的是其導數值:
# sigmoid function
def nonlin(x,deriv=False):
if(deriv==True):
return x*(1-x)
return 1/(1+np.exp(-x))
其函數圖像如下圖所示:
sigmoid
sigmoid函數的特點是,其導數可以用其自身表示出來,在計算的時候,我們只需要計算出其函數值,就可以計算出其導數值,從而可以減少浮點運算次數,提高效率,其導數如下:
接下來,我們開始訓練神經網絡:
for iter in range(10000):
# forward propagation
l0 = X
l1 = nonlin(np.dot(l0,syn0))
# how much did we miss?
l1_error = y - l1
# multiply how much we missed by the
# slope of the sigmoid at the values in l1
l1_delta = l1_error * nonlin(l1,True)
# update weights
syn0 += np.dot(l0.T,l1_delta)
我們的訓練過程迭代10000次,以得到一個較優的結果,每一次迭代的過程可以描述為:
計算輸入層的加權和,即用輸入矩陣L0乘以權重矩陣syn0,并通過sigmid函數進行歸一化。得到輸出結果l1;
計算輸出結果L1與真實結果y之間的誤差L1_error;
計算權重矩陣的修正L1_delta,即用誤差乘以sigmoid在L處的導數;
用L1_delta更新權重矩陣syn0
此處著重解釋 下第三步,這里利用的是梯度下降法,算法的原理我們暫不深究,只需要明白其目的是為了使迭代后的誤差逐漸減小即可。
一次訓練過程的參數更新如下圖所示:
由于我們的輸入X中一共有四個樣本,我們進行“批量的訓練”,所以其過程類似于下圖所示:
在上述代碼中,我們通過10000次迭代,我們得到的輸出結果如下:
Output syn0 After Training:
[[ 9.67299303]
[-0.2078435 ]
[-4.62963669]]
可以看出,syn0的第一個元素,也就是第一個輸入特征(長發)的權重最大,而第二個和第三個特征都很小,所以神經網絡學習的結果是加重第一個特征的權重,而其他兩個特征對于是女性這個推測的貢獻較小,所以減小其權重。為了驗證訓練結果,我們加入兩組新數據,(短頭發,紅衣服,矮個子),(長頭發,不是紅衣服,矮個子),并用神經網絡來進行分類:
X_new = np.array([[0,1,0],
[1,0,0]])
y_new = np.dot(X_new,syn0)
計算結果如下:
Predicte With syn0:
[[-0.2078435 ]
[ 9.67299303]]
二層神經網絡
上面的例子中,我們只用了一層神經網絡,這只能解決線性問題,而現實中,一個孤立的特征并不是對應一個分類,還是用上面的例子說明:上面的問題中,我們假定了長頭發是女性的概率一定大于男性,高個子是男性的概率一定大于女性,這種假設中,特征和分類是一種確定的關系,而特征之間沒有依賴關系。而現在,我修改這種假設,在穿紅衣服的人群中,長頭發更可能是女性,而在穿其他顏色的衣服中,短頭發更有可能是女性,此時,我們上面的神經網絡模型就失效了,因為我們無法直接建頭發這個輸入特征到性別這個輸入的直接聯系。
為了解決上面的問題,我們需要在加入一層神經網絡,將輸入層的特征進行組合,然后在傳導到輸出層,這就是二層神經網絡的模型,其示意圖如下:
中間加入的這一層佳作隱含層,由于這一層的加入,我們多了一層傳導,所以初始化的時候需要再加入一個權重矩陣:
syn1 = 2*np.random.random((4,1)) - 1
兩層神經網絡的學習更新過程如下:
for j in range(60000):
# Feed forward through layers 0, 1, and 2
l0 = X
l1 = nonlin(np.dot(l0,syn0))
l2 = nonlin(np.dot(l1,syn1))
# how much did we miss the target value?
l2_error = y - l2
if (j% 10000) == 0:
print("Error:" + str(np.mean(np.abs(l2_error))))
# in what direction is the target value?
# were we really sure? if so, don't change too much.
l2_delta = l2_error*nonlin(l2,deriv=True)
# how much did each l1 value contribute to the l2 error (according to the weights)?
l1_error = l2_delta.dot(syn1.T)
# in what direction is the target l1?
# were we really sure? if so, don't change too much.
l1_delta = l1_error * nonlin(l1,deriv=True)
syn1 += l1.T.dot(l2_delta)
syn0 += l0.T.dot(l1_delta)
結合前面的單層神經網絡的實現,就很容易理解上面的代碼了,代碼中,L0的輸出沒有直接作為最終輸出層,而是傳導給了L2層,L2層以相同的方式傳導到輸出層。而更新權重的時候,采用的是相反的過程,先依據L2輸出的誤差,更新syn1,再用L2的誤差乘以syn1,作為L1層的誤差,最后用同樣的方法更新第一層權重矩陣syn0
結語
這篇文章以最簡單的方式構建了一個基本的神經網絡,雖然離實用還相去甚遠,但是已經初現神經網絡的雛形框架,如果需要構建一個實用級別的神經網絡,還需要加入一些其他的功能,原作者建議我們從以下這些概念開始入手,優化我們的神經網絡):
Alpha
Bias Units
Mini-Batches
Delta Trimming
Parameterized Layer Sizes
Regularization
Dropout
Momentum
Batch Normalization
GPU Compatability
其他腦洞
作者:ZPPenny
鏈接:http://www.jianshu.com/p/bfabcc47cb4d
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
- 15張圖閱盡人工智能現狀
- LeCun臺大演講:AI最大缺陷是缺乏常識,無監督學習突破困境
- Google首席科學家談Google是怎么做深度學習的
- 為你的深度學習任務挑選性價比最高GPU
- 史上最全面的深度學習硬件指南
- 機器學習
- 普通程序員如何向人工智能靠攏?
- 從機器學習談起
- 普通程序員如何轉向AI方向
- 機器學習6大算法,優勢劣勢全解析
- 除了 Python ,這些語言寫的機器學習項目也很牛(二)
- 五個鮮為人知,但又不可不知的機器學習開源項目
- 機器學習入門算法:從線性模型到神經網絡
- 機器學習常見算法分類匯總
- 最實用的機器學習算法Top5
- NLP
- Lucene的原理和應用
- 理解和使用自然語言處理之終極指南(Python編碼)(經典收藏版12k字,附數據簡化籌技術人員)
- 神經網絡
- 曾經歷過兩次低谷的人工神經網絡,還會迎來下一個低谷么?
- 人工神經網絡——維基
- 深度學習——維基
- A Neural Network in 11 lines of Python (Part 1)
- 深度學習
- 基于深度學習的機器翻譯
- 谷歌研究員2萬字批駁上海交大用深度學習推斷犯罪分子
- 理解這25個概念,你的「深度學習」才算入門!
- Deep Learning(深度學習)學習筆記整理系列
- 概述、背景、人腦視覺機理
- 特征
- Deep Learning
- Deep Learning 訓練
- Deep Learning(中文)
- 第1章 引言
- 深度學習如何入門?——知乎
- 文章收錄
- 神經系統