神经网络中的前向后向传播算法
神经网络中的代价函数与后向传播算法
代价(损失)函数
依照惯例,我们仍然首先定义一些我们需要的变量:
L:网络中的总层数,\(s_l\):在第l层所有单元(units)的数目(不包含偏置单元),k:输出单元(类)的数目
回想一下,在神经网络中,我们可能有很多输出节点。 我们将\(h_\Theta(x)_k\)表示为导致第k个输出的假设。 我们的神经网络的成本函数将是我们用于逻辑回归的一般化。 回想一下,正则逻辑回归的成本函数是:
注意:
- 两级求和公式是对于输出层的每个单元的逻辑回归代价函数相加求和
- 三级求和是将所有的\(\Theta\)平方后求和
- 这里i在三级求和中不是代表第i个案例,而是第l层所有单元(units)的数目(不包含偏置单元)
后向传播算法
“反向传播”是用于最小化成本函数的神经网络术语,就像之前在逻辑和线性回归中的梯度下降一样。 Goal--目标是计算:\(min_\Theta J(\Theta)\)
也就是说,我们想使用θ中的最佳参数集来最小化我们的成本函数J。 用来计算J(Θ)的偏导数的方程:
由上,我们利用以下的算法:
(2)利用前向传播算法来计算\(a^{(l)}\),其中l=2,3,...,L。具体的计算流程为:
(4)依次计算\(\delta^{(L-1)},\delta^{(L-2)},...,\delta^{(2)}\),主要利用\(\delta^{(l)}=((\Theta^{(l)})^T\delta^{(l+1)}).*a^{(l)}.*(1-a^{(l)})\)
层L的δ是通过在与层L的θ矩阵下一层的δ相乘来计算。 接着以元素方式乘以一个称为g'的函数,该值是使用\(z^{(l)}\)给出的输入值进行评估的激励函数g的导数,即\(g'(z^{(l)})=a^{(l)}.*(1-a^{(l)})\)。
(5)\(Δ_{i,j}^{(l)}:=Δ_{i,j}^{(l)}+a_j^{(l)}\delta_i^{l+1}\)
或者向量化为:\(\Delta^{(l)}:=\Delta^{(l)}+\delta^{(l+1)}(a^{(l)})^T\)
因此,我们一下总结的公式进行更新:
直观了解-后向传播
一直以来。神经网络的代价函数为:
\(cost(t)=y^{(t)}log(h_\Theta(x^{(t)}))+(1-y^{(t)})log(1-h_\Theta(x^{(t)}))\)
直观感受下:\(\delta_j^{(l)}\)是第l层j单元\(a_j^{(l)}\)的误差,为代价函数的偏微分:
后向传播算法的实际应用
实现注意事项:展开参数
对于神经网络,我们有以下矩阵集:
\(\Theta^{(1)},\Theta^{(2)},\Theta^{(3)}...\)
\(D^{(1)},D^{(2)},D^{(3)}...\)
为了使用诸如“fminunc()”的优化函数,首先要“展开”所有元素并将它们放入一个长向量中:
thetaVector = [ Theta1(:); Theta2(:); Theta3(:); ]
deltaVector = [ D1(:); D2(:); D3(:) ]
如果参数Theta1的维度为10*11,Theta2的维度为10*11,Theta3的维度为1*11,我们可以按照以下的方式展开矩阵:
Theta1 = reshape(thetaVector(1:110),10,11)
Theta2 = reshape(thetaVector(111:220),10,11)
Theta3 = reshape(thetaVector(221:231),1,11)
总结如下:
梯度检查将确保我们的反向传播按预期工作。 我们可以用以下方法近似我们的成本函数的导数:
epsilon = 1e-4;
for i = 1:n,
thetaPlus = theta;
thetaPlus(i) += epsilon;
thetaMinus = theta;
thetaMinus(i) -= epsilon;
gradApprox(i) = (J(thetaPlus) - J(thetaMinus))/(2*epsilon)
end;
我们以前看过如何计算deltaVector。 所以一旦我们计算了我们的gradApprox向量,我们可以检查gradApprox≈deltaVector。一旦验证了您的反向传播算法是否正确,您就不需要再次计算gradApprox实际上计算gradApprox的代码可能非常慢。
随机初始化
将所有theta权重初始化为零不适用于神经网络(当权重初始化为零时,可以推出随着梯度的不断更新,参数会回到原始值,即神经网络的性能下降)。 当我们反向传播时,所有节点将重复更新为相同的值。 相反,我们可以使用以下方法随机初始化我们的Θ矩阵的权重:
If the dimensions of Theta1 is 10x11, Theta2 is 10x11 and Theta3 is 1x11.
Theta1 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
Theta2 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
Theta3 = rand(1,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
rand(x,y)只是octave软件中自带的一个随机函数,生成值在0-1之间。
(知识点汇集)Putting it together
首先,挑选出一种NN架构:选择你的NN的层数,包含在每一层中所出现的隐藏单元数量,与你一共想拥有多少层。
-
输入单元数=特征集\(x^{(i)}\)的维度
-
输出层单元数=欲分类的数目
-
每层的隐藏单元数=一般越多越好-性能越佳(随着隐藏单元数目的增加,相应地必须增加计算量)
-
默认:包含一个隐藏层。如果,多余一个隐藏层,建议在每一个隐藏层拥有相同的单元数
训练一个神经网络
1.随机初始化权重
2.利用前向传播函数对每个\(x^{(i)}\)计算假设值\(h_\Theta(x^{(i)})\)
3.计算代价函数
4.通过后向传播函数计算偏微分值
5.使用梯度检查确认您的反向传播是否有效。 然后禁用梯度检查。
6.使用梯度下降或内置优化函数,以最小化theta中权重的成本函数。
在前向和后向传播的计算中,对每一个训练样本都做相同的循环计算:
for i = 1:m,
Perform forward propagation and backpropagation using example (x(i),y(i))
(Get activations a(l) and delta terms d(l) for l = 2,...,L
下图给出了实现神经网络发生的具体过程: