Darknet 正向预测与反向传播

本文深入探讨了Darknet框架中的神经网络正向预测与反向传播机制,通过数学公式和源码分析,详细讲解了全联接层与卷积层的工作原理,包括梯度计算和权重更新过程。

Darknet 正向预测与反向传播

这篇文章是没有配图的,很多事情,配图反而说不清楚。
关于正向与反向传播,我仅仅类比梯度下降一个做计算,并结合源码。但这样做的意义和效果不做分析。能力有限。更不知道网络每一层到底干了什么。玄学

∑k=1n∂f(x)∂xkcosβk \sum_{k=1}^n\frac{\partial f(x)}{\partial x_k}cos \beta_kk=1nxkf(x)cosβk
其中:
∑k=1ncos2βk=1\sum_{k=1}^ncos^2\beta_k=1k=1ncos2βk=1
则:
∑k=1n∂f(x)∂xicosβi≤(∑k=1n(∂f(x)∂xi)2)(∑k=1ncos2βk) \sum_{k=1}^n\frac{\partial f(x)}{\partial x_i}cos \beta_i\leq \Big(\sum_{k=1}^{n}\Big(\frac{\partial f(x)}{\partial x_i}\Big)^2\Big)\Big(\sum_{k=1}^{n}cos^2\beta_k\Big)k=1nxif(x)cosβi(k=1n(xif(x))2)(k=1ncos2βk)
梯度下降很简单,根据施瓦茨不等式和全微分知识,我门可以知道,对于连续函数,梯度方向是其曾长最快的方向,这里最快有点瞬时的味道,就是说只仅限于当前点,那么反向是其下降最快的方向。而沿着与梯度正交的方向运动,则相当于沿着等势面运动。此时函数值不变。
沿着梯度反方向搜索,可以保证函数值下降,直到梯度消失,当梯度消失时,算法结束在一个极小值点。有人说不存在最优结果,对于训练集来说。这样理解是不对的。其实只能说有时候不存在解析解,最优解还是存在的,因为losslossloss函数是有下界的。

全联接层其实可以看作是特殊的卷积层。你也可以叫他不全联接。我觉得这个名字不错。

全联接层

全联接层的前向

(如果不知道什么是全联接可以百度,介绍还是比较多的)
ctc_tctttt层神经元个数,全联接运算矩阵表示:
[wt(0,0)wt(0,1)…wt(0,ct−1)wt(1,0)wt(1,1)…wt(1,ct−1)⋮⋮⋱⋮wt(ct,0)wt(ct,1)…wt(ct,ct−1)][yt−1(0)yt−1(1)⋮yt−1(ct−1)]=vt \left[\begin{matrix} w_t(0,0)&w_t(0,1)&\dots&w_t(0,c_{t-1})\\ w_t(1,0)&w_t(1,1)&\dots&w_t(1,c_{t-1})\\ \vdots&\vdots&\ddots &\vdots\\ w_t(c_t,0)&w_t(c_t,1)&\dots&w_t(c_t,c_{t-1}) \end{matrix}\right]\left[\begin{matrix}y_{t-1}(0)\\ y_{t-1}(1)\\ \vdots\\ y_{t-1}(c_{t-1}) \end{matrix}\right]=v_twt(0,0)wt(1,0)wt(ct,0)wt(0,1)wt(1,1)wt(ct,1)wt(0,ct1)wt(1,ct1)wt(ct,ct1)yt1(0)yt1(1)yt1(ct1)=vt
这里,yt−1y_{t-1}yt1是上一层输出,wtw_twt表示各个突触权重。vtv_tvt就是还未激活的信号(局部诱导域)。

记:φt(vt)=[φt(vt(0))φt(vt(1))⋮φt(vt(ct))]\varphi_t(v_t)=\left[\begin{matrix}\varphi_t(v_{t}(0))\\ \varphi_t(v_{t}(1))\\ \vdots\\ \varphi_t(v_{t}(c_t)) \end{matrix}\right]φt(vt)=φt(vt(0))φt(vt(1))φt(vt(ct))
其中φt\varphi_tφt表示第ttt层的激活函数。
简化矩阵表示为:
vt=wtyt−1yt=φt(vt)v_t=w_ty_{t-1}\\ y_t=\varphi_t(v_t)vt=wtyt1yt=φt(vt)

这部分操作于代码是对应的。

void forward_connected_layer(connected_layer l, network_state state)
{
    int i;
    fill_cpu(l.outputs*l.batch, 0, l.output, 1);
    int m = l.batch;
    int k = l.inputs;
    int n = l.outputs;
    float *a = state.input;
    float *b = l.weights;
    float *c = l.output;
    gemm(0, 1, m, n, k, 1, a, k, b, k, 1, c, n);
    activate_array(l.output, l.outputs*l.batch, l.activation);
}

上面代码删掉了batch normalizebatch\ normalizebatch normalize部分的代码。这部分代码可以先不用看。
其中,gemmgemmgemm函数负责矩阵乘法。batchbatchbatch是训练用的参数,可以自行百度。在预测时,这个数值被强行置为111.
gemmgemmgemm的前两个参数表示矩阵是否进行转置。mmm表述数据个数。n,kn,kn,k为维度答案保存在ccc中,也就是l.outputl.outputl.output.
对应关系:
c:vts:yt−1activate_array():φ(vt)c :v_t \\ s : y_{t-1}\\ activate\_array():\varphi(v_t)c:vts:yt1activate_array():φ(vt)

全联接层的反向传播

这里以batch=1batch=1batch=1来考虑定义每一层的代价函数:
Jt=12∑k=0ct(dt(k)−yt(k))2=12[et,et]et(k)=dt(k)−yt(k)J_t=\frac{1}{2}\sum_{k=0}^{c_t}(d_t(k)-y_t(k))^2=\frac{1}{2}[e_t,e_t]\\ e_t(k)=d_t(k)-y_t(k)Jt=21k=0ct(dt(k)yt(k))2=21[et,et]et(k)=dt(k)yt(k)
其中,dt(k)d_t(k)dt(k)是我门期望的第ttt层的输出。对于最后一层输出层来说,这个期望就是我门的标注数据。
ttt为输出层,也就是说,我门可以直接获得期望输出和实输出的误差ete_tet
那么可以很方便的计算最外层的权重梯度∇Jt\nabla J_tJt
∂Jt∂wt(a,b)=∑k=0ctet(k)∂et(k)∂wt(a,b)=∑k=0ctet(k)∂et(k)∂vt(k)∂vt(k)∂wt(a,b)=−et(a)φt′(vt(a))∂∑iwt(a,i)yt−1(i)∂wt(a,b)=−et(a)φt′(vt(a))yt−1(b)\frac{\partial J_t}{\partial w_t(a,b)}=\sum_{k=0}^{c_t}e_t(k)\frac{\partial e_t(k)}{\partial w_t(a,b)}=\sum_{k=0}^{c_t}e_t(k)\frac{\partial e_t(k)}{\partial v_t(k)}\frac{\partial v_t(k)}{\partial w_t(a,b)}\\ =-e_t(a)\varphi'_t(v_t(a))\frac{\partial \sum_{i}w_{t}(a,i)y_{t-1}(i)}{\partial w_t(a,b)}\\= -e_t(a)\varphi'_t(v_t(a))y_{t-1}(b)wt(a,b)Jt=k=0ctet(k)wt(a,b)et(k)=k=0ctet(k)vt(k)et(k)wt(a,b)vt(k)=et(a)φt(vt(a))wt(a,b)i

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值