向量化逻辑回归

  • 讨论如何实现逻辑回归的向量化计算。这样就能处理整个数据集,甚至不会用一个明确的for循环就能实现对于整个数据集梯度下降算法的优化

首先回顾一下逻辑回归的前向传播步骤。所以,如果有 \(m\) 个训练样本,然后对第一个样本进行预测,需要这样计算。计算 \(z\),正在使用这个熟悉的公式 \(z^{(1)}=w^{T}x^{(1)}+b\) 。然后计算激活函数 \(a^{(1)}=\sigma (z^{(1)})\) ,计算第一个样本的预测值 \(y\) 。

然后对第二个样本进行预测,需要计算 \(z^{(2)}=w^{T}x^{(2)}+b\) , \(a^{(2)}=\sigma (z^{(2)})\) 。然后对第三个样本进行预测,需要计算 \(z^{(3)}=w^{T}x^{(3)}+b\) , \(a^{(3)}=\sigma (z^{(3)})\) ,依次类推。如果有 \(m\) 个训练样本,可能需要这样做 \(m\) 次,可以看出,为了完成前向传播步骤,即对的 \(m\) 个样本都计算出预测值。有一个办法可以并且不需要任何一个明确的for循环。让来看一下该怎样做。

首先,回忆一下曾经定义了一个矩阵 \(X\) 作为的训练输入,(如下图中蓝色 \(X\) )像这样在不同的列中堆积在一起。这是一个 \(n_x\) 行 \(m\) 列的矩阵。现在将它写为Python numpy的形式 $$(n_{x},m)$$ ,这只是表示 \(X\) 是一个 \(n_x\) 乘以 \(m\) 的矩阵 $$R^{n_x \times m}$$。

现在首先想做的是告诉该如何在一个步骤中计算 \(z_1\)、 \(z_2\) 、\(z_3\) 等等。实际上,只用了一行代码。所以,打算先构建一个 \(1\times m\) 的矩阵,实际上它是一个行向量,同时准备计算 \(z^{(1)}\), \(z^{(2)}\) ……一直到 \(z^{(m)}\) ,所有值都是在同一时间内完成。结果发现它可以表达为 \(w\) 的转置乘以大写矩阵 \(x\) 然后加上向量 \([b b...b]\) , \(([z^{(1)} z^{(2)}...z^{(m)}]=w^{T}+[bb...b])\) 。\([b b...b]\) 是一个 \(1\times m\) 的向量或者 \(1\times m\) 的矩阵或者是一个 \(m\) 维的行向量。所以希望熟悉矩阵乘法,会发现的 \(w\) 转置乘以 \(x^{(1)}\) , \(x^{(2)}\) 一直到 \(x^{(m)}\) 。所以 \(w\) 转置可以是一个行向量。所以第一项 \(w^{T}X\) 将计算 \(w\) 的转置乘以 \(x^{(1)}\), \(w\) 转置乘以\(x^{(2)}\) 等等。然后加上第二项 \([b b...b]\) ,最终将 \(b\) 加到了每个元素上。所以最终得到了另一个 \(1\times m\) 的向量, \([z^{(1)} z^{(2)}...z^{(m)}]=w^{T}X+[b b...b]=[w^{T}x^{(1)}+b,w^{T}x^{(2)}+b...w^{T}x^{(m)}+b]\) 。

\(w^{T}x^{(1)}+b\) 这是第一个元素,\(w^{T}x^{(2)}+b\) 这是第二个元素, \(w^{T}x^{(m)}+b\) 这是第 \(m\) 个元素。

