Logistic代码实战

转载过程中,图片丢失,代码显示错乱。

为了更好的学习内容,请访问原创版本:

http://www.missshi.cn/api/view/blog/59aa08fee519f50d04000170

Ps:初次访问由于js文件较大,请耐心等候(8s左右)

本节课中,我们将学习如何利用Python的来Logistic。
这是第一节Python代码内容,接下来我们将从一些基本的Python编程开始讲述。

 本文中的代码经过作者改进,修改bug,已经提交到github。地址为:

https://github.com/Lite-Java/missshi_deeplearning_ai

使用numpy构建基本函数

numpy是Python在科学计算中最常用的库。接下来我们将要学习一些numpy中包含的常用函数。

 

练习1:利用np.exp()实现sigmod函数:

在利用np.exp()函数之前,我们首先使用math.exp()函数来实现sigmod函数,并将二者对比来突出np.exp()的优点。

其中,

  1. import math
  2.  
  3. def basic_sigmod(x):
  4.     """
  5.     # 计算单个标量的sigmod函数
  6.     """
  7.     s = 1.0 / (1 + 1/ math.exp(x))
  8.     return s
  9.     
  10. print basic_sigmod(3)
  11. # 0.9525741268224334

上述描述了如何对一个标量执行sigmod函数,而在深度学习的应用中,我们通过是对向量或者矩阵来执行sigmod运算。

如何执行将该函数用于矢量或者矩阵,那么系统会抛出异常:

 
 
  1. print basic_sigmod([3, 2, 1])

而如果使用的是np.exp函数的话,如果输入的是一个矢量或者矩阵,那么对应的输出也会是矢量或矩阵,即针对每个元素进行指数计算。

  1. import numpy as np
  2. = np.array([1, 2, 3])
  3. print np.exp(x)
  4. # [  2.71828183   7.3890561   20.08553692]

此外,对于numpy array类型的变量,其加减乘除的方法也统一被改写。

以下面的例子为例:

 
 
  1. = np.array([1, 2, 3])
  2. print x + 3
  3. # [4 5 6]

接下来,我们来实现一个真正的、可用于矢量或矩阵的sigmod函数:

其需求如下:

  1. import numpy as np
  2.  
  3. def sigmod(x):
  4.     """
  5.     # sigmod函数,可用于矢量和矩阵
  6.     """
  7.     s = 1.0 / (1 + 1 / np.exp(x))
  8.     return s
  9.  
  10. = np.array([1, 2, 3])
  11. print np.exp(x) 
  12. # [ 0.73105858,  0.88079708,  0.95257413]

 

练习2:计算sigmod函数的导数

在之前的理论课程中,我们学习到了sigmod函数的导数公式如下:

接下来,我们通过Python代码进行实现:

 
 
  1. def sigmoid_derivative(x):
  2.     """
  3.     Compute the gradient (also called the slope or derivative) of the sigmoid function with respect to its input x.
  4.     You can store the output of the sigmoid function into variables and then use it to calculate the gradient.
  5.      
  6.     Arguments:
  7.     x -- A scalar or numpy array
  8.     Return:
  9.     ds -- Your computed gradient.
  10.     """
  11.  
  12.     s = 1.0 / (1 + 1 / np.exp(x))
  13.     ds = s * (1 - s)
  14.      
  15.     return ds
  16.      
  17. = np.array([1, 2, 3])
  18. print "sigmoid_derivative(x) = " + str(sigmoid_derivative(x))
  19. # sigmoid_derivative(x) = [ 0.19661193  0.10499359  0.04517666]

 

练习3:将一副图像转为为一个向量

在numpy中,有两个常用的函数:np.shape和np.reshape()。

其中,X.shape可以用于查看当前矩阵的维度。

X.reshape()可以用于修改矩阵的维度或形状。

例如,对于一副彩色图像,其通常是由一个三维矩阵组成的(RGB三个通道)。然而,在深度学习的应用中,我们通常需要将其转换为一个矢量,其长度为3*length*width。

即我们需要将一个三维的矩阵转换为一个一维的向量。

