向量化
对于向量之间的点乘,最开始会想到用 for 循环遍历,但是 for 循环速度很慢。可以在 python 中可以使用向量化(批量化处理)代码来实现快速的计算:
其原理为:第三方库 numpy 能充分利用并行化来加快计算,并行化指令(SIMD指令)在 CPU 和 GPU 上都是允许的。
import numpy as np
c = np.dot(a,b) # 向量点乘
-
关于 numpy 中 dot 函数的使用,可参考CSDN上的博客:
https://blog.csdn.net/g310773517/article/details/139266771
关于 numpy 中其他内置函数的使用,可参考CSDN上的博客:
https://blog.csdn.net/nihaoxiaocui/article/details/51992860
示例:
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(i)·dz(i),dw和x都是n维向量,相当于第 i 个样本上 x 向量的 n 个特征分别乘上本次算出的 dz 值,再进行向量相加。
此时,
dw=[dw1,dw2,...,dwn]
。 -
去除外部for循环:
这里的 b 为 1 个实数,但当把向量加上此实数时,python 会自动把实数扩展成符合条件的向量(这里扩成 1×m 的行向量)
→ 这在 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中的广播 |