前言:引入周志华《机器学习》书中对数几率统计中的理论和吴恩达深度学习系列结合自己理解的内容。

应用场景:逻辑回归是一个应用于二分类的算法。其输出标记为

对数函数回归方程_对数函数回归方程

,而线性回归模型所产生的预测值

对数函数回归方程_对数函数回归方程_02

是实数,于是将实值z转化为0/1值,

对数函数回归方程_损失函数_03

如果预测值大于0则标记为1,反之则标记为0.

 

逻辑回归的假设函数(Hypothesis function):

对数函数回归方程_损失函数_04

  •   值为预测值 更正式的说是表示y等于1的可能性或机会
  • w   实际上是特征权重,维度与特征向量相同
  • b   表示偏差

这时我们得到是一个关于x的线性函数,但此时对于二分类问题却不是一个非常好的算法,因为如果想让对数函数回归方程_代价函数_05表示实际值y等于1的几率的话,对数函数回归方程_代价函数_05应该是在0~1之间,因为实际

对数函数回归方程_对数函数回归方程_07

的值比1要大的多,或者甚至可能为一个负值。因此我们在逻辑回归中应使用sigmoid函数,将线性函数转化为非线性函数,如下图所示:

对数函数回归方程_损失函数_08

sigmoid函数的公式为:

对数函数回归方程_损失函数_09

对数函数回归方程_损失函数_10

,这里z是一个实数,当z的值特别大时,对数函数回归方程_机器学习_11趋向于0,而此时sigmoid函数的值趋向于1,反之,当z的值特别小时,sigmoid函数的值趋向于0.,亦可将公式变形为

对数函数回归方程_机器学习_12

,这里将y视为样本x作为正例的可能性,1-y视为作为反例的可能性。则两者的比值

对数函数回归方程_机器学习_13

,称为几率,反映了x作为正例的相对可能性。所以在实现逻辑回归时,主要任务就说让机器学习参数w和b。

 

逻辑回归的代价函数(Logistic Regression Cost Function):

代价函数的作用是训练参数w和参数b,通过给定m个训练样本,我们可以得到w和b,并以此得到预测值。

对数函数回归方程_机器学习_14

上标i的含义是样本的索引。

 

损失函数(Loss function):又叫误差函数,用于衡量算法的运行情况

对数函数回归方程_深度学习_15

,通过L来衡量预测值和真实值得差距,一般情况下我们用到得损失函数是用均方误差来衡量,即

对数函数回归方程_代价函数_16

,而在逻辑回归中,我们使用

对数函数回归方程_深度学习_17

来衡量误差值。

  • 当y=1时,损失函数,如果想让误差尽可能小,那么就要尽可能大,因为sigmoid函数取值0~1,所以会无限接近于1。
  • 当y=1时,损失函数,如果想让误差尽可能小,那么就要尽可能小,因为sigmoid函数取值0~1,所以会无限接近于0。

损失函数是在单个函数上定义的,它衡量的是算法在单个训练样本中表现如何,为了衡量算法在全部训练样本上的表现如何,我们需要定义一个算法的代价函数,算法的代价函数是对m个样本的损失函数求和然后除以m:

对数函数回归方程_深度学习_18

损失函数只适用于像这样的单个训练样本,而代价函数是参数的总代价,所以在训练逻辑回归模型时候,我们需要找到合适的w和b,来让代价函数 J的总代价降到最低。

 

逻辑回归中的梯度下降(Logistic Regression Gradient Descent):

对数函数回归方程_代价函数_19

对数函数回归方程_深度学习_20

对数函数回归方程_对数函数回归方程_21

w和b的修正量表示如下:

对数函数回归方程_深度学习_22

假设样本只有两个特征x1和x2,为了计算z,需要输入w1,w2和b,以及特征值x1,x2.

首先我们需要反向计算出代价函数

对数函数回归方程_对数函数回归方程_23

关于a的导数,

对数函数回归方程_机器学习_24

对数函数回归方程_对数函数回归方程_25

,因为

对数函数回归方程_代价函数_26

所以

对数函数回归方程_对数函数回归方程_27

,由链式求导法则可知,

对数函数回归方程_损失函数_28


对数函数回归方程_损失函数_29

所以

对数函数回归方程_机器学习_30

。又因为

对数函数回归方程_对数函数回归方程_31

dw1 =

对数函数回归方程_损失函数_32

,dw2 =

对数函数回归方程_代价函数_33

,db = dz

所以单个样本的逻辑回归梯度下降要做的就是先用a-y计算出dz,再分别计算出dw1,dw2,db,最后更新w和b的值即完成一次梯度下降

 

m个样本的梯度下降:

J=0;dw1=0;dw2=0;db=0;

