用单隐层NN做平面数据分类

参考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), ' %')

分类结果为:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值