接下来,我们需要实现一个image2vector函数,其输入为一个三维矩阵(length, height, 3),输出为一个矢量。

  1. def image2vector(image):
  2.     """
  3.     Argument:
  4.     image -- a numpy array of shape (length, height, depth)
  5.     
  6.     Returns:
  7.     v -- a vector of shape (length*height*depth, 1)
  8.     """
  9.     
  10.     v = image.reshape((image.shape[0] * image.shape[1] * image.shape[2], 1))
  11.     
  12.     return v
  13.     
  14. image = np.array([[[ 0.67826139,  0.29380381],
  15.         [ 0.90714982,  0.52835647],
  16.         [ 0.4215251 ,  0.45017551]],
  17.  
  18.        [[ 0.92814219,  0.96677647],
  19.         [ 0.85304703,  0.52351845],
  20.         [ 0.19981397,  0.27417313]],
  21.  
  22.        [[ 0.60659855,  0.00533165],
  23.         [ 0.10820313,  0.49978937],
  24.         [ 0.34144279,  0.94630077]]])
  25.  
  26. print "image2vector(image) = " + str(image2vector(image))
  27. # [[ 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]]

 

练习4:按行归一化

在深度学习中,常用的一个技巧是需要对我们的数据进行归一化。

通过,在对数据进行归一化后,梯度下降算法的收敛速度会明显加快。

接下来,我们需要对一个矩阵进行按行归一化,归一化后的结果是每一个的长度为1。

例如:

  

 
 
  1. def normalizeRows(x):
  2.     """
  3.     Implement a function that normalizes each row of the matrix x (to have unit length).
  4.     
  5.     Argument:
  6.     x -- A numpy matrix of shape (n, m)
  7.     
  8.     Returns:
  9.     x -- The normalized (by row) numpy matrix. You are allowed to modify x.
  10.     """
  11.     
  12.     x_norm = np.linalg.norm(x, axis=1, keepdims = True)  #计算每一行的长度,得到一个列向量
  13.     x = x / x_norm  #利用numpy的广播,用矩阵与列向量相除。
  14.  
  15.     return x
  16.     
  17. = np.array([
  18.     [0, 3, 4],
  19.     [1, 6, 4]])
  20. print "normalizeRows(x) = " + str(normalizeRows(x))
  21. # normalizeRows(x) = [[0.    0.6    0.8]  [ 0.13736056  0.82416338  0.54944226]]

在上面的代码中,我们利用了广播的特性,接下来我们主要学习一下广播的使用。

 

练习5:广播的使用及softmax函数的实现

广播是numpy中一个非常强大的功能,它可以帮助我们对不同维度的矩阵、向量、标量之前快速计算。

接下来,我们需要实现一个softmax函数,其定义如下:

  1. def softmax(x):
  2.     """Calculates the softmax for each row of the input x.
  3.  
  4.     Your code should work for a row vector and also for matrices of shape (n, m).
  5.  
  6.     Argument:
  7.     x -- A numpy matrix of shape (n,m)
  8.  
  9.     Returns:
  10.     s -- A numpy matrix equal to the softmax of x, of shape (n,m)
  11.     """
  12.     
  13.     x_exp = np.exp(x) # (n,m)
  14.     x_sum = np.sum(x_exp, axis = 1, keepdims = True) # (n,1)
  15.     s = x_exp / x_sum  # (n,m) 广播的作用
  16.     
  17.     return s
  18.     
  19. = np.array([
  20.     [9, 2, 5, 0, 0],
  21.     [7, 5, 0, 0 ,0]])
  22. print "softmax(x) = " + str(softmax(x))
  23. # softmax(x) = [[ 9.80897665e-01 8.94462891e-04 1.79657674e-02 1.21052389e-04 1.21052389e-04] [ 8.78679856e-01 1.18916387e-01 8.01252314e-04 8.01252314e-04 8.01252314e-04]]

 

矢量化

在深度学习中,我们通常会处理大数据量的数据集。

因此=,计算速度可能会成为整个训练过程中的瓶颈。

为了保证我们计算的效率,我们需要对进行过程矢量化。

接下来,我们对比一下是否使用矢量化对于点乘、外积和按元素相乘等操作来说,计算效率的比较。

