码迷,mamicode.com
首页 > 其他好文 > 详细

BP神经网

时间:2018-03-14 20:06:43      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:一起   过程   shape   numpy   tps   book   for   checked   error:   

本文针对https://yoyoyohamapi.gitbooks.io/mit-ml/content/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C/codes/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E8%AE%BE%E8%AE%A1.html
对其中神经网络一些解释,用于自己以后理解方便。
BP神经网,是最简单的神经网,其中的感知机,也是很有意思滴,其他的高级神经网,以后再针对学习。BP神经网包括输入层,隐藏层,输出层,基本知识看吴恩达coursera上的教学视频
以下就是BP神经网的建立过程,其中有详细的解释
# coding = utf-8
import numpy as np

def sigmoid(z):
#sigmoid函数,激励函数
return 1/(1 + np.exp(-z))

def sigmoidderivate(a):
#d对激励函数求导
return np.multiply(a,(1-a))

def initThetas(hiddenNum, unitNum, inputSize, classNum, epsilon):
‘‘‘
随机初始化权值矩阵
:param hiddenNum: 隐藏层数目
:param unitNum: 每个隐藏层的神经元数目
:param inputSize: 输入层单元个数
:param classNum: 分类数目,即输出层的单元数目
:param epsilon: 收敛精度
:return: thetas
‘‘‘
hiddens = [unitNum for i in range(hiddenNum)]
#每个隐藏层的单元数组,定义的是每个隐藏层的单元数相等,将他们按照隐藏层的个数,展开成矩阵
units = [inputSize] + hiddens + [classNum]
#将输入层,隐藏层,输出层的单元数,形成新的矩阵
thetas = []
#建立一个空权值矩阵,两层之间有一个,所有比units少一个
for idx,unit in enumerate(units):#对含有每层单元数的个数的矩阵进行遍历,idx从0开始到len(units)-1,
if idx == len(units) - 1:#已经遍历到输出层,跳出
break
nextUnit = units[idx + 1]
theta = np.random.rand(nextUnit,unit + 1)*2*epsilon - epsilon#只要是随机的就行,
#随机数模块,的rand函数产生随机数,nextunit 是下一层的单元数,不包括偏置单位,unit +1 是当前层的单元数,包括偏执单位,因为在传播
# 过程中,才会用到偏置单位,来获得激活向量,然后再加上偏置单位向前传播
#随机生成,nextunit行,unit+1(包含bias term)列,该层上的神经元,分别有一组theta,结合起来,成为matrix
#运算过程取一行一行运算
thetas.append(theta)
#依次将theta,键入到thetas中
return thetas
#定义参数展开与参数还原函数
def unroll(matrixes):
‘‘‘

:param matrixes:接受矩阵
:return: 返回向量,是列向量
‘‘‘
vec = []
for matrix in matrixes:
vector = matrix.reshape(1,-1)[0]#将矩阵转化为一列,不加0变成行向量
vec = np.concatenate((vec , vector))#将两个向量拼接一起,列向量累加
return vec

def roll(vector , shapes):
‘‘‘

