神经网络方法的可视化步骤
我们将重复上述步骤,可视化输入,权重,偏差,输出,误差矩阵,以了解神经网络(MLP)的工作方法。
- 注意:
- 对于良好的可视化图像,我有2或3个位置的十进制小数位。
- 黄色填充的细胞代表当前活动细胞
- 橙色单元格表示用于填充当前单元格值的输入
- 步骤1:读取输入和输出
Step 1
- 步骤2:用随机值初始化权重和偏差(有初始化权重和偏差的方法,但是现在用随机值初始化)
Step 2
- 步骤3:计算隐层输入:
hidden_layer_input= matrix_dot_product(X,wh) + bh
Step 3
- 步骤4:对隐藏的线性输入进行非线性变换
hiddenlayer_activations = sigmoid(hidden_layer_input)
Step 4
- 步骤5:在输出层执行隐层激活的线性和非线性变换
output_layer_input = matrix_dot_product (hiddenlayer_activations * wout ) + bout
output = sigmoid(output_layer_input)
Step 5
- 步骤6:计算输出层的误差(E)梯度
E = y-output
Step 6
- 步骤7:计算输出和隐藏层的斜率
Slope_output_layer= derivatives_sigmoid(output)
Slope_hidden_layer = derivatives_sigmoid(hiddenlayer_activations)
py26-10.png
- 步骤8:计算输出层的增量
d_output = E * slope_output_layer*lr
py26-11.png
- 步骤9:计算隐藏层的误差
Error_at_hidden_layer = matrix_dot_product(d_output, wout.Transpose)
py26-12.png
- 步骤10:计算隐藏层的增量
d_hiddenlayer = Error_at_hidden_layer * slope_hidden_layer
py26-13.png
- 步骤11:更新输出和隐藏层的权重
wout = wout + matrix_dot_product(hiddenlayer_activations.Transpose, d_output)*learning_rate
wh = wh+ matrix_dot_product(X.Transpose,d_hiddenlayer)*learning_rate
py26-14.png
- 步骤12:更新输出和隐藏层的偏置量
bh = bh + sum(d_hiddenlayer, axis=0) * learning_rate
bout = bout + sum(d_output, axis=0)*learning_rate
py26-15.png
以上,您可以看到仍然有一个很好的误差而不接近于实际目标值,因为我们已经完成了一次训练迭代。 如果我们多次训练模型,那么这将是一个非常接近的实际结果。 我完成了数千次迭代,我的结果接近实际的目标值([[0.98032096] [0.96845624] [0.04532167]]
)。
使用Numpy(Python)实现NN
import numpy as np #Input array X=np.array([[1,0,1,0],[1,0,1,1],[0,1,0,1]]) #Output y=np.array([[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 of Forward Propogation:\n{}".format(output)) print("wout,bout of Backpropagation:\n{},\n{}".format(wout,bout))
output of Forward Propogation: [[ 0.98497471] [ 0.96956956] [ 0.0416628 ]] wout,bout of Backpropagation: [[ 3.34342103] [-1.97924327] [ 3.90636787]], [[-1.71231223]]
在R中实现NN
# input matrix X=matrix(c(1,0,1,0,1,0,1,1,0,1,0,1),nrow = 3, ncol=4,byrow = TRUE) # output matrix Y=matrix(c(1,1,0),byrow=FALSE) #sigmoid function sigmoid<-function(x){ 1/(1+exp(-x)) } # derivative of sigmoid function derivatives_sigmoid<-function(x){ x*(1-x) } # variable initialization epoch=5000 lr=0.1 inputlayer_neurons=ncol(X) hiddenlayer_neurons=3 output_neurons=1 #weight and bias initialization wh=matrix( rnorm(inputlayer_neurons*hiddenlayer_neurons,mean=0,sd=1), inputlayer_neurons, hiddenlayer_neurons) bias_in=runif(hiddenlayer_neurons) bias_in_temp=rep(bias_in, nrow(X)) bh=matrix(bias_in_temp, nrow = nrow(X), byrow = FALSE) wout=matrix( rnorm(hiddenlayer_neurons*output_neurons,mean=0,sd=1), hiddenlayer_neurons, output_neurons) bias_out=runif(output_neurons) bias_out_temp=rep(bias_out,nrow(X)) bout=matrix(bias_out_temp,nrow = nrow(X),byrow = FALSE) # forward propagation for(i in 1:epoch){ hidden_layer_input1= X%*%wh hidden_layer_input=hidden_layer_input1+bh hidden_layer_activations=sigmoid(hidden_layer_input) output_layer_input1=hidden_layer_activations%*%wout output_layer_input=output_layer_input1+bout output= sigmoid(output_layer_input) # Back Propagation E=Y-output slope_output_layer=derivatives_sigmoid(output) slope_hidden_layer=derivatives_sigmoid(hidden_layer_activations) d_output=E*slope_output_layer Error_at_hidden_layer=d_output%*%t(wout) d_hiddenlayer=Error_at_hidden_layer*slope_hidden_layer wout= wout + (t(hidden_layer_activations)%*%d_output)*lr bout= bout+rowSums(d_output)*lr wh = wh +(t(X)%*%d_hiddenlayer)*lr bh = bh + rowSums(d_hiddenlayer)*lr } output
[可选]反向传播算法的数学理解
设Wi为输入层和隐层之间的权重。 Wh是隐层和输出层之间的权重。
现在,h =σ(u)=σ(WiX)
,即h是u的函数,u是Wi和X的函数。这里我们将我们的函数表示为σ
Y =σ(u')=σ(Whh)
,即Y是u'的函数,u'是Wh和h的函数。
我们将不断参考上述方程来计算偏导数。
我们主要感兴趣的是找到两个项:∂E/∂Wi和∂E/∂Wh即改变输入和隐藏层之间权重的误差变化,改变隐层和输出之间权重的变化 层。
但是为了计算这两个偏导数,我们将需要使用部分微分的链规则,因为E是Y的函数,Y是u'的函数,u'是Wi的函数。
让我们把这个属性很好的用于计算梯度。
`∂E/∂Wh = (∂E/∂Y).( ∂Y/∂u’).( ∂u’/∂Wh), ……..(1)
We know E is of the form E=(Y-t)2/2.
So, (∂E/∂Y)= (Y-t)`
现在,σ是一个S形函数,并具有σ(1-σ)形式的有意义的区分。 我敦促读者在他们身边进行验证。
所以, (∂Y/∂u’)= ∂( σ(u’)/ ∂u’= σ(u’)(1- σ(u’))
.
但是, σ(u’)=Y, So
,
(∂Y/∂u’)=Y(1-Y)
现在得出, ( ∂u’/∂Wh)= ∂( Whh)/ ∂Wh = h
取代等式(1)中的值我们得到,
∂E/∂Wh = (Y-t). Y(1-Y).h
所以,现在我们已经计算了隐层和输出层之间的梯度。 现在是计算输入层和隐藏层之间的梯度的时候了。
∂E/∂Wi =(∂ E/∂ h). (∂h/∂u).( ∂u/∂Wi)
但是,(∂ E/∂ h) = (∂E/∂Y).( ∂Y/∂u’).( ∂u’/∂h)
. 在上述方程中替换这个值得到:
∂E/∂Wi =[(∂E/∂Y).( ∂Y/∂u’).( ∂u’/∂h)]. (∂h/∂u).( ∂u/∂Wi)……………(2)
那么,首先计算隐层和输出层之间的梯度有什么好处?
如等式(2)所示,我们已经计算出∂E/∂Y和∂Y/∂u'节省了空间和计算时间。 我们会在一段时间内知道为什么这个算法称为反向传播算法。
让我们计算公式(2)中的未知导数。
∂u’/∂h = ∂(Whh)/ ∂h = Wh
∂h/∂u = ∂( σ(u)/ ∂u= σ(u)(1- σ(u))
但是, σ(u)=h, So,
(∂Y/∂u)=h(1-h)
得出, ∂u/∂Wi = ∂(WiX)/ ∂Wi = X
取代等式(2)中的所有这些值,我们得到:
∂E/∂Wi = [(Y-t). Y(1-Y).Wh].h(1-h).X
所以现在,由于我们已经计算了两个梯度,所以权重可以更新为:
Wh = Wh + η . ∂E/∂Wh
Wi = Wi + η . ∂E/∂Wi
其中η是学习率。
所以回到这个问题:为什么这个算法叫做反向传播算法?
原因是:如果您注意到∂E/∂Wh和∂E/∂Wi的最终形式,您将看到术语(Yt)即输出错误,这是我们开始的,然后将其传播回输入 层重量更新。
那么,这个数学在哪里适合代码?
hiddenlayer_activations= H
E = Y-t
Slope_output_layer = Y(1-Y)
lr =η
slope_hidden_layer = h(1-h)
wout = Wh
现在,您可以轻松地将代码与数学联系起来。
结束语
本文主要从头开始构建神经网络,并了解其基本概念。 我希望你现在可以理解神经网络的工作,如前向和后向传播的工作,优化算法(全批次和随机梯度下降),如何更新权重和偏差,Excel中每个步骤的可视化以及建立在python和R的代码.
因此,在即将到来的文章中,我将解释在Python中使用神经网络的应用,并解决与以下问题相关的现实生活中的挑战:
- 计算机视觉
- 言语
- 自然语言处理
我在写这篇文章的时候感到很愉快,并希望从你的反馈中学习。 你觉得这篇文章有用吗? 感谢您的建议/意见。 请随时通过以下意见提出您的问题。
(转载请注明来源)