深度神经网络基础
二元分类
假设有以下一张图片,要判断其输出是否为猫,若是,则可以用表示,否则用表示。
计算机保存一张图片通常使用3个独立矩阵,分别对应红、绿、蓝三个颜色通道。如果输入像素是64×64
,则会有3个64×64
的矩阵,即输入是一个3×64×64
的高维度数据,而输出是。
与机器学习之单变量线性回归一样,可以用表示一个训练样本,其中,而,通常用表示整个训练集,其中表示训练样本的大小,以上,由个训练样本可以组成输入矩阵,且,是一个输出矩阵,且。
逻辑回归
对于以上分类问题,给定输入,我们想知道的输出概率,的输出概率代表着该分类问题的结果,的值表示是猫的概率可以简单表示为,且。
对于线性回归,有,而对于逻辑回归,采用激活函数,即:表示,令,则:
,其函数图像如下所示:
当,即也就是时,认为其输出
而,即也就是时,其输出.
逻辑回归损失函数
对于逻辑回归问题,给定训练样本:
,我们希望得到。逻辑回归的损失函数可以由以下公式定义:
对于以上损失函数,有:
若,则,而想让损失函数尽可能小,意味着要尽可能大,又因为,所以是,损失函数最小。
若,则,损失函数要取得最小值,意味着需取得最大值,则需满足。
以上损失函数只适用于单个样本,对于个样本的损失函数可以有如下定义:
梯度下降法
对于以上损失函数,需要找到损失函数的最小值,最常用的算法就是梯度下降算法,即对于一个凸函数,总能通过梯度下降算法找到它的全局最优解,对于此损失函数的梯度下降算法,在机器学习之逻辑回归的算法介绍中已经做了较为详细的推导,在此不再过多叙述,梯度下降算法的简单实现步骤如下所示:
重复以上过程,直到损失函数收敛,以求得参数的值,其中,代表学习率。
计算图
计算图介绍:
假设有一函数表达式为:,其计算过程可以简单分为三个步骤,如下所示:
-
对于以上三个步骤,用计算图可以有如下表示
计算图的导数:
如上图所示,利用计算图从左向右的流程,一步步可以算出的值,那么,依靠从右向左的反向传播就可以算出对每个变量的导数,如下图所示:
其反向传播过程如图中红色箭头所示,根据导数定义以及链式计算法则,有如下计算:
逻辑回归中的梯度下降算法
单个样本的逻辑回归梯度下降算法
关于逻辑回归的损失函数,有如下公式:
假设有两个输入特征和两个参数,则用计算图(流程图)表示其计算过程如下所示:
依照其计算图中的反向传播过程和链式法则,其导数计算如下所示:
···
最后,参数的更新规律为:
其中,表示学习率。
个样本的逻辑回归
个样本的损失函数,如下所示:
其梯度计算公式,可以有如下表示:
在实际计算过程中,需要计算每一个样本的关于的梯度,最后求和取平均,在一个具体算法实现中,其为代码可以如下所示:
假设有2个特征向量,个样本,则有:
初始化:
以上,是应用一次梯度下降的过程,应用多次梯度下降算法之后,其参数的更新如下所示:
注意:以上,算法实现过程中,有两个特征和参数,分别是和,当有个特征和参数时,可以利用循环完成。
向量化
向量化的简单示例:
如以上算法表示,通过for
循环来遍历个样本和个特征,当在整个算法运行过程中,需要考虑运行时间的问题,当样本数量和特征足够大时,采用传统的for
循环不是一个明智的选择,为了减少算法运行时间,特地引入了向量化的实现。
将一以下代码作为示例:
import numpy as np
import random
import time
a = np.random.rand(1000000)
b = np.random.rand(1000000)
ts = time.time()
c = np.dot(a,b)
te = time.time()
print(c)
print("向量化的代码实现花费时间:"+str((te-ts)*1000)+" ms")
c = 0
ts = time.time()
for i in range(1000000):
c += a[i]*b[i]
te = time.time()
print(c)
print("for循环代码实现花费时间:"+str((te-ts)*1000)+" ms")
如上所示,同样实现两个数组(向量)相乘的过程,对于百万级别的数据,for
循环的实现方式所花费的时间差不多是向量化的400倍左右,向量化的实现可以简单的理解为是一个并行的过程,而for
循环可以简单理解为串行的过程,所以通过向量化的实现,大大节省了运行程序所耗费的时间。在算法实现过程中,应该尽量避免使用for
循环。
用向量化实现逻辑回归:
对于逻辑回归的算法,需要考虑输入向量和权重参数,其中,,,而根据矩阵乘法运算法则和逻辑回归的实现原理,有:
在python
中用numpy
库,可以简单的用以下一行代码实现(一般认为是一个R^{1×1}的偏置常量):
z = np.dot(W.T,x)+b
根据之前的学习,对于逻辑回归利用反向传播算法计算导数,有:
对于以上,公式,有如下定义:
对于以上过程,摈弃传统的for
循环实现,采用向量化的实现方式可以简单表示为:
dw = np.dot(X,dZ^T)
db = 1/m*np.sum(dZ)
综合以上所有向量化的实现,可以得到利用python
实现的一个高度向量化的逻辑回归梯度下降算法(a代表学习率):
Z = np.dot(W^T,X)+b
A = np.exp(Z)
dZ = A-Y
dw = np.dot(X,dZ^T)
db = 1/m*np.sum(dZ)
w = w-a*dw
b = b-a*db
以上,只是实现一次梯度下降的伪代码,在实际算法运行过程中,我们仍然需要利用循环实现多次梯度下降。