:param vector:
:param shapes: 形状列表
:return:
‘‘‘
matrixes = []
begin = 0
for shape in shapes:
end = begin + shape[0]*shape[1]
matrix = vector[begin:end].reshape(shape)
begin = end
matrixes.append(matrix)
return matrixes
def fp(Thetas , X):
‘‘‘
前向传播
:param Thetas: 权值矩阵
:param X: 输入样本
:return: a 各层激活向量
‘‘‘
layers = list(range(len(Thetas) + 1))#按层数形成一系列连续的值,层数的值比thetas的多一个
layerNum = len(layers)#总共多少层
a = list(range(layerNum))#对每层标号化,记录a,不支持对range的直接遍历,需要加list,列表限制
for l in layers:
#根据前向传播公式计算
if l == 0:
a[l] = X.T
else :
z = Thetas[l-1]*a[l-1]#根据输入层,一层一层地推
a[l] = sigmoid(z)
if l != layerNum - 1:#除去最后一层输出层,其他层都要加入偏置项
a[l] = np.concatenate((np.ones((1,a[l].shape[1])),a[l]))
return a
def comuteCost(Thetas , y , thelamda , X = None , a = None):
‘‘‘
代价函数
:param Thetas: q权值矩阵
:param y: 标签集
:param thelamda: 修正
:param X: 样本
:param a: 各层激活值
:return: 预测的代价
‘‘‘
m = y.shape[0]
if a is None:
a = fp(Thetas , X)
error = -np.sum(np.multiply(y.T,np.log(a[-1])) + np.multiply((1-y).T,np.log(1-a[-1])))
reg = -np.sum([np.sum(theta[:,1:])for theta in Thetas])
return (1.0/m)*error + (1.0/(2*m))*thelamda*reg
def bp(Thetas , a , y , thelamda):
‘‘‘
反向传播
:param Thetas:
:param a:
:param y:
:param thelamda:
:return: D权值梯度
‘‘‘
m = y.shape[0]
layers = list(range(len(Thetas) + 1))
layerNum = len(layers)
d = list(range(layerNum))
delta = [np.zeros(theta.shape)for theta in Thetas]
#根据不同的theta,,初始化
for l in layers[::-1]:#翻转,用来反向传播
if l == 0:
break
if l == layerNum - 1:
d[l] = a[l] - y.T
else:#忽略偏置
d[l] = np.multiply((Thetas[l][:,1:]).T*d[l+1]),sigmoidderivate(a[l][1:,:])
# 对thetas矩阵,取除去第一列后面的,因为,计算偏差时不考虑偏置单位,,取求导后的除去第一行的
# 因为忽略偏置,所以选取theta【l】,从第一列开始,后面的也是
#以上计算出误差
for l in layers[0:layerNum-1]:
delta[l] = d[l+1]*(a[l].T)
#计算出权值梯度
D = [np.zeros(theta.shape)for theta in Thetas]
for l in list(range(len(Thetas))):
Theta = Thetas[l]
D[l][:,0] = (1.0/m)*(delta[l][0:,0].reshape(1,-1))#reshape可加可不加,是吧变成一列,本身就是一个
D[l][:,1:] = (1.0/m)*(delta[l][0:,1:] + thelamda*Theta[:,1:])
#分别对偏执单位和不是偏执单位进行,权值更新增量的研究
return D
def updateThetas(m , Thetas , D , alpaha , theLamda):
‘‘‘
权值更新
:param m:
:param Thetas:
:param D:
:param alpaha:
:param theLamda:
:return:
‘‘‘
for l in range(len(Thetas)):
Thetas[l] = Thetas[l]-alpaha*D[l]
return Thetas
def gradientDescent(Thetas , X, y , alpha , thelamda):
‘‘‘
梯度下降过程
:param Thetas:
:param X:
:param y:
:param alpha:
:param thelamda:
:return:
‘‘‘
m ,n = X.shape
a = fp(Thetas , X)
D = bp(Thetas , a ,y, thelamda)
J = comuteCost(Thetas,y,thelamda,a=a)
Thetas = updateThetas(m,Thetas,D,alpha,thelamda)
if np.isnan(J):
J = np.inf
return J,Thetas
def gradientCheck(Thetas , X , y , thelamda):
‘‘‘
梯度检验过程
:param Thetas:
:param X:
:param y:
:param thelamda:
:return:
‘‘‘
m , n = X.shape
a = fp(Thetas , X)
D = bp(Thetas , a , y , thelamda)
J = comuteCost(Thetas , y , thelamda , a=a)
Dvec = unroll(D)
epsilon = 1e-4
gradApprox = np.zeros(Dvec.shape)
ThetaVec = unroll(Thetas)
shapes = [theta.shape for theta in Thetas]
for i,item in enumerate(ThetaVec):
ThetaVec[i] = item - epsilon
JMinus = comuteCost(roll(ThetaVec , shapes),y ,thelamda,X=X)
ThetaVec[i] = item + epsilon
Jplus = comuteCost(roll(ThetaVec , shapes),y ,thelamda,X=X)
gradApprox[i] = (Jplus - JMinus)/(2*epsilon)
diff = np.linalg.norm(gradApprox - Dvec)
if diff < 1e-2:
return True
else:
return False
def adjustLabel(y):
#保证标签集是逻辑标识
if y.shape[1] == 1:
classes = set(np.ravel(y))#集合表示,重复代替
classNum = len(classes)
minClass = min(classes)
if classNum>2:
yAdjusted = np.zeros((y.shape[0],classNum),np.float64)
for row ,label in enumerate(y):
yAdjusted[row , label - minClass] = 1
else:
yAdjusted = np.zeros((y.shape[0], 1), np.float64)
for row, label in enumerate(y):
if label != minClass:
yAdjusted[row, 0] = 1.0
return yAdjusted
return y
def train(X , y , Thetas = None, hiddenNum = 0, unitNum = 5 , epsilon = 1 , alpha = 1 , thelamda = 0 , precision = 0.01 , maxIters = 50):
m , n =X.shape
y = adjustLabel(y)
classNum = y.shape[1]
if Thetas is None:
Thetas = initThetas(inputSize=n , hiddenNum=hiddenNum , unitNum=unitNum , classNum=classNum , epsilon=epsilon)
#进行梯度检验
print(‘doing gradient Check‘)
checked = gradientCheck(Thetas , X , y , thelamda)
if checked:
for i in range(maxIters):
error, thetas = gradientDescent(Thetas, X, y, alpha=alpha, thelamda=thelamda)
if error < precision:
break
if error == np.inf:
break
if error < precision:
success = True
else:
success =False
return {‘error‘:error,‘Thetas‘:thetas,‘iters‘:i,‘success‘:error}
else:
print(‘Error:Gradient Failed‘)
return{‘error‘:None,‘Thetas‘:None,‘iters‘:0,‘success‘:False}

