主要内容:

  • 逻辑回归
  • 梯度下降
  • 向量化逻辑回归

    1. 逻辑回归 logistic regression

  • 逻辑回归主要用于二分类问题,估计某种事物的可能性。比如判断图中是否有猫,有的话输出标签1,没有输出标签0。

    • 注意,这里用的是“可能性”,而非数学上的“概率”,logisitc回归的结果并非数学定义中的概率值,不可以直接当做概率值来用。该结果往往用于和其他特征值加权求和,而非直接相乘。
    • 逻辑回归(Logistic Regression)与线性回归(Linear Regression)都是一种广义线性模型(generalized linear model)。逻辑回归假设因变量 y 服从伯努利分布,而线性回归假设因变量 y 服从高斯分布。 因此与线性回归有很多相同之处,去除Sigmoid映射函数的话,逻辑回归算法就是一个线性回归。可以说,逻辑回归是以线性回归为理论支持的,但是逻辑回归通过Sigmoid函数引入了非线性因素,因此可以轻松处理0/1分类问题。

    逻辑回归(Logistic Regression)(一) - 知乎 (zhihu.com)

  • 在二分类问题中,我们的目标是训练一个分类器,输入特征向量,输出预测结果。

  • 图片的特征向量如下:

L1W2-Basics - 图1

符号定义
L1W2-Basics - 图2:表示一个L1W2-Basics - 图3维数据,为输入数据,维度为L1W2-Basics - 图4#card=math&code=%28n_x%2C1%29&id=jHbY2);
L1W2-Basics - 图5:表示输出结果,取值为L1W2-Basics - 图6#card=math&code=%280%2C1%29&id=Ahb8q);
L1W2-Basics - 图7%7D%2Cy%5E%7B(i)%7D)#card=math&code=%28x%5E%7B%28i%29%7D%2Cy%5E%7B%28i%29%7D%29&id=NWLVb):表示第L1W2-Basics - 图8组数据,可能是训练数据,也可能是测试数据,此处默认为训练数据;
L1W2-Basics - 图9%7D%2Cx%5E%7B(2)%7D%2C…%2Cx%5E%7B(m)%7D%5D#card=math&code=X%3D%5Bx%5E%7B%281%29%7D%2Cx%5E%7B%282%29%7D%2C…%2Cx%5E%7B%28m%29%7D%5D&id=C73iY):表示所有的训练数据集的输入值,放在一个 L1W2-Basics - 图10的矩阵中,其中L1W2-Basics - 图11表示样本数目;
L1W2-Basics - 图12%7D%2Cy%5E%7B(2)%7D%2C…%2Cy%5E%7B(m)%7D%5D#card=math&code=Y%3D%5By%5E%7B%281%29%7D%2Cy%5E%7B%282%29%7D%2C…%2Cy%5E%7B%28m%29%7D%5D&id=DH7Oc):对应表示所有训练数据集的输出值,维度为L1W2-Basics - 图13

L1W2-Basics - 图14

逻辑回归的假设函数 (Hypothesis Function)

  • L1W2-Basics - 图15是一个L1W2-Basics - 图16维的向量(相当于有L1W2-Basics - 图17个特征的特征向量)。L1W2-Basics - 图18是特征权重,维度与特征向量相同,L1W2-Basics - 图19是一个实数,表示偏差。
  • 输入L1W2-Basics - 图20以及参数L1W2-Basics - 图21L1W2-Basics - 图22之后,我们怎样产生输出预测值L1W2-Basics - 图23?假设令L1W2-Basics - 图24,我们想让L1W2-Basics - 图25表示实际值L1W2-Basics - 图26等于1的机率的话,L1W2-Basics - 图27 应该在0到1之间。而L1W2-Basics - 图28可能比1要大得多,或者甚至为一个负值。因此在逻辑回归中,我们的输出应该是L1W2-Basics - 图29等于由上面得到的线性函数式子作为自变量的sigmoid函数,将线性函数转换为非线性函数。
  • L1W2-Basics - 图30#card=math&code=%5Chat%7By%7D%3D%5Csigma%28%7B%7Bw%7D%5E%7BT%7D%7Dx%2Bb%29&id=wx5mO),L1W2-Basics - 图31%3D%5Cfrac%7B1%7D%7B1%2B%7B%7Be%7D%5E%7B-z%7D%7D%7D#card=math&code=%5Csigma%20%5Cleft%28%20z%20%5Cright%29%3D%5Cfrac%7B1%7D%7B1%2B%7B%7Be%7D%5E%7B-z%7D%7D%7D&id=dFTv5),在这里L1W2-Basics - 图32是一个实数。下图是sigmoid函数的图像,通常都使用L1W2-Basics - 图33来表示L1W2-Basics - 图34的值。

