首页 > 推荐 > BP神经网络判定笑傲江湖人物门派

BP神经网络判定笑傲江湖人物门派

沧海一声笑

滔滔两岸潮

浮沉随浪只记今朝

苍天笑

纷纷世上潮

谁负谁胜出天知晓

江山笑

烟雨遥

涛浪淘尽红尘俗事知多少

啦......

 

朋友圈的热点纷纷扰扰,转眼间满屏都是向Andrew Ng(吴恩达)同志学习,占领机器学习阵地的帖子。翻看一下Coursera的课程目录,默默从积灰的书堆底下翻出十多年前的《人工神经网络》教材,过上一把怀旧瘾。

 

金庸大侠笔下《笑傲江湖》一书中,既有正邪之判,复存门户之别,少林、武当、青城、五岳自诩正教与魔教(日月神教)誓不两立,出场人物的权谋武功高下各有不同。加之华山派气宗剑宗分野,嵩山派耗时数年搜集整理各派剑法遗存,葵花宝典化身辟邪剑法重现江湖……无疑加深了识别人物门派的难度,本文尝试BP神经网络算法(误差反向传播,Error Back Propagation)予以求解。

 

训练数据

输出结果

构造一个BP神经网络,根据人物的权谋、内功、剑法、轻功特征判断是否出自华山派。

 

  • 神经元模型

神经网络中最基本的成分是神经元模型。取一组二进制输入值(附近的神经元),将每个输入值乘以一个连续值权重(每个附近神经元的突触强度),并设立一个阈值,如果这些加权输入值的和超过这个阈值,就输出1,否则输出0(同理于神经元是否放电)。


  • BP算法的基本思想

通过计算输出结果和期望输出的误差来间接调整隐含层的权值,学习过程由信号的正向传播与误差的反向传播两个过程组成。

-   正向传播时,输入样本从输入层传入,经各隐含层逐层处理后,传向输出层。若输出层的实际输出与期望的输出不符,则转入误差的反向传播阶段。

-   反向传播时,将输出以某种形式通过隐含层向输入层逐层反传,并将误差分摊给各层的所有单元,作为修正各单元权值的依据。

Python代码解析

  • 正向传播(1~5步)

1.设定输入数组X 和输出数组Y


2.初始化连接权值和阈值

wh 隐含层权值

bh 隐含层阈值

wout 输出层权值

bout 输出层阈值


3.  计算输入数组与隐含层权值的点积,加上阈值(线性变换)

hidden_layer_input= matrix_dot_product(X,wh)+ bh


4.  采用Sigmoid激活函数进行非线性变换f(x)=1/(1 + exp(-x)).

hiddenlayer_activations= sigmoid(hidden_layer_input)

 

5.  对隐含层激活函数的结果进行线性变换,求出与输出层权值的点积,再加上输出层阈值。通过Sigmoid函数预测输出值。

output_layer_input =matrix_dot_product (hiddenlayer_activations * wout ) + bout

output =sigmoid(output_layer_input)

 

  • 反向传播(6~12步)

6. 将预测结果与实际结果进行比较,其中误差损失函数表示为 ((Y-t)^2)/2

E = y – output


7.  计算隐含层与输出层神经元的梯度

slope_output_layer =derivatives_sigmoid(output)

slope_hidden_layer =derivatives_sigmoid(hiddenlayer_activations)

 

8.  将误差乘以输出层的梯度,得出输出层的调整因子

d_output = E *slope_output_layer

 

9.  将误差反向传播到隐含层,计算输出层调整因子与隐含层至输出层连接权值的点积。

Error_at_hidden_layer= matrix_dot_product(d_output, wout.Transpose)

 

10.  继续计算隐含层的调整因子,求出隐含层误差与隐含层梯度的点积。

d_hiddenlayer =Error_at_hidden_layer * slope_hidden_layer

 

11.  借助前几步得出的调整因子,更新隐含层与输出层连接的权值

wout = wout +matrix_dot_product(hiddenlayer_activations.Transpose, d_output)*learning_rate

wh =  wh +matrix_dot_product(X.Transpose,d_hiddenlayer)*learning_rate

 

12.  最后更新隐含层和输出层的阈值

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 Feb11 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 ofSigmoid Function

defderivatives_sigmoid(x):

    return x * (1 - x)

 

#Variableinitialization

epoch=5000 #Settingtraining iterations

lr=0.1 #Settinglearning 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 biasinitialization

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 inrange(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]]