如果参照上面的定义,第一个元素恰好是 \(z^{(1)}\) 的定义,第二个元素恰好是 \(z^{(2)}\) 的定义,等等。所以,因为\(X\)是一次获得的,当得到的训练样本,一个一个横向堆积起来,这里将 \([z^{(1)} z^{(2)} ... z^{(m)}]\) 定义为大写的 \(Z\) ,用小写 \(z\) 表示并将它们横向排在一起。所以当将不同训练样本对应的小写 \(x\) 横向堆积在一起时得到大写变量 \(X\) 并且将小写变量也用相同方法处理,将它们横向堆积起来,就得到大写变量 \(Z\) 。结果发现,为了计算 \(W^{T}X+[b b ... b]\) ,numpy命令是\(Z=np.dot(w.T,X)+b\)。这里在Python中有一个巧妙的地方,这里 \(b\) 是一个实数,或者可以说是一个 \(1\times 1\) 矩阵,只是一个普通的实数。但是当将这个向量加上这个实数时,Python自动把这个实数 \(b\) 扩展成一个 \(1\times m\) 的行向量。所以这种情况下的操作似乎有点不可思议,它在Python中被称作广播(brosdcasting),目前不用对此感到顾虑,将在下一个博客中进行进一步的讲解。话说回来它只用一行代码,用这一行代码,可以计算大写的 \(Z\),而大写 \(Z\) 是一个包含所有小写\(z^{(1)}\) 到 $ z^{(m)}$ 的 \(1\times m\) 的矩阵。这就是 \(Z\) 的内容,关于变量 \(a\) 又是如何呢?

接下来要做的就是找到一个同时计算 \([a^{(1)} a^{(2)} ... a^{(m)}]\) 的方法。就像把小写 \(x\) 堆积起来得到大写 \(X\) 和横向堆积小写 \(z\) 得到大写 \(Z\) 一样,堆积小写变量 \(a\) 将形成一个新的变量,将它定义为大写 \(A\)。在编程作业中,将看到怎样用一个向量在sigmoid函数中进行计算。所以sigmoid函数中输入大写 \(Z\) 作为变量并且非常高效地输出大写 \(A\)。

总结一下,不需要for循环,利用 \(m\) 个训练样本一次性计算出小写 \(z\) 和小写 \(a\),用一行代码即可完成。

Z = np.dot(w.T,X) + b

这一行代码:\(A=[a^{(1)} a^{(2)} ... a^{(m)}]=\sigma (Z)\) ,通过恰当地运用\(\sigma\)一次性计算所有 \(a\)。这就是在同一时间内如何完成一个所有 \(m\) 个训练样本的前向传播向量化计算。

概括一下,刚刚看到如何利用向量化在同一时间内高效地计算所有的激活函数的所有 \(a\)值。接下来,可以证明,也可以利用向量化高效地计算反向传播并以此来计算梯度。

向量化 logistic 回归的梯度输出(Vectorizing Logistic Regression's Gradient)

注:以下内容大写字母代表向量,小写字母代表元素

如何向量化计算的同时,对整个训练集预测结果\(a\),这是之前已经讨论过的内容。在本次博客中将学习如何向量化地计算\(m\)个训练数据的梯度,本次博客的重点是如何同时计算 \(m\) 个数据的梯度,并且实现一个非常高效的逻辑回归算法(Logistic Regression)。

之前在讲梯度计算的时候,列举过几个例子, \(dz^{(1)}=a^{(1)}-y^{(1)}\),\(dz^{(2)}=a^{(2)}-y^{(2)}\) ……等等一系列类似公式。现在,对 \(m\)个训练数据做同样的运算,可以定义一个新的变量 \(dZ=[dz^{(1)} ,dz^{(2)} ... dz^{(m)}]\)

,所有的 \(dz\) 变量横向排列,因此,\(dZ\) 是一个 \(1\times m\) 的矩阵,或者说,一个 \(m\) 维行向量。在之前的叙述中,已经知道如何计算\(A\),即 \([a^{(1)},a^{(2)} ... a^{(m)}]\),需要找到这样的一个行向量 \(Y=[y^{(1)} y^{(2)} ... y^{(m)}]\) ,由此,可以这样计算 \(dZ=A-Y=[a^{(1)}-y^{(1)} a^{(2)}-y^{(2)} ... a^{(m)}-y^{(m)}]\),不难发现第一个元素就是 \(dz^{(1)}\),第二个元素就是 \(dz^{(2)}\) ……所以现在仅需一行代码,就可以同时完成这所有的计算。

在之前的实现中,已经去掉了一个for循环,但仍有一个遍历训练集的循环,如下所示:

\(dw=0\)

\(dw + = x^{(1)}*{dz}^{(1)}\)

\(dw + = x^{(2)}\ *dz^{(2)}\)

………….

\(dw + = x^{(m)}*{dz}^{(m)}\)

\(dw = \frac{{dw}}{m}\)

\(db = 0\)

\(db + = {dz}^{(1)}\)

\(db + = {dz}^{(2)}\)

………….

\(db + = dz^{(m)}\)

\(db = \frac{{db}}{m}\)

上述(伪)代码就是在之前实现中做的,已经去掉了一个for循环,但用上述方法计算 \(dw\) 仍然需要一个循环遍历训练集,现在要做的就是将其向量化!

首先我们来看 \(db\),不难发现 \(db=\frac{1}{m}\sum_{i=1}^{m}dz^{(i)}\) ,

之前的叙述中,我们知道所有的\(dz^{i)}\)已经组成一个行向量 \(dZ\)了,所以在Python中,我们很容易地想到\(db=\frac{1}{m}*np.sum(dZ)\);接下来看\(dw\),我们先写出它的公式 \(dw=\frac{1}{m}*X*dz^{T}\)

