以一个单隐层神经网络作二分类为例,如图: python
1.先简单介绍一个各个参数:算法
m:表示样本数量。bash
y:各个样本真实值,维度为m*1网络
:表示第l层的神经元个数。app
:表示第l层的输入变量,也是第l-1层
通过激活函数处理后的结果。其维度通常为
dom
:表示第l层权重参数,其维度通常为
函数
:表示第l层偏置量参数,其维度通常为
学习
:表示第l层线性变换后的结果,其维度通常为
ui
2.前向传播计算过程:spa
一是线性变换,为第一个隐藏层的第i个隐藏单元参数,
为第一个隐藏层的第i个隐藏单元偏置量;
第二步是激活函数,非线性变换,而且将数值变换到0-1之间,本例选择sigmoid函数做为激活函数。
3.反向传播过程,更新参数值:
反向传播是利用链式法则对各个参数求偏导数的过程。咱们的训练目标是使得损失函数最小化,神经网络中利用梯度降低法更新参数w和b使得损失函数L值最小化。了解梯度降低的话,应该知道梯度降低中更新参数的办法是使得各个参数按必定步长(学习率)沿着函数降低最快的方向(因为梯度方向就是函数上升最快的方向,所以函数降低最快的方向就是梯度反方向)移动,直到找到全局或局部最优解为止。
首先要清楚
与
的来源:
#f为一种激活函数
那么接下来求第k层和第k-1层的w与b的偏导数。
一是求=
,定义
为第k层的偏差项,反映了该层对最终总偏差的影响。根据链式法则:
=
=
![]()
二是求 和
:
=
所以求第k层的偏导数依赖于第k+1层的偏导数的值,体现了反向传播的意义。
=
而后更新参数为:
在屡次循环迭代中,不断执行前向传播计算损失函数值与反向传播更新参数,最终使得损失在必定范围内。
#coding:utf-8
#BP算法的python实现
import numpy as np
def sigmoid(x):
return 1/(1+np.exp(-x))
def derivative(x):
return (1-x)*x
class nn(object):
def __init__(self,layer):
np.random.seed(2)
self.w=[]
for i in range(1,len(layer)):
# np.random.random((1000,20))表明生成1000行 20列的浮点数,浮点数都是从0-1中随机。
self.w.append(2*np.random.random((layer[i-1],layer[i]))-1)
def train(self,x,y,lr,echo):
a=[x]
for ech in range(echo):
for i in range(0,len(self.w)):
a.append(sigmoid(np.dot(a[i],self.w[i])))
if(ech%100==0):
print('echo',ech,'-error %f:',np.mean((a[-1]-y)**2))
l_error=-(y-a[-1])
for k in range(len(self.w)-1,-1,-1):
l_delta = l_error*derivative(np.array(a[k+1]))
w_update=np.dot(a[k].T,l_delta)
l_error=np.dot(l_delta,self.w[k].T)
self.w[k]-=lr*w_update
return self.w
def predict(self,w,test):
l1 = sigmoid(np.dot(test, self.w[0]))
l2 = sigmoid(np.dot(l1, self.w[1]))
if l2 >= 0.5:
print(l2,"1")
else:
print(l2,"0")
layer=[3,4,1]
x = np.array([[0, 0, 1],[0, 1, 1],[1, 0, 1],[1, 1, 1],[0, 0, 1]])
y = np.array([[0],[1],[1],[0],[0]])
nn=nn(layer)
w=nn.train(x,y,0.1,2000)
nn.predict(w,[1,1,0])
复制代码
待更新
复制代码