python实现浅层神经网络算法

吴恩达第三周课后编程作业

第一次开始真正意义上接触算法,并且使用python来编码,用博客来梳理自己的学习思路。

首先load一些需要使用的包

import numpy as np
import matplotlib.pyplot as plt
import sklearn
import sklearn.datasets
import sklearn.linear_model
from planar_utils import plot_decision_boundary, sigmoid, load_planar_dataset, load_extra_datasets
np.random.seed(1)   ###保证随机数生成的一样

下面需要load一些测试用的函数,都是课件里自己提供的

def layer_sizes_test_case():
    np.random.seed(1)
    X_assess = np.random.randn(5, 3)
    Y_assess = np.random.randn(2, 3)
    return X_assess, Y_assess

def initialize_parameters_test_case():
    n_x, n_h, n_y = 2, 4, 1
    return n_x, n_h, n_y

def forward_propagation_test_case():
    np.random.seed(1)
    X_assess = np.random.randn(2, 3)

    parameters = {'W1': np.array([[-0.00416758, -0.00056267],
        [-0.02136196,  0.01640271],
        [-0.01793436, -0.00841747],
        [ 0.00502881, -0.01245288]]),
     'W2': np.array([[-0.01057952, -0.00909008,  0.00551454,  0.02292208]]),
     'b1': np.array([[ 0.],
        [ 0.],
        [ 0.],
        [ 0.]]),
     'b2': np.array([[ 0.]])}

    return X_assess, parameters

def compute_cost_test_case():
    np.random.seed(1)
    Y_assess = np.random.randn(1, 3)
    parameters = {'W1': np.array([[-0.00416758, -0.00056267],
        [-0.02136196,  0.01640271],
        [-0.01793436, -0.00841747],
        [ 0.00502881, -0.01245288]]),
     'W2': np.array([[-0.01057952, -0.00909008,  0.00551454,  0.02292208]]),
     'b1': np.array([[ 0.],
        [ 0.],
        [ 0.],
        [ 0.]]),
     'b2': np.array([[ 0.]])}

    a2 = (np.array([[ 0.5002307 ,  0.49985831,  0.50023963]]))

    return a2, Y_assess, parameters

def backward_propagation_test_case():
    np.random.seed(1)
    X_assess = np.random.randn(2, 3)
    Y_assess = np.random.randn(1, 3)
    parameters = {'W1': np.array([[-0.00416758, -0.00056267],
        [-0.02136196,  0.01640271],
        [-0.01793436, -0.00841747],
        [ 0.00502881, -0.01245288]]),
     'W2': np.array([[-0.01057952, -0.00909008,  0.00551454,  0.02292208]]),
     'b1': np.array([[ 0.],
        [ 0.],
        [ 0.],
        [ 0.]]),
     'b2': np.array([[ 0.]])}

    cache = {'A1': np.array([[-0.00616578,  0.0020626 ,  0.00349619],
         [-0.05225116,  0.02725659, -0.02646251],
         [-0.02009721,  0.0036869 ,  0.02883756],
         [ 0.02152675, -0.01385234,  0.02599885]]),
  'A2': np.array([[ 0.5002307 ,  0.49985831,  0.50023963]]),
  'Z1': np.array([[-0.00616586,  0.0020626 ,  0.0034962 ],
         [-0.05229879,  0.02726335, -0.02646869],
         [-0.02009991,  0.00368692,  0.02884556],
         [ 0.02153007, -0.01385322,  0.02600471]]),
  'Z2': np.array([[ 0.00092281, -0.00056678,  0.00095853]])}
    return parameters, cache, X_assess, Y_assess

def update_parameters_test_case():
    parameters = {'W1': np.array([[-0.00615039,  0.0169021 ],
        [-0.02311792,  0.03137121],
        [-0.0169217 , -0.01752545],
        [ 0.00935436, -0.05018221]]),
 'W2': np.array([[-0.0104319 , -0.04019007,  0.01607211,  0.04440255]]),
 'b1': np.array([[ -8.97523455e-07],
        [  8.15562092e-06],
        [  6.04810633e-07],
        [ -2.54560700e-06]]),
 'b2': np.array([[  9.14954378e-05]])}

    grads = {'dW1': np.array([[ 0.00023322, -0.00205423],
        [ 0.00082222, -0.00700776],
        [-0.00031831,  0.0028636 ],
        [-0.00092857,  0.00809933]]),
 'dW2': np.array([[ -1.75740039e-05,   3.70231337e-03,  -1.25683095e-03,
          -2.55715317e-03]]),
 'db1': np.array([[  1.05570087e-07],
        [ -3.81814487e-06],
        [ -1.90155145e-07],
        [  5.46467802e-07]]),
 'db2': np.array([[ -1.08923140e-05]])}
    return parameters, grads