for i = 1 to m

    z(i) = wx(i)+b;

    a(i) = sigmoid(z(i));

    J += -[y(i)log(a(i))+(1-y(i))log(1-a(i));

    dz(i) = a(i)-y(i);

    dw1 += x1(i)dz(i);

    dw2 += x2(i)dz(i);

    db += dz(i);

J/= m;

dw1/= m;

dw2/= m;

db/= m;

w=w-alpha*dw

b=b-alpha*db

将其向量化来简化上述代码

首先来看db,因为

对数函数回归方程_深度学习_34

,不难看出,db可用1/m*np.sum(dz)来代替,然后来看dw

对数函数回归方程_对数函数回归方程_35

,X是一个行向量,因此展开后

对数函数回归方程_代价函数_36

则处理后代码可简化为:

对数函数回归方程_对数函数回归方程_37

代码实际演练 (采取吴恩达深度学习第二周编程作业):

定义sigmoid函数,返回经过处理后的预测值

def sigmoid(z):
    """
    参数:
        z  - 任何大小的标量或numpy数组。
    
    返回:
        s  -  sigmoid(z)
    """
    s = 1 / (1 + np.exp(-z))
    return s

 计算代价函数及其渐变

def propagate(w, b, X, Y):
	"""
    实现前向和后向传播的成本函数及其梯度。
    参数:
        w  - 权重,大小不等的数组(num_px * num_px * 3,1)
        b  - 偏差,一个标量
        X  - 矩阵类型为(num_px * num_px * 3,训练数量)
        Y  - 真正的“标签”矢量(如果非猫则为0,如果是猫则为1),矩阵维度为(1,训练数据数量)

    返回:
        cost- 逻辑回归的负对数似然成本
        dw  - 相对于w的损失梯度,因此与w相同的形状
        db  - 相对于b的损失梯度,因此与b的形状相同
    """
	m = X.shape[1]
    
    #正向传播
    A = sigmoid(np.dot(w.T,X) + b) #计算激活值,请参考公式2。
    cost = (- 1 / m) * np.sum(Y * np.log(A) + (1 - Y) * (np.log(1 - A))) #计算成本,请参考公式3和4。
    
    #反向传播
    dw = (1 / m) * np.dot(X, (A - Y).T) #请参考视频中的偏导公式。
    db = (1 / m) * np.sum(A - Y) #请参考视频中的偏导公式。
	
	#使用断言确保我的数据是正确的
    assert(dw.shape == w.shape)
    assert(db.dtype == float)
    cost = np.squeeze(cost)
    assert(cost.shape == ())
    
    #创建一个字典,把dw和db保存起来。
    grads = {
                "dw": dw,
                "db": db
             }
    return (grads , cost)

使用渐变下降更新参数w和b

def optimize(w , b , X , Y , num_iterations , learning_rate , print_cost = False):
    """
    此函数通过运行梯度下降算法来优化w和b
    
    参数:
        w  - 权重,大小不等的数组(num_px * num_px * 3,1)
        b  - 偏差,一个标量
        X  - 维度为(num_px * num_px * 3,训练数据的数量)的数组。
        Y  - 真正的“标签”矢量(如果非猫则为0,如果是猫则为1),矩阵维度为(1,训练数据的数量)
        num_iterations  - 优化循环的迭代次数
        learning_rate  - 梯度下降更新规则的学习率
        print_cost  - 每100步打印一次损失值
    
    返回:
        params  - 包含权重w和偏差b的字典
        grads  - 包含权重和偏差相对于成本函数的梯度的字典
        成本 - 优化期间计算的所有成本列表,将用于绘制学习曲线。
    
    提示:
    我们需要写下两个步骤并遍历它们:
        1)计算当前参数的成本和梯度,使用propagate()。
        2)使用w和b的梯度下降法则更新参数。
    """
    
    costs = []
    
    for i in range(num_iterations):
        
        grads, cost = propagate(w, b, X, Y)
        
        dw = grads["dw"]
        db = grads["db"]
        
        w = w - learning_rate * dw
        b = b - learning_rate * db
        
        #记录成本
        if i % 100 == 0:
            costs.append(cost)
        #打印成本数据
        if (print_cost) and (i % 100 == 0):
            print("迭代的次数: %i , 误差值: %f" % (i,cost))
        
    params  = {
                "w" : w,
                "b" : b }
    grads = {
            "dw": dw,
            "db": db } 
    return (params , grads , costs)

optimize函数会输出已学习的w和b的值,我们可以使用w和b来预测数据集X的标签。

计算预测值

对数函数回归方程_机器学习_38

将a的值变为0(如果激活值<= 0.5)或者为1(如果激活值> 0.5)