DEEPLREARNING.Ai-2.11~14 笔记

吴老师这四节课,主要讲述了向量化计算。虽然在大多数情况中,for循环都适用,而且是最常用的方法之一,但是对于深度学习的计算,反而是向量化的方法更为适用。下面就来探究一下原因和实践一下吧。

2.11 向量化(Vectorization)

向量化和for循环的对比
在上一次我们介绍逻辑回归时,曾经提到要计算表达式 Z = w T x + b , \Z = w^{T}x+b, Z=wTx+b,其中的 w 和 x 分别为   n x \ n_x  nx维的列向量。如果不采用向量化的方法,那么 w 和 x 分别是两个庞大的数组,用循环的方法使它们一次一次完成相应的计算,计算次数多,而且耗时长;如若采用向量化的手段计算上述表达式,对于python来说,一个表达式(需要调用numpy模块的相应函数)就足够:z = np.dot(w,x)+b 比起既耗时又费力的for循环,向量化的方法显然会让我们的研究过程更轻松愉快。
下面是一个代码例子来比较两个方法的时长:

	import numpy as np
	import time
	a = np.random.rand(1000000)#产生一个百万维的数组
	b = np.random.rand(1000000)#同上
	tic = time.time()#记录下当时的时间
	c = np.dot(a,b)
	toc = time.time()
	print(c)
	print("Vectorized version"+str(1000*(toc-tic))+"ms")#将时间扩大成毫秒级
	
	c = 0
	tic = time.time()
	for i in range(1000000):
		c += a[i]*b[i]
	toc = time.time()
	print(c)
	print("For loop:"+str(1000*(toc-tic))+"ms")

输出结果为:
在这里插入图片描述
从这个例子看出,非向量化的方法,也就是for循环的方法,要比向量化的方法多花费了34倍向量化版本的时间。在需要大量数据的深度学习模型中,向量化是很必要的减少程序运行时间的方法。

PS:运行时间减少的原因:
CPU 和GPU 都有并行化的指令,有时候也叫做SIMD指令,意思是单指令流多数据流,如果你使用了这样的内置函数,比如np.function或者别的可以去掉for循环的函数,这样的话,python中的numpy模块就可以充分利用并行化去做更快的计算。虽然GPU比较擅长SIMD计算,但CPU也不差。
所以我们以后需要注意的是:在你的指令里,尽量避免for循环。如果你能找到一个内置函数或者别的方式去代替for循环, 那么通常会比直接使用for循环更快。

2.12 向量化的更多例子

第一个例子
举例#1 如果你想计算向量   U = A ∗ v   \ U = A*v\,  U=Av(其中u,A,v均为向量矩阵),那么对于常规的for循环思维,就是采用两重循环,用表达式   U [ i ] + = A [ i ] [ j ] ∗ v [ j ] \ U[i] += A[i][j] *v[j]  U[i]+=A[i][j]v[j]来完成运算;对于向量化的计算,则只需一条指令解决:U = np.dot(A,v)

举例#2 假设你的内存中已经有一个v列向量,如果你想做作用到向量v的每个元素上的指数运算,那么你会怎么做呢?
在这里插入图片描述
左边是显然的for循环思路,而我们依旧可以用一条指令完成运算。numpy内置了很多函数来帮助我们满足各种各样的运算需求,比如正在应用的np.exp()就是计算指数运算的。他相对于左边,少了for循环,所需的运算时间也会少很多。
除此之外,numpy还有很多常用向量化计算的函数,比如:

np.log(v)
np.abs(v)
np.maxnum(v,0)
v**2 #计算v中每个元素的平方
1/v  #v中每个元素取倒数

所以python对向量是预设了很多种不同的运算的,这些运算基本都支持广播操作,所以python对于转换真的很人性化呀(
举例#3 logistic回归梯度下降算法实现

for循环实现
显然这是一个逻辑回归梯度下降算法的for循环实现(伪)代码,我们实际上需要更新所有的   d w 1 , d w 2 … … d w n   \ dw_1,dw_2……dw_n\,  dw1,dw2dwn, 但这里只写了一部分(逃
而对于向量化的改进方法,就是把   d w 1 , d w 2 … … d w n   \ dw_1,dw_2……dw_n\,  dw1,dw2dwn变成一个向量,
在这里插入图片描述
之后我们就不需要再对其用for循环更新,而直接采用
在这里插入图片描述
将其更新,最后,为了去掉最后一个for循环,我们只需   d w / = m   . \ dw /= m\,.  dw/=m.
好了现在我们把三个for循环简化成一个for循环了。
在这里插入图片描述
在这里插入图片描述
本小节主要深化了向量化的概念,同时去掉一个for循环之后,你将会发现你的代码处理速度会快很多

2.13向量化 logistic回归

不使用任何的显式for循环,来实现对整个数据集的一步迭代
1.逻辑回归的正向传播步骤:
在这里插入图片描述

2.实现
首先我们定义一个X来作为你训练的输入,像这样在不同的列中堆叠在一起,X是一个   n x ∗ m   \ n_x *m\,  nxm的矩阵。首先要做的是一步完成计算   z ( 1 ) , z ( 2 ) , … … z ( m )   \ z^{(1)},z^{(2)},……z^{(m)}\,  z(1),z(2),z(m),事实上用了一行代码。
在这里插入图片描述
所以第一步是求   w T ∗ x 1 , w T ∗ x 2 … …   \ w^T*x_1,w^T*x_2……\,  wTx1,wTx2
在这里插入图片描述
第二步是加上第二项 b,
在这里插入图片描述
则这个   1 ∗ m   \ 1*m\,  1m的行向量的第一个元素,恰好是   Z ( 1 )   \ Z^{(1)}\,  Z(1)的定义,以此类推,所以我们就得到了关于Z的一个向量,并一步算出了所有的Z。
在这里插入图片描述
z在python中的表达式:
在这里插入图片描述
且由于python的广播操作,你不用担心实数b是否会不适用向量之间的加法。
接下来,我们来找一个办法来计算   a ( 1 ) , a ( 2 ) , … … a ( m )   \ a^{(1)},a^{(2)},……a^{(m)}\,  a(1),a(2),a(m),调用sigmoid函数高效率地计算出激活函数的向量集合

本小节我们实现了不使用任何for循环,就实现了从m个训练样本中一次性计算出所有的z和a,所以这就是逻辑回归正向传播一步迭代的向量化实现,同时处理所有m个训练样本

2.14 向量化 逻辑回归的梯度输出

在之前你知道了如何通过向量化计算来计算整个训练集的预测值a,本小节会讲解如何用向量化计算来计算梯度
根据上一小节的经验,我们会定义一个向量来作为我们的输出,它是一个1*m的向量
在这里插入图片描述
我们已经学会了如何计算A和Y,所以dZ可以用一个式子来完成计算。
在这里插入图片描述
参考2.12的举例#3,我们最后还有一个for循环没有实现简化,现在我们来想办法去掉这个for循环
之前for循环内容
我们可以这么做来实现db的计算:
在这里插入图片描述
对于dw,我们可以这么做:
在这里插入图片描述
向量化导数的计算的分析就完成了。
下面我们来总结一下:
在这里插入图片描述
但如果你想把梯度下降的操作做多次迭代,比如1000次导数梯度下降,那么你仍旧需要一次最外层的for循环:
在这里插入图片描述
但每一次迭代中不使用for循环已经节约了大量的时间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值