对于大规模的多次迭代的深度学习,通常训练时间都比较长,所以性能优化就格外重要。这里我们看一下向量运算。它用到一些线性代数的知识,但是不多,你不用担心。向量运算比起循环运算要说要快,尤其是对GPU来说。
比如我们的输入feature有多个x1,x2,…xn,则对应的参数也会有多个:w1,w2,…wn. 我们如果求解:
w1*x1+w2*x2…+wn\xn,有两种方法,一种是通过循环计算,一种是通过向量计算。在图像识别时,图片里的每个像素点都是一个feature。n可能是百万到千万级别。
下边的python代码展示了通过循环和通过向量运算的时间差异:


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)))
c = 0
tic = time.time()
for i in range(1000000):
    c+=a[i]*b[i]
toc = time.time()
print("Loop version:"+str(1000*(toc-tic)))

而得到的结果是向量化计算后的速度是循环计算的500多倍:


Vectorized version:0.9999275207519531
Loop version:539.9999618530273

np.dot(a,b) 如果a,b都是一维向量,求的是内积(就像我们例子里那样),对于矩阵,求得的是矩阵积。不熟悉的话,你可以去复习一下。
对于向量操作numpy里还有很多。但是numpy的向量操作里有一个特性很重要,那就是广播(Broadcasting)
广播的意思是,如果一个矩阵和一个数值,一个行向量,列向量进行进行加减乘除操作时,会自动把数值,行向量,列向量扩展到和矩阵同维度,然后进行计算。这些知识在我们后来进行神经网络的矩阵运算时会用到。


import numpy as np
A = np.zeros((3,3))
print(A)
print(A+1)
print(A+[2,2,2])
print(A+[[3],[3],[3]])

得到的结果为:


[[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]

[[1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]

[[2. 2. 2.]
 [2. 2. 2.]
 [2. 2. 2.]]

[[3. 3. 3.]
 [3. 3. 3.]
 [3. 3. 3.]]

还有就是如果你在python里生成矩阵时,如果是行向量,有时候会和array类型混淆,你要做的是每次在生成行向量或列向量时明确指定行列:


np.random.randn(4) //产生的是数组
np.random.randn(1,4) //产生行向量
np.random.randn(4,1) //产生列向量

你也可以通过下边的语句来检查一个矩阵是不是你认为的结构:


assert(a.shape == (5,1))

你也可以通过下边的语句进行转化:


a.reshape((5,1))

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: