代价函数
定义变量
- L是神经网络的总层数
-
sl为第
l层的单元数量(不包括偏置单元)
- K为输出层的单元数量/分类类型数量
表示式子
神经网络的代价函数是正则化逻辑回归的代价函数的概括:
J(θ)=−m1i=1∑mk=1∑K[yk(i)log(hθ(x(i))k)+(1−yk(i))log(1−hθ(x(i))k)]+2mλl=1∑L−1i=1∑sl+1j=1∑sl(Θi,j(l))2
其中,
hθ(x(i))k表示第
k种类型的分类结果(概率),与样本中
yk(i)表示的第
k种类型的实际结果相对应。
反向传播(重点)
“反向传播”是用于最小化我们的代价函数的神经网络术语,就像我们在逻辑和线性回归中使用梯度下降一样。 我们的目标是计算
minΘJ(Θ),也即计算得到能使代价函数最小的模型参数。
代价函数的偏导数
为了求
∂Θi,j(l)∂J(Θ),执行以下步骤:
- 获取训练集
{(x(1),y(1))…(x(m),y(m))},并设
Δi,j(l):=0(也即得到一个元素均为零的矩阵)
- 训练样本
t=1tom,依次执行下列步骤:
2.1 设
a(1):=x(t)
2.2 通过向前传播算法计算
a(l)(forl=2,3,…,L)
2.3 通过样本中的实际分类结果
y(t),计算
δ(L)=a(L)−y(t),其中,
a(L)也即输出层的输出结果(分类结果向量),该式实际为实际分类结果与向前传播计算得到的
a(L)的差值。
2.4 计算
δ(L−1),δ(L−1),…,δ(2),
δ(1)表示第一层输入层的误差:(第一层为训练样本中的输入特征,肯定没有误差,所以不用计算)
δ(l)=((Θ(l))Tδ(l+1)).∗a(l).∗(1−a(l))
2.5
Δi,j(l):=Δi,j(l)+aj(l)δi(l+1),或者用向量法:
Δ(l):=Δ(l)+δi(l+1)(aj(l))T
因此,上述步骤2.1-2.5可以不断更新矩阵
Δ。
最终得到偏导数
∂Θi,j(l)∂J(Θ)=Di,j(l):
{Di,j(l)=m1Δi,j(l)Di,j(l)=m1(Δi,j(l)+λΘi,j(l))if j=0if j̸=0
原理剖析
关于
δj(l)的计算。
J(θ)=−m1t=1∑mk=1∑K[yk(t)log(hθ(x(t))k)+(1−yk(t))log(1−hθ(x(t))k)]+2mλl=1∑L−1i=1∑sl+1j=1∑sl(Θi,j(l))2
令K=1,并忽略惩罚项,有:
cost(t)=yk(t)log(hθ(x(t))k)+(1−yk(t))log(1−hθ(x(t))k)
则,
δj(l)=∂zj(l)∂cost(t)。
从上图可知,反向传播计算时,有
δ2(2)=Θ1,2(2)∗δ1(3)+Θ2,2(2)∗δ2(3)和
δ3(2)=Θ1,2(2)∗δ1(4)
实操经验
多矩阵
在神经网络算法中,可能出现如下矩阵:
Θ(1),Θ(2),Θ(3),…D(1),D(2),D(3),…
但是,如果我们才使用高级的优化算法,比如:fminunc(),那就需要把矩阵摊开成一个向量:
thetaVector = [Theta1(:); Theta2(:); Theta3(:)]; \\
deltaVector = [D1(:); D2(:); D3(:)];
如果矩阵Theta1的尺寸为1011,矩阵Theta2的尺寸为1011,矩阵Theta3的尺寸为1*11,我们可以通过以下步骤重获矩阵:
Theta1 = reshape(thetaVector(1:110),10,11)
Theta2 = reshape(thetaVector(111:220),10,11)
Theta3 = reshape(thetaVector(221:231),1,11)
- 初始化模型参数:
Θ(1),Θ(2),Θ(3),…
- 将模型参数矩阵摊开为initialTheta,传到高级优化算法fminunc(@costFunction, initialTheta, options)
- 在function [jval,gradientVec] costFunction(thetaVec)中,先从thetaVec获取模型参数,然后计算
D(1),D(2),D(3),…,以及
J(Θ),最后展开
D(1),D(2),D(3),…得到gradientVec。
梯度检查
为了检查反向传播算法工作符合预期,将代价函数的偏导数近似于:
αΘαJ(Θ)≈2ϵJ(Θ+ϵ)−J(Θ−ϵ)
对于多个模型参数矩阵,我们对于
Θj的偏导数近似有:
αΘjαJ(Θ)≈2ϵJ(Θ1,…,Θ+ϵ,…,Θn)−J(Θ1,…,Θ−ϵ,…,Θn)
其中,
ϵ的值取得较小,例如
10−4,但是太小可能会遇到数值问题,也即电脑可能无法计算这么小的数值,或者计算时取小数点后四位而忽略了四位后的位数,造成计算错误。
在octave中,代码如下:
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;
我们在计算得到gradApprox后,就可以将其与deltaVector(
D(1),D(2),D(3),…)比较,检查两者之间是否近似。
PS:一旦验证了反向传播算法是正确的,则无需在下次迭代时继续计算gradApprox,因为gradApprox的计算效率低。
随机初始化
将神经网络的权重(模型参数)全都初始为零(或者满足对称性,比如
Θ(1)全初始为零,
Θ(2)全初始为1)的话,会使反向传播时,所有节点将重复更新为相同的值。因此,我们可以使用以下方法随机初始化权重:
在
[−ϵ,ϵ]的范围内随机初始化权重,具体为:
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函数的作用是在0到1之间进行初始化。
PS:上式中的
ϵ与梯度检查中的
ϵ无关。
总结
- 选择网络架构;选择神经网络的布局(每层有多少隐藏单元,以及总共需要有多少层)
- 输入层的单元数量等于输入特征的种数
(x0,x1,…)
- 输出层的单元数量等于输出特征的种数(分类的类数)
- 隐藏层的单元数量越多越好(平衡计算成本)
- 如果有多个隐藏层,建议每个隐藏层的单元数量相等
- 训练神经网络
2.1 随机初始化权重
2.2 向前传播计算所有样本
x(i)的输出
hθ(x(i))。
2.3 计算代价函数
2.4 通过反向传播计算代价函数的偏导数
2.5 使用梯度检查确认反向传播是否有效工作,然后去掉梯度检查步骤
2.6 使用梯度下降或者更高级的优化算法求得使代价函数最小化的权重(模型参数)
- 在向前和向后传播时,我们分别对个训练样本进行操作:
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