DL总结(一)---logistic regression as a neural network

二元分类Binary classification与逻辑回归logistic regression

逻辑回归即是一个二元分类模型,例如给定一定数量的猫的样本图片,经过模型训练后,随意给定一张图片,判断是否是猫,这里把结果设为y,输入的数据为x,若图片是64x64的大小,且为RGB色彩模式,则x为一个64x64x3的矩阵,即n=12288,用n(x) = 12288 来表示输入特征向量x的维度,为了简化,直接用小写n 来表示输入特征向量的维度 所以,在此二元分类问题中 我们的目标是学习到这样的一个分类器: 我们输入一幅以特征向量x表示的图像 然后预测对应的输出y是1还是0 即,这幅图上是猫还是不是猫。
在这里插入图片描述在这里插入图片描述

首先,先罗列出一些变量与符号,这些变量与符号将在后续用到
单个样本由一对(x,y):表示x是一个n(x)维的特征向量 ,y是标签,取值为0或1 训练集包含m个训练样本 所以训练集将被写成 ( x ( 1 ) , y ( 1 ) ) (x^{(1)}, y^{(1)}) (x(1),y(1))表示第一个样本的输入和输出, ( x ( 2 ) , y ( 2 ) ) (x^{(2)}, y^{(2)}) (x(2),y(2))代表第二个样本的输入和输出 直到 ( x ( m ) , y ( m ) ) (x^{(m)}, y^{(m)}) (x(m),y(m)),表示最后一个样本输入和输出
在这里插入图片描述

Cost function and Grandient

对于逻辑回归学习算法会得到的输出标签y,y在监督学习问题中全是0或者1,因此这是一种针对二分类问题的算法,给定的输入特征向量 x 和一幅图片对应,识别这是否是一张猫的图片 因此我们想要一种算法能够输出一个预测值 我们称之为 y ^ \hat{y} y^这代表对真实标签 Y 的估计,事实上讲 y ^ \hat{y} y^是当给定输入特征x时,预测标签 y 为1的概率 换种说法就是当x是一张图片, y ^ \hat{y} y^告诉你这是一张猫图的概率:
即:
y ^ = P { y = 1 ∣ x } \hat{y} = P\{y=1|x\} y^=P{y=1x}
那么如何产生 y ^ \hat{y} y^呢,如果是线性回归,则有如下的假设,
y ^ = w T x + b \hat{y} = w^Tx+b y^=wTx+b
而在二元分类算法中, y ^ \hat{y} y^的取值范围必须为(0,1),那么可以带入sigmoid函数:
g ( z ) = 1 1 + e − z g(z) = \frac{1}{1+e^{-z}} g(z)=1+ez1
其函数图像为:
在这里插入图片描述
在构建好逻辑回归的假设函数后的目标即是优化参数W和b,使得预测的标签 y ^ \hat{y} y^能够尽可能接近真实的输出y,因此需要计算代价函数以优化参数,若按照线性回归的损失函数(error function),即 L ( y ^ , y ) = 1 2 ( y ^ − y ) 2 L(\hat{y},y)=\frac1{2}(\hat{y}-y)^2 L(y^,y)=21(y^y)2,然而对于二元分类问题,采用此法计算损失函数将导致所得得代价函数不为凸函数,即有多个局部最优点,如图:
在这里插入图片描述
因此,所采用得损失函数为:
L ( y ^ , y ) = − y l o g ( y ^ ) − ( 1 − y ) l o g ( 1 − y ^ ) L(\hat{y},y) = -ylog(\hat{y})-(1-y)log(1-\hat{y}) L(y^,y)=ylog(y^)(1y)log(1y^)
代价函数为:
J ( w , b ) = − 1 m ∑ i = 0 m L ( y ^ , y ) = − 1 m ∑ i = 0 m ( y l o g ( y ^ ) + ( 1 − y ) l o g ( 1 − y ^ ) ) J(w, b) = -\frac1{m}\sum_{i=0}^{m}L(\hat{y},y) = -\frac1{m}\sum_{i=0}^{m}(ylog(\hat{y})+(1-y)log(1-\hat{y})) J(w,b)=m1i=0mL(y^,y)=m1i=0m(ylog(y^)+(1y)log(1y^))
这样所得到得代价函数图像为:
在这里插入图片描述
根据不断地迭代w和b的值即可得到使代价最小的最优化的参数:
w : = w − α ∂ J ∂ w w:=w-\alpha\frac{\partial{J}}{\partial{w}} w:=wαwJ
b : = b − α ∂ J ∂ b b:=b-\alpha\frac{\partial{J}}{\partial{b}} b:=bαbJ

计算图(compute graph)

根据上文,对逻辑回归作以下概要,首先根据输入的标签X(vectorizing)与初始的参数,带入线性回归假设函数得到z,再带入sigmoid函数得到 y ^ \hat{y} y^标签;
z = w T x + b z = w^Tx +b z=wTx+b
y ^ = a = σ ( z ) \hat{y} = a = \sigma(z) y^=a=σ(z)
L ( a , y ) = − y l o g ( a ) − ( 1 − y ) l o g ( 1 − a ) L(a,y)=-ylog(a)-(1-y)log(1-a) L(a,y)=ylog(a)(1y)log(1a)