首先,利用原生方法的实现过程如下:

 
 
  1. import time
  2.  
  3. x1 = [9, 2, 5, 0, 0, 7, 5, 0, 0, 0, 9, 2, 5, 0, 0]
  4. x2 = [9, 2, 2, 9, 0, 9, 2, 5, 0, 0, 9, 2, 5, 0, 0]
  5.  
  6. ### CLASSIC DOT PRODUCT OF VECTORS IMPLEMENTATION ###
  7. tic = time.process_time()
  8. dot = 0
  9. for i in range(len(x1)):
  10.     dot+= x1[i]*x2[i]
  11. toc = time.process_time()
  12. print ("dot ----- Computation time = " + str(1000*(toc - tic)) + "ms")
  13.  
  14. ### CLASSIC OUTER PRODUCT IMPLEMENTATION ###
  15. tic = time.process_time()
  16. outer = np.zeros((len(x1),len(x2))) # we create a len(x1)*len(x2) matrix with only zeros
  17. for i in range(len(x1)):
  18.     for j in range(len(x2)):
  19.         outer[i,j] = x1[i]*x2[j]
  20. toc = time.process_time()
  21. print ("outer ----- Computation time = " + str(1000*(toc - tic)) + "ms")
  22.  
  23. ### CLASSIC ELEMENTWISE IMPLEMENTATION ###
  24. tic = time.process_time()
  25. mul = np.zeros(len(x1))
  26. for i in range(len(x1)):
  27.     mul[i] = x1[i]*x2[i]
  28. toc = time.process_time()
  29. print ("elementwise multiplication ----- Computation time = " + str(1000*(toc - tic)) + "ms")
  30.  
  31. ### CLASSIC GENERAL DOT PRODUCT IMPLEMENTATION ###
  32. = np.random.rand(3,len(x1)) # Random 3*len(x1) numpy array
  33. tic = time.process_time()
  34. gdot = np.zeros(W.shape[0])
  35. for i in range(W.shape[0]):
  36.     for j in range(len(x1)):
  37.         gdot[i] += W[i,j]*x1[j]
  38. toc = time.process_time()
  39. print ("gdot ----- Computation time = " + str(1000*(toc - tic)) + "ms")
  40.  
  41. # dot ----- Computation time = 0.17002099999974263ms
  42. # outer ----- Computation time = 0.34057500000006513ms
  43. # elementwise multiplication ----- Computation time = 0.1940779999998199ms
  44. # gdot ----- Computation time = 0.2362039999999066ms

接下来,利用矢量化实现的结果如下:

  1. x1 = [9, 2, 5, 0, 0, 7, 5, 0, 0, 0, 9, 2, 5, 0, 0]
  2. x2 = [9, 2, 2, 9, 0, 9, 2, 5, 0, 0, 9, 2, 5, 0, 0]
  3.  
  4. ### VECTORIZED DOT PRODUCT OF VECTORS ###
  5. tic = time.process_time()
  6. dot = np.dot(x1,x2)
  7. toc = time.process_time()
  8. print ("dot ----- Computation time = " + str(1000*(toc - tic)) + "ms")
  9.  
  10. ### VECTORIZED OUTER PRODUCT ###
  11. tic = time.process_time()
  12. outer = np.outer(x1,x2)
  13. toc = time.process_time()
  14. print ("outer ----- Computation time = " + str(1000*(toc - tic)) + "ms")
  15.  
  16. ### VECTORIZED ELEMENTWISE MULTIPLICATION ###
  17. tic = time.process_time()
  18. mul = np.multiply(x1,x2)
  19. toc = time.process_time()
  20. print ("elementwise multiplication ----- Computation time = " + str(1000*(toc - tic)) + "ms")
  21.  
  22. ### VECTORIZED GENERAL DOT PRODUCT ###
  23. tic = time.process_time()
  24. dot = np.dot(W,x1)
  25. toc = time.process_time()
  26. print ("gdot ----- Computation time = " + str(1000*(toc - tic)) + "ms")
  27.  
  28. # dot ----- Computation time = 0.16546899999991815ms
  29. # outer ----- Computation time = 0.14168100000011563ms
  30. # elementwise multiplication ----- Computation time = 0.10738799999998605ms
  31. # gdot ----- Computation time = 0.38393900000022185ms

从上述结果中,我们可以看到矢量化的代码明显简单了很多。

同时,运行时间也有了一定程度的降低。降低的幅度不大主要是由于数据量较小的原因,随着数据量的增大,减小的幅度也会越来越明显。

 

练习1:L1误差函数的实现

我们需要使用numpy函数来实现L1误差函数:

其中,L1误差函数的定义如下:

