参考https://blog.csdn.net/u013733326/article/details/79702148
需要做的是将平面上的点按照某种类别分开:
代码:
# 现在有一组数据集,代表的是某个点的坐标以及这个点的颜色
# 现在要做的是学习点的坐标和颜色之间的联系
# 神经网络的构建步骤:
# 1.搭建网络结构(输入层隐藏层输出层结点数量)
# 2.初始化参数
# 3.迭代
# 3.1每次迭代先用正向传播函数得到计算成本函数需要用到的量
# 3.2然后用计算成本函数得到成本函数值
# 3.3然后用反向传播函数得到成本函数对参数的导数
# 3.4最后用得到的导数更新参数,进行下一次迭代
# 本demo中数据集X的维度为:2, 400
# 代表400个点及其坐标
# 本demo中的每个数据集X的长度为2
import matplotlib.pyplot as plt
import numpy as np
from testCases import *
from planar_utils import load_planar_dataset, sigmoid, plot_decision_boundary, relu
# np.random.seed(1)# 设置随机种子
X, Y = load_planar_dataset()# 加载和查看数据集
# 网络结构搭建
# 参数:数据集X, Y
# 返回:单隐层NN各层的结点数量
def layer_sizes(X, Y):# 此函数已OK
n_x = X.shape[0]
n_h = 4
n_y = Y.shape[0]
return (n_x, n_h, n_y)
# 初始化网络参数
# 参数:网络中各层的结点数量
# 返回:NN初始参数w和b
def initialize_parameters(n_x, n_h, n_y):# 此函数已OK
np.random.seed(2)# 设置随机种子
# 确定各参数的维度
W1 = np.random.randn(n_h, n_x) * 0.01
b1 = np.zeros(shape = (n_h, 1))
W2 = np.random.randn(n_y, n_h) * 0.01
b2 = 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 parameters
# 正向传播
# 参数:输出层结点数量、输入向量、初始化的参数
# 返回:计算成本函数需要用到的量A2
# 还有一些计算的一些中间结果,后面反向传播会用到
def forward_propagation(X, parameters):# 此函数已OK
m = X.shape[1]
W1 = parameters['W1']
b1 = parameters['b1']
W2 = parameters['W2']
b2 = parameters['b2']
Z1 = np.dot(W1, X) + b1# 为啥不用转置?因为W1初始化的就已经转置好了
A1 = np.tanh(Z1)
Z2 = np.dot(W2, A1) + b2
A2 = sigmoid(Z2)
assert (A2.shape == (1, m))# 这里应该不是1吧???
cache = {
'W2': W2,
'A1': A1,
'A2': A2,
'b2': b2
}
return A2, cache
# 计算成本函数值
# 参数:训练集Y, A2
# 返回:成本函数值
def cost_computation(Y, A2):# 此函数已OK
m = Y.shape[1]
sum = np.sum(Y * np.log(A2) + (1 - Y) * np.log(1 - A2))
cost = (-1 / m) * sum
assert (isinstance(cost, float))
return cost
# 反向传播函数
# 参数:, Y, X, W2 A2 A1 Z1
# 也就是正向传播的一些中间计算结果cache、训练集X, Y
# 返回:成本函数对各个参数的梯度
def backward_propagation(cache, X, Y):# 此函数已OK
m = X.shape[1]
# 取出计算梯度需要用到的量
W2 = cache['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 = {
'dZ2': dZ2,
'dW2': dW2,
'db2': db2,
'dZ1': dZ1,
'dW1': dW1,
'db1': db1,
}
return grads
# 更新参数函数
# 参数:上一次迭代后的参数、反向传播得到的梯度、学习率
# 返回:更新后的参数
def parameters_updation(parameters, grads, learning_rate):# 此函数已OK
# 取出上一次的参数
W1 = parameters['W1']
b1 = parameters['b1']
W2 = parameters['W2']
b2 = parameters['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
# 预测函数
# 参数:训练好的参数、测试特征集、输出层结点数量
# 返回:预测标签集
def predict(parameters, test_X):# 此函数已OK
A2, cache = forward_propagation(X=test_X, parameters=parameters)
Y = np.round(A2)
return Y
# 单隐层神经网络训练模型
def OHNN(X, Y, n_h_p = None, num_iterations = 100000, learning_rate = 0.01, print_cost = True):# 此函数已OK
# 搭建网络结构
n_x, n_h_now, n_y = layer_sizes(X, Y)
# 初始化网络参数
n_h = None
if n_h_p != None:
n_h = n_h_p
else:
n_h = n_h_now
parameters = initialize_parameters(n_x, n_h=n_h, n_y=n_y)
# 迭代
for i in range(num_iterations):
parameters_for_cost, cache = forward_propagation(X, parameters)# 正向传播
cost = cost_computation(Y, cache['A2'])# 计算成本函数值
if i != 0 and i % 1000 == 0 and print_cost:
print('第' + str(i) + '次迭代成本为:' + str(cost))
grads = backward_propagation(cache, X, Y)# 反向传播
parameters = parameters_updation(parameters, grads, learning_rate=learning_rate)# 更新参数
return parameters
# 用不同的隐藏层结点数量实验
h_sizes = [1, 2, 3, 4, 5, 20, 50]
for i, size in enumerate(h_sizes):
plt.title('隐藏层结点数量为%d的决策边界' % size)
parameters = OHNN(X, Y, n_h_p=size, num_iterations=5000, learning_rate=1.2, print_cost=False)
plot_decision_boundary(lambda x: predict(parameters, x.T), X, np.squeeze(Y))
predictions = predict(parameters, X)
print('隐藏层结点数量为%d的模型的准确率为:%d' % (size, float(np.dot(Y, predictions.T) +
np.dot(1 - Y, 1 - predictions.T)) / float(Y.size) * 100), ' %')
分类结果为: