梯度下降与向量化操作
梯度下降与向量化操作
我们在前文二元分类与
$$ \hat{y} = \sigma(w^Tx + b), , \sigma(z) = \frac{1}{1+e^{-z}} $$
整个训练集的损失函数为:
$$ J(w,b) = \frac{1}{m}\sum*{i=1}^mL(\hat{y}^{(i)} - y^{(i)}) = \ -\frac{1}{m} \sum*{i=1}^m [y^{(i)}log\hat{y}^{(i)} + (1-y^{(i)})log(1-\hat{y}^{(i)})] $$
模型的训练目标即是寻找合适的
上图所示的函数
参数
$$ w := w - \alpha \frac{dJ(w)}{dw} $$
其中
导数
本部分是对于微积分中导数
上图中,
上图中,

下表列举了常用的导数复合运算公式:
计算图(Computation Graph)
神经网络中的计算即是由多个计算网络输出的前向传播与计算梯度的后向传播构成,我们可以将复杂的代价计算函数切割为多个子过程:
$$ J(a, b, c) = 3 \times (a + bc) $$
定义
根据导数计算公式,我们可知:
$$ \frac{dJ}{dv} = 3, , \frac{dJ}{da} = \frac{dJ}{dv} \frac{dv}{da} = 3 $$
在复杂的计算图中,我们往往需要经过大量的中间计算才能得到最终输出值与原始参数的导数
Logistic 回归中的导数计算
我们在上文中讨论过
$$ z = w^Tx + b \ \hat{y} = a = \sigma(z) \ L(a,y) = -( ylog(a) + (1-y)log(1-a) ) $$
这里我们假设输入的特征向量维度为
首先我们反向求出
$$ da = \frac{dL(a,y)}{da} = -\frac{y}{a} + \frac{1-y}{1-a} $$
然后继续反向求出
$$ dz = \frac{dL}{dz} =\frac{dL(a,y)}{dz} = \frac{dL}{da} \frac{da}{dz} = a-y $$
依次类推求出最终的损失函数相较于原始参数的导数之后,根据如下公式进行参数更新:
$$ w_1 := w_1 - \alpha dw_1 \ w_2 := w_2 - \alpha dw_2 \
b := b - \alpha db $$
接下来我们需要将对于单个用例的损失函数扩展到整个训练集的代价函数:
$$ J(w,b) = \frac{1}{m} \sum*{i=1}^m L(a^{(i)},y) \ a^{(i)} = \hat{y}^{(i)} = \sigma(z^{(i)}) = \sigma(w^Tx^{(i)} + b) $$
我们可以对于某个权重参数
$$ \frac{\partial J(w,b)}{\partial w_1} = \frac{1}{m} \sum*{i=1}^m \frac{\partial}{\partial w_1}L(a^{(i)},y^{(i)}) $$
完整的
向量化操作
在上述的
z = 0;
for i in range(n_x):
z += w[i] * x[i]
z += b
而如果是向量化的操作,我们的代码则会简洁很多:
z = np.dot(w, x) + b
在未来的章节中我们会实际比较循环操作与向量化操作二者的性能差异,可以发现向量化操作能够带来近百倍的性能提升;目前无论np.exp(v)
用于进行指数计算,np.log(v)
用于进行对数计算,np.abs(v)
用于进行绝对值计算。
下面我们将上述的
$$ Z = np.dot(W^TX) + b \ A = [a^{(1)},a^{(2)},…,a^{(m)}] = \sigma(z) $$
我们可以得到各个变量梯度计算公式为:
$$ dZ = A - Y = [a^{(1)} y^{(1)}…] \ db = \frac{1}{m}\sum*{i=1}^mdz^{(i)}=\frac{1}{m}np.sum(dZ) \ dW = \frac{1}{m} X dZ^{T}= \frac{1}{m} \begin{bmatrix} \vdots \
x^{(i1)} … x^{(im)} \
\vdots \ \end{bmatrix} \begin{bmatrix} \vdots \
dz^{(i)} \
\vdots \ \end{bmatrix} \ = \frac{1}{m} \begin{bmatrix} \vdots \
x^{(1)}dz^{(1)} + … + x^{(m)}dz^{(m)} \
\vdots \ \end{bmatrix} \ $$