^y表示估计值,y表示真实值。

 
 
  1. import numpy as np
  2. def L1(yhat, y):
  3.     """
  4.     Arguments:
  5.     yhat -- vector of size m (predicted labels)
  6.     y -- vector of size m (true labels)
  7.     
  8.     Returns:
  9.     loss -- the value of the L1 loss function defined above
  10.     """
  11.     
  12.     loss = np.sum(np.abs(- yhat))
  13.     return loss
  14.  
  15. yhat = np.array([.9, 0.2, 0.1, .4, .9])
  16. = np.array([1, 0, 0, 1, 1])
  17. print "L1 = " + str(L1(yhat,y))
  18. # L1 = 1.1

 

练习2:L2误差函数的实现

L2误差函数的定义如下:

  1. import numpy as np
  2. def L2(yhat, y):
  3.     """
  4.     Arguments:
  5.     yhat -- vector of size m (predicted labels)
  6.     y -- vector of size m (true labels)
  7.     
  8.     Returns:
  9.     loss -- the value of the L2 loss function defined above
  10.     """
  11.     
  12.     loss = np.sum(np.power((- yhat), 2))
  13.     return loss
  14.     
  15. yhat = np.array([.9, 0.2, 0.1, .4, .9])
  16. = np.array([1, 0, 0, 1, 1])
  17. print "L2 = " + str(L2(yhat,y))
  18. # L2 = 0.43


Logistic的实现

接下来的内容中,我们将实现一个完成Logistic函数。包括:初始化、计算代价函数和梯度、使用梯度下降算法进行优化等并把他们整合成为一个函数。

本实验用于通过训练来判断一副图像是否为猫。

在这个过程中,我们将会用到如下库:

numpy:Python科学计算中最重要的库

h5py:Python与H5文件交互的库

mathplotlib:Python画图的库

PIL:Python图像相关的库

scipy:Python科学计算相关的库

在程序的开头,我们首先需要引入相关的库:

 
 
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import h5py
  4. import scipy
  5. from PIL import Image
  6. from scipy import ndimage
  7.  
  8. %matplotlib inline  #设置matplotlib在行内显示图片

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

  1. def load_dataset():
  2.     """
  3.     # 加载数据集
  4.     """
  5.     train_dataset = h5py.File('datasets/train_catvnoncat.h5', "r")  #读取H5文件
  6.     train_set_x_orig = np.array(train_dataset["train_set_x"][:]) # your train set features
  7.     train_set_y_orig = np.array(train_dataset["train_set_y"][:]) # your train set labels
  8.  
  9.     test_dataset = h5py.File('datasets/test_catvnoncat.h5', "r")
  10.     test_set_x_orig = np.array(test_dataset["test_set_x"][:]) # your test set features
  11.     test_set_y_orig = np.array(test_dataset["test_set_y"][:]) # your test set labels
  12.  
  13.     classes = np.array(test_dataset["list_classes"][:]) # the list of classes
  14.     
  15.     train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))  #对训练集和测试集标签进行reshape
  16.     test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))
  17.     
  18.     return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes
  19.     
  20. train_set_x_orig, train_set_y, test_set_x_orig, test_set_y, classes = load_dataset()

Ps:为了给大家提供更好的学习效果,我们提供了原始数据集。

请访问http://www.missshi.cn/#/books搜索train_catvnoncat.h5和test_catvnoncat.h5进行下载,首次访问Js可能加载微慢,请耐心等候(约10s)。

如果感觉不错希望大家推广下网站哈!不建议大家把训练集直接在QQ群或CSDN上直接分享。

数据说明:

对于训练集的标签而言,对于猫,标记为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中的每一个元素对于这一副图像,我们可以用如下代码将图像显示出来:

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

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

  1. m_train = train_set_x_orig.shape[0]
  2. m_test = test_set_x_orig.shape[0]
  3. num_px = train_set_x_orig.shape[1]
  4. print (m_train, m_test, num_px)
  5. # 209, 50, 64

接下来,我们需要对将每幅图像转为一个矢量,即矩阵的一列。

最终,整个训练集将会转为一个矩阵,其中包括num_px*numpy*3行,m_train列。

 
 
  1. train_set_x_flatten = train_set_x_orig.reshape(train_set_x_orig.shape[0], -1).T
  2. test_set_x_flatten = test_set_x_orig.reshape(test_set_x_orig.shape[0], -1).T

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

接下来,我们需要对图像值进行归一化。

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

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

接下来,我们来看一下Logistic的结构:

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

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

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

1. 定义模型结构

2. 初始化模型参数

3. 循环

    3.1 前向传播

    3.2 反向传递

    3.3 更新参数

4. 整合成为一个完整的模型

 