L1W2-Basics - 图35

逻辑回归的代价函数(Logistic Regression Cost Function)

  • 当你实现逻辑回归时,你的工作就是去让机器学习参数L1W2-Basics - 图36以及L1W2-Basics - 图37,来得到你想要的输出。
  • 损失函数又叫做误差函数,用来衡量预测输出值和实际值有多接近,Loss function:L1W2-Basics - 图38#card=math&code=L%5Cleft%28%20%5Chat%7By%7D%2Cy%20%5Cright%29&id=zSZ1Y).
  • 一般我们用预测值和实际值的平方差或者它们平方差的一半,但是通常在逻辑回归中我们不这么做,因为当我们在学习逻辑回归参数的时候,会发现我们的优化目标不是凸优化,只能找到多个局部最优值,梯度下降法很可能找不到全局最优值。
  • 逻辑回归中用到的损失函数是:L1W2-Basics - 图39%3D-y%5Clog(%5Chat%7By%7D)-(1-y)%5Clog%20(1-%5Chat%7By%7D)#card=math&code=L%5Cleft%28%20%5Chat%7By%7D%2Cy%20%5Cright%29%3D-y%5Clog%28%5Chat%7By%7D%29-%281-y%29%5Clog%20%281-%5Chat%7By%7D%29&id=Wuj8w)
    • L1W2-Basics - 图40时损失函数L1W2-Basics - 图41#card=math&code=L%3D-%5Clog%20%28%5Chat%7By%7D%29&id=lcWvK),如果想要损失函数L1W2-Basics - 图42尽可能得小,那么L1W2-Basics - 图43就要尽可能大。因为sigmoid函数取值L1W2-Basics - 图44,所以L1W2-Basics - 图45会无限接近于1。
    • L1W2-Basics - 图46时损失函数L1W2-Basics - 图47#card=math&code=L%3D-%5Clog%20%281-%5Chat%7By%7D%29&id=tLNeO),如果想要损失函数L1W2-Basics - 图48尽可能得小,那么L1W2-Basics - 图49就要尽可能小。因为sigmoid函数取值L1W2-Basics - 图50,所以L1W2-Basics - 图51会无限接近于0。
  • 上式中损失函数是在单个训练样本中定义的,为了衡量算法在全部训练样本上的表现如何,我们需要定义一个算法的代价函数,算法的代价函数是对L1W2-Basics - 图52个样本的损失函数求和然后除以L1W2-Basics - 图53:
    L1W2-Basics - 图54%3D%5Cfrac%7B1%7D%7Bm%7D%5Csum%5Climits%7Bi%3D1%7D%5E%7Bm%7D%7BL%5Cleft(%20%7B%7B%7B%5Chat%7By%7D%7D%7D%5E%7B(i)%7D%7D%2C%7B%7By%7D%5E%7B(i)%7D%7D%20%5Cright)%7D%3D%5Cfrac%7B1%7D%7Bm%7D%5Csum%5Climits%7Bi%3D1%7D%5E%7Bm%7D%7B%5Cleft(%20-%7B%7By%7D%5E%7B(i)%7D%7D%5Clog%20%7B%7B%7B%5Chat%7By%7D%7D%7D%5E%7B(i)%7D%7D-(1-%7B%7By%7D%5E%7B(i)%7D%7D)%5Clog%20(1-%7B%7B%7B%5Chat%7By%7D%7D%7D%5E%7B(i)%7D%7D)%20%5Cright)%7D#card=math&code=J%5Cleft%28%20w%2Cb%20%5Cright%29%3D%5Cfrac%7B1%7D%7Bm%7D%5Csum%5Climits%7Bi%3D1%7D%5E%7Bm%7D%7BL%5Cleft%28%20%7B%7B%7B%5Chat%7By%7D%7D%7D%5E%7B%28i%29%7D%7D%2C%7B%7By%7D%5E%7B%28i%29%7D%7D%20%5Cright%29%7D%3D%5Cfrac%7B1%7D%7Bm%7D%5Csum%5Climits%7Bi%3D1%7D%5E%7Bm%7D%7B%5Cleft%28%20-%7B%7By%7D%5E%7B%28i%29%7D%7D%5Clog%20%7B%7B%7B%5Chat%7By%7D%7D%7D%5E%7B%28i%29%7D%7D-%281-%7B%7By%7D%5E%7B%28i%29%7D%7D%29%5Clog%20%281-%7B%7B%7B%5Chat%7By%7D%7D%7D%5E%7B%28i%29%7D%7D%29%20%5Cright%29%7D&id=zFBMe)
  • 损失函数只适用于单个训练样本,而代价函数是参数的总代价,我们训练的目标就是找到合适的L1W2-Basics - 图55L1W2-Basics - 图56,来让代价函数 L1W2-Basics - 图57 的总代价降到最低。

