第二周 第二部分 Python与向量化
- 2.11 向量化
逻辑回归中要计算 ,向量化的表示为 z = np.dot(w,x)+b
课程中给出如下代码,分别计算向量化和非向量化之后的计算时间对比
import numpy as np
import time
a = np.random.rand(1000000)
b = np.random.rand(1000000)
tic = time.time()
c = np.dot(a,b)
toc = time.time()
print(c)
print('Vectorization 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(c)
print('For loop:' + str(1000*(toc-tic)) + 'ms')
可以自己运算下结果,看看向量化的力量。
很多深度学习的程序都是在GPU上跑的。其实GPU和CPU都有SIMD,即单指令流多数据流。
Python中的NumPy可以充分利用并行化,去进行更快的运算。
- 2.12 更多向量化例子
经验法则:当编写新的神经网络或者LR算法时,一定要尽量避免使用for循环。
例:要将 v --> u
# 非向量化表示
u = np.zeros((n,1))
for i in range(n):
u[i] = math.exp(v[i])
# 向量化表示
u = np.exp(v)
在2.10节中(https://blog.csdn.net/weixin_41153216/article/details/80922975),完成m个训练样本的梯度下降,需要两个循环,在本节中,去掉内部的循环,代码修改如下
# 单次梯度下降V2.py
# 修改部分:向量初始化,内部参数的计算(去掉计算参数的循环,也是本节的重点)。平均值的向量化
import numpy as np
dJ = 0
dw = np.zeros((nx,1))
db = 0
# 遍历m次训练样例,对相应的值进行累加
for ind in range(0,m):
zi = W.T * x[:,ind] + b
ai = sigmoid(zi)
J += -[yi*np.log(ai)+(1-yi)*np.log(1-ai)]
dzi = ai - yi
dw += xi * dzi
db += dzi
# 对所有m个样本的累积梯度值,求平均
J /= m
dw /= m
db /= m
- 2.13 正向传播的向量化
本节中主要介绍正向传播的向量化表示,根据2.1节((https://blog.csdn.net/weixin_41153216/article/details/80922975))中的介绍,X.shape = (nx,m),一共m个训练样例,因此会生成m个输出值Z。
本节内容是向量化如下的代码
for ind in range(0,m):
zi = W.T * x[:,ind] + b
ai = sigmoid(zi)
向量化的数学思想如下:
Python的表示
Z = np.dot(W.T,X) + b
这里涉及到一个概念是Python广播,b实际上是一个数,但是在计算时,会扩展成1*m的矩阵。
- 2.14 向量化的梯度输出
定义
下面求参数的导数
在Python中的实现是 db = np.sum(dZ)/m
向量优化后的代码
# 梯度下降.py
# 向量化
import numpy as np
dJ = 0
dw = 0
db = 0
# 假设迭代1000次
for ind in range(0,1000):
Z = np.dot(W.T,X) + b
A = sigmoid(Z)
dZ = A - Y
dw = (X*dZ.T)/m
db = np.sum(dZ)/m
# 进行参数更新
w -= alpha * dw
b -= alpha * db
注:在神经网络或者LR中,要尽量少用循环,但是外层的迭代循环,目前还没有办法省略。