Step1:实现sigmod函数

 
 
  1. def sigmoid(z):
  2.     """
  3.     Compute the sigmoid of z
  4.  
  5.     Arguments:
  6.     z -- A scalar or numpy array of any size.
  7.  
  8.     Return:
  9.     s -- sigmoid(z)
  10.     """
  11.     s = 1.0 / (1 + 1 / np.exp(z))
  12.     return s

Step2:初始化参数

  1. def initialize_with_zeros(dim):
  2.     """
  3.     This function creates a vector of zeros of shape (dim, 1) for w and initializes b to 0.
  4.     
  5.     Argument:
  6.     dim -- size of the w vector we want (or number of parameters in this case)
  7.     
  8.     Returns:
  9.     w -- initialized vector of shape (dim, 1)
  10.     b -- initialized scalar (corresponds to the bias)
  11.     """
  12.     w = np.zeros((dim, 1))
  13.     b = 0
  14.     return w, b

Step3:前向传播与反向传播

Ps:计算公式如下:(具体计算公式来源请查看之前的理论课)

 
 
  1. def propagate(w, b, X, Y):
  2.     """
  3.     Implement the cost function and its gradient for the propagation explained above
  4.  
  5.     Arguments:
  6.     w -- weights, a numpy array of size (num_px * num_px * 3, 1)
  7.     b -- bias, a scalar
  8.     X -- data of size (num_px * num_px * 3, number of examples)
  9.     Y -- true "label" vector (containing 0 if non-cat, 1 if cat) of size (1, number of examples)
  10.  
  11.     Return:
  12.     cost -- negative log-likelihood cost for logistic regression
  13.     dw -- gradient of the loss with respect to w, thus same shape as w
  14.     db -- gradient of the loss with respect to b, thus same shape as b
  15.     
  16.     Tips:
  17.     - Write your code step by step for the propagation. np.log(), np.dot()
  18.     """
  19.     
  20.     m = X.shape[1]
  21.     
  22.     # FORWARD PROPAGATION (FROM X TO COST)
  23.     A = sigmoid(np.dot(w.T, X) + b)                                     # compute activation
  24.     cost = -1.0 / m * np.sum(* np.log(A) + (1.0 - Y) * np.log(1.0 - A))                                  # compute cost
  25.     
  26.     # BACKWARD PROPAGATION (TO FIND GRAD)
  27.     dw = 1.0 / m * np.dot(X, (- Y).T)
  28.     db = 1.0 / m * np.sum(- Y)
  29.     cost = np.squeeze(cost)
  30.     
  31.     grads = {"dw": dw,
  32.              "db": db}
  33.     
  34.     return grads, cost

Step4:更新参数

更新参数的公式如下:

完整代码如下:

  1. def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost = False):
  2.     """
  3.     This function optimizes w and b by running a gradient descent algorithm
  4.     
  5.     Arguments:
  6.     w -- weights, a numpy array of size (num_px * num_px * 3, 1)
  7.     b -- bias, a scalar
  8.     X -- data of shape (num_px * num_px * 3, number of examples)
  9.     Y -- true "label" vector (containing 0 if non-cat, 1 if cat), of shape (1, number of examples)
  10.     num_iterations -- number of iterations of the optimization loop
  11.     learning_rate -- learning rate of the gradient descent update rule
  12.     print_cost -- True to print the loss every 100 steps
  13.     
  14.     Returns:
  15.     params -- dictionary containing the weights w and bias b
  16.     grads -- dictionary containing the gradients of the weights and bias with respect to the cost function
  17.     costs -- list of all the costs computed during the optimization, this will be used to plot the learning curve.
  18.     
  19.     Tips:
  20.     You basically need to write down two steps and iterate through them:
  21.         1) Calculate the cost and the gradient for the current parameters. Use propagate().
  22.         2) Update the parameters using gradient descent rule for w and b.
  23.     """
  24.     
  25.     costs = []
  26.     
  27.     for i in range(num_iterations): #每次迭代循环一次, num_iterations为迭代次数
  28.         
  29.         
  30.         # Cost and gradient calculation 
  31.         grads, cost = propagate(w, b, X, Y)
  32.         
  33.         # Retrieve derivatives from grads
  34.         dw = grads["dw"]
  35.         db = grads["db"]
  36.         
  37.         # update rule 
  38.         w = w - learning_rate * dw
  39.         b = b - learning_rate * db
  40.         
  41.         # Record the costs
  42.         if i % 100 == 0:
  43.             costs.append(cost)
  44.         
  45.         # Print the cost every 100 training examples
  46.         if print_cost and i % 100 == 0:
  47.             print ("Cost after iteration %i: %f" %(i, cost))
  48.     params = {"w": w,
  49.               "b": b}
  50.     grads = {"dw": dw,
  51.              "db": db}
  52.     return params, grads, costs

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

