吴恩达深度学习 | (7) 神经网络与深度学习专项课程第四周编程作业

吴恩达深度学习专项课程的所有实验均采用Jupyter Notebooks实现,不熟悉的朋友可以提前使用一下Notebooks。本周的实验是实现一个L层的神经网络进行图片2分类,这也是深度学习和神经网络专项课程的最后一个实验,实验非常长,需要花一些时间。下一个专项是改善深层神经网络,还会学习一些更高级的优化方法、mini-batch、正则化、dropout、多分类等内容,介时还将实现更强大的模型。

目录

1.实验综述

2.导入必要的包

3.数据集

3.模型结构

4.双层神经网络(L=2,单隐层)

5.L层神经网络(L>=3,隐层数>=2)

6.结果分析

7.用你自己的图片做测试


1.实验综述

2.导入必要的包

import time
import numpy as np
import h5py #用于与存储为.h5文件的数据集交互
import matplotlib.pyplot as plt
#用自己的图片测试模型时会用带scipy和PIL库
import scipy  
from PIL import Image
from scipy import ndimage
#定义在dnn_app_utils_v2.py文件中 提供本次实验所需要的函数
from dnn_app_utils_v2 import *

%matplotlib inline
plt.rcParams['figure.figsize']=(5.0,4.0) #设置绘图的默认大小
#设置绘图的默认风格
plt.rcParams['image.interpolation']='nearest'
plt.rcParams['image.cmap']='gray' 

%load_ext autoreload
%autoreload 2

np.random.seed(1) #设置随机种子 每次生成的随机数一样 确保和原始实验标准一致

3.数据集

  • 加载原始数据集