def predict(X ,Thetas):
a = fp(Thetas , X)
return a[-1]
定义好我们的BP神经网,下面的我们用来实现一个逻辑and
# coding = utf-8
import neural
import numpy as np
data = np.mat([[0 , 0 ,0],[0 , 1 , 0],[1 , 0 ,0],[1 ,1 , 1]])
data1 = np.mat([[0 , 0 ],[0 , 1 ],[1 , 0],[1 ,1 ]])
print(data1)
X = data[:,0:2]
y = data[:,2]
res = neural.train(X ,y , hiddenNum = 0 , alpha = 10 , maxIters = 5000 , precision = 0.01)
print(‘Run %d iterations ‘%res[‘iters‘])
print(‘Error is : %.4f‘%res[‘error‘])
print(‘Thetas is : ‘,res[‘Thetas‘][0])
print(neural.predict(data1 , res[‘Thetas‘][0]))
输出结果为
doing gradient Check Run 164 iterations Error is : 0.0100 Thetas is : [[-13.00390967 8.55548574 8.55548578]] [[2.25150445e-06 1.15617505e-02 1.15617501e-02 9.83810364e-01]]
结果显示,权值向量theta,以及我们对and的预测,预测结果概率值较高,说明不错
总体上 BP神经网在层数较少是,感觉还是很好的,文章仅为个人理解,,谢谢。转载请注明出处。

δ(l)Δ(l)D(l)i,j={a(l)?y(Θ(l)δ(l+1))T.?g(z(l))l=Ll=2,3,...,L?1=δ(l+1)(a(l))T=?????1m(Δ(l)i,j+λΘ(l)i,j),if j01mΔ(l)ij,if j=0

BP神经网

标签:一起   过程   shape   numpy   tps   book   for   checked   error:   

原文地址:https://www.cnblogs.com/zhang-rong-cheng/p/8569664.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!