def nn_model_test_case():
    np.random.seed(1)
    X_assess = np.random.randn(2, 3)
    Y_assess = np.random.randn(1, 3)
    return X_assess, Y_assess

def predict_test_case():
    np.random.seed(1)
    X_assess = np.random.randn(2, 3)
    parameters = {'W1': np.array([[-0.00615039,  0.0169021 ],
        [-0.02311792,  0.03137121],
        [-0.0169217 , -0.01752545],
        [ 0.00935436, -0.05018221]]),
     'W2': np.array([[-0.0104319 , -0.04019007,  0.01607211,  0.04440255]]),
     'b1': np.array([[ -8.97523455e-07],
        [  8.15562092e-06],
        [  6.04810633e-07],
        [ -2.54560700e-06]]),
     'b2': np.array([[  9.14954378e-05]])}
    return parameters, X_assess

浅层神经网络实现流程

1.先定义sigmoid函数

def sigmoid(z):
	A = 1/(1+np.exp(-z)return A

2.再定义initialize函数

def initialize_with_zeros(X,y,n_h):
    n_0, n_1, n_2 = X.shape[0],n_h,y.shape[0]   ###这里是
    W1 = np.random.randn(n_1,n_0)
    b1 = np.zeros((n_1,1))
    W2 = np.random.randn(n_2,n_1)
    b2 = np.zeros((n_2,1))
    
    params = {
        'W1':W1,
        'b1':b1,
        'W2':W2,
        'b2':b2
    }
    return params

犯过的错:

  1. n_0, n_1, n_2 是根据X和y的shape[0]定义的,shape[0]代表的特征值的数量。
  2. 这里np.zeros(()) 中间规定b1和b2的格式时需要再在中间加一个括号
  3. 这里最后加上一个n_h 是为了以后设定不同的隐藏层的值来画一组图

3.forward propagate

def forward_propagate(X,params):
    W1 = params['W1']
    b1 = params['b1']
    W2 = params['W2']
    b2 = params['b2']
    
    A1 = np.tanh(np.dot(W1,X)+b1)
    A2 = sigmoid(np.dot(W2,A1)+b2)
    
    assert(A2.shape == (1,X.shape[-1]))
    cache = {
        'A1':A1,
        'A2':A2
    }
    return cache

注意:最后决定W1和W2就不采取转置的模式了。

4.在forward propagate后计算成本

def compute_cost(y,cache):
    m = y.shape[-1]
    A2 = cache['A2']
    cost = (-1/m)*np.sum((y*np.log(A2) + (1-y)*np.log(1-A2)))
    cost = np.float(np.squeeze(cost))
    return cost

犯过的错
(y*np.log(A2) + (1-y)*np.log(1-A2)) 这里是(1,m)乘(1,m)不是向量内积,最后得出来也是(1,m)的结果。所以最后需要用np.sum进行加和,并且用np.squeeze保证最后是一个实数。

5.back propagate

def backward_propagate(X,y,params,cache):
    m = y.shape[-1]
    W1=params['W1']
    W2=params['W2']
    A1=cache['A1']
    A2=cache['A2']
    
    dZ2 = A2-y
    dW2 = (1/m)*np.dot(dZ2,A1.T)  ##dw2是直接在w2上减的 所以就是(1,4)
    db2 = (1/m)*np.sum(dZ2,axis = 1,keepdims=True)
    dZ1 =  np.multiply(np.dot(W2.T,dZ2),(1-np.power(A1,2))) ##这里这个公式记住(4,4)
    dW1 = (1/m)*np.dot(dZ1,X.T) 
    db1 = (1/m)*np.sum(dZ1,axis = 1,keepdims=True)
    
    assert(dW2.shape == (y.shape[0],n_h))
    assert(dW1.shape == (n_h,X.shape[0]))

    
    grads = {
        'dW2':dW2,
        'db2':db2,
        'dW1':dW1,
        'db1':db1
    }
    return grads

这里dZ1的计算公式要记牢: d l d Z 1 = d l d Z 2 ∗ d Z 2 d A 1 ∗ d A 1 d Z 1 = d Z 2 ∗ W 2 ∗ g ‘ ( Z 1 ) \frac{dl}{dZ1} =\frac{dl}{dZ2}*\frac{dZ2}{dA1}*\frac{dA1}{dZ1} = dZ2*W2*g`(Z1) dZ1dl=dZ2dldA1dZ2dZ1dA1=dZ2W2g(Z1)
用向量的代码形式就是下面:

dZ1 = np.multiply(np.dot(W2.T,dZ2),g`(Z1))