其中,\(X\) 是一个行向量。因此展开后 \(dw=\frac{1}{m}*(x^{(1)}dz^{(1)}+x^{(2)}dz^{(2)}+...+x^{m}dz^{m})\) 。因此我们可以仅用两行代码进行计算:\(db=\frac{1}{m}*np.sum(dZ)\), \(dw=\frac{1}{m}*X*dz^{T}\)。这样,我们就避免了在训练集上使用for循环。

现在,让回顾一下,看看之前怎么实现的逻辑回归,可以发现,没有向量化是非常低效的,如下图所示代码:

的目标是不使用for循环,而是向量,可以这么做:

\(Z = w^{T}X + b = np.dot( w.T,X)+b\)

\(A = \sigma( Z )\)

\(dZ = A - Y\)

\({{dw} = \frac{1}{m}*X*dz^{T}\ }\)

\(db= \frac{1}{m}*np.sum( dZ)\)

\(w: = w - a*dw\)

\(b: = b - a*db\)

现在利用前五个公式完成了前向和后向传播,也实现了对所有训练样本进行预测和求导,再利用后两个公式,梯度下降更新参数。目的是不使用for循环,所以就通过一次迭代实现一次梯度下降,但如果希望多次迭代进行梯度下降,那么仍然需要for循环,放在最外层。不过还是觉得一次迭代就进行一次梯度下降,避免使用任何循环比较舒服一些。

最后,得到了一个高度向量化的、非常高效的逻辑回归的梯度下降算法,将在下次博客中讨论Python中的Broadcasting技术。

