神经网络已经被开发来模仿人脑。尽管我们还不存在,但神经网络在机器学习中非常有效。它在80年代和90年代很流行。最近,它变得越来越流行。可能是因为计算机速度足够快,可以在合理的时间内运行大型神经网络。在本文中,我将讨论如何在Python中从头开始开发神经网络算法。我建议仔细阅读“神经网络思想”部分。但是,如果您不清楚,请不要担心。继续本节。我把它分解成小块。此外,自己运行所有代码将使您更加清晰。神经网络如何工作在一个简单的神经网络中,神经元是计算的基本单位。他们获取输入特征并将其作为输出输出。一个基本的神经网络看起来像这样:这里,“layer1”是输入特征。“第1层”转到另一个节点layer2,最终输出预测的类或假设。Layer2是隐藏层。您可以使用多个隐藏层。您必须根据数据集和精度要求设计神经网络。前向传播从第1层移动到第3层的过程称为前向传播。前向传播步骤:(1)初始化每个输入特征的系数theta。假设有10个输入特征。比如说,我们有100个训练样本。这意味着100行数据。在这种情况下,我们的输入矩阵大小为100x10。现在,您确定theta1的大小。行数必须与输入要素的数量相同。在此示例中,该值为10。列数应为您选择的隐藏层的大小。(2)将输入特征X乘以对应的theta,然后加上一个偏置项。通过激活函数传递结果。有几种可用的激活函数,例如sigmoid、tanh、relu、softmax、swish我将使用sigmoid激活函数来演示神经网络。这里,“a”代表隐藏层或layer2,b是偏差。g(z)是一个sigmoid激活函数:(3)初始化隐藏层的theta2。大小将是隐藏层的长度乘以输出类的数量。在这个例子中,下一层是输出层,因为我们没有更多的隐藏层。(4)然后,我们需要遵循与之前相同的过程。Theta与隐藏层相乘,然后通过sigmoid激活层以获得假设或预测输出。Backpropagation反向传播是从输出层移动到layer2的过程。在此过程中,我们计算误差。(1)首先,将原输出y减去假设。那将是我们的增量。(2)现在,计算theta2的梯度。将delta3乘以theta2。将其乘以“a2”乘以“1-a2”。在下面的公式中,“a”上的上标2表示layer2。请不要把它误认为是正方形。(3)根据训练样本数m,从divingdelta计算梯度的非归一化形式。训练网络修改theta。Theta1是通过将输入特征乘以学习率乘以delta2得到的。注意theta的大小。重复前向传播和反向传播的过程,不断更新参数,直到达到最优代价。这是成本函数的公式。提醒一下,成本函数表示预测与原始输出变量的距离。如果您注意到,这个成本函数公式几乎类似于逻辑回归成本函数。神经网络实施我将使用来自AndrewNg在Coursera上的机器学习课程的数据集。欢迎从以下链接下载数据集:https://github.com/rashida048/Machine-Learning-With-Python/blob/master/ex3d1.xlsx这是实现神经网络的分步方法.我鼓励您自己运行每一行代码并打印输出以更好地理解它。(1)首先导入必要的包和数据集。importpandasaspdimportnumpyasnpxls=pd.ExcelFile('ex3d1.xlsx')df=pd.read_excel(xls,'X',header=None)这是数据集的前五行。这些是数字的像素值。请随意下载数据集并继续操作:在此数据集中,输入和输出变量组织在单独的Excel工作表中。让我们将输出变量导入笔记本:y=pd.read_excel(xls,'y',header=None)这也只是数据集的前五行。输出变量是一个介于1和10之间的数字。该项目的目标是使用存储在“df”中的输入变量来预测一个数字。(2)求输入变量和输出变量的维度df.shapey.shape输入变量或df的形状为5000x400,输出变量或y的形状为5000x1。(3)定义神经网络为了简单起见,我们只使用一个包含25个神经元的隐藏层。hidden_??layer=25找出输出类。yy_arr=y[0].unique()#Output:array([10,1,2,3,4,5,6,7,8,9],dtype=int64)如上图有10个输出类.(4)初始化θ和偏置我们将随机初始化layer1和layer2的theta。由于我们有三层,所以会有theta1和theta2。theta1的形状:第1层的大小x第2层的大小theta2的形状:第2层的大小x第3层的大小从第2步开始,“df”的形状为5000x400。这意味着有400个输入特征。所以layer1的大小为400。由于我们将隐藏层的大小指定为25,因此layer2的大小为25。我们有10个输出类。因此,layer3的大小为10。theta1的形状:400x25theta2的形状:25x10同样,将有两个随机初始化的偏置项b1和b2。b1的形状:layer2的大小(本例中为25)b2的形状:layer3的大小(本例中为10)定义一个随机初始化theta的函数:defrandInitializeWeights(Lin,Lout):epi=(6**1/2)/(Lin+Lout)**0.5w=np.random.rand(Lout,Lin)*(2*epi)-epireturnw使用这个函数并初始化thetahidden_??layer=25output=10theta1=randInitializeWeights(len(df.T),hidden_??layer)theta2=randInitializeWeights(hidden_??layer,output)theta=[theta1,theta2]现在,如上所述,初始化偏置项:b1=np.random.randn(25,)b2=np.random.randn(10,)(5)使用前向传播部分中的公式实现前向传播。为方便起见,定义了一个函数defz_calc(X,theta)将theta和X相乘:returnnp.dot(X,theta.T)我们还将多次使用激活函数。还有sigmoid激活函数defsigmoid(z):return1/(1+np.exp(-z))下面一步步演示前向传播。首先计算z项:z1=z_calc(df,theta1)+b1现在把这个z1通过激活函数得到我们的隐藏层a1=sigmoid(z1)a1就是隐藏层。a1的形状为5000x25。重复同样的过程,计算layer3或输出层的shapez2=z_calc(a1,theta2)+b2a2=sigmoid(z2)a2为5000x10。10列代表10个类。a2是我们的layer3或最终输出或假设。如果此示例中有更多隐藏层,则将重复相同的过程以从一层转移到另一层。使用输入特征计算输出层的过程称为前向传播。将它们放入一个函数中,这样我们就可以对任意数量的层执行前向传播:l=3#theumberoflayersb=[b1,b2]defhypothesis(df,theta):a=[]z=[]foriinrange(0,l-1):z1=z_calc(df,theta[i])+b[i]out=sigmoid(z1)a.append(out)z.append(z1)df=outreturnout,a,z(6)实现反向传播这个是向后计算梯度和更新theta的过程。在此之前,我们需要修改“y”。“y”有10个等级。但是我们需要将每个类分成它的列。例如,第一列是第10类。对于其余类,我们将10替换为1,将0替换为它。这样我们将为每个类创建一个单独的列。y1=np.zeros([len(df),len(y_arr)])y1=pd.DataFrame(y1)foriinrange(0,len(y_arr)):forjinrange(0,len(y1)):ify[0][j]==y_arr[i]:y1.iloc[j,i]=1else:y1.iloc[j,i]=0y1.head()下面我先一步步演示前向传播,然后把这一切都变成了一个函数,对于反向传播,我也会这样做。使用上面反向传播部分的梯度公式,首先计算delta3。我们将使用前向传递实现中的z1、z2、a1和a2。del3=y1-a2现在,使用以下公式计算delta2:这是delta2:del2=np.dot(del3,theta2)*a1*(1-a1)这里我们需要学习一个新概念。那是一个S形渐变。sigmoid梯度的公式为:如果您注意到,这与增量公式中的a(1—a)完全相同。因为a是sigmoid(z)。因为约定俗成,当我把它们全部组合起来写函数的时候,我会把delta2公式中的a(1-a)项换成这个sigmoid梯度。它们完全一样。我只是想演示两个。让我们为sigmoid梯度编写一个函数:defsigmoid_grad(z):returnssigmoid(z)*(1-sigmoid(z))最后,是时候使用以下公式更新theta:我们需要选择学习率。我选择了0.003。我鼓励您尝试其他学习率以查看效果:theta1=np.dot(del2.T,pd.DataFrame(a1))*0.003theta2=np.dot(del3.T,pd.DataFrame(a2))*0.003这就是theta需要更新的方式。这个过程称为反向传播,因为它向后移动。在编写反向传播函数之前,我们需要定义成本函数。因为我在反向传播方法中也包含了成本的计算。虽然可以在forwardpass中加入,但是在训练网络的时候也可以分开。这是成本函数方法defcost_function(y,y_calc,l):return(np.sum(np.sum(-np.log(y_calc)*y-np.log(1-y_calc)*(1-y))))/m其中m是训练样本的数量。把它们放在一起:y1=np.zeros([len(df),len(y_arr)])y1=pd.DataFrame(y1)foriinrange(0,len(y_arr)):forjinrange(0,len(y1)):ify[0][j]==y_arr[i]:y1.iloc[j,i]=1else:y1.iloc[j,i]=0y1.head()(7)训练网络我会训练20个网络时代。我将在此代码片段中再次初始化theta。因为我已经使用了theta并更新了它。所以如果我不再次初始化它,我最终会从更新的theta开始。但我想重新开始。theta1=randInitializeWeights(len(df.T),hidden_??layer)theta2=randInitializeWeights(hidden_??layer,output)theta=[theta1,theta2]cost_list=[]foriinrange(20):theta,cost=backpropagation(df,theta,y1,0.003)cost_list.append(cost)cost_list我使用了0.003的学习率并运行了20个epochs。但是请查看下面提供的GitHub链接。我尝试了不同的学习率和不同的时代,终于到了这里。我们得到在每个时期计算的成本列表和最终更新的theta。使用这个最终的theta来预测输出。(8)预测输出并计算准确率只需使用假设函数传递这个更新后的theta来预测输出:out,a,z=hypothesis(df,theta)现在计算准确率,accuracy=0foriinrange(0,len(out)):forjinrange(0,len(out[i])):ifout[i][j]>=0.5andy1.iloc[i,j]==1:accuracy+=1accuracy/len(df)精度是100%。完美,对吧?然而,我们并不总能获得100%的准确率。有时,获得70%的准确率已经很不错了,具体取决于数据集。恭喜!你刚刚开发了一个完整的神经网络!结论对于比较简单的分类问题,逻辑回归还是很有效的!但对于更复杂的问题,神经网络可以给出更好的结果。如您所见,它通过向前和向后传播更好地学习训练数据。在自然语言处理和图像分类方面,神经网络在AI行业表现非常出色。这是Github上的完整工作代码链接:https://github.com/rashida048/Machine-Learning-With-Python/blob/master/NeuralNetworkFinal.ipynb