logistic 损失函数的解释

  • 我们约定 L1W2-Basics - 图58#card=math&code=%5Chat%7By%7D%3Dp%28y%3D1%7Cx%29&id=KmUav) ,即算法的输出L1W2-Basics - 图59 是给定训练样本 L1W2-Basics - 图60 条件下 L1W2-Basics - 图61 等于1的概率。换句话说,如果L1W2-Basics - 图62,在给定训练样本 L1W2-Basics - 图63 条件下L1W2-Basics - 图64;反过来说,如果L1W2-Basics - 图65,在给定训练样本L1W2-Basics - 图66条件下 L1W2-Basics - 图67 等于1减去L1W2-Basics - 图68,即L1W2-Basics - 图69
    L1W2-Basics - 图70

上述的两个条件概率公式可以合并成一个公式:

  • L1W2-Basics - 图71%3D%7B%5Chat%7By%7D%7D%5E%7By%7D%7B(1-%5Chat%7By%7D)%7D%5E%7B(1-y)%7D%0A#card=math&code=p%28y%7Cx%29%3D%7B%5Chat%7By%7D%7D%5E%7By%7D%7B%281-%5Chat%7By%7D%29%7D%5E%7B%281-y%29%7D%0A&id=oeR5D)

这就是L1W2-Basics - 图72#card=math&code=p%28y%7Cx%29&id=elN8i) 的完整定义。下图是原因解释。
L1W2-Basics - 图73
由于 log 函数是严格单调递增的函数,最大化 L1W2-Basics - 图74)#card=math&code=log%28p%28y%7Cx%29%29&id=LhA7M) 等价于最大化 L1W2-Basics - 图75#card=math&code=p%28y%7Cx%29&id=jhVh7) 并且地计算 L1W2-Basics - 图76#card=math&code=p%28y%7Cx%29&id=rgETe) 的 log对数,也就等于计算
L1W2-Basics - 图77log(1-%5Chat%7By%7D)#card=math&code=ylog%5Chat%7By%7D%2B%281-y%29log%281-%5Chat%7By%7D%29&id=ttVid)
前面提到的损失函数前面有一个负号,因为当你训练学习算法时需要算法输出值的概率是最大的(以最大的概率预测这个值),然而在逻辑回归中我们需要最小化损失函数,因此最小化损失函数与最大化条件概率的对数 L1W2-Basics - 图78)#card=math&code=log%28p%28y%7Cx%29%29&id=BChhk) 关联起来了。
这就是单个训练样本的损失函数表达式。那么,在 L1W2-Basics - 图79个训练样本的整个训练集中又该如何表示呢?
假设所有的训练样本服从同一分布且相互独立,也即独立同分布的,所有这些样本的联合概率就是每个样本概率的乘积:
L1W2-Basics - 图80%20%3D%20%5Cprod%7Bi%20%3D1%7D%5E%7Bm%7D%7BP(y%5E%7B(i)%7D%7Cx%5E%7B(i)%7D)%7D#card=math&code=P%5Cleft%28%5Ctext%7Blabels%20%20in%20training%20set%7D%20%5Cright%29%20%3D%20%5Cprod%7Bi%20%3D1%7D%5E%7Bm%7D%7BP%28y%5E%7B%28i%29%7D%7Cx%5E%7B%28i%29%7D%29%7D&id=ZRWEp)

