【前言】
这是第三周的编程作业
以下只是主要部分的代码,需要用到的资料可以访问 我的GitHub 进行获取
这是我的文件目录:
我是用的PyCharm,如果你没有安装相应的依赖库,请按照以下方式进行安装:
首先打开:terminal
输入以下命令:
pip install matplotlib
诸如此类…
one_hiddenlayer_neural_network.py文件:
import numpy as np
import matplotlib.pyplot as plt
from testCases import *
from planar_utils import plot_decision_boundary, sigmoid, load_planar_dataset, load_extra_datasets#%matplotlib inline #如果你使用用的是Jupyter Notebook的话请取消注释。np.random.seed(1) #设置一个固定的随机种子,以保证接下来的步骤中我们的结果是一致的。#训练集数据
X, Y = load_planar_dataset()
plt.scatter(X[0, :], X[1, :], c=np.squeeze(Y), s=40, cmap=plt.cm.Spectral) #绘制散点图
# print(X[0,:]) X的第一行
# print(X[1,:]) X的第二行
# print(X) X是2行800列的数组,每一列中的第一行和第二行分别对应x和y,800列即800个样本数据
# print(Y) Y是(1,400)的行向量[[1,2,...,400]]
# print(np.squeeze(Y)) np.squeeze(Y)将消除维度1,结果是[1,2,...,400]
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 #,隐藏层,硬编码为4n_y = Y.shape[0] #输出层return (n_x,n_h,n_y)def initialize_parameters( n_x , n_h ,n_y):"""参数:n_x - 输入节点的数量n_h - 隐藏层节点的数量n_y - 输出层节点的数量返回:parameters - 包含参数的字典: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.randn(n_h,n_x) * 0.01b1 = np.zeros(shape=(n_h, 1))W2 = np.random.randn(n_y,n_h) * 0.01b2 = np.zeros(shape=(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 parametersdef forward_propagation( X , parameters ):"""参数:X - 维度为(n_x,m)的输入数据。parameters - 初始化函数(initialize_parameters)的输出返回:A2 - 使用sigmoid()函数计算的第二次激活后的数值cache - 包含“Z1”,“A1”,“Z2”和“A2”的字典类型变量"""W1 = parameters["W1"]b1 = parameters["b1"]W2 = parameters["W2"]b2 = parameters["b2"]#前向传播计算A2Z1 = np.dot(W1 , X) + b1A1 = np.tanh(Z1)Z2 = np.dot(W2 , A1) + b2A2 = sigmoid(Z2)#使用断言确保我的数据格式是正确的assert(A2.shape == (1,X.shape[1]))cache = {"Z1": Z1,"A1": A1,"Z2": Z2,"A2": A2}return (A2, cache)def compute_cost(A2,Y,parameters):"""计算方程(6)中给出的交叉熵成本,参数:A2 - 使用sigmoid()函数计算的第二次激活后的数值Y - "True"标签向量,维度为(1,数量)parameters - 一个包含W1,B1,W2和B2的字典类型的变量返回:成本 - 交叉熵成本给出方程(13)"""m = Y.shape[1]# W1 = parameters["W1"]# W2 = parameters["W2"]#计算成本logprobs = np.multiply(np.log(A2), Y) + np.multiply((1 - Y), np.log(1 - A2))cost = - np.sum(logprobs) / mcost = float(np.squeeze(cost))assert(isinstance(cost,float))return costdef backward_propagation(parameters,cache,X,Y):"""使用上述说明搭建反向传播函数。参数:parameters - 包含我们的参数的一个字典类型的变量。cache - 包含“Z1”,“A1”,“Z2”和“A2”的字典类型的变量。X - 输入数据,维度为(2,数量)Y - “True”标签,维度为(1,数量)返回:grads - 包含W和b的导数一个字典类型的变量。"""m = X.shape[1]W1 = parameters["W1"]W2 = parameters["W2"]A1 = cache["A1"]A2 = cache["A2"]dZ2= A2 - YdW2 = (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 gradsdef 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 * dW1b1 = b1 - learning_rate * db1W2 = W2 - learning_rate * dW2b2 = b2 - learning_rate * db2parameters = {"W1": W1,"b1": b1,"W2": W2,"b2": b2}return parametersdef nn_model(X,Y,n_h,num_iterations,print_cost=False):"""参数:X - 数据集,维度为(2,示例数)Y - 标签,维度为(1,示例数)n_h - 隐藏层的数量num_iterations - 梯度下降循环中的迭代次数print_cost - 如果为True,则每1000次迭代打印一次成本数值返回: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 parametersdef predict(parameters,X):"""使用学习的参数,为X中的每个示例预测一个类参数:parameters - 包含参数的字典类型的变量。X - 输入数据(n_x,m)返回predictions - 我们模型预测的向量(红色:0 /蓝色:1)"""A2 , cache = forward_propagation(X,parameters)predictions = np.round(A2)return predictions#使用逻辑回归预测的准确率只有0.47,因为数据集不是线性可分的,不属于二分类的问题
# clf = sklearn.linear_model.LogisticRegressionCV()
# clf.fit(X.T,Y.T)
# plot_decision_boundary(lambda x: clf.predict(x), X, Y) #绘制决策边界
# plt.title("Logistic Regression") #图标题
# plt.show()
# LR_predictions = clf.predict(X.T) #预测结果
# print ("逻辑回归的准确性: %d " % float((np.dot(Y, LR_predictions) +
# np.dot(1 - Y,1 - LR_predictions)) / float(Y.size) * 100) +
# "% " + "(正确标记的数据点所占的百分比)")parameters = nn_model(X, Y, n_h = 4, num_iterations=10000, print_cost=True)#绘制边界
plot_decision_boundary(lambda x: predict(parameters, x.T), X, Y)
plt.title("Decision Boundary for hidden layer size " + str(4))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))
plt.show()
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, Y)plt.figure(figsize=(16, 32))plt.show()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))
神经网络和深度学习系列笔记: 传送门