计算公式如下:

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

 
 
  1. def predict(w, b, X):
  2.     '''
  3.     Predict whether the label is 0 or 1 using learned logistic regression parameters (w, b)
  4.     
  5.     Arguments:
  6.     w -- weights, a numpy array of size (num_px * num_px * 3, 1)
  7.     b -- bias, a scalar
  8.     X -- data of size (num_px * num_px * 3, number of examples)
  9.     
  10.     Returns:
  11.     Y_prediction -- a numpy array (vector) containing all predictions (0/1) for the examples in X
  12.     '''
  13.     
  14.     m = X.shape[1]
  15.     Y_prediction = np.zeros((1,m))
  16.     w = w.reshape(X.shape[0], 1)
  17.     
  18.     # Compute vector "A" predicting the probabilities of a cat being present in the picture
  19.     A = sigmoid(np.dot(w.T, X) + b)
  20.     
  21.     for i in range(A.shape[1]):
  22.         # Convert probabilities A[0,i] to actual predictions p[0,i]
  23.         if A[0][i] > 0.5:
  24.             Y_prediction[0][i] = 1
  25.         else:
  26.             Y_prediction[0][i] = 0
  27.     
  28.     return Y_prediction

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

  1. def model(X_train, Y_train, X_test, Y_test, num_iterations = 2000, learning_rate = 0.5, print_cost = False):
  2.     """
  3.     Builds the logistic regression model by calling the function you've implemented previously
  4.     
  5.     Arguments:
  6.     X_train -- training set represented by a numpy array of shape (num_px * num_px * 3, m_train)
  7.     Y_train -- training labels represented by a numpy array (vector) of shape (1, m_train)
  8.     X_test -- test set represented by a numpy array of shape (num_px * num_px * 3, m_test)
  9.     Y_test -- test labels represented by a numpy array (vector) of shape (1, m_test)
  10.     num_iterations -- hyperparameter representing the number of iterations to optimize the parameters
  11.     learning_rate -- hyperparameter representing the learning rate used in the update rule of optimize()
  12.     print_cost -- Set to true to print the cost every 100 iterations
  13.     
  14.     Returns:
  15.     d -- dictionary containing information about the model.
  16.     """
  17.     # initialize parameters with zeros 
  18.     w, b = initialize_with_zeros(X_train.shape[0])
  19.  
  20.     # Gradient descent
  21.     parameters, grads, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost)
  22.     
  23.     # Retrieve parameters w and b from dictionary "parameters"
  24.     w = parameters["w"]
  25.     b = parameters["b"]
  26.     
  27.     # Predict test/train set examples 
  28.     Y_prediction_test = predict(w, b, X_test)
  29.     Y_prediction_train = predict(w, b, X_train)
  30.  
  31.     # Print train/test Errors
  32.     print("train accuracy: {} %".format(100 - np.mean(np.abs(Y_prediction_train - Y_train)) * 100))
  33.     print("test accuracy: {} %".format(100 - np.mean(np.abs(Y_prediction_test - Y_test)) * 100))
  34.  
  35.     
  36.     d = {"costs": costs,
  37.          "Y_prediction_test": Y_prediction_test, 
  38.          "Y_prediction_train" : Y_prediction_train, 
  39.          "w" : w, 
  40.          "b" : b,
  41.          "learning_rate" : learning_rate,
  42.          "num_iterations": num_iterations}
  43.     
  44.     return d

测试一下该模型吧:

 
 
  1. = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 2000, learning_rate = 0.005, print_cost = True)

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

而对于训练集,其准确性达到了99%。这表明了我们的模型有着一定的过拟合,不过不要着急,我们会在后续的内容中来解决这一问题。

 

使用如下代码,我们可以挑选其中的一些图片来看我们的预测结果:

  1. # Example of a picture that was wrongly classified.
  2. index = 14
  3. plt.imshow(test_set_x[:,index].reshape((num_px, num_px, 3)))
  4. 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.")