在统计学中,最大似然估计(英语:Maximum Likelihood Estimation,简作MLE),也称极大似然估计,是用来估计一个概率模型的参数的一种方法。 给定一个概率分布L1W2-Basics - 图81,已知其概率密度函数(连续分布)或概率质量函数(离散分布)为L1W2-Basics - 图82,以及一个分布参数$\theta L1W2-Basics - 图83nL1W2-Basics - 图84X1, X_2,\ldots, X_nL1W2-Basics - 图85f_D$计算出其似然函数: ![](https://g.yuque.com/gr/latex?%7B%5Cdisplaystyle%20%7B%5Cmbox%7BL%7D%7D(%5Ctheta%20%5Cmid%20x%7B1%7D%2C%5Cdots%20%2Cx%7Bn%7D)%3Df%7B%5Ctheta%20%7D(x%7B1%7D%2C%5Cdots%20%2Cx%7Bn%7D).%7D#card=math&code=%7B%5Cdisplaystyle%20%7B%5Cmbox%7BL%7D%7D%28%5Ctheta%20%5Cmid%20x%7B1%7D%2C%5Cdots%20%2Cx%7Bn%7D%29%3Df%7B%5Ctheta%20%7D%28x%7B1%7D%2C%5Cdots%20%2Cx_%7Bn%7D%29.%7D&id=sfuVJ) 最大化一个似然函数同最大化它的自然对数是等价的。因为自然对数log是一个连续且在似然函数的值域内严格递增的上凹函数。求对数通常能够一定程度上简化运算 最大似然估计 - 维基百科,自由的百科全书

这样我们就推导出了前面给出的logistic回归的成本函数,如下所示。
L1W2-Basics - 图86

由于训练模型时,目标是让成本函数最小化,所以我们不是直接用最大似然概率,要去掉这里的负号。最后为了方便,可以对成本函数进行适当的缩放,我们就在前面加一个额外的常数因子L1W2-Basics - 图87,即:L1W2-Basics - 图88%3D%20%5Cfrac%7B1%7D%7Bm%7D%5Csum%7Bi%20%3D%201%7D%5E%7Bm%7D%7BL(%5Chat%20y%5E%7B(i)%7D%2Cy%5E%7B(i)%7D)%7D#card=math&code=J%28w%2Cb%29%3D%20%5Cfrac%7B1%7D%7Bm%7D%5Csum%7Bi%20%3D%201%7D%5E%7Bm%7D%7BL%28%5Chat%20y%5E%7B%28i%29%7D%2Cy%5E%7B%28i%29%7D%29%7D&id=azoVo)。

梯度下降

  • 初始化L1W2-Basics - 图89L1W2-Basics - 图90,朝最陡的下坡方向走一步,不断地迭代,直到走到全局最优解或者接近全局最优解的地方。这个点就是代价函数(成本函数)L1W2-Basics - 图91#card=math&code=J%28w%2Cb%29&id=ECzNk)这个凸函数的最小值点。

L1W2-Basics - 图92

  • L1W2-Basics - 图93 表示学习率(learning rate),用来控制步长(step),即向下走一步的长度L1W2-Basics - 图94%7D%7Bdw%7D#card=math&code=%5Cfrac%7BdJ%28w%29%7D%7Bdw%7D&id=PWfEI) 就是函数L1W2-Basics - 图95#card=math&code=J%28w%29&id=f2uJp)对L1W2-Basics - 图96 求导(derivative),在代码中我们会使用L1W2-Basics - 图97表示这个结果。
  • L1W2-Basics - 图98 表示求偏导符号,可以读作round,小写字母L1W2-Basics - 图99 用在求导数(derivative),即函数只有一个参数,偏导数符号$\partial $ 用在求偏导(partial derivative),即函数含有两个以上的参数。
    L1W2-Basics - 图100

单个样本的梯度下降

计算图(链式法则):用L1W2-Basics - 图101表示L1W2-Basics - 图102,即 L1W2-Basics - 图103#card=math&code=%5Chat%7By%7D%3Da%3D%5Csigma%20%28z%29&id=IwbQP)。假设现在只考虑单个样本的情况,单个样本的代价函数定义如下:L1W2-Basics - 图104%3D-(y%5Clog%20(a)%2B(1-y)%5Clog%20(1-a))#card=math&code=L%28a%2Cy%29%3D-%28y%5Clog%20%28a%29%2B%281-y%29%5Clog%20%281-a%29%29&id=nsSci),反向计算出代价函数L1W2-Basics - 图105#card=math&code=L%28a%2Cy%29&id=rr1Yd)关于各参数的导数:
L1W2-Basics - 图106%7D%7Bda%7D%3D-y%2Fa%2B(1-y)%2F(1-a)#card=math&code=da%3D%5Cfrac%7BdL%28a%2Cy%29%7D%7Bda%7D%3D-y%2Fa%2B%281-y%29%2F%281-a%29&id=U6acM) ,L1W2-Basics - 图107#card=math&code=%5Cfrac%7Bda%7D%7Bdz%7D%3Da%5Ccdot%20%281-a%29&id=ftFD5)
L1W2-Basics - 图108%7D%7Bdz%7D%3D%5Cfrac%7BdL%7D%7Bda%7D%5Ccdot%20%5Cfrac%7Bda%7D%7Bdz%7D%3D(%20-%20%5Cfrac%7By%7D%7Ba%7D%20%2B%20%5Cfrac%7B1%20-%20y%7D%7B1%20-%20a%7D)%5Ccdot%20a(1%20-%20a)%20%3D%20a-y#card=math&code=dz%3D%5Cfrac%7BdL%28a%2Cy%29%7D%7Bdz%7D%3D%5Cfrac%7BdL%7D%7Bda%7D%5Ccdot%20%5Cfrac%7Bda%7D%7Bdz%7D%3D%28%20-%20%5Cfrac%7By%7D%7Ba%7D%20%2B%20%5Cfrac%7B1%20-%20y%7D%7B1%20-%20a%7D%29%5Ccdot%20a%281%20-%20a%29%20%3D%20a-y&id=f0cA7)
L1W2-Basics - 图109

现在进行最后一步反向推导,也就是计算L1W2-Basics - 图110L1W2-Basics - 图111变化对代价函数L1W2-Basics - 图112的影响,特别地,可以用:
L1W2-Basics - 图113%7D%7D(%7B%7Ba%7D%5E%7B(i)%7D%7D-%7B%7By%7D%5E%7B(i)%7D%7D)#card=math&code=d%7B%7Bw%7D%7B1%7D%7D%3D%5Cfrac%7B1%7D%7Bm%7D%5Csum%5Climits%7Bi%7D%5E%7Bm%7D%7Bx%7B1%7D%5E%7B%28i%29%7D%7D%28%7B%7Ba%7D%5E%7B%28i%29%7D%7D-%7B%7By%7D%5E%7B%28i%29%7D%7D%29&id=Lbbia)
![](https://g.yuque.com/gr/latex?d%7B%7Bw%7D
%7B2%7D%7D%3D%5Cfrac%7B1%7D%7Bm%7D%5Csum%5Climits%7Bi%7D%5E%7Bm%7D%7Bx%7B2%7D%5E%7B(i)%7D%7D(%7B%7Ba%7D%5E%7B(i)%7D%7D-%7B%7By%7D%5E%7B(i)%7D%7D)#card=math&code=d%7B%7Bw%7D%7B2%7D%7D%3D%5Cfrac%7B1%7D%7Bm%7D%5Csum%5Climits%7Bi%7D%5E%7Bm%7D%7Bx%7B2%7D%5E%7B%28i%29%7D%7D%28%7B%7Ba%7D%5E%7B%28i%29%7D%7D-%7B%7By%7D%5E%7B%28i%29%7D%7D%29&id=zv2DC)
![](https://g.yuque.com/gr/latex?db%3D%5Cfrac%7B1%7D%7Bm%7D%5Csum%5Climits
%7Bi%7D%5E%7Bm%7D%7B(%7B%7Ba%7D%5E%7B(i)%7D%7D-%7B%7By%7D%5E%7B(i)%7D%7D)%7D#card=math&code=db%3D%5Cfrac%7B1%7D%7Bm%7D%5Csum%5Climits%7Bi%7D%5E%7Bm%7D%7B%28%7B%7Ba%7D%5E%7B%28i%29%7D%7D-%7B%7By%7D%5E%7B%28i%29%7D%7D%29%7D&id=VjGkM)
因此,关于单个样本的梯度下降算法,你所需要做的就是如下的事情:
使用公式L1W2-Basics - 图114#card=math&code=dz%3D%28a-y%29&id=ApTN0)计算L1W2-Basics - 图115,使用![](https://g.yuque.com/gr/latex?d%7B%7Bw%7D
%7B1%7D%7D%3D%7B%7Bx%7D%7B1%7D%7D%5Ccdot%20dz#card=math&code=d%7B%7Bw%7D%7B1%7D%7D%3D%7B%7Bx%7D%7B1%7D%7D%5Ccdot%20dz&id=manUQ) 计算![](https://g.yuque.com/gr/latex?d%7B%7Bw%7D%7B1%7D%7D#card=math&code=d%7B%7Bw%7D%7B1%7D%7D&id=k8W0S), ![](https://g.yuque.com/gr/latex?d%7B%7Bw%7D%7B2%7D%7D%3D%7B%7Bx%7D%7B2%7D%7D%5Ccdot%20dz#card=math&code=d%7B%7Bw%7D%7B2%7D%7D%3D%7B%7Bx%7D%7B2%7D%7D%5Ccdot%20dz&id=ZzPQA)计算![](https://g.yuque.com/gr/latex?d%7B%7Bw%7D%7B2%7D%7D#card=math&code=d%7B%7Bw%7D%7B2%7D%7D&id=p0Oje),L1W2-Basics - 图116 来计算L1W2-Basics - 图117,然后:
更新![](https://g.yuque.com/gr/latex?%7B%7Bw%7D
%7B1%7D%7D%3A%3D%7B%7Bw%7D%7B1%7D%7D-%5Calpha%20d%7B%7Bw%7D%7B1%7D%7D#card=math&code=%7B%7Bw%7D%7B1%7D%7D%3A%3D%7B%7Bw%7D%7B1%7D%7D-%5Calpha%20d%7B%7Bw%7D%7B1%7D%7D&id=D63Ny),更新![](https://g.yuque.com/gr/latex?%7B%7Bw%7D%7B2%7D%7D%3A%3D%7B%7Bw%7D%7B2%7D%7D-%5Calpha%20d%7B%7Bw%7D%7B2%7D%7D#card=math&code=%7B%7Bw%7D%7B2%7D%7D%3A%3D%7B%7Bw%7D%7B2%7D%7D-%5Calpha%20d%7B%7Bw%7D_%7B2%7D%7D&id=x1B0j),更新L1W2-Basics - 图118

m个样本的梯度下降

上一节我们只使用了一个训练样本L1W2-Basics - 图119%7D%7D%2C%7B%7By%7D%5E%7B(i)%7D%7D)#card=math&code=%28%7B%7Bx%7D%5E%7B%28i%29%7D%7D%2C%7B%7By%7D%5E%7B%28i%29%7D%7D%29&id=T8j64)。 现在你知道全局代价函数,实际上是1到L1W2-Basics - 图120项各个损失的平均, 所以它表明全局代价函数对L1W2-Basics - 图121的微分。对L1W2-Basics - 图122的微分也同样是各项损失对L1W2-Basics - 图123微分的平均。

L1W2-Basics - 图124
我们把每个样本得出的微分值累加,然后求平均即可。代码流程:

L1W2-Basics - 图125
这种计算中有两个缺点,也就是说应用此方法在逻辑回归上你需要编写两个for循环。第一个for循环是一个小循环遍历L1W2-Basics - 图126个训练样本,第二个for循环是一个遍历所有特征的for循环。向量化可以避开显式的for循环,极大地减少计算时间。

向量化

向量化计算L1W2-Basics - 图127z=np.dot(w,x)+b
numpy库有很多向量函数。比如 u=np.log是计算对数函数(L1W2-Basics - 图128)、 np.abs() 计算数据的绝对值、np.maximum(v, 0) 按元素计算L1W2-Basics - 图129中每个元素和和0相比的最大值,v**2 代表获得元素 L1W2-Basics - 图130 每个值的平方、 1/v 获取 L1W2-Basics - 图131 中每个元素的倒数等等。所以当你想写循环时候,检查numpy是否存在类似的内置函数,从而避免使用循环(loop)方式。
运用在逻辑回归的梯度下降上,我们想要消除第二循环。我们不用分别初始化 L1W2-Basics - 图132L1W2-Basics - 图133 等于0,而是定义 L1W2-Basics - 图134 为一个向量,设置 L1W2-Basics - 图135#card=math&code=u%3Dnp.zeros%28n_x%2C1%29&id=NhQBJ)。使 L1W2-Basics - 图136%7Ddz%5E%7B(i)%7D#card=math&code=dw%2B%3Dx%5E%7B%28i%29%7Ddz%5E%7B%28i%29%7D&id=bDLfv) ,最后令 L1W2-Basics - 图137

向量化逻辑回归

前向传播
首先我们回顾一下逻辑回归的前向传播步骤。如果你有 L1W2-Basics - 图138 个训练样本,对第一个样本的计算过程是:计算 L1W2-Basics - 图139%7D%3Dw%5E%7BT%7Dx%5E%7B(1)%7D%2Bb#card=math&code=z%5E%7B%281%29%7D%3Dw%5E%7BT%7Dx%5E%7B%281%29%7D%2Bb&id=fo4Qj) ,然后计算激活函数 L1W2-Basics - 图140%7D%3D%5Csigma%20(z%5E%7B(1)%7D)#card=math&code=a%5E%7B%281%29%7D%3D%5Csigma%20%28z%5E%7B%281%29%7D%29&id=SwNN8) ,最后计算得到第一个样本的预测值 L1W2-Basics - 图141%7D#card=math&code=%5Chat%7By%7D%5E%7B%281%29%7D&id=V6APz) 。对每个样本进行相同的操作。向量化如下图所示:
L1W2-Basics - 图142

因此可以对 L1W2-Basics - 图143 个训练样本一次性计算出 L1W2-Basics - 图144L1W2-Basics - 图145
L1W2-Basics - 图146%2Bb#card=math&code=Z%3Dnp.dot%28w.T%2CX%29%2Bb&id=spcD6)
L1W2-Basics - 图147%7D%20a%5E%7B(2)%7D%20…%20a%5E%7B(m)%7D%5D%3D%5Csigma%20(Z)#card=math&code=A%3D%5Ba%5E%7B%281%29%7D%20a%5E%7B%282%29%7D%20…%20a%5E%7B%28m%29%7D%5D%3D%5Csigma%20%28Z%29&id=LeLfb)
这里在Python中有一个巧妙的地方: L1W2-Basics - 图148 是一个实数(或者说是一个 L1W2-Basics - 图149 矩阵)。将向量与实数相加时,Python自动把这个实数 L1W2-Basics - 图150 扩展成一个 L1W2-Basics - 图151 的行向量。将常数横向扩展或纵向扩展,这在Python中被称作广播(brosdcasting)。
反向传播
在上一节我们计算得到L1W2-Basics - 图152,由此L1W2-Basics - 图153%7D-y%5E%7B(1)%7D%20a%5E%7B(2)%7D-y%5E%7B(2)%7D%20…%20a%5E%7B(m)%7D-y%5E%7B(m)%7D%5D#card=math&code=dZ%3DA-Y%3D%5Ba%5E%7B%281%29%7D-y%5E%7B%281%29%7D%20a%5E%7B%282%29%7D-y%5E%7B%282%29%7D%20…%20a%5E%7B%28m%29%7D-y%5E%7B%28m%29%7D%5D&id=BAIsD)
L1W2-Basics - 图154#card=math&code=db%3D%5Cfrac%7B1%7D%7Bm%7D%2Anp.sum%28dZ%29&id=g0QBz),L1W2-Basics - 图155
L1W2-Basics - 图156
对于一次梯度下降,我们实现了不用for循环对所有训练样本进行预测和求导。
如果你希望多次迭代进行梯度下降,那么仍然需要for循环,例如下图实现的1000次迭代:
L1W2-Basics - 图157

python中的broadcasting

L1W2-Basics - 图158
我们现在想要计算不同食物中不同营养成分中的卡路里百分比。
L1W2-Basics - 图159
下面使用如下代码计算每列的和,可以看到输出是每种食物(100g)的卡路里总和。axis用来指明将要进行的运算是沿着哪个轴执行,在numpy中,0轴是垂直的,也就是列,而1轴是水平的,也就是行。
L1W2-Basics - 图160
接下来计算百分比,这条指令将 L1W2-Basics - 图161的矩阵L1W2-Basics - 图162除以一个L1W2-Basics - 图163的矩阵,得到了一个 L1W2-Basics - 图164的结果矩阵,这个结果矩阵就是我们要求的百分比含量。
L1W2-Basics - 图165

  • A/cal.reshape(1,4)指令调用了numpy中的广播机制, L1W2-Basics - 图166的矩阵L1W2-Basics - 图167除以L1W2-Basics - 图168的矩阵L1W2-Basics - 图169 ,在计算时L1W2-Basics - 图170自动向下复制自己,复制到3行。
  • 其实这里 L1W2-Basics - 图171 本身就是L1W2-Basics - 图172,不需要reshape
  • 重塑操作reshape是一个常量时间的操作,时间复杂度是L1W2-Basics - 图173#card=math&code=O%281%29&id=oSLE0),它的调用代价极低。
  • 由于广播巨大的灵活性,有时候你对于广播的特点以及广播的工作原理这些细节不熟悉的话,你可能会产生很细微或者看起来很奇怪的bug。例如,如果你将一个列向量添加到一个行向量中,你会以为它报出维度不匹配或类型错误之类的错误,但是实际上你会得到一个行向量和列向量的求和。

总结一下broadcasting,可以看看下面的图:
L1W2-Basics - 图174

关于python numpy向量

为了演示Python-numpy的一个容易被忽略的效果,特别是怎样在Python-numpy中构造向量,让我来做一个快速示范。
首先设置L1W2-Basics - 图175#card=math&code=a%3Dnp.random.randn%285%29&id=u8nH0),这样会生成存储在数组 L1W2-Basics - 图176 中的5个高斯随机数变量。之后输出 L1W2-Basics - 图177,从屏幕上可以得知,此时 L1W2-Basics - 图178shape(形状)是一个L1W2-Basics - 图179#card=math&code=%285%2C%29&id=JnRuM)的结构。这在Python中被称作一个一维数组它既不是一个行向量也不是一个列向量,这也导致它有一些不是很直观的效果。举个例子,如果我输出一个转置阵,最终结果它会和L1W2-Basics - 图180看起来一样,所以L1W2-Basics - 图181L1W2-Basics - 图182的转置阵最终结果看起来一样。而如果我输出L1W2-Basics - 图183L1W2-Basics - 图184的转置阵的内积,你可能会想:L1W2-Basics - 图185乘以L1W2-Basics - 图186的转置返回给你的可能会是一个矩阵。但是如果我这样做,你只会得到一个数。
L1W2-Basics - 图187
所以建议你编写神经网络时,不要使用shape为 (5,)(n,) 或者其他一维数组的数据结构。相反,如果你设置 L1W2-Basics - 图188L1W2-Basics - 图189#card=math&code=%285%2C1%29&id=sgkLW),那么这就将置于5行1列向量中。在先前的操作里 L1W2-Basics - 图190L1W2-Basics - 图191 的转置看起来一样,而现在这样的 L1W2-Basics - 图192 变成一个新的 L1W2-Basics - 图193 的转置,并且它是一个行向量。请注意一个细微的差别,在这种数据结构中,当我们输出 L1W2-Basics - 图194 的转置时有两对方括号,而之前只有一对方括号,所以这就是1行5列的矩阵和一维数组的差别。
L1W2-Basics - 图195
如果你输出 L1W2-Basics - 图196L1W2-Basics - 图197 的转置的乘积,然后会返回给你一个向量的外积,是吧?所以这两个向量的外积返回给你的是一个矩阵。
L1W2-Basics - 图198
所以我建议,当你在编程练习或者在执行逻辑回归和神经网络时,不要使用L1W2-Basics - 图199#card=math&code=a%3Dnp.random.randn%285%29&id=RRRRk)生成一维数组。而是写明它是行向量还是列向量。
L1W2-Basics - 图200
L1W2-Basics - 图201
我写代码时还有一件经常做的事,那就是如果我不完全确定一个向量的维度(dimension),我经常会扔进一个断言语句(assertion statement)。像这样,去确保在这种情况下是一个L1W2-Basics - 图202#card=math&code=%285%2C1%29&id=Lf34U)向量,或者说是一个列向量。这些断言语句实际上是要去执行的,并且它们也会有助于为你的代码提供信息。所以不论你要做什么,不要犹豫直接插入断言语句。如果你不小心以一维数组来执行,你也能够重新改变数组维数 L1W2-Basics - 图203,表明一个L1W2-Basics - 图204#card=math&code=%285%2C1%29&id=DGU3e)数组或者一个L1W2-Basics - 图205#card=math&code=%281%2C5%29&id=kXDJH)数组,以致于它表现更像列向量或行向量。
L1W2-Basics - 图206
总是使用 L1W2-Basics - 图207 维矩阵(基本上是列向量),或者 L1W2-Basics - 图208 维矩阵(基本上是行向量),这样你可以减少很多assert语句来节省审核矩阵和数组的维数的时间。另外,为了确保你的矩阵或向量所需要的维数时,不要羞于 reshape 操作。
总之,我希望这些建议能帮助你解决一个Python中的bug,从而使你更容易地完成练习。