使代码更高效
什么是向量化?
在Logistic回归中,需要计算 z = w T x + b z=w^Tx+b z=wTx+b,w和x都是n维列向量,当特征很多时就有很多的向量
在python中的一个非向量实现:
for i in range(n-x):
z+=w[i]*x[i]
z+=b
这种形式的计算很慢,在numpy中,z=np.dot(w,x)是在计算 w T x w^Tx wTx后面直接加上b,计算的速度非常快
比较向量化版本和非向量化版本时间消耗的值:
import time
import numpy as np
# 创建一个一百万维度的随机数组
a = np.random.rand(1000000)
b = np.random.rand(1000000)
tic = time.time()
c = np.dot(a, b)
toc = time.time()
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("for loop=" + str(1000*(toc-tic)) + "ms")
例子1:
向量u作为矩阵A和另一个向量v的乘积:
u
=
A
v
u=Av
u=Av
矩阵乘法的定义:
u
i
=
∑
j
A
i
j
v
j
u_i=\sum_jA_{ij}v_j
ui=∑jAijvj
非向量化:
u=np.zeros((n,1))
for i .....:
for j ....:
u[i]+=A[i][j]*v[j]
向量化:
u=np.dot(A,v)
例子2:
假设内存中已经有一个向量v,现在要做指数运算,作用到向量v中的每个元素
可以令u等于那个向量
非向量化:
u=np.zeros((n,1))
for i in range(n):
u[i]=math.exp(v[i])
一开始让u初始化成全0向量,for循环一次计算一个元素
向量化:
使用numpy中的内置函数
import numpy as np
#v作为输入,u作为输出,一个内置函数替换了for循环
u=np.exp(v)
【扩展】numpy中常用内置函数:
#逐个元素计算log
np.log(v)
#计算绝对值
np.abs(v)
#计算所有元素和0之间相比的最大值
np.maximum(v,0)
#计算每个元素的平方
v**2
#计算每个元素的倒数
1/v