深度学习:(三)向量化在梯度下降中的应用
发布时间
阅读量:
阅读量
向量化
在处理向量之间的点乘时,默认思路是采用 for 循环遍历的方法。然而这种 for 循环的方式运行速度较慢。实际上,在 Python 中可以通过采用向量化的操作(即批量化处理)来显著提高计算效率。
其核心原理是:第三方库numpy能够充分运用多线程处理技术来提高计算效率,并行化的SIMD指令在CPU和GPU上均被支持。
import numpy as np
c = np.dot(a,b) # 向量点乘
关于 numpy 中 dot 函数的使用,可参考上的博客:
关于 numpy 中其他内置函数的使用,可参考上的博客:
示例:
import numpy as np
import time
a = np.random.rand(1000000) # 随机成一个维度一百万的向量a
b = np.random.rand(1000000) # 随机成一个维度一百万的向量b
c = 0
# 向量化版本
tic = time.time() # 查询时间(单位s)
c = np.dot(a,b) # 向量点乘
toc = time.time() # 查询时间(单位s)
print ("Vectorized version:" + str(1000*(toc-tic)) +"ms") # 打印向量化版本的计算时间
# for循环版本
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循环版本的计算时间
——————————————————————————————————————————————————————————————————————————————————————————————————————
# 输出结果为:
Vectorized version:1.0004043579101562ms
249690.94904401066
For loop:309.94439125061035ms
249690.94904401703
# 精确到小数点后8位,则无误差
按照经验法则,在神经网络的训练过程中,尽量避免在可能的情况下显式使用 for 循环结构。
向量化逻辑回归的一次梯度输出
去除内部for循环:

在这一计算步骤中, dw 累加运算等于 x 向量与 dz 向量按元素相乘后的结果之和。 其中变量 dw 与输入样本特征向量 x 均为 n 维空间中的元素。 这等价于将输入样本中的每一个特征维度与其对应的梯度值相乘后累加至目标变量 dw 的过程。
此时,dw=[dw1,dw2,...,dwn]。
去除外部for循环:

这里的 b 被定义为一个实数。然而,在将该向量与这个实数相加时,Python会自动地将这个实数转化为满足维度要求的一个行向量。
→ 这在 python 中叫做“广播 ”(broadcasting)。

接着:

最终化简为:

转化成代码,最终代码为:
import numpy as np
# 定义σ函数
def sigmoid(x):
z = np.exp(-x)
sig = 1 / (1 + z)
return sig
# 开始一次梯度下降法
Z = np.dot(w.T,x)+b # 小x,且这里b被广播了
A = sigmoid(Z)
dz = A-Y
dw = (1/m)*np.dot(X,dz.T) # 大X
db = (1/m)*np.sum(dz) # 大X
w = w-α*dw
b = b-α*db
向量化逻辑回归的多次梯度输出
一次梯度输出可以通过向量化消除 for 循环,但多批次梯度输出仍然需要在外层使用一层 for 循环。循环次数代表了 w 和 b 被更新的次数。
————————————————————————————————————————————————————————
| 上一篇博客 | 下一篇博客 |
|---|---|
| 计算图及其应用,以及梯度下降法的初版程序 | python中的广播 |
全部评论 (0)
还没有任何评论哟~
