上一篇讲解了深度学习的逻辑回归模型,本篇就接下来讲逻辑回归的向量化以及编译所需的基础代码。
1.sigmoid函数:
sigmoid函数可用python的math库编译,但是这么编译无法应用于庞大的矩阵数据库(运用矩阵作为变量会报错)
import math
def basic_sigmoid(x):
s = 1 / (1 + math.exp(-x))
return s
basic_sigmoid([1,2,3])
这里我们引用numpy库,对矩阵进行运算
import numpy as np
x = np.array([1, 2, 3])
print(np.exp(x))
这样子就不会报错了,于是我们成功的将sigmoid函数应用于矩阵
numpy库的简介放在下面,读者可以自行查看
所以我们引用numpy函数库,通过np.array将输入的数据转变为矩阵,也可用np.reshape改变矩阵的维数,可以轻松地将数据转变为我们想要的一维矩阵。
例如识别图片时将图片的三通套rgb像素值放入一个特征向量中:
我们来看看一张图片在计算机中是如何表示的,为了保存一张图片,需要保存三个矩阵,它们分别对应图片中的红、绿、蓝三种颜色通道,如果你的图片大小为64x64像素,那么你就有三个规模为64x64的矩阵,分别对应图片中红、绿、蓝三种像素的强度值。通过输入三通道像素值,即64x64的三个矩阵,我们可以使用np.reshape函数来将他们放入一个矩阵中:
import numpy as np
def image2vector(image):
v = image.reshape((image.shape[0] * image.shape[1] * image.shape[2], 1))
return v
image = np.array([[[ 0.67826139, 0.29380381],
[ 0.90714982, 0.52835647],
[ 0.4215251 , 0.45017551]],
[[ 0.92814219, 0.96677647],
[ 0.85304703, 0.52351845],
[ 0.19981397, 0.27417313]],
[[ 0.60659855, 0.00533165],
[ 0.10820313, 0.49978937],
[ 0.34144279, 0.94630077]]])
print(image2vector(image))
运行效果如图,成功将3x2的三维矩阵转换为18x1的一维矩阵
numpy中需要理解的一个非常重要的概念是“广播”。它对于在不同形状的数组之间进行数学运算非常有用。
先来看一个例子:
import numpy as np
def softmax(x):
x_exp = np.exp(x) #对所有元素使用sigmoid函数
x_sum = np.sum(x_exp, axis=1, keepdims=True) #对各行进行累加
s = x_exp / x_sum #每个元素除以对应行的sum
return s
x = np.array([
[9, 2, 5, 0, 0],
[7, 5, 0, 0 ,0]])
print("softmax(x) = " + str(softmax(x)))
其中np.sum(x,axis=0|1,keepdims=True)
axis=1时矩阵按列相加,即算列的和
axis=2时矩阵按行相加,即算行的和
keepdims用来保持矩阵的维数性质(不太懂的童鞋可自行查找函数)
输出结果如下
这就是对两行进行sigmoid函数运算后再算出各自所占比重的广播
向量化:
深度学习中如果对每个数据都运用for循环while循环进行遍历计算,会让算法变得低效,同时在深度学习领域会有越来越大的数据集,所以能够应用你的算法且没有显式的for循环会是重要的,并且会帮助你适用于更大的数据集,向量化的作用就是减少运算时间,优化算法
import time #导入时间库
a = np.random.rand(1000000)
b = np.random.rand(1000000) #通过round随机得到两个一百万维度的数组
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(c)
print('For loop:' + str(1000*(toc-tic)) + 'ms')#打印for循环的版本的时间
返回值如图
可以看出运算时间快了差不多一百倍
同理,通过运用向量化,我们可以减少(矩阵转置)wt * X(特征向量)的运算量
上一篇我们讲过求出偏导后需要循环进行梯度下降,如果w是二维以上的向量,就需要对w1,w2等等都进行梯度下降,但是我们如果定义dw为矩阵,将dw1,dw2等放入矩阵中一次次进行运算就可以减少for遍历,从而提升算法的性能
数据集也是同理,将它们放入矩阵中,运用点乘来计算