1.2 神经网络基础
逻辑回归中的梯度下降算法
L为逻辑回归的损失函数,其中a是逻辑回归的输出,y是样本的真值。
假设有两个特征x1\x2,那么就还需要两个参数w1\w2,再加上一个b(常数项,就是机器学习中的x0),才能得到逻辑回归的结果a,继而算出损失函数L。
此处我们学习的是梯度下降算法,实际上核心就是右下角蓝色字体写出的公式,不断的更新w1\w2\b,以使其达到局部最优解。这个公式中包含学习率α(学过),以及导数项。注意!本教程中“da”的意思就是L对a的(偏)导数,推广一下则dx就是损失函数对x的(偏)导数(本教程在写变量尤其是编程时,对谁的导数一律写d谁,也不区分导数和偏导数,作者认为意义不大),由于复合函数涉及链式求导法则,所以dw1实际上需要的dz又需要da,所以从右边反向一步一步计算各项。
逻辑回归在m个样本上
全局成本函数J是损失函数L在m个样本上的平均值,注意区分。
此处又重写了一遍公式,a(逻辑回归结果)=y帽=sigmoid(z)=sigmoid(xxxxx)
全局梯度值w1在梯度下降时,用的是全局成本函数J对w1的偏导数,而J对w1的偏导数来自于所有L对w1偏导数的平均值。
图中是逻辑回归在m个样本上的梯度下降算法下降一次的详细步骤,全局梯度的每个参数下降一次,用的都是全局成本函数J对各参数的偏导数,而这个偏导数来自于所有样本上偏导数的平均值。
如图中所示,便利每一个样本需要for循环,每一次梯度下降也需要for循环,如果参数w非常多可能同样需要for循环,这样显式的使用过多的for循环会使算法的效率非常低下,所以接下来学习向量化技术。
向量化
向量化是消除代码中显式for循环语句的艺术,视频中计算同一个结果向量化方法用了1.5ms,而显式的for循环则用了481.3ms。
如果你想计算一个向量u=Av (u,v是向量,A是矩阵),可以写两个for嵌套在一起,也可以使用np库快速进行矩阵向量运算。
numpy库中提供了各种各样的运算,例如你想给向量的每个元素做指数运算,甚至是log,取绝对值等,在写一个for循环时应当先考虑是否能够向量化。
蓝色字体是逻辑回归梯度下降算法中两个for循环,绿色字体是将其中dw参数的那个循环向量化的实例。
向量化的逻辑回归(正向传播)
当我们像图中黑色字体中一个一个样本的计算逻辑回归时,其实可以首先构造一个X矩阵作为训练输入,由所有训练样本堆叠得到。那么Z(由各个样本计算出来的z所构成的行向量)就可以由绿色字体写出的矩阵运算得到,其中注意b是一个都是实数b的行向量,在python代码中只需要在式中加上一个实数b,它就会自动被扩充为行向量b,这被称为python广播。计算A就较为简单了, z到a只是经过了一个sigmoid函数,可以直接实现。而红色圈在下面画出来的两行公式或者说代码,就是正向传播一步迭代(同时处理m个样本)的向量化实现。
回归的梯度输出(反向传播)
dz=a-y是dz链式法则求导最后化简的公式。注意!dw此时是一个向量,它包含了每一个特征的参数,但此时还需要遍历每一个样本的dw,最后再1/m,得到全局dw。db(好像是一个数不是向量)也是一样的,算平均值。在向量化时,由于db实际上就是dz的平均值,而dz已经是一个向量了所以直接算即可。dw的公式可能稍显复杂,但把握m是样本个数,x的列向量是每个样本的所有特征输入,实际上非常好理解。
总结一下之前向量化的内容,就如上图所示。我们已经完成了逻辑回归梯度下降的一次迭代,并取代了所有显示的for循环,但要进行梯度下降的多次迭代仍需要使用for循环,尽管如此我们依然得到了一个非常高效的逻辑回归梯度下降算法。
Python中的广播
图表中的数据是100g每种食物中卡路里的三种不同的来源。我们希望先算出100g每种食物有多少卡路里,再算出每种卡路里来源占总量的百分比。
在python中两行代码即可实现。其中参数axix=0(axix=0表示垂直轴,1表示水平轴)在求和中表示按列求和,第二行中的cal经过第一行的计算实际上已经是一个1×4的向量了,所以reshape语句可以删去,但当你不确定一个矩阵是不是你要的矩阵例如行向量或列向量时,你可以使用reshape。以下我们举几个例子来说明这行代码中如何让一个3×4矩阵除以一个1×4的矩阵的。
很简单,就是将一个数或者一个行\列向量扩展成所需要的矩阵的形状。
Python_numpy向量的说明
(没看懂,有需要再看)
代码实现要点
将图像数据集展开的方法
- 将(样本个数,长,宽,3) 展开为 (长×宽×3,样本个数)
这是对图像数据较为常用的一种方法,reshape中的两个参数第一个表示样本个数,第二个表示自动计算剩下的维数(我猜的)。
图像数据集标准化
直接除以255(RGB值的范围)
创建一个0向量的方法
两个返回值
成本函数的计算
注意cost的计算完全可以靠np的运算完成,不需要循环
按照公式计算出A和cost,注意这里面有向量之间的点积和两个向量按位相乘,点积是需要np.dot(),按位相乘直接用*就行,但要注意前后两个必须是向量,也就是用np.array()申明的东西,否则只是一个普通的list,不能做乘法运算。
np.dot np.multiply * 三者区别在01.3中详细介绍