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

import numpy as np
import matplotlib.pyplot as plt
from testCases import *
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)
X,Y=load_planar_dataset()
#用matplotlib可视化数据
plt.scatter(X[0,:],X[1,:],c=np.squeeze(Y),s=40,cmap=plt.cm.Spectral)
plt.show()
shape_X=X.shape
shape_Y=Y.shape
m=Y.shape[1] #训练集里面的数据
print("X的维度为:"+str(shape_X))
print("Y的维度为:"+str(shape_Y))
print("数据集里面的数据有:"+str(m)+"个")
def layer_sizes(X,Y):
    '''参数:
    X:输入数据集,维度是(输入的数量,训练/测试的数量)
    Y:标签
    返回:
    n_x:输入层的数量
    n_h:隐藏层的数量
    n_y:输出层的数量'''
    n_x=X.shape[0]#输入层
    n_h=4#隐藏层,硬编码为4
    n_y=Y.shape[0]
    return (n_x,n_h,n_y)
#测试layer_sizes
print("=========================测试layer_sizes=========================")
X_asses , Y_asses = layer_sizes_test_case()
(n_x,n_h,n_y) =  layer_sizes(X_asses,Y_asses)
print("输入层的节点数量为: n_x = " + str(n_x))
print("隐藏层的节点数量为: n_h = " + str(n_h))
print("输出层的节点数量为: n_y = " + str(n_y))
#初始化模型的参数
def initialize_parameters(n_x,n_h,n_y):
    '''
    参数:
    n_x:输入层结点的数量
    n_h:隐藏层结点的数量
    n_y:输出层结点的数量
    返回:
    paraneters:包含参数的字典
    W1:权重矩阵,维度为(n_h,n_x)
    b1:偏向量,维度为(n_h,1)
    W2:权重矩阵,维度为(n_y,n_h)
    b2:偏向量,维度为(n_y,1)
    '''
    np.random.seed(2)#指定一个随机种子
    W1=np.random.rand(n_h,n_x)*0.01
    b1=np.zeros(shape=(n_h,1))
    W2=np.random.rand(n_y,n_h)
    b2=np.random.rand(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
#测试initialize_parameters
n_x,n_h,n_y=initialize_parameters_test_case()
parameters=initialize_parameters(n_x,n_h,n_y)
print("W1="+str(parameters["W1"]))
print("b1="+str(parameters["b1"]))
print("W2="+str(parameters["W2"]))
print("b2="+str(parameters["b2"]))
#实现循环
'''我们现在要实现前向传播函数forward_propagation()。 
我们可以使用sigmoid()函数,也可以使用np.tanh()函数。  
步骤如下:
使用字典类型的parameters(它是initialize_parameters() 的输出)检索每个参数。
实现向前传播, 计算Z[1],A[1],Z[2]Z[1],A[1],Z[2] 和 A[2]A[2]( 训练集里面所有例子的预测向量)。
反向传播所需的值存储在“cache”中,cache将作为反向传播函数的输入。
'''
def forward_propagation(X,parameters):
    '''
    参数:
    X-维度为(n_x,m)的输入数据
    parameters:初始化函数(initialize_parameters)的输出
    返回:
    A2:使用激活函数后的激活值
    cache-包含“Z1","A1","Z2"和“A2”的字典型变量
    '''
    W1=parameters["W1"]
    b1=parameters['b1']
    W2=parameters['W2']
    b2=parameters['b2']
    #向前传播计算A2
    Z1=np.dot(W1,X)+b1
    A1=np.tanh(Z1)
    Z2=np.dot(W2,A1)+b2
    A2=sigmoid(Z2)
    #使用断言保证我的数据格式是正确的
    assert(A2.shape==(1,X.shape[1]))
    cache={"Z1":Z1,
           "A1":A1,
           "Z2":Z2,
           "A2":A2
    }
    return (A2,cache)
#测试模型
X_assess,parameters=forward_propagation_test_case()
A2,cache=forward_propagation(X_assess,parameters)
print(np.mean(cache["Z1"]),np.mean(cache['A1']),np.mean(cache['Z2']),np.mean(cache['A2']))
#计算成本函数与损失函数

def compute_cost(A2,Y,parameters):
    '''计算交叉熵
    参数:
    A2:使用sigmoid函数计算的第二次激活后的函数值
    Y:True标签向量,维度为(1,数量)
    parameters:一个包含W1,W2,b1,b2的字典类型的变量
    返回:成本交叉熵函数,给出方程
    '''
    m=Y.shape[1]
    W1=parameters['W1']
    W2=parameters['W2']
    #计算成本
    logprobs=logprobs=np.multiply(np.log(A2),Y)+np.multiply((1-Y),np.log(1-A2))
    cost=-np.sum(logprobs)/m
    cost=float(np.squeeze(cost))
    assert(isinstance(cost,float))
    return cost
#预测compute_cost
A2,Y_assess,parameters=compute_cost_test_case()
print("cost="+str(compute_cost(A2,Y_assess,parameters)))
#搭建反向传播函数
def backward_propagation(parameters,cache,X,Y):
    '''参数:
    parameters:包含参数的一个字典变量
    cache:包含Z1,A1,Z2,A2的字典类型的变量
    X:输入数据,维度为(2,数量)
    Y:输出数据,唯独为(1,数量)
    返回:
    grads:包含W和b的导数的一个字典变量'''
    m=X.shape[1]
    W1=parameters['W1']
    W2=parameters['W2']
    A1=cache['A1']
    A2=cache['A2']
    dZ2=A2-Y
    dW2=(1/m)*np.dot(dZ2,A1.T)
    db2=(1/m)*np.sum(dZ2,axis=1,keepdims=True)
    dZ1=np.multiply(np.dot(W2.T,dZ2),1-np.power(A1,2))
    dW1 = (1 / m) * np.dot(dZ1, X.T)
    db1 = (1 / m) * np.sum(dZ1, axis=1, keepdims=True)
    grads={'dW1':dW1,
           'db1':db1,
           'dW2':dW2,
           'db2':db2}
    return grads
#更新参数
def update_parameters(parameters,grads,learning_rate=1.2):
    '''参数:
    parameters:包含参数的字典类型数据的变量
    grads:包含导数值得字典类型变量
    learning_rate:学习速率
    返回:
    parameters:包含更新参数的字典类型和变量'''
    W1,W2=parameters['W1'],parameters['W2']
    b1,b2=parameters['b1'],parameters['b2']
    dW1,dW2=grads['dW1'],grads['dW2']
    db1,db2=grads['db1'],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
#测试update_parameters
parameters,grads=update_parameters_test_case()
parameters=update_parameters(parameters,grads)
print("W1="+str(parameters["W1"]))
print("b1="+str(parameters["b1"]))
print("W2="+str(parameters["W2"]))
print("b2="+str(parameters['b2']))
#把上述内容整合到nn_model()中,神经网络模型必须以正确的顺序使用先前的功能
def nn_model(X,Y,n_h,num_iterations,print_cost=False):
    '''参数:
    X-数据集,维度为(2,示例数)
    Y-标签,维度为(1,示例数)
    n_h:隐藏层的数量
    num_iterations:梯度下降循环中的迭代次数
    print_cost:如果为True,则每100次迭代打印一次成本数值
    返回:
    parameters:模型学习的参数,它们可以用来预测
    '''
    np.random.seed(3)#指定随机种子
    n_x=layer_sizes(X,Y)[0]
    n_y=layer_sizes(X,Y)[2]
    parameters=initialize_parameters(n_x,n_h,n_y)
    W1=parameters['W1']
    b1=parameters['b1']
    W2=parameters['W2']
    b2=parameters['b2']
    for i in range(num_iterations):
        A2,cache=forward_propagation(X,parameters)
        cost=compute_cost(A2,Y,parameters)
        grads=backward_propagation(parameters,cache,X,Y)
        parameters=update_parameters(parameters,grads,learning_rate=0.5)
        if print_cost:
            if i%1000==0:
                print("第",i,"次循环","成本为:"+str(cost))
    return parameters
#测试nn_model
X_assess,Y_assess=nn_model_test_case()
parameters=nn_model(X_assess,Y_assess,4,num_iterations=10000,print_cost=False)
print("W1="+str(parameters["W1"]))
print("b1="+str(parameters["b1"]))
print("W2="+str(parameters["W2"]))
print("b2="+str(parameters["b2"]))
#predict模型
'''激活值大于0.5,预测值为1,否则为0'''
def predict(parameters,X):
    '''使用学习的参数为X分类
    参数:
    parameters:包含参数的字典类型的变量
    X:输入数据
    返回:
    predictions:我们模型预测的向量(红色:0/蓝色:1)
    '''
    A2,cache=forward_propagation(X,parameters)
    predictions=np.round(A2)
    return predictions
#测试predict
parameters,X_assess=predict_test_case()
predictions=predict(parameters,X_assess)
print("预测的平均值="+str(np.mean(predictions)))
parameters = nn_model(X, Y, n_h = 4, num_iterations=10000, print_cost=True)

#绘制边界
'''注:数组的可视化
通常算法的结果是可以表示向量的数组,直接利用数组画图时界面为空
利用sequeeze()函数转化为秩为1的数组可以正常画图'''
plot_decision_boundary(lambda x: predict(parameters, x.T), X, np.squeeze(Y))
plt.title("Decision Boundary for hidden layer size " + str(4))
plt.show()
predictions = predict(parameters, X)
print ('准确率: %d' % float((np.dot(Y, predictions.T) + np.dot(1 - Y, 1 - predictions.T)) / float(Y.size) * 100) + '%')
#更改隐藏结点的数量
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=5000)
    plot_decision_boundary(lambda x:predict(parameters,x.T),X,np.squeeze(Y))
    predictions=predict(parameters,X)
    accuracy=float((np.dot(Y,predictions.T)+np.dot(1-Y,1-predictions.T))/float(Y.size)*100)
    print("隐藏结点的数量:{},准确率:{}%".format(n_h,accuracy))

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值