此外,我们还可以画出我们的代价函数变化曲线:

 
 
  1. # Plot learning curve (with costs)
  2. costs = np.squeeze(d['costs'])
  3. plt.plot(costs)
  4. plt.ylabel('cost')
  5. plt.xlabel('iterations (per hundreds)')
  6. plt.title("Learning rate =" + str(d["learning_rate"]))
  7. plt.show()

之前的理论课程中,我们已经提及过学习速率对于最终的结果有着较大影响,现在,我们来用实验让大家有一个直观的了解。

  1. learning_rates = [0.01, 0.001, 0.0001]
  2. models = {}
  3. for i in learning_rates:
  4.     print ("learning rate is: " + str(i))
  5.     models[str(i)] = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 1500, learning_rate = i, print_cost = False)
  6.     print ('\n' + "-------------------------------------------------------" + '\n')
  7.  
  8. for i in learning_rates:
  9.     plt.plot(np.squeeze(models[str(i)]["costs"]), label= str(models[str(i)]["learning_rate"]))
  10.  
  11. plt.ylabel('cost')
  12. plt.xlabel('iterations')
  13.  
  14. legend = plt.legend(loc='upper center', shadow=True)
  15. frame = legend.get_frame()
  16. frame.set_facecolor('0.90')
  17. plt.show()

分析:不同的学习速率会导致不同的预测结果。较小的学习速度收敛速度较慢,而过大的学习速度可能导致震荡或无法收敛。

 

如果你希望用一副你自己的图像,而不是训练集或测试集中的图像,那么该如何实现呢?

 
 
  1. ## START CODE HERE ## (PUT YOUR IMAGE NAME) 
  2. my_image = "my_image.jpg"   # change this to the name of your image file 
  3. ## END CODE HERE ##
  4.  
  5. # We preprocess the image to fit your algorithm.
  6. fname = "images/" + my_image
  7. image = np.array(ndimage.imread(fname, flatten=False))  #读取图片
  8. my_image = scipy.misc.imresize(image, size=(num_px,num_px)).reshape((1, num_px*num_px*3)).T  #放缩图像
  9. my_predicted_image = predict(d["w"], d["b"], my_image)  #预测
  10.  
  11. plt.imshow(image)
  12. print("y = " + str(np.squeeze(my_predicted_image)) + ", your algorithm predicts a \"" + classes[int(np.squeeze(my_predicted_image)),].decode("utf-8") +  "\" picture.")

上一篇: 3. Python矢量化实现神经网络

下一篇: 5. 浅层神经网络


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我可以为您提供这个问题的实战代码,这是一个使用PyTorch实现对多元高斯分布进行分类的Logistic回归代码: ``` import torch from torch.autograd import Variable import numpy as np import matplotlib.pyplot as plt #生成数据集 np.random.seed(1) num_observations = 5000 x1 = np.random.multivariate_normal([0, 0], [[1, .75],[.75, 1]], num_observations) x2 = np.random.multivariate_normal([1, 4], [[1, .75],[.75, 1]], num_observations) simulated_separableish_features = np.vstack((x1, x2)).astype(np.float32) simulated_labels = np.hstack((np.zeros(num_observations), np.ones(num_observations))) #绘制数据集 fig, ax = plt.subplots() ax.scatter(simulated_separableish_features[:, 0], simulated_separableish_features[:, 1], c = simulated_labels, alpha=.4) #将数据集转换成Tensor features = Variable(torch.from_numpy(simulated_separableish_features)) labels = Variable(torch.from_numpy(simulated_labels)) #定义模型 model = torch.nn.Sequential( torch.nn.Linear(2, 1), torch.nn.Sigmoid() ) #定义误差函数和优化器 loss_fn = torch.nn.BCELoss() optimizer = torch.optim.SGD(model.parameters(), lr=0.01) #训练模型 for epoch in range(500): #向前传播 y_pred = model(features) #计算误差 loss = loss_fn(y_pred, labels) #清除梯度 optimizer.zero_grad() #反向传播 loss.backward() #更新参数 optimizer.step() #预测 predicted = model(features).data.numpy().flatten() plt.plot(simulated_separableish_features[:, 0], simulated_separableish_features[:, 1], 'go', alpha=.3) plt.plot(simulated_separableish_features[:, 0], simulated_separableish_features[:, 1], 'ro', alpha=.3) plt.legend(['False', 'True']) plt.show() ``` 希望这段代码能够帮助您解决问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值