深度学习第二课(2):神经网络的编程基础
2.11 向量化(Vectorization)
逻辑回归中计算$z=w^Tx+b$,其中$w,x$都是列向量,下面是两种方法的对比:
1.循环
z=0
for i in range(n_x):
z+=w[i]*x[i]
z+=b
2.向量化
z=np.dot(w,x)+b
很明显向量化方法较快
举例说明:
import numpy as np #导入numpy库
a=np.array([1,2,3,4])#创建数据a
print(a)
#输出[1,2,3,4]
import time #导入时间库
a=np.random.rand(1000000)
b=np.random.rand(1000000)
tic=time.time()#输出当前时间
#向量化版本
c=np.dot(a,b)
toc=time.time()
print(f"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(c)
print(f"For loop:{str(1000*(toc-tic))}ms")
输出如下:
可以看到,向量化版本能快速得到结果。
大规模的机器学习一般都使用GPU或者图像处理单元进行实现,CPU和GPU都有并行化指令,他们有时候叫做SIMD指令,通常GPU更擅长SIMD计算。如果我们应用类似np.dot这样的函数,Pytho会自动进行并行化处理。
2.12 向量化的更多例子
numpy库中有很多向量函数,如:
import numpy as np
np.exp(v)#计算指数函数
np.log()#计算对数函数
np.abs()#绝对值函数
np.maximum()#计算元素y中的最大值
v**2#算平方
1/v#求倒数
#通常numpy中有类似的内置函数可以避免使用循环
2.13 向量化逻辑回归
先计算$Z$,如上图所示:
z=np.dot(w.T,x)+b#注意z的维度:1*m 参数b使用了python广播
再计算A,也就是由a组成的矩阵,也就是我们之前提到的$\widehat{y}$:
通过编写sigmoid函数
#通过Python定义sigmoid函数
def sigmoid(z):
return 1 / (1 + np.exp(-z))
然后直接调用:
a=sigmoid(z)#和z的维度保持一致
2.14 向量化logistic回归的梯度输出
向量化方法如下:
前五个公式完成了前向和后向传播,后面两个公式用来更新参数(具体参考上面图片的内容)
2.15 python中的广播
cal=A.sum(axis=0)#在A数组的竖直方向上求和,axis=1表示在水平方向上求和
percentage=100*A/cal.reshape(1,4)#reshape(1,4)将其变为1*4矩阵,这块有点多余了,本身就是1*4
reshape是常用的时间操作,时间复杂度是O(1),
如上图所示,如果两个矩阵有一个维度相同,而其中一个矩阵的另外一个维度为1,则可以将维度为1的矩阵沿着1维度的方向上进行广播。
2.16 python_numpy向量的说明
注意断言函数的用法:assert(a.shape==(5,1))
上图总结:在实际使用时候,尽量定义为一个列向量,这样会减少bug,如果不小心定义为一个秩为1的向量,可以使用a=a.reshape((5,1))
来转换。断言函数用来检查某些变量或数组是否是我们预期的,若不是则会报错,在实际程序出现bug时候调试非常有用。
2.17 Jupyter/iPython Notebooks快速入门
$shift+enter$执行块代码
2.18 logistic损失函数的解释
PASS