利用假期時間閱讀了大牛Michael Nieson編寫的關於神經網路與深度學習的python程式碼network2.py,在這裡把相關的東西寫下來,有助於大家理解。
Network2py閱讀筆記函式load(filename)本函式用來載入神經網路資料。其中,filename是一個JSON格式的檔案,儲存神經網路的代價函式名稱、神經網路的大小、權重和偏置。本函式使用getattr來獲取代價函式物件。本函式使用numpy.array函式來把列表轉化為numpy陣列,以便提高後續操作的速度。numpy中的 array比python的列表效率要高。
函式sigmoid(z)本函式是S型函式。其中,z定義為z=w*a+b,w為神經元的權重,a為輸入神經元的值,b為神經元的偏置值。
函式sigmoid_prime(z)本函式是S型函式的導數。其中,z定義為z=w*a+b,w為神經元的權重,a為輸入神經元的值,b為神經元的偏置值。
函式vectorized_result(j)本函式用來產生一個10維度的向量,向量的每個值也是一個向量,除了第j個向量是[1.0],其它向量都是[0.0]。例如,當j等於0時,結果是:
array([[1.],
[0.],
[0.],
[0.],
[0.],
[0.],
[0.],
[0.],
[0.],
[0.]])
二次代價函式物件QuadraticCost成員函式fn(a, y)@staticmethod 靜態函式,不需要例項即可呼叫。
本函式用來計算輸出的代價。其中,a是輸出層啟用函式的值,y是輸出期望值。
使用到函式np.linalg.norm,用來計算線性代數二範數的值。這裡先計算二範數再平方,相當於先開方然後再平方,有點浪費CPU了,但是通俗易懂。
delta(z, a, y)@staticmethod 靜態函式,不需要例項即可呼叫。
本函式用來計算輸出層的。其中,z定義為,為神經元的權重,為輸入神經元的值,為神經元的偏置值;a是輸出層啟用函式的值,y是輸出期望值。
交叉熵代價函式物件CrossEntropyCost成員函式fn(a, y)@staticmethod 靜態函式,不需要例項即可呼叫。
本函式用來計算輸出的代價。其中,a是輸出層啟用函式的值,y是輸出期望值。
這裡使用np.nan_to_num來確保nan值可以轉化為(0.0)。
delta(z, a, y)@staticmethod 靜態函式,不需要例項即可呼叫。
本函式用來計算輸出層的。其中,z未使用;a是輸出層啟用函式的值,y是輸出期望值。
神經網路物件Network成員變數num_layers整數,神經網路的層數,包括輸入層、隱藏層和輸出層。
sizes列表,列表中的每個數字表示當前層的神經元個數。例如:列表[2, 3, 1]表示num_layers等於3,輸入層2個神經元,隱藏層3個神經元,輸出層1個神經元。
cost代價函式物件,預設是交叉熵代價函式物件。
biases列表,每個元素是一個向量A,向量A的維度是當前層的神經元數目,向量A的元素是向量B,向量B的維度是1。例如:當sizes=[2, 3, 1]時,
[array([[-1.18467892],
[ 0.64330142],
[ 2.51833825]]), array([[-0.38237145]])]
weights列表,每個元素是一個向量A,向量A的維度是當前層的神經元數目,向量A的元素是向量B,向量B的維度是前一層的神經元數目。例如:當sizes=[2, 3, 1]時,
[array([[ 1.36998439, -1.01334963],
[ 0.11534823, 0.93371543],
[-0.57107839, 0.56883094]]), array([[ 0.1750382 , -0.07063372, 0.14115862]])]
成員函式__init__(self, sizes, cost=CrossEntropyCost)本函式用來初始化神經網路的成員變數為預設值。其中,sizes為列表,每個元素指定該層的神經元的個數;cost指定代價函式物件。
default_weight_initializer(self)本函式用來初始預設的偏置和權重。
使用numpy.random.randn(d0, d1)來生成正態分佈的一組隨機數,其中,d0和d2指定向量的維度,如:
np.random.randn(2, 4)
array([[-2.12589545, -0.47298189, 0.08957842, 1.07026475],
[-0.02507939, -0.9636912 , -0.43697501, -0.09704965]])
計算權重時,必須還要除以上一層的神經元個數的開方(不知道為什麼需要這樣)。
large_weight_initializer(self)本函式用來設定偏置和權重。本函式的實現與network.py的一樣,在這裡僅僅用作比較。
feedforward(self, a)本函式實現前向傳播。其中,a是一個numpy陣列,是input層的輸入。
本函式使用numpy的dot方法計算w*a。dot product計算方法:
w = [[1, 2], [3, 4]]
a = [5, 6]
np.dot(w, a) = array([17, 39])
SGD(self, training_data, epochs, mini_batch_size, eta, lmbda = 0.0, evaluation_data=None, monitor_evaluation_cost=False, monitor_evaluation_accuracy=False, monitor_training_cost=False, monitor_training_accuracy=False)本函式用來訓練神經網路。其中,training_data是用了訓練神經網路的資料集,epochs指定訓練幾個回合,每個回合都會把訓練集資料都訓練一次,mini_batch_size指定每次更新網路時必須先多少個樣本,eta是學習速率,lmbda是規範引數,evaluation_data指定用來驗證網路的資料集,其它引數是用了監控訓練情況的。
本函式使用xrange函式來生成一些資料,xgrange的結果是產生一個序列生成器,格式有:
xrange(stop)
xrange(start, stop[, step])
例子:
>>>xrange(8)
xrange(8)
>>> list(xrange(8))
[0, 1, 2, 3, 4, 5, 6, 7]
>>> range(8) # range 使用
[0, 1, 2, 3, 4, 5, 6, 7]
>>> xrange(3, 5)
xrange(3, 5)
>>> list(xrange(3,5))
[3, 4]
>>> range(3,5) # 使用 range
[3, 4]
>>> xrange(0,6,2)
xrange(0, 6, 2) # 步長為 2
>>> list(xrange(0,6,2))
[0, 2, 4]
本函式沒其它特殊的值得注意的東西。
update_mini_batch(self, mini_batch, eta, lmbda, n)本函式使用一小批資料來進行反向傳播,並更新權重和偏置。其中,mini_batch是用來學習的一批資料,eta是學習速率,lmbda是規範引數,n是總的訓練資料。
請參考公式(98)。
backprop(self, x, y)本函式實現方向傳播。其中,x是一個numpy陣列,是input層的輸入,y是一個numpy陣列,是output層的啟用輸出的期望值。本函式返回所有偏置和權重的相對於代價函式的梯度(斜率)。
本函式使用到numpy中的zeros函式來初始化返回資料;偏置和權重都是列表,列表中的元素是numpy的陣列,此陣列就是由zeros來初始化。
本函式的反向傳播過程是這樣的,首先前向傳播,計算出所有的z和a;然後根據代價函式來計算-1層的梯度,接著使用PB2~4的公式計算各層的梯度,以達到計算所有層梯度的目的。
accuracy(self, data, convert=False)本函式用來計算準確度。其中,data是用來計算的資料集,convert是用了指定如何計算,即當資料集是訓練資料時,應該設定為True,其它設定為False。
本函式返回前向傳播和結果相等的計數。
本函式使用到numpy中的argmax來返回陣列中第一次出現的最大值的索引號(從0開始)。
total_cost(self, data, lmbda, convert=False)本函式用來計算總誤差。其中,data是用來計算的資料集,lmbda是規範化引數,convert是用了指定如何計算,即當資料集是訓練資料時,應該設定為False,其它設定為True。
請參考公式(85)和(86)。
save(self, filename)本函式用來以JSON格式儲存神經網路。