得到如图逻辑回归的前向传播计算图:
在这里插入图片描述
再从计算图末端(即损失函数)向后递推求到损失函数关于a、z、wj以及b的偏导数,如图:

称为其反向传播算法(其实就是向后依次求复合函数的偏微分)

由此对于代价函数,即有公式:
∂ J ∂ w = 1 m X ( A − Y ) T \frac{\partial J}{\partial w} = \frac{1}{m}X(A-Y)^T wJ=m1X(AY)T
∂ J ∂ b = 1 m ∑ i = 1 m ( a ( i ) − y ( i ) ) \frac{\partial J}{\partial b} = \frac{1}{m} \sum_{i=1}^m (a^{(i)}-y^{(i)}) bJ=m1i=1m(a(i)y(i))

上图即位文首所谈到的区分图片是否是猫的用于逻辑回归的计算图,也是最简单的神经网络,下面即介绍对该神经网络模型搭建的算法实现

算法实现

导入模块

import numpy
import matplotlib.pyplot as plt

train_set_x_orig:训练集的x数据(m_train个样本)
train_set_y:训练集的y数据
test_set_x_orig:测试集的x数据(m_test个样本)
test_set_y:训练集的y数据

m_train = train_set_x_orig.shape[0]
m_test = test_set_x_orig.shape[0]
num_px = train_set_x_orig.shape[1]#每个样本的特征数

实现sigmoid函数

def sigmoid(z):
    """
    Compute the sigmoid of z
    Arguments:
    z -- 标量或任意大小的numpy数组
    Return:
    s -- sigmoid(z)
    """
    s = 1/(1+np.exp(-z))
    return s

初始化神经网络参数:

def initialize_with_zeros(dim):

    w = np.zeros((dim, 1))#由于逻辑回归是单个神经元,故可以将w参数初始化为0,在后续的深度神经网络中,若w均初始化为0,则所有结点都会做相同的运算,无法破坏其对称性
    b = 0
    
    assert(w.shape == (dim, 1))
    assert(isinstance(b, float) or isinstance(b, int))
    
    return w, b

根据上述计算图的前向后向传播算法计算对参数的导数:

def propagate(w, b, X, Y):
    
    m = X.shape[1]#样本数
    
    # 前向传播算法(From X to Cost)
    A = sigmoid(np.dot(w.T, X)+b)  # 计算激活函数
    cost = (-1/m)*np.sum(Y*np.log(A)+(1-Y)*np.log(1-A)).sum()    #计算代价函数                             
    
    # 反向传播算法 (TO FIND GRAD)
    dw = np.dot(X, (A-Y).T)/m
    db = np.sum(A-Y).sum()/m

    assert(dw.shape == w.shape)
    assert(db.dtype == float)
    cost = np.squeeze(cost)#把[[[17]]]变为17
    assert(cost.shape == ())
    
    grads = {"dw": dw,
             "db": db}
    
    return grads, cost

反复迭代,优化参数

def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost = False):

    costs = []
    
    for i in range(num_iterations):
             
        #代价和梯度计算
        grads, cost = propagate(w, b, X, Y)
        print_cost = True
        
        dw = grads["dw"]
        db = grads["db"]
        
        # 更新梯度
        w = w - learning_rate*dw
        b = b - learning_rate*db
        
        #每100次迭代输出一次代价
        if i % 100 == 0:
            costs.append(cost)
       
        if print_cost and i % 100 == 0:
            print ("Cost after iteration %i: %f" %(i, cost))
    
    params = {"w": w,
              "b": b}
    
    grads = {"dw": dw,
             "db": db}
    
    return params, grads, costs

利用优化好的参数进行预测:

def predict(w, b, X):

    
    m = X.shape[1]
    Y_prediction = np.zeros((1,m))#初始化预测值
    w = w.reshape(X.shape[0], 1)
    A = sigmoid(np.dot(w.T, X)+b)#通过训练好的参数计算A

    
    for i in range(A.shape[1]):
        
        if A[0,i] > 0.5:(当概率大于0.5时视预测值为1)
            Y_prediction[0,i] = 1
  
    assert(Y_prediction.shape == (1, m))
    
    return Y_prediction

整合上述函数构建训练模型:

def model(X_train, Y_train, X_test, Y_test, num_iterations = 2000, learning_rate = 0.5, print_cost = False):

    # 初始化参数
    w, b = initialize_with_zeros(X_train.shape[0])

    # 梯度下降算法优化参数
    parameters, grads, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost = False)
    
    # 提取迭代优化后的的参数
    w = parameters["w"]
    b = parameters["b"]
    
    # 预测给定的样本
    Y_prediction_test = predict(w, b, X_test)
    Y_prediction_train = predict(w, b, X_train)

    print("train accuracy: {} %".format(100 - np.mean(np.abs(Y_prediction_train - Y_train)) * 100))
    print("test accuracy: {} %".format(100 - np.mean(np.abs(Y_prediction_test - Y_test)) * 100))

    
    d = {"costs": costs,
         "Y_prediction_test": Y_prediction_test, 
         "Y_prediction_train" : Y_prediction_train, 
         "w" : w, 
         "b" : b,
         "learning_rate" : learning_rate,
         "num_iterations": num_iterations}
    
    return d
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值