滄海一聲笑
滔滔兩岸潮
浮沉隨浪只記今朝
蒼天笑
紛紛世上潮
誰負誰勝出天知曉
江山笑
煙雨遙
濤浪淘盡紅塵俗事知多少
啦......
朋友圈的熱點紛紛擾擾戚哎,轉眼間滿屏都是向Andrew Ng(吳恩達)同志學習裸诽,占領機器學習陣地的帖子。翻看一下Coursera的課程目錄型凳,默默從積灰的書堆底下翻出十多年前的《人工神經(jīng)網(wǎng)絡》教材丈冬,過上一把懷舊癮。
金庸大俠筆下《笑傲江湖》一書中甘畅,既有正邪之判埂蕊,復存門戶之別往弓,少林、武當蓄氧、青城函似、五岳自詡正教與魔教(日月神教)誓不兩立,出場人物的權謀武功高下各有不同喉童。加之華山派氣宗劍宗分野撇寞,嵩山派耗時數(shù)年搜集整理各派劍法遺存,葵花寶典化身辟邪劍法重現(xiàn)江湖……無疑加深了識別人物門派的難度堂氯,本文嘗試BP神經(jīng)網(wǎng)絡算法(誤差反向傳播蔑担,Error Back Propagation)予以求解。
訓練數(shù)據(jù)
輸出結果
構造一個BP神經(jīng)網(wǎng)絡咽白,根據(jù)人物的權謀啤握、內功、劍法晶框、輕功特征判斷是否出自華山派恨统。
l 神經(jīng)元模型
?神經(jīng)網(wǎng)絡中最基本的成分是神經(jīng)元模型。取一組二進制輸入值(附近的神經(jīng)元)三妈,將每個輸入值乘以一個連續(xù)值權重(每個附近神經(jīng)元的突觸強度)苫纤,并設立一個閾值万栅,如果這些加權輸入值的和超過這個閾值材泄,就輸出1染簇,否則輸出0(同理于神經(jīng)元是否放電)。
l BP算法的基本思想
通過計算輸出結果和期望輸出的誤差來間接調整隱含層的權值,學習過程由信號的正向傳播與誤差的反向傳播兩個過程組成模燥。
正向傳播時,輸入樣本從輸入層傳入,經(jīng)各隱含層逐層處理后,傳向輸出層咖祭。若輸出層的實際輸出與期望的輸出不符,則轉入誤差的反向傳播階段。
-
反向傳播時蔫骂,將輸出以某種形式通過隱含層向輸入層逐層反傳,并將誤差分攤給各層的所有單元,作為修正各單元權值的依據(jù)么翰。
Python代碼解析
l 正向傳播(1~5步)
設定輸入數(shù)組X 和輸出數(shù)組Y
初始化連接權值和閾值
wh 隱含層權值
bh 隱含層閾值
wout 輸出層權值
bout 輸出層閾值
- 計算輸入數(shù)組與隱含層權值的點積,加上閾值(線性變換)
hidden_layer_input= matrix_dot_product(X,wh) + bh
- 采用Sigmoid激活函數(shù)進行非線性變換f(x)=1/(1 + exp(-x)).
hiddenlayer_activations = sigmoid(hidden_layer_input)
- 對隱含層激活函數(shù)的結果進行線性變換辽旋,求出與輸出層權值的點積浩嫌,再加上輸出層閾值。通過Sigmoid函數(shù)預測輸出值补胚。
output_layer_input = matrix_dot_product (hiddenlayer_activations * wout ) + bout
output = sigmoid(output_layer_input)
l 反向傳播(6~12步)
- 將預測結果與實際結果進行比較码耐,其中誤差損失函數(shù)表示為 ((Y-t)^2)/2
E = y – output
- 計算隱含層與輸出層神經(jīng)元的梯度
slope_output_layer = derivatives_sigmoid(output)
slope_hidden_layer = derivatives_sigmoid(hiddenlayer_activations)
- 將誤差乘以輸出層的梯度,得出輸出層的調整因子
d_output = E * slope_output_layer
- 將誤差反向傳播到隱含層溶其,計算輸出層調整因子與隱含層至輸出層連接權值的點積骚腥。
Error_at_hidden_layer = matrix_dot_product(d_output, wout.Transpose)
- 繼續(xù)計算隱含層的調整因子,求出隱含層誤差與隱含層梯度的點積瓶逃。
d_hiddenlayer = Error_at_hidden_layer * slope_hidden_layer
- 借助前幾步得出的調整因子束铭,更新隱含層與輸出層連接的權值
wout = wout + matrix_dot_product(hiddenlayer_activations.Transpose, d_output)*learning_rate
wh = wh + matrix_dot_product(X.Transpose,d_hiddenlayer)*learning_rate
- 最后更新隱含層和輸出層的閾值
bias at output_layer =bias at output_layer + sum of delta of output_layer at row-wise * learning_rate
bias at hidden_layer =bias at hidden_layer + sum of delta of output_layer at row-wise * learning_rate
bh = bh + sum(d_hiddenlayer, axis=0) * learning_rate
bout = bout + sum(d_output, axis=0)*learning_rate
Python源代碼
# -*- coding: utf-8 -*-
"""
Created on Sun Feb 11 22:42:30 2018
@author: vincentqiao
"""
import numpy as np
#Input array
X=np.array([[1,1,1,1],[1,1,1,0],[0,1,1,0],[1,0,1,1]])
#Output
y=np.array([[0],[1],[1],[0]])
#Sigmoid Function
def sigmoid (x):
return 1/(1 + np.exp(-x))
#Derivative of Sigmoid Function
def derivatives_sigmoid(x):
return x * (1 - x)
#Variable initialization
epoch=5000 #Setting training iterations
lr=0.1 #Setting learning rate
inputlayer_neurons = X.shape[1] #number of features in data set
hiddenlayer_neurons = 3 #number of hidden layers neurons
output_neurons = 1 #number of neurons at output layer
#weight and bias initialization
wh=np.random.uniform(size=(inputlayer_neurons,hiddenlayer_neurons))
bh=np.random.uniform(size=(1,hiddenlayer_neurons))
wout=np.random.uniform(size=(hiddenlayer_neurons,output_neurons))
bout=np.random.uniform(size=(1,output_neurons))
for i in range(epoch):
#Forward Propogation
hidden_layer_input1=np.dot(X,wh)
hidden_layer_input=hidden_layer_input1 + bh
hiddenlayer_activations = sigmoid(hidden_layer_input)
output_layer_input1=np.dot(hiddenlayer_activations,wout)
output_layer_input= output_layer_input1+ bout
output = sigmoid(output_layer_input)
#Backpropagation
E = y-output
slope_output_layer = derivatives_sigmoid(output)
slope_hidden_layer = derivatives_sigmoid(hiddenlayer_activations)
d_output = E * slope_output_layer
Error_at_hidden_layer = d_output.dot(wout.T)
d_hiddenlayer = Error_at_hidden_layer * slope_hidden_layer
wout += hiddenlayer_activations.T.dot(d_output) *lr
bout += np.sum(d_output, axis=0,keepdims=True) *lr
wh += X.T.dot(d_hiddenlayer) *lr
bh += np.sum(d_hiddenlayer, axis=0,keepdims=True) *lr
print (output)
輸出結果
[[ 0.03964938]
[ 0.96135949]
[ 0.98159661]
[ 0.01767599]]