每日一学———深度学习中的向量化
- 作用
当处理大数据时,若使用for循环多次运算,因为迭代次数很多,运算速度往往会非常慢,从而花费许多时间,在线性代数中,数据经常利用向量和矩阵处理,实际上多个列向量或行向量拼凑在一起,就成了矩阵,在python的numpy库中有专门用于矩阵运算的模块,linalg model,有很多内置函数可以取代for循环,加快运算。举个例子。
#比较for循环和numpy中内置函数的dot()的速度 ---用于计算矩阵的乘法
import numpy as np #导入numpy库
a = np.array([1,2,3,4]) #创建一个数组
print(a)
[1 2 3 4]
import time #导入时间库
a = np.random.rand(1000000)
b = np.random.rand(1000000) #通过random随机得到两个一百万维度的数组
#两个一维向量的乘法就是点成,对应位置相乘再求和
#random.rand(d0,d1,...dn)dn表示第n维的元素个数
#eg. random.rand(1,2,3),得shape为(1,2,3)的array,
# random.rand(3),得shape为(3,)的array
#向量化的版本
tic1 = time.time() #现在测量一下当前时间
c = np.dot(a,b)
toc1 = time.time()
print("Vectorized version:"+str(1000*(toc1-tic1)) + "ms")#打印一下向量化的版本的时间
print(c)
#继续增加非向量化的版本
tic2 = time.time()
c = 0
for i in range(1000000):
c += a[i]*b[i]
toc2 = time.time()
print("For loop:"+str(1000*(toc2-tic2)) + "ms")#打印for循环的版本的时间
print(c)
Vectorized version:1.001596450805664ms
250236.71556814743
For loop:385.35094261169434ms
250236.7155681432
- 结果分析
非向量版(即采用for循环)所花费的时间是向量化版本的300多倍,可见数据的向量化处理确实大大加快运算速度。
经验法则:能不用for循环就不用for循环,尽量减小时间复杂度。
- 更多向量化的例子
(1) 计算一个矩阵(mn)和一个一维向量(n1)的乘积
(2) 已经有一个向量𝑣,并且想要对向量𝑣的每个元素做指数操作,得到向量𝑢等于𝑒的𝑣1,𝑒的𝑣2,一直到𝑒的𝑣𝑛次方。
#例1 计算一个矩阵(m*n)和一个一维向量(n*1)的乘积
A = np.array([[1,2,3],
[4,5,6]])
B = np.array([7,8,9])
#print(B.shape)
C = np.zeros((A.shape[0],),dtype = np.int32)
#非向量版本
for i in range(A.shape[0]):
for j in range(A.shape[1]):
C[i] += A[i][j]*B[j]
print(C)
#向量版本
D = np.dot(A,B)
print(D)
#显然向量化版本更加简洁,尽量不直接使用for循环
[ 50 122]
[ 50 122]
#例2 对向量的每个元素做指数操作
import numpy as np #导入numpy模块构造矩阵,数组,向量
import math #导入python中的math模块进行更高级的数学运算
u = np.array([0,1,2,3]) #构造一个向量
#向量化的版本
v = np.exp(u) #调用numpy中的矩阵操作函数,一行代码搞定
print(v)
#非向量化的版本
v = np.zeros((4,))
#print(u)
for i in range(4):
v[i] = math.exp(u[i]) #math里的exp()没有向量的概念,需要循环求出单个的值
print(v)
#总结:numpy中有向量,矩阵的概念,所以numpy的一些内置函数认识矩阵,可以直接操作,不需循环
#而math.exp()不认识矩阵,向量,只能直接实现一个数的指数操作
[ 1. 2.71828183 7.3890561 20.08553692]
[ 1. 2.71828183 7.3890561 20.08553692]
- 向量化逻辑回归
以房价模型为例:
(1) 按一个样本分析: 假如房屋的尺寸(x)与房价(y)存在这样一个函数关系:
y = θ x + b {\rm{y = \theta x + b}} y=θx+b
假如我们要预测100个房屋的房价,100个房屋有100个尺寸,则这里的x就可以构成一个向量,或1 x 100的矩阵,形如:
[
x
(
1
)
,
x
(
2
)
,
x
(
3
)
,
x
(
4
)
,
…
…
,
x
(
100
)
]
\left[ {{x^{\left( 1 \right)}},{x^{\left( 2 \right)}},{x^{\left( 3 \right)}},{x^{\left( 4 \right)}}, \ldots \ldots ,{x^{\left( {100} \right)}}} \right]
[x(1),x(2),x(3),x(4),……,x(100)]
(2) 特征矩阵
但这只是一个特征,但现实生活中的房价不可能只跟房屋尺寸有关,还可能与房屋的楼层数,房屋的材料等等许多因素有关,所以假设有i个房屋,每个房屋有j个特征会影响房价,一个房屋的特征可以表示为一个列向量,以第一个房屋为例,形如:
那i个这样的房屋拼凑起来就可以得到一个(j x i 型)特征矩阵,每个特征对应函数关系式中的一个
θ
\theta
θ ,所以也可以得到一个(j x 1 型)的列向量:
[
θ
1
θ
2
θ
3
.
.
.
θ
j
]
\left[ \begin{array}{l} {\rm{\theta 1}}\\ {\rm{\theta 2}}\\ {\rm{\theta 3}}\\ ...\\ {\rm{\theta j}} \end{array} \right]
⎣⎢⎢⎢⎢⎡θ1θ2θ3...θj⎦⎥⎥⎥⎥⎤ ,我们把这个称为W。由线性函数关系式和矩阵相乘的法则,可知
简洁明了的写呢,就是 Y = W T X + B Y = W^T X+B Y=WTX+B
用python一行代码就可以实现:线性回归:Z = np.dot(w.T,X) + b
逻辑回归:A = 𝜎(𝑍)
𝜎(𝑍)为激励函数,目的是为了使它变得非线性。(一方面是为了贴合实际情况,另一方面处理二分类问题时,控制范围为(0,1))
(3)向量化 logistic 回归的梯度输出
用一下这5个公式即可完成前向和后向传播,也实现了对所有训练样本进行预测和求导。
之后再利用后两个公式,梯度下降更新参数。
对以上5个公式的一些注解:
①具体流程如下:
分析实际问题,构建函数模型 --> 得到代价函数(反映预测值和真实值之间的差距)–> 代价函数对参数求导,用于参数更新(向着真实值的方向不断调整)
②以多特征的逻辑回归问题为例,流程图如下:
- 总结啦!总结啦!
(1)总的来说,前向传播是计算出所有预测值,然后再反向传播求出各预测值对应的梯度,你会发现使用向量化,可以一次性将所有梯度求出来,这是非常高效哒\ o^ 0 ^o/,梯度求出来,就可以利用这些梯度调整学习率,不断减小参数,寻求最合适的参数,不断地朝着真实值的方向靠近啦 !!
(2)这里面很多地方可以结合矩阵的维度理解,矩阵与矩阵相乘得到什么形状的矩阵等等……可以更快的推导出来。
(3)下次的内容是向量化和逻辑回归的实战题目。