神经网络基础篇:详解向量化逻辑回归(Vectorizing Logistic Regression)的更多相关文章

  1. 逻辑回归模型(Logistic Regression, LR)基础

    逻辑回归模型(Logistic Regression, LR)基础   逻辑回归(Logistic Regression, LR)模型其实仅在线性回归的基础上,套用了一个逻辑函数,但也就由于这个逻辑函 ...

  2. Python实践之(七)逻辑回归(Logistic Regression)

    机器学习算法与Python实践之(七)逻辑回归(Logistic Regression) zouxy09@qq.com http://blog.csdn.net/zouxy09 机器学习算法与Pyth ...

  3. 机器学习算法与Python实践之(七)逻辑回归(Logistic Regression)

    http://blog.csdn.net/zouxy09/article/details/20319673 机器学习算法与Python实践之(七)逻辑回归(Logistic Regression) z ...

  4. [机器学习] Coursera ML笔记 - 逻辑回归(Logistic Regression)

    引言 机器学习栏目记录我在学习Machine Learning过程的一些心得笔记,涵盖线性回归.逻辑回归.Softmax回归.神经网络和SVM等等.主要学习资料来自Standford Andrew N ...

  5. 通俗地说逻辑回归【Logistic regression】算法(二)sklearn逻辑回归实战

    前情提要: 通俗地说逻辑回归[Logistic regression]算法(一) 逻辑回归模型原理介绍 上一篇主要介绍了逻辑回归中,相对理论化的知识,这次主要是对上篇做一点点补充,以及介绍sklear ...

  6. 机器学习——逻辑回归(Logistic Regression)

    1 前言 虽然该机器学习算法名字里面有"回归",但是它其实是个分类算法.取名逻辑回归主要是因为是从线性回归转变而来的. logistic回归,又叫对数几率回归. 2 回归模型 2. ...

  7. 机器学习/逻辑回归(logistic regression)/--附python代码

    个人分类: 机器学习 本文为吴恩达<机器学习>课程的读书笔记,并用python实现. 前一篇讲了线性回归,这一篇讲逻辑回归,有了上一篇的基础,这一篇的内容会显得比较简单. 逻辑回归(log ...

  8. 分类算法之逻辑回归(Logistic Regression

    分类算法之逻辑回归(Logistic Regression) 1.二分类问题 现在有一家医院,想要对病人的病情进行分析,其中有一项就是关于良性\恶性肿瘤的判断,现在有一批数据集是关于肿瘤大小的,任务就 ...

  9. 逻辑回归(Logistic Regression)算法小结

    一.逻辑回归简述: 回顾线性回归算法,对于给定的一些n维特征(x1,x2,x3,......xn),我们想通过对这些特征进行加权求和汇总的方法来描绘出事物的最终运算结果.从而衍生出我们线性回归的计算公 ...

  10. Python机器学习算法 — 逻辑回归(Logistic Regression)

    逻辑回归--简介 逻辑回归(Logistic Regression)就是这样的一个过程:面对一个回归或者分类问题,建立代价函数,然后通过优化方法迭代求解出最优的模型参数,然后测试验证我们这个求解的模型 ...

随机推荐

  1. RAC 环境中 gc block lost 和私网通信性能问题的诊断

    声明:此文来自于MOS(Doc ID 1674865.1),整理在此以便于大家阅读学习. ■ 概要 在Oracle的RAC环境中,数据库会收集global cache 的工作负载统计信息,并把这些信息 ...

  2. linux特殊权限rws和rwt

    Linux文件,除了rwx这些权限外,还有一些特殊的权限,如rws.rwt. 1.s权限(setuid) 1.1 设置方法:chmod u+s 该位可以让普通用户以root用户的角色运行只有root帐 ...

  3. commons中StringUtils的全解

    StringUtils()方法的导入包是:org.apache.commons.lang3.StringUtils 作用是:StringUtils()方法是 Apache Commons Lang 库 ...

  4. BGP路由协议学习一

    转载请注明出处: 1.BGP的特点: BGP使用TCP作为其传输层协议(端口号为179),使用触发式路由更新,而不是周期性路由更新. BGP能够承载大批量的路由信息,能够支撑大规模网络. BGP提供了 ...

  5. NPOI在EXCEL中插入图片和超链接

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  6. InnoDB 存储引擎之 Buffer Pool

    Mysql 5.7 InnoDB 存储引擎整体逻辑架构图 一.Buffer Pool 概述 InnoDB 作为一个存储引擎,为了降低磁盘 IO,提升读写性能,必然有相应的缓冲池机制,这个缓冲池就是 B ...

  7. 如何避免JavaScript中的内存泄漏?

    前言 过去,我们浏览静态网站时无须过多关注内存管理,因为加载新页面时,之前的页面信息会从内存中删除. 然而,随着单页Web应用(SPA)的兴起,应用程序消耗的内存越来越多,这不仅会降低浏览器性能,甚至 ...

  8. IDEA的Maven换源

    打开IDEA安装路径,然后打开下面的文件夹 plugins\maven\lib\maven3\conf 在conf文件目录下出现一个setting.xml的文件.(ps:如果没有,请忽略本文,自行创建 ...

  9. 大白话说Python+Flask入门(三)

    写在前面 今天状态很不好,我发现学这部分知识的时候,会出现溜号或者注意力无法集中的情况. 我能想到的是,大概率是这部分知识,应该是超出了我现在的水平了,也就是说我存在知识断层了,整体感觉真的是一知半解 ...

  10. [WPF]动手写一个简单的消息对话框

    消息对话框是UI界面中不可或缺的组成部分,用于给用户一些提示,警告或者询问的窗口.在WPF中,消息对话框是系统原生(user32.dll)的MessageBox,无法通过Style或者Template ...