【DL笔记2】矢量化技巧&Logistic Regression算法解析
- 2020 年 3 月 11 日
- 笔记
【DL笔记2】矢量化技巧&Logistic Regression的算法解析
一、神经网络中的矢量化技巧
就一句话:
❝“只要阔能,就不要使用显示for循环(explicit for-loop),而是尽可能采用矢量化技术(Vectorization)” ❞
为啥呢,因为深度学习中的数据量往往巨大,用for循环去跑的话效率会非常低下,相比之下,矩阵运算就会快得多。而python的矩阵“传播机制(broadcasting)”和专门用于矩阵计算的numpy包更是给了我们使用矩阵运算的理由。
因此,我们在面对深度学习问题的时候,首先要想一想,如何把数据进行“矢量化”,就是转化成向量或者矩阵,这样可以大大提高我们的效率。
有关python的传播机制、numpy的典型使用以及for-loop和vectorization运算时间的对比,可以参见我的另一篇文章:Python的矩阵传播机制&矩阵运算——消灭for循环!
具体怎么把我们的数据进行Vectorization呢?我们在Logistic regression的python实现里面去看一看:
二、Logistic regression算法解析
在写python代码之前,我们先用伪代码来示意一下Logistic regression的过程。
首先回顾一下上一篇文章【DL笔记1】Logistic Regression:最基础的神经网络中对Logistic regression模型的学习和预测的步骤:
- 初始化W和b
- 指定learning rate和迭代次数
- 每次迭代,根据当前W和b计算对应的梯度(J对W,b的偏导数),然后更新W和b
- 迭代结束,学得W和b,带入模型进行预测,分别测试在训练集合测试集上的准确率,从而评价模型
假设我们的样本数为m,每一个样本的特征数为n,我们设置的迭代次数为2000,那么按照上述步骤,如果使用for循环的话,我们需要几个for,总循环多少次呢?
1.初始化:
J=0 (这是cost), , (J对w的偏导,即梯度), b=0
2.一次迭代:
For i = 1 to m: { (行向量乘以列向量,就是个数了) (a就是上一篇文章中的y',就是经过Activation之后的值) (注意这里的+=,说明是个累加,就是要累加每一个样本的loss,最后还要除以m,就是代价cost) }
For j = 1 to n: { } (这里一样,都是累加,因为要遍历完m个样本,然后求平均梯度,再更新) }
3.计算平均梯度,并更新:
更新完之后别忘了,“这只是一次迭代,接着把上面过程重复2000次!”
简单看一下:
for iteration=1 to 2000: #梯度下降2000次迭代 for i=1 to m: # 遍历m个样本 for j=1 to n # 求每一个特征对应的w的梯度
3个for循环啊!共循环2000×m×n次!通常情况下,m至少也有大几千吧,特征n更是成千上万,尤其是对于图片识别类的问题。这样for下去简直阔怕!
事实上,我们可以“通过Vectorization来消除第二个和第三个for循环”,因为一个样本的n个特征可以组成一个向量,m个样本也可以组成一个大矩阵。于是:
可以设: 其中 是一个列向量: ,包含了n个特征。
对应的,n个权重也可以定义成一个列向量:
于是,我们将上面的算法都转换成矩阵或者向量: (上面出现的np.dot()是numpy包的矩阵乘法,就是点乘,np.sum()就是numpy的矩阵求和)
搞定,一次迭代中,一个for也没有用。(当然,这个迭代的for循环我们没法消除,因为迭代次数是我们人为设定的,这里设为2000次,也可以设为1500次、3000次等等)
上面就是Logistic regression的算法了.
我们总结一下:
所谓的Vectorization,就是把我们需要用for-loop来对那些只有上标或者下标变化的变量,放进一个向量或者矩阵中,让他们所有变量同时计算!因此,Logistic regression算法向量化的过程,就是:
- 把m个样本,同时计算,同时算出它们的,也就是直接算Z这个m维行向量
- 同时把Z的m维都激活,得到m维行向量A
- 得到A和Z之后,就可以直接计算J对Z的梯度dZ了,得到dZ之后,也就可以直接算出W和b的梯度了
- 同时更新所有的和b