Minipatch从零开始的反向传播

北京最佳皮肤科医院 http://disease.39.net/bjzkbdfyy/210805/9278663.html

文章将重点介绍mini-patch逐步实现的反向传播算法。有许多教程和博客详细介绍了反向传播算法,以及演算和代数背后的所有逻辑。因此,我将跳过这一部分,并在数学和使用Python的实现中切入方程式。

关于为什么我们应该从头开始实现一个算法,即使几乎所有框架都已经可以使用它,这也是一个长期存在的普遍问题。显然,在使用某些高级框架时,你甚至都不会注意到反向传播确实发挥了魔力。要完全颠倒地理解它,一次尝试肯定是不够的。反向传播在游戏中也是可以进行实验的。

为什么要使用mini-patch?

mini-patch的原理很简单。通过将数据分成小批处理,并在训练循环的每次迭代中为算法提供一部分数据集,可以节省内存和处理时间。一次馈入x矩阵不仅会消耗内存,还会花费很长时间才能运行。相反,每次迭代将其降低到50个不仅会减少内存使用量,而且可以跟踪进度。

注意:这与随机方法不同,在随机方法中,我们从每个类别的数据中抽取了分层样本,并在假设模型可以推广的基础上进行训练。

开始实验

这是将用于实验的数据头。

此处的目标变量是占用率,它是类别变量(0/1)。这将是我们将要编码的架构。

算法:

对于i:=1到i:=m:

执行正向传播或正向传递以计算每一层中神经元的激活值。

反向传播步骤:

使用数据中的标签计算误差项(MSE或LogLoss或您的期望):

隐藏层中的误差项使用以下公式计算:

设置梯度:初始化Δ=0

3.梯度下降和权重更新步骤:

代码展示:

weight_dim=[5,H,1]#[numberofinputfeatures,numberofhiddenunits,numberofoutputunits]print(InitializingusingHeinitialization)np.random.seed(3)w1=np.random.randn(weight_dim[1],weight_dim[0])*np.sqrt(2/weight_dim[0])#0.01b1=np.zeros((weight_dim[1],1))w2=np.random.randn(weight_dim[2],weight_dim[1])*np.sqrt(2/weight_dim[1])#0.01b2=np.zeros((weight_dim[2],1))

如前所述,这将是一个三层网络。为了使梯度和误差方程更好,更容易地识别,我们保持层的数量简洁。之后,我们将定义一个函数,该函数将用作网络中的转发器。

defforward(X,w1,w2,b1,b2):z1=np.matmul(w1,np.transpose(np.asmatrix(X)))+b1a1=sigmoid(z1)z2=np.matmul(w2,a1)+b2a2=sigmoid(z2)returnz1,a1,z2,a2

这里要注意的一件事是,已经将Input层视为我的第0层。可能还有其他博客/教程被认为是第一名。因此,绝对要为所需的索引编制索引。

因此,现在,在初始化权重和偏差并定义前向传播函数之后,我们将在size=data-of-setset/N的mini-patch上定义反向传播函数。通过调整N来调整所需的批次大小。

defbackprop(w1,b1,w2,b2,X_train,X_test):foriinrange(epoch):no_of_batches=len(X_train)//Nforjinrange(no_of_batches):#Initilazinggradientsdelta1=np.zeros(w1.shape)#(5,5)delta2=np.zeros(w2.shape)#(1,5)db1=0.0db2=0.0forrowinrange(j*N,(j+1)*N):#DropthedatecolumnandtheindexcolumnX=X_train[row,2:7]Y=X_train[row,7]#feedforwardz1,a1,z2,a2=forward(X,w1,w2,b1,b2)#(5,1)(5,1)(1,1)(1,1)h=a2#(1,1)#initializationsd3=a2-Y#(1,1)delta2+=d3*np.transpose(a2)#(1,1)db2+=d3d2=np.multiply((np.transpose(w2)*d3),sigmoid_gradient(z1),dtype=float)#(5,1)delta1+=d2*np.transpose(a1)#(5,5)db1+=d2#GradientDescentStep#updatingweightsaftereverybatchbyaveragingthegradientsw1=w1-lr*1.0/N*delta1#takingtheaverageofgradientsb1=b1-lr*1.0/N*db1w2=w2-lr*1.0/N*delta1b2=b2-lr*1.0/N*db2print(************************************************)print(Trainerrorafterepoch{}is:.format(i),np.sum(error(calc_out(X_train[:,2:7],w1,b1,w2,b2),X_train[:,7]))/len(X_train)*)print(Testerrorafterepoch{}is:.format(i),np.sum(error(calc_out(X_test[:,2:7],w1,b1,w2,b2),X_test[:,7]))/len(X_test)*)print(************************************************)print()train_error[i]=np.sum(error(calc_out(X_train[:,2:7],w1,b1,w2,b2),X_train[:,7]))/len(X_train)*test_error[i]=np.sum(error(calc_out(X_test[:,2:7],w1,b1,w2,b2),X_test[:,7]))/len(X_test)*return[w1,b1,w2,b2]

步骤分解

如前所述,Ist循环会遍历您想要使模型遍历数据的次数,只需将其放在神经网络术语“时代”中即可。第二次循环:指定了批次数量后,此循环针对每个时期“i”遍历每个微型批次第三循环遍历该小批量中的每个训练示例,并计算梯度和误差值最后,对于每个批次,都执行梯度下降步骤,并对权重矩阵进行更改。这就是mini-patch的反向传播实现。需要注意的是,此实验为网络中的每一层使用了一个矩阵变量,当网络规模扩大时,这是一种不明智的做法,我们这样做是为了了解它的实际工作原理。如果要增加“隐藏层”的数量,可以简单地使用3d矩阵进行误差和梯度计算,其中第3维将保存该层的值。




转载请注明:http://www.aierlanlan.com/grrz/2804.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了