#加载原始数据集
train_x_orig,train_y,test_x_orig,test_y,classes = load_data()
def load_data():
    train_dataset = h5py.File('datasets/train_catvnoncat.h5', "r")
    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('datasets/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]))#(1,m) 二维数组表示行向量 
    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

 

  • 可视化某一张图片
#可视化某一张图片
index=10
plt.imshow(train_x_orig[index]) #可视化原始训练集中第index+1张图片
print("y = "+str(train_y[0,index])+". It is a "+classes[train_y[0,index]].decode("utf-8")+" picture.")

  • 查看原始数据集信息
#查看原始数据集的详细信息
m_train=train_x_orig.shape[0] #训练集图片数
num_px=train_x_orig.shape[1] #图片的宽度,高度  宽度=高度
m_test=test_x_orig.shape[0] #测试集图片数

print ("Number of training examples: " + str(m_train))
print ("Number of testing examples: " + str(m_test))
print ("Each image is of size: (" + str(num_px) + ", " + str(num_px) + ", 3)")
print ("train_x_orig shape: " + str(train_x_orig.shape))#四维数组 (m_train,num_px,num_px,3)
print ("train_y shape: " + str(train_y.shape)) #2维数组表示的行向量 (1,m_train)
print ("test_x_orig shape: " + str(test_x_orig.shape))#四维数组 (m_test,num_px,num_px,3)
print ("test_y shape: " + str(test_y.shape)) #2维数组表示的行向量 (1,m_test)

  • 数据集预处理
#对训练集和测试集中的图片进行转型
train_x_flatten=train_x_orig.reshape(m_train,-1).T #训练集图片的特征矩阵 (num_px*num_px*3,m_train) 每一列为一张图片的拉伸后的特征向量
test_x_flatten=test_x_orig.reshape(m_test,-1).T #测试集图片的特征矩阵 (num_px*num_px*3,m_test) 每一列为一张图片的拉伸后的特征向量

#对图片的特征矩阵进行标准化 除以最大值255 使特征数值在0-1之间
train_x=train_x_flatten/255
test_x=test_x_flatten/255

print ("train_x's shape: " + str(train_x.shape))
print ("test_x's shape: " + str(test_x.shape))

3.模型结构

  • 双层神经网络(L=2 单隐层)

  • L层 深层神经网络(L>=3,隐层数>=2)

  • 构建神经网络的一般步骤

4.双层神经网络(L=2,单隐层)

  • 初始化模型参数
def initialize_parameters(n_x,n_h,n_y):
    '''
    初始化双层神经网络的参数
    
    参数:
    n_x:输入层单元数 取决于输入样本的特征向量维数
    n_h:隐层单元数 可以任意设置
    n_y:输出层单元数 取决于目的 对于2分类任务 n_y=1
    
    返回:
    parameters:初始化后的参数(字典形式)
        W1:(n_h,n_x)
        b1:(n_h,1)
        W2:(n_y,n_h)
        b2:(n_y,1)
    '''
    
    W1=np.random.randn(n_h,n_x)*0.01
    b1=np.zeros((n_h,1))
    W2=np.random.randn(n_y,n_h)*0.01
    b2=np.zeros((n_y,1))
    
    assert(W1.shape == (n_h,n_x))
    assert(b1.shape == (n_h, 1))
    assert(W2.shape == (n_y, n_h))
    assert(b2.shape == (n_y, 1))
    
    parameters = {"W1": W1,
                  "b1": b1,
                  "W2": W2,
                  "b2": b2}
    
    return parameters     
  • 前向传播
#以下定义的前向传播是在某一层上的前向传播  不是总体的前向传播
#对于浅层神经网络 总体的前向传播可以一层层写出来 也可以用for循环
#对于深层神经网络 总体的前向传播用for循环迭代单层的前向传播 直到最后的输出,当然也可以一层层的写
def linear_forward(A,W,b):
    '''
    隐层/输出层 前向传播的线性组合部分
    
    参数:
    A:上一层的激活函数输出 初始值是样本特征矩阵X
    W:当前层的权重参数矩阵
    b: 当前层的偏置参数向量
    
    返回:
    Z:当前层的线性组合输出
    cache:元组形式 (A,W,b)
    '''
    Z = np.dot(W,A)+b
    
    assert(Z.shape == (W.shape[0],A.shape[1]))
    cache = (A,W,b) 
    
    return Z,cache

def sigmoid(Z):
    '''
    2分类,输出层采用sigmoid激活函数
    输出层前向传播的激活函数部分
    
    参数:
    Z:当前层(输出层)的线性组合输出
    
    返回:
    A:当前层(输出层)的激活输出
    cache: Z
    '''
    A = 1./(1+np.exp(-Z))
    cache = Z
    
    assert(A.shape == Z.shape)
    
    return A,cache

def relu(Z):
    '''
    隐层统一采用relu激活函数
    
    参数:
    Z:当前层(隐层)的线性组合输出
    
    返回:
    A:当前层(隐层)的激活输出
    cache: Z
    '''
    
    A = np.maximum(0,Z)
    cache = Z
    
    assert(A.shape == Z.shape)
    
    return A,cache
    
    
def linear_activation_forward(A_prev,W,b,activation):
    '''
    隐层(输出层)的前向传播操作,包括线性组合和激活函数两部分
    
    参数:
    A_perv:上一层的激活函数输出 初始值是样本特征矩阵X
    W:上一层和当前层之间的权重参数矩阵
    b: 上一层和当前层之间的偏置参数向量
    activation:使用的激活函数类型 一般所有隐层的激活函数是一样的 输出层如果作2分类使用sigmoid
    
    返回:
    A: 当前层的激活函数输出
    cache:存储重要的中间结果,方便运算。元组形式(linear_cache,activation_cache)=((A_prev,W,b),Z)
    
    '''
    
    if activation == 'sigmoid':
        Z,linear_cache = linear_forward(A_prev,W,b) #线性单元
        A,activation_cache = sigmoid(Z)  #激活单元
    elif activation == 'relu':
        Z,linear_cache = linear_forward(A_prev,W,b) #线性单元
        A,activation_cache = relu(Z)  #激活单元
    
    assert(A.shape == (W.shape[0],A_prev.shape[1]))
    cache=(linear_cache,activation_cache)
    
    return A,cache

    
  • 计算代价
def compute_cost(AL,Y):
    '''
    实现cost函数,计算代价
    
    参数:
    AL:输出层的激活输出 模型最终输出 (1,m)
    Y:样本的真实标签 0/1 (1,m)
    
    返回:
    cost: 交叉熵代价
    '''
    
    cost = np.mean(-Y*np.log(AL)-(1-Y)*np.log(1-AL))
    cost = np.squeeze(cost) #Y和AL都是用2维数组表示的向量 cost算出来是[[cost]],利用squeeze把它变成cost
    
    assert(cost.shape == ()) 
    
    return cost
  • 反向传播计算梯度
#以下定义的反向传播是在某一层上的反向传播  不是总体的反向传播
#对于浅层神经网络 总体的反向传播可以一层层写出来 也可以用for循环
#对于深层神经网络 总体的反向传播用for循环迭代单层的反向传播 直到求得每个参数的梯度,当然也可以一层层写
def sigmoid_backward(dA,cache):
    '''
    sigmoid激活单元(输出层)的反向传播
    
    参数:
    dA:当前层(输出层)激活输出AL的梯度
    cache:存储当前层(输出层)的线性组合输出Z,方便激活单元反向传播的计算
    
    返回:
    dZ:当前层(输出层)线性组合输出Z的梯度
    '''
    
    Z = cache
    s = 1./(1+np.exp(-Z))
    #dZ=dA*(A对Z求导) A=sigmoid(Z) A对Z的导数=A(1-A)
    dZ = dA*s*(1-s) 
    
    assert(dZ.shape == Z.shape)
    
    return dZ

def relu_backward(dA,cache):
    '''
    隐层统一使用relu激活函数
    relu激活单元(隐层)的反向传播
    
    参数:
    dA:当前层(隐层)激活输出Al的梯度
    cache:存储当前层(隐层)的线性组合输出Z,方便激活单元反向传播的计算
    
    返回:
    dZ:当前层(隐层)线性组合输出Z的梯度
    '''
    
    Z = cache
    #dZ=dA*(A对Z求导) 当Z>0时 A对Z求导=1 否则为0
    dZ = np.array(dA,copy=True)
    
    dZ[Z<=0] = 0
    
    assert(dZ.shape == Z.shape)
    
    return dZ

def linear_backward(dZ,cache):
    '''
    输出层/隐层 线性单元的反向传播
    
    参数:
    dZ:当前层组合输出Z的梯度
    cache:存储当前层前向传播的线性单元参数 (A_prev,W,b),方便线性单元反向传播的计算
    
    返回:
    dA_prev:前一层激活输出的梯度
    dW:当前层权重参数矩阵的梯度
    db:当前层偏置参数向量的梯度
    '''
    A_prev,W,b = cache
    
    m = A_prev.shape[1] #样本数
    
    dW = 1./m*np.dot(dZ,A_prev.T) #m个样本的平均梯度
    db = np.mean(dZ,axis=1,keepdims=True)
    dA_prev = np.dot(W.T,dZ)
    
    assert(dW.shape == W.shape)
    assert(db.shape == b.shape)
    assert(dA_prev.shape == A_prev.shape)
    
    return dA_prev,dW,db
    

def linear_activation_backward(dA,cache,activation):
    '''
    输出层\隐层的反向传播操作,包括激活函数和线性组合两部分
    dvar 代表 最终输出对var的偏导
    
    参数:
    dA:当前层的激活输出梯度dAl 初始值是dAL (代价函数对AL求偏导)
    cache:前向传播阶段存储的重要参数和中间结果,便于与反向传播共享参数,方便运算。元组形式(linear_cache,activation_cache)=((A_prev,W,b),Z)
    activation:使用的激活函数类型 一般所有隐层的激活函数是一样的 输出层如果作2分类使用sigmoid
    
    返回:
    dA_prev:前一层激活输出的梯度dA(l-1)
    dW:当前层权重矩阵的梯度 和当前层W维度一致
    db:当前层偏置向量的梯度 和当前层b维度一致
    '''
    
    linear_cache,activation_cache = cache
    
    if activation == 'sigmoid':
        dZ = sigmoid_backward(dA,activation_cache) #激活单元反向传播
        dA_prev,dW,db = linear_backward(dZ,linear_cache)#线性单元反向传播
    elif activation == 'relu':
        dZ = relu_backward(dA,activation_cache) #激活单元反向传播
        dA_prev,dW,db = linear_backward(dZ,linear_cache)#线性单元反向传播
    
    return dA_prev,dW,db
    
  • 更新参数(梯度下降法)
def update_parameters(parameters,grads,learning_rate):
    '''
    使用梯度下降法更新模型参数
    
    参数:
    parameters:模型参数
    grads:计算的参数梯度 字典形式
    learning_rate:学习率
    
    返回:
    
    parameters:更新后的参数 字典形式
        parameters["W" + str(l)] = ... 
        parameters["b" + str(l)] = ...
    '''
    
    L = len(parameters)//2 #神经网络层数(输入层是第0层 不算输入层)
    
    #一次梯度下降迭代 更新参数
    for l in range(L):  #l 0~L-1
        parameters['W'+str(l+1)] = parameters['W'+str(l+1)] - learning_rate*grads['dW'+str(l+1)]
        parameters['b'+str(l+1)] = parameters['b'+str(l+1)] - learning_rate*grads['db'+str(l+1)]
    
    return parameters
  • 把之前定义的各部分汇总到模型中
#定义网络结构
n_x = 12288 #num_px*num_px*3
n_h = 7  #隐层单元数 可以设置
n_y = 1 #2分类

layers_dims = (n_x,n_h,n_y)  #各层单元数
#双层神经网络模型
def two_layer_model(X,Y,layers_dims,learning_rate=0.0075,num_iterations=3000,print_cost=False):
    '''
    实现双层网络结构
    
    参数:
    X:训练集特征矩阵 (n_x,m_train) 
    Y:训练集样本对于的标签 0/1 (1,m_train)
    layers_dims:各层的单元数
    learning_rate:学习率
    num_iterations:梯度下降法迭代次数
    print_cost:为True时,每100次迭代打印一次cost
    
    返回:
    parameters:训练好的参数 字典形式
        parameters["W" + str(l)] = ... 
        parameters["b" + str(l)] = ...
    '''
    
    np.random.seed(1)
    grads = {} #存储每一次反向传播计算的梯度
    costs = [] #存储每100次前向传播计算的代价
    m = X.shape[1]
    (n_x,n_h,n_y) = layers_dims
    
    #初始化模型参数
    parameters = initialize_parameters(n_x,n_h,n_y)
    
    #取出每一个初始化后的参数
    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']
    
    #梯度下降迭代
    #batch GD 每一次使用全部的样本计算梯度
    for i in range(num_iterations):
        #前向传播
        A1,cache1 = linear_activation_forward(X,W1,b1,'relu')
        A2,cache2 = linear_activation_forward(A1,W2,b2,'sigmoid')
        
        #计算代价
        cost = compute_cost(A2,Y)
        
        #计算反向传播的初始项 dAL=dA2
        dA2 = -Y/A2 + (1-Y)/(1-A2)
        
        dA1,dW2,db2 = linear_activation_backward(dA2,cache2,'sigmoid')
        dA0,dW1,db1 = linear_activation_backward(dA1,cache1,'relu')
        
        grads['dW1']=dW1
        grads['db1']=db1
        grads['dW2']=dW2
        grads['db2']=db2
        
        #更新参数
        parameters = update_parameters(parameters,grads,learning_rate)
        
         #取出每一个更新后的参数
        W1 = parameters['W1']
        b1 = parameters['b1']
        W2 = parameters['W2']
        b2 = parameters['b2']
        
        #每100次迭代打印一次代价 并存储
        if print_cost and i%100==0:
            print("Cost after iteration {}: {}".format(i, np.squeeze(cost)))
            costs.append(cost)
            
    #绘制代价对迭代次数的变化曲线
    plt.plot(np.squeeze(costs))
    plt.ylabel('cost')
    plt.xlabel('iterations (per hundreds)')
    plt.title("Learning rate =" + str(learning_rate))
    plt.show()
    
    return parameters
    

训练网络:

#训练双层网络
parameters = two_layer_model(train_x, train_y, layers_dims = (n_x, n_h, n_y), num_iterations = 2500, print_cost=True)

 

  • 预测
def predict(X,Y,parameters):
    '''
    使用训练好的模型进行预测
    
    参数:
    X:数据集样本特征矩阵(n_x,m)
    Y:数据集样本真实标签 0/1 (1,m)
    parameters:训练好的参数
    
    返回:
    p:数据集样本预测标签 0/1
    '''
    #取出每一个学习好的的参数
    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']
    
    #前向传播  linear_activation_forward定义了一层的前向传播
    A1,cache1 = linear_activation_forward(X,W1,b1,'relu')
    A2,cache2 = linear_activation_forward(A1,W2,b2,'sigmoid')
    
    m = X.shape[1]
    p = np.zeros((1,m))
    
    p[A2 > 0.5] = 1
    print("Accuracy: "  + str(np.mean(p == Y)))
    
    return p
    
predictions_train = predict(train_x, train_y, parameters) #训练集上的准确率

predictions_test = predict(test_x, test_y, parameters)#测试集上的准确率

  • 总结

5.L层神经网络(L>=3,隐层数>=2)

  • 初始化参数
def initialize_parameters_deep(layer_dims):
    '''
    参数:
    layer_dims:网络每一层的单元数
    
    返回:
    parameters:初始化后的参数 字典形式
       "W1", "b1", ..., "WL", "bL":
                    Wl -- weight matrix of shape (layer_dims[l], layer_dims[l-1])
                    bl -- bias vector of shape (layer_dims[l], 1)
    '''
    
    np.random.seed(1)
    parameters = {}
    L = len(layer_dims) #神经网络层数+1 包括输入层
    
    for l in range(1,L):
        parameters['W'+str(l)] = np.random.randn(layer_dims[l],layer_dims[l-1])/np.sqrt(layer_dims[l-1]) #*0.01
        parameters['b'+str(l)] = np.zeros((layer_dims[l],1))
        
        assert(parameters['W' + str(l)].shape == (layer_dims[l], layer_dims[l-1]))
        assert(parameters['b' + str(l)].shape == (layer_dims[l], 1))
    
    return parameters
  • 前向传播

#之前定义了每层的前向传播 对于深层网络来说整体的前向传播 可以使用for循环迭代每层的前向传播

def L_model_forward(X,parameters):
    '''
    L层神经网络整体的前向传播 调用之前写好的每层的前向传播 用for循环迭代
    
    参数:
    X:数据集的特征矩阵 (n_x,m)
    parameters:模型参数
    
    返回:
    AL:模型最后的输出
    caches:列表形式,存储每一层前向传播的cache=(linear_cache,activation_cache)
        =((A_prev,W,b),Z)  
        对于linear_relu_forward()有L-1项cache  下标0~L-2
        对于linear_sigmoid_forward()有1项cache  下标L-1
    '''
    
    caches = []
    A = X  #A0  前向传播初始项
    L = len(parameters)//2 #神经网络层数(不包含输入层)
    
    #前向传播通项
    #隐层和输出层激活函数不同 for循环迭代隐层前向传播 输出层前向传播单独算
    #隐层
    for l in range(1,L): #l: 1~L-1 
        A_prev = A
        A,cache = linear_activation_forward(A_prev,parameters['W'+str(l)],
                            parameters['b'+str(l)],'relu')
        caches.append(cache)
    #输出层
    AL,cache = linear_activation_forward(A,parameters['W'+str(L)],
                            parameters['b'+str(L)],'sigmoid')
    caches.append(cache)
    
    return AL,caches
  • 计算代价
def compute_cost(AL,Y):
    '''
    实现cost函数,计算代价
    
    参数:
    AL:输出层的激活输出 模型最终输出 (1,m)
    Y:样本的真实标签 0/1 (1,m)
    
    返回:
    cost: 交叉熵代价
    '''
    
    cost = np.mean(-Y*np.log(AL)-(1-Y)*np.log(1-AL))
    cost = np.squeeze(cost) #Y和AL都是用2维数组表示的向量 cost算出来是[[cost]],利用squeeze把它变成cost
    
    assert(cost.shape == ()) 
    
    return cost
  • 反向传播计算梯度

#之前定义了每层的反向传播 对于深层网络来说整体的反向传播 可以使用for循环迭代每层的反向传播

def L_model_backward(AL,Y,caches):
    '''
    L层神经网络整体的反向传播 调用之前写好的每层的反向传播 用for循环迭代
    
    参数:
    AL:前向传播最终的输出
    Y:数据集样本真实标签 0/1
    caches:前向传播缓存的重要参数和中间结果 方便运算
        列表形式,存储每一层前向传播的cache=(linear_cache,activation_cache)
        =((A_prev,W,b),Z)  
        对于linear_relu_forward()有L-1项cache  下标0~L-2
        对于linear_sigmoid_forward()有1项cache  下标L-1
    
    返回:
    grads:字典形式 存储每一层参数的梯度:
             grads["dA" + str(l)] = ... 
             grads["dW" + str(l)] = ...
             grads["db" + str(l)] = ... 
    '''
    
    grads = {}
    L = len(caches) #网络层数 不包含输入层
    
    m = AL.shape[1]
    Y = Y.reshape(AL.shape)
    
    #反向传播初始项
    dAL = -Y/AL + (1-Y)/(1-AL)
    
    #输出层单独计算 隐层统一用for循环计算
    current_cache = caches[L-1] #输出层前向传播的cache
    grads['dA'+str(L)],grads['dW'+str(L)],grads['db'+str(L)] = linear_activation_backward(dAL,
            current_cache,'sigmoid') #grads['dAl']实际上是grads['dAl-1'] 便于与dW,db统一处理

    
    for l in reversed(range(L-1)): #l:L-2~0
        current_cache = caches[l]
        dA_prev_temp, dW_temp, db_temp = linear_activation_backward(grads['dA'+str(l+2)],current_cache,'relu')
        grads["dA" + str(l + 1)] = dA_prev_temp
        grads["dW" + str(l + 1)] = dW_temp
        grads["db" + str(l + 1)] = db_temp
    
    return grads
  • 更新参数
def update_parameters(parameters,grads,learning_rate):
    '''
    使用梯度下降法更新模型参数
    
    参数:
    parameters:模型参数
    grads:计算的参数梯度 字典形式
    learning_rate:学习率
    
    返回:
    
    parameters:更新后的参数 字典形式
        parameters["W" + str(l)] = ... 
        parameters["b" + str(l)] = ...
    '''
    
    L = len(parameters)//2 #神经网络层数(输入层是第0层 不算输入层)
    
    #一次梯度下降迭代 更新参数
    for l in range(L):  #l 0~L-1
        parameters['W'+str(l+1)] = parameters['W'+str(l+1)] - learning_rate*grads['dW'+str(l+1)]
        parameters['b'+str(l+1)] = parameters['b'+str(l+1)] - learning_rate*grads['db'+str(l+1)]
    
    return parameters
  • 把以上各部分汇总到一个模型中
#定义网络结构
layers_dims = [12288, 20, 7, 5, 1] # 各层的单元数 四层网络(不算输入层) 可以定义任意层数和各层单元数的网络
def L_layer_model(X, Y, layers_dims, learning_rate = 0.0075, num_iterations = 3000, print_cost=False):
    '''
    实现L层网络
    
    参数:
    X:训练集样本特征矩阵(n_x,m_train)
    Y:训练集样本标签 0/1 (1,m_train)
    layers_dims:各层的单元数
    learning_rate:学习率
    num_iterations:梯度下降法迭代次数
    print_cost:为True时,每100次迭代打印一次cost
    
    返回:
    parameters:训练好的参数 字典形式
        parameters["W" + str(l)] = ... 
        parameters["b" + str(l)] = ...
    '''
    
    np.random.seed(1)
    costs = [] #存储每100次前向传播计算的代价
    
    #初始化参数
    parameters = initialize_parameters_deep(layers_dims)
    
    #梯度下降迭代
    #batch GD 每次反向传播使用全部样本计算梯度
    for i in range(num_iterations):
        
        #前向传播
        AL,caches = L_model_forward(X,parameters)
        
        #计算代价
        cost = compute_cost(AL,Y)
        
        #反向传播计算梯度
        grads = L_model_backward(AL,Y,caches)
        
        #更新参数
        parameters = update_parameters(parameters,grads,learning_rate)
        
        #每100次迭代打印一次代价 并存储
        if print_cost and i%100==0:
            print("Cost after iteration {}: {}".format(i, np.squeeze(cost)))
            costs.append(cost)
            
    #绘制代价对迭代次数的变化曲线
    plt.plot(np.squeeze(costs))
    plt.ylabel('cost')
    plt.xlabel('iterations (per hundreds)')
    plt.title("Learning rate =" + str(learning_rate))
    plt.show()
    
    return parameters
        
#训练模型
parameters = L_layer_model(train_x, train_y, layers_dims, num_iterations = 2500, print_cost = True)

  • 预测
def predict(X,Y,parameters):
    '''
    使用训练好的模型进行预测
    
    参数:
    X:数据集样本特征矩阵(n_x,m)
    Y:数据集样本真实标签 0/1 (1,m)
    parameters:训练好的参数
    
    返回:
    p:数据集样本预测标签 0/1
    '''
    
    #前向传播  
    AL,caches = L_model_forward(X,parameters)
    
    m = X.shape[1]
    p = np.zeros((1,m))
    
    p[AL > 0.5] = 1
    print("Accuracy: "  + str(np.mean(p == Y)))
    
    return p
#训练集准确率
pred_train = predict(train_x, train_y, parameters)

#测试集准确率
pred_test = predict(test_x, test_y, parameters)

 

6.结果分析

print_mislabeled_images(classes, test_x, test_y, pred_test) #该函数定义在dnn_app_utils_v2.py中

7.用你自己的图片做测试

#图片名
my_image = "cat.jpg"
my_label_y = [1] #图片的真实标签 1:猫

fname = "images/" + my_image #图片相对路径
#读取图片存储在数组中 并作预处理
image = np.array(ndimage.imread(fname, flatten=False))
my_image = scipy.misc.imresize(image, size=(num_px,num_px)).reshape((num_px*num_px*3,1))
#用训练好的参数做预测
my_predicted_image = predict(my_image, my_label_y, parameters)

plt.imshow(image)
print ("y = " + str(np.squeeze(my_predicted_image)) + ", your L-layer model predicts a \"" + classes[int(np.squeeze(my_predicted_image)),].decode("utf-8") +  "\" picture.")

 

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值