dW2的格式为(1,4)……(n_y,n_h)
db2的格式为(1,1)……(n_y,1)
dW1的格式为(4,3)……(n_h,n_x)
db1的格式为(4,1)….(n_h,1)
这里b1和b2的列数为1,因为每个训练对象的b相同,可以利用python中的broadcast来加到每个训练集上。

6.updata parameters

def update_parameters(params,grads,learning_rate = 1.2):
    W1=params['W1']
    b1=params['b1']
    W2=params['W2']
    b2=params['b2']
    
    dW1 = grads['dW1']
    db1 = grads['db1']
    dW2 = grads['dW2']
    db2 = grads['db2']
    
    W1 = W1 - learning_rate*dW1
    b1 = b1 - learning_rate*db1
    W2 = W2 - learning_rate*dW2
    b2 = b2 - learning_rate*db2
    
    parameters ={
        'W1':W1,
        'b1':b1,
        'W2':W2,
        'b2':b2
    }
    return parameters  

梳理一下上面的几个流程:
  1. 初始化w1,b1,w2,b2
  2. forward propagate计算A1和A2,A2也就是浅层神经网络中的y的预测值。
  3. 计算本次forward propagate的cost
  4. backward propagate计算dw1,db1,dw2,db2
  5. 更新参数得到新的w1,b1,w2,b2
  6. 回到第2步,开始新的forward propagate

7.加上循环将上面梳理的流程放在一起,命名为nn_model

def nn_model(X,y,num_iterations,print_cost=False):
    params = initialize_with_zeros(X,y)
    for i in range(num_iterations):
        cache = foward_propagate(X,params)
        cost = compute_cost(y,cache)
        grads = backward_propagate(X,y,params,cache)
        params = update_parameters(params,grads,learning_rate = 0.05)
        
        if(print_cost) and i%1000 == 0:
            print("第 ",i," 次循环,成本为:"+str(cost))
    return params
            

8.通过nn_model可以得到经过num_iterations重复后的最新的parameters的值,这里再用最新的参数值计算最终的y的预测值

def predict(X,parameters):
    cache = forward_propagate(X,parameters)
    A2 = cache['A2']
    y_predictions = np.round(A2)
    return y_predictions

这里np.round的作用就是将大于0.5的预测值记录为1,小于0.5的预测值记录为0

9.设置predict函数,用循环最后得出的W和b计算最终的预测值y

def predict(X,parameters):
    cache = forward_propagate(X,parameters)
    A2 = cache['A2']
    y_predictions = np.round(A2)
    return y_predictions

以上便是浅层神经网络构建的全部代码,下面对模型进行测试:

parameters = nn_model(X,Y,4,5000,print_cost=True)
plot_decision_boundary(lambda x: predict(x.T, parameters),X, np.squeeze(Y))
plt.title("Decision Boundary for hidden layer size " + str(4))

predictions = predict(X, parameters)
print ('准确率: %d' % float((np.dot(Y, predictions.T) + np.dot(1 - Y, 1 - predictions.T)) / float(Y.size) * 100) + '%')

第 0 次循环,成本为:1.3228871944341336
第 1000 次循环,成本为:0.29683168219859646
第 2000 次循环,成本为:0.28305492191379644
第 3000 次循环,成本为:0.2761861074786332
第 4000 次循环,成本为:0.2713672098405463
准确率: 88%
在这里插入图片描述
下面改变n_h的值:

plt.figure(figsize=(16, 32))
hidden_layer_sizes = [1, 2, 3, 4, 5, 20, 50] #隐藏层数量
for i, n_h in enumerate(hidden_layer_sizes):
    plt.subplot(5, 2, i + 1)
    plt.title('Hidden Layer of size %d' % n_h)
    parameters = nn_model(X, Y, n_h, num_iterations=10000)
    plot_decision_boundary(lambda x: predict(x.T, parameters), X, np.squeeze(Y))
    predictions = predict(X, parameters)
    accuracy = float((np.dot(Y, predictions.T) + np.dot(1 - Y, 1 - predictions.T)) / float(Y.size) * 100)
    print ("隐藏层的节点数量: {}  ,准确率: {} %".format(n_h, accuracy))

隐藏层的节点数量: 1 ,准确率: 66.0 %
隐藏层的节点数量: 2 ,准确率: 64.75 %
隐藏层的节点数量: 3 ,准确率: 90.75 %
隐藏层的节点数量: 4 ,准确率: 90.75 %
隐藏层的节点数量: 5 ,准确率: 90.5 %
隐藏层的节点数量: 20 ,准确率: 90.5 %
隐藏层的节点数量: 50 ,准确率: 91.5 %
在这里插入图片描述

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值