此篇博客承接上一篇的内容,在上一篇博客中,通过基本定义以及公式实现了对一个简单网络的梯度求解,在这篇博客将,将会更多的利用网络图来实现参数梯度的求解。
要完成此篇网络图的梯度推导需要有一定的基础知识,下面给出知乎中对于softmax的损失函数的讲解以及网络图推导梯度所需要的一些基础。这里给出比较重要的内容:
softmax的损失函数loss公式:
回传流中的模式:
加法门单元把输出的梯度相等地分发给它所有的输入,这一行为与输入值在前向传播时的值无关。这是因为加法操作的局部梯度都是简单的+1,所以所有输入的梯度实际上就等于输出的梯度,因为乘以1.0保持不变。上例中,加法门把梯度2.00不变且相等地路由给了两个输入。
取最大值门单元对梯度做路由。和加法门不同,取最大值门将梯度转给其中一个输入,这个输入是在前向传播中值最大的那个输入。这是因为在取最大值门中,最高值的局部梯度是1.0,其余的是0。上例中,取最大值门将梯度2.00转给了z变量,因为z的值比w高,于是w的梯度保持为0。
乘法门单元相对不容易解释。它的局部梯度就是输入值,但是是相互交换之后的,然后根据链式法则乘以输出值的梯度。
下面来看网络中的数据流向(黑实线为前向传播,红虚线为反向传播过程):
这里我省略了softmax的函数对全连接网络输出的求导,如果不了解可以查看前面给出的链接。
现在假设我们求出了并命名为df(以分母命名,代表Loss值对f进行求导,后面的命名也是类似的意思,方便表示)。根据数据网络梯度推算的原理,因为,所以可以算出X*W的梯度和b的梯度db,进而求得X和W的梯度dX和dW。要注意的是,因为是矩阵相乘,在程序中需要注意维度问题。
代码中的维度细节
假设输入的维度为(N,D),的维度为(D,H),的维度为(,H),那么容易得和和的维度都相同且为(N,H),为(N,H),因为是加法,所以和的梯度都完全相同且为,在求的梯度时,因为要涉及矩阵乘法,所以需要注意维度,从维度上看即为(N,H)*(H,D) = (N,D),符合的维度,的解法类似,这里不再给出。
代码如下:
def affine_backward(dout, cache):
"""
Computes the backward pass for an affine layer.
Inputs:
- dout: Upstream derivative, of shape (N, M)
- cache: Tuple of:
- x: Input data, of shape (N, d_1, ... d_k)
- w: Weights, of shape (D, M)
Returns a tuple of:
- dx: Gradient with respect to x, of shape (N, d1, ..., d_k)
- dw: Gradient with respect to w, of shape (D, M)
- db: Gradient with respect to b, of shape (M,)
"""
x, w, b = cache
dx, dw, db = None, None, None
x_rsp = x.reshape(N , -1)
dx = dout.dot(w.T)
dx = dx.reshape(*x.shape)
dw = x_rsp.T.dot(dout)
db = np.sum(dout, axis = 0)
return dx, dw, db
这里给出基于流量图和数学公式两种方法算出的参数导数的误差,接近可以忽略不计。
算法误差
总结
了解了以上导数的推导,后面更复杂的神经网络导数的推导也是类似的,比较不同的也只是不同的层的处理方法的不同,依然可以用这两种方法来求解,为了验证前两次的方法,下一篇将基于批量标准化来对参数的梯度使用两种方法进行求解。
下篇预告:基于批量标准化(Batch Normalization)的梯度的求解
网友评论