美文网首页
DeepLearning学习笔记#Logistic Regres

DeepLearning学习笔记#Logistic Regres

作者: 茶尽 | 来源:发表于2018-01-25 11:25 被阅读0次

    概述

    本文主要内容:如何利用Python的来实现Logistic函数。包括:初始化、计算代价函数和梯度、使用梯度下降算法进行优化等并把他们整合成为一个函数。本文将通过训练来判断一副图像是否为猫。

    准备

    在这个过程中,我们将会用到如下库:
    numpy:Python科学计算中最重要的库
    h5py:Python与H5文件交互的库
    mathplotlib:Python画图的库
    PIL:Python图像相关的库
    scipy:Python科学计算相关的库

    import numpy as np
    import matplotlib.pyplot as plt
    import h5py
    import scipy
    from PIL import Image
    from scipy import ndimage
    from lr_utils import load_dataset
    
    %matplotlib inline
    

    数据集

    在训练之前,首先需要读取数据,读取数据的代码如下:

    def load_dataset():
        """
        # 加载数据集
        """
        train_dataset = h5py.File('E:/python/week2/train_catvnoncat.h5', "r")  #读取H5文件
        train_set_x_orig = np.array(train_dataset["train_set_x"][:]) # your train set features
        train_set_y_orig = np.array(train_dataset["train_set_y"][:]) # your train set labels
     
        test_dataset = h5py.File('E:/python/week2/test_catvnoncat.h5', "r")
        test_set_x_orig = np.array(test_dataset["test_set_x"][:]) # your test set features
        test_set_y_orig = np.array(test_dataset["test_set_y"][:]) # your test set labels
     
        classes = np.array(test_dataset["list_classes"][:]) # the list of classes
        
        train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))  #对训练集和测试集标签进行reshape
        test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))
        
        return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes
        
    train_set_x_orig, train_set_y, test_set_x_orig, test_set_y, classes = load_dataset()
    

    数据说明:

    对于训练集的标签而言,对于猫,标记为1,否则标记为0。每一个图像的维度都是(num_px, num_px, 3),其中,长宽相同,3表示是RGB图像。train_set_x_orig和test_set_x_orig中,包含_orig是由于我们稍候需要对图像进行预处理,预处理后的变量将会命名为train_set_x和train_set_y。train_set_x_orig中的每一个元素对于这一副图像,我们可以用如下代码将图像显示出来:

    # Example of a picture
    index = 25
    plt.imshow(train_set_x_orig[index])
    print ("y = " + str(train_set_y[:, index]) + ", it's a '" + classes[np.squeeze(train_set_y[:, index])].decode("utf-8") +  "' picture.")
    

    接下来,根据图像集来计算出训练集的大小、测试集的大小以及图片的大小:

    ### START CODE HERE ### (≈ 3 lines of code)
    m_train = train_set_x_orig.shape[0]
    m_test = test_set_x_orig.shape[0]
    num_px = train_set_x_orig.shape[1]
    ### END CODE HERE ###
    
    print ("Number of training examples: m_train = " + str(m_train))
    print ("Number of testing examples: m_test = " + str(m_test))
    print ("Height/Width of each image: num_px = " + str(num_px))
    print ("Each image is of size: (" + str(num_px) + ", " + str(num_px) + ", 3)")
    print ("train_set_x shape: " + str(train_set_x_orig.shape))
    print ("train_set_y shape: " + str(train_set_y.shape))
    print ("test_set_x shape: " + str(test_set_x_orig.shape))
    print ("test_set_y shape: " + str(test_set_y.shape))
    

    Ps:其中X_flatten = X.reshape(X.shape[0], -1).T可以将一个维度为(a,b,c,d)的矩阵转换为一个维度为(b∗∗c∗∗d, a)的矩阵。

    接下来,对图像值进行归一化。

    由于图像的原始值在0到255之间,最简单的方式是直接除以255即可。

    train_set_x = train_set_x_flatten/255.
    test_set_x = test_set_x_flatten/255.
    

    logistics介绍

    对于每个训练样本x,其误差函数的计算方式如下:

    而整体的代价函数计算如下:

    实现

    接下来,我们将按照如下步骤来实现Logistic:

    1. 定义模型结构
    2. 初始化模型参数
    3. 循环
    3.1 前向传播
    3.2 反向传递
    3.3 更新参数
    4. 整合成为一个完整的模型

    Step1:实现sigmod函数

    # GRADED FUNCTION: sigmoid
    
    def sigmoid(z):
        """
        Compute the sigmoid of z
    
        Arguments:
        z -- A scalar or numpy array of any size.
    
        Return:
        s -- sigmoid(z)
        """
    
        ### START CODE HERE ### (≈ 1 line of code)
        s = 1/(1+np.exp(-(z)))
        ### END CODE HERE ###
        
        return s
    

    Step2:初始化参数

    # GRADED FUNCTION: initialize_with_zeros
    
    def initialize_with_zeros(dim):
        """
        This function creates a vector of zeros of shape (dim, 1) for w and initializes b to 0.
        
        Argument:
        dim -- size of the w vector we want (or number of parameters in this case)
        
        Returns:
        w -- initialized vector of shape (dim, 1)
        b -- initialized scalar (corresponds to the bias)
        """
        
        ### START CODE HERE ### (≈ 1 line of code)
        w = np.zeros((dim,1))
        b = 0
        ### END CODE HERE ###
    
        assert(w.shape == (dim, 1))
        assert(isinstance(b, float) or isinstance(b, int))
        
        return w, b
    

    Step3:前向传播与反向传播

    计算公式如下:



    # GRADED FUNCTION: propagate
    
    def propagate(w, b, X, Y):
        """
        Implement the cost function and its gradient for the propagation explained above
    
        Arguments:
        w -- weights, a numpy array of size (num_px * num_px * 3, 1)
        b -- bias, a scalar
        X -- data of size (num_px * num_px * 3, number of examples)
        Y -- true "label" vector (containing 0 if non-cat, 1 if cat) of size (1, number of examples)
    
        Return:
        cost -- negative log-likelihood cost for logistic regression
        dw -- gradient of the loss with respect to w, thus same shape as w
        db -- gradient of the loss with respect to b, thus same shape as b
        
        Tips:
        - Write your code step by step for the propagation. np.log(), np.dot()
        """
        
        m = X.shape[1]
        
        # FORWARD PROPAGATION (FROM X TO COST)
        ### START CODE HERE ### (≈ 2 lines of code)
        A = sigmoid(np.dot(w.T,X)+b)                                    # compute activation
        cost = -1.0/m*(np.sum(Y*np.log(A)+(1-Y)*np.log(1-A)))                                 # compute cost
        ### END CODE HERE ###
        
        # BACKWARD PROPAGATION (TO FIND GRAD)
        ### START CODE HERE ### (≈ 2 lines of code)
        dw = 1/m*(np.dot(X,(A-Y).T))
        db = 1/m*(np.sum(A-Y))
        ### END CODE HERE ###
    
        assert(dw.shape == w.shape)
        assert(db.dtype == float)
        cost = np.squeeze(cost)
        assert(cost.shape == ())
        
        grads = {"dw": dw,
                 "db": db}
        
        return grads, cost
    

    Step4:更新参数

    更新参数的公式如下:

    完整代码如下:

    # GRADED FUNCTION: optimize
    
    def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost = False):
        """
        This function optimizes w and b by running a gradient descent algorithm
        
        Arguments:
        w -- weights, a numpy array of size (num_px * num_px * 3, 1)
        b -- bias, a scalar
        X -- data of shape (num_px * num_px * 3, number of examples)
        Y -- true "label" vector (containing 0 if non-cat, 1 if cat), of shape (1, number of examples)
        num_iterations -- number of iterations of the optimization loop
        learning_rate -- learning rate of the gradient descent update rule
        print_cost -- True to print the loss every 100 steps
        
        Returns:
        params -- dictionary containing the weights w and bias b
        grads -- dictionary containing the gradients of the weights and bias with respect to the cost function
        costs -- list of all the costs computed during the optimization, this will be used to plot the learning curve.
        
        Tips:
        You basically need to write down two steps and iterate through them:
            1) Calculate the cost and the gradient for the current parameters. Use propagate().
            2) Update the parameters using gradient descent rule for w and b.
        """
        
        costs = []
        
        for i in range(num_iterations):
            
            
            # Cost and gradient calculation (≈ 1-4 lines of code)
            ### START CODE HERE ### 
            grads, cost = propagate(w,b,X,Y)
            ### END CODE HERE ###
            
            # Retrieve derivatives from grads
            dw = grads["dw"]
            db = grads["db"]
            
            # update rule (≈ 2 lines of code)
            ### START CODE HERE ###
            w = w - learning_rate*dw
            b = b - learning_rate*db
            ### END CODE HERE ###
            
            # Record the costs
            if i % 100 == 0:
                costs.append(cost)
            
            # Print the cost every 100 training examples
            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
    

    Step5:利用训练好的模型对测试集进行预测:

    计算公式如下:

    当输入大于0.5时,我们认为其预测认为结果是猫,否则不是猫。

    # GRADED FUNCTION: predict
    
    def predict(w, b, X):
        '''
        Predict whether the label is 0 or 1 using learned logistic regression parameters (w, b)
        
        Arguments:
        w -- weights, a numpy array of size (num_px * num_px * 3, 1)
        b -- bias, a scalar
        X -- data of size (num_px * num_px * 3, number of examples)
        
        Returns:
        Y_prediction -- a numpy array (vector) containing all predictions (0/1) for the examples in X
        '''
        
        m = X.shape[1]
        Y_prediction = np.zeros((1,m))
        w = w.reshape(X.shape[0], 1)
        
        # Compute vector "A" predicting the probabilities of a cat being present in the picture
        ### START CODE HERE ### (≈ 1 line of code)
        A = sigmoid(np.dot(w.T,X)+b)   
        ### END CODE HERE ###
        
        for i in range(A.shape[1]):
            
            # Convert probabilities A[0,i] to actual predictions p[0,i]
            ### START CODE HERE ### (≈ 4 lines of code)
            if(A[0][i]<=0.5):
                Y_prediction[0][i] = 0
            else:
                Y_prediction[0][i] = 1
            ### END CODE HERE ###
        
        assert(Y_prediction.shape == (1, m))
        
        return Y_prediction
    

    Step5:将以上功能整合到一个模型中:

    # GRADED FUNCTION: model
    
    def model(X_train, Y_train, X_test, Y_test, num_iterations = 2000, learning_rate = 0.5, print_cost = False):
        """
        Builds the logistic regression model by calling the function you've implemented previously
        
        Arguments:
        X_train -- training set represented by a numpy array of shape (num_px * num_px * 3, m_train)
        Y_train -- training labels represented by a numpy array (vector) of shape (1, m_train)
        X_test -- test set represented by a numpy array of shape (num_px * num_px * 3, m_test)
        Y_test -- test labels represented by a numpy array (vector) of shape (1, m_test)
        num_iterations -- hyperparameter representing the number of iterations to optimize the parameters
        learning_rate -- hyperparameter representing the learning rate used in the update rule of optimize()
        print_cost -- Set to true to print the cost every 100 iterations
        
        Returns:
        d -- dictionary containing information about the model.
        """
        
        ### START CODE HERE ###
        
        # initialize parameters with zeros (≈ 1 line of code)
        w, b = initialize_with_zeros(X_train.shape[0])
    
        # Gradient descent (≈ 1 line of code)
        parameters, grads, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost)
        
        # Retrieve parameters w and b from dictionary "parameters"
        w = parameters["w"]
        b = parameters["b"]
        
        # Predict test/train set examples (≈ 2 lines of code)
        Y_prediction_test = predict(w,b,X_test)
        Y_prediction_train = predict(w,b,X_train)
    
        ### END CODE HERE ###
    
        # Print train/test Errors
        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
    

    测试一下该模型吧:

    # Example of a picture that was wrongly classified.
    index = 1
    plt.imshow(test_set_x[:,index].reshape((num_px, num_px, 3)))
    print ("y = " + str(test_set_y[0,index]) + ", you predicted that it is a \"" + classes[int(d["Y_prediction_test"][0,index])].decode("utf-8") +  "\" picture.")
    

    此时观察打印结果,测试准确率已经可以达到70.0%。

    而对于训练集,其准确性达到了99%。这表明了模型有着一定的过拟合。

    相关文章

      网友评论

          本文标题:DeepLearning学习笔记#Logistic Regres

          本文链接:https://www.haomeiwen.com/subject/uuamaxtx.html