为了获得隐藏层的最终值,我们需要应用激活函数。激活函数的作用是引入非线性。这样做的一个优点是输出从0到1的范围映射,使得将来更容易改变权重。
那里有很多激活功能。在这种情况下,我们将坚持一个更受欢迎的--Sigmoid函数。
现在,我们需要再次使用矩阵乘法和另一组随机权重来计算我们的输出图层值。
(.9994*.4)+(1.000*.5)+(.9984*.9)=1.79832
最后,为了标准化输出,我们再次应用激活函数。
S(1.79832)=.8579443067
而且,你去了!理论上,用这些权重,out神经网络将计算.85为我们的测试分数!但是,我们的目标是.92。我们的结果并不差,但它不是最好的。当我为这个例子选择随机权重时,我们有点幸运。
我们如何训练我们的模型来学习?那么,我们很快就会发现。现在,我们来统计我们的网络编码。
如果您仍然感到困惑,我强烈建议您查看这个带有相同示例的神经网络结构的信息性视频。
实施计算
现在,让我们随机生成我们的权重np.random.randn()。请记住,我们需要两组权重。一个从输入到隐藏层,另一个从隐藏层到输出层。
#weights
self.W1=np.random.randn(self.inputSize,self.hiddenSize)#(3x2)weightmatrixfrominputtohiddenlayer
self.W2=np.random.randn(self.hiddenSize,self.outputSize)#(3x1)weightmatrixfromhiddentooutputlayer
一旦我们有了所有的变量,我们就可以编写我们的forward传播函数了。让我们传入我们的输入,X在这个例子中,我们可以使用变量z来模拟输入层和输出层之间的活动。正如所解释的那样,我们需要获取输入和权重的点积,应用激活函数,取另一个隐藏层的点积和第二组权重,最后应用最终激活函数来接收我们的输出:
defforward(self,X):
#forwardpropagationthroughournetwork
self.z=np.dot(X,self.W1)#dotproductofX(input)andfirstsetof3x2weights
self.z2=self.sigmoid(self.z)#activationfunction
self.z3=np.dot(self.z2,self.W2)#dotproductofhiddenlayer(z2)andsecondsetof3x1weights
o=self.sigmoid(self.z3)#finalactivationfunction
returno
最后,我们需要定义我们的sigmoid函数:
defsigmoid(self,s):
#activationfunction
return1/(1+np.exp(-s))
我们终于得到它了!一个能够产生输出的(未经训练的)神经网络。
importnumpyasnp
#X=(hourssleeping,hoursstudying),y=scoreontest
X=np.array(([2,9],[1,5],[3,6]),dtype=float)
y=np.array(([92],[86],[89]),dtype=float)
#scaleunits
X=X/np.amax(X,axis=0)#maximumofXarray
y=y/100#maxtestscoreis100
classNeural_Network(object):
def__init__(self):
#parameters
self.inputSize=2
self.outputSize=1
self.hiddenSize=3
#weights
self.W1=np.random.randn(self.inputSize,self.hiddenSize)#(3x2)weightmatrixfrominputtohiddenlayer
self.W2=np.random.randn(self.hiddenSize,self.outputSize)#(3x1)weightmatrixfromhiddentooutputlayer
defforward(self,X):
#forwardpropagationthroughournetwork
self.z=np.dot(X,self.W1)#dotproductofX(input)andfirstsetof3x2weights
self.z2=self.sigmoid(self.z)#activationfunction
self.z3=np.dot(self.z2,self.W2)#dotproductofhiddenlayer(z2)andsecondsetof3x1weights
o=self.sigmoid(self.z3)#finalactivationfunction
returno
defsigmoid(self,s):
#activationfunction
return1/(1+np.exp(-s))
NN=Neural_Network()
#definingouroutput
o=NN.forward(X)
print"PredictedOutput:\n"+str(o)
print"ActualOutput:\n"+str(y)
正如您可能已经注意到的那样,我们需要训练我们的网络来计算更准确的结果。
反向传播
由于我们有一组随机的权重,我们需要对它们进行修改,以使我们的输入等于我们数据集的相应输出。这是通过一种称为反向传播的方法完成的。
反向传播通过使用丢失函数来计算网络与目标输出的距离。
在这个函数中,o是我们的预测输出,并且y是我们的实际输出。既然我们有损失函数,那么我们的目标就是尽可能接近零。这意味着我们将需要接近完全没有损失。当我们正在训练我们的网络时,我们所做的一切就是尽量减少损失。
为了找出改变我们的权重的方向,我们需要找出我们的损失相对于权重的变化率。换句话说,我们需要使用损失函数的导数来理解权重如何影响输入。
在这种情况下,我们将使用偏导数来允许我们考虑另一个变量。