入门神经网络——浅层神经网络

2023-11-02

一、基础知识

1.浅层神经网络介绍

此次构件浅层神经网络,相比于单神经元,浅层神经网络拥有多个神经元,因此又可以称为多神经元网络,如下图所示。
在这里插入图片描述
多神经元网络基本由三部分组成:输入层、隐藏层、输出层
**输入层:**最前面负责输入特征的层(注:在统计神经网络层数时通常不把这一层统计在内,像上图是一个2层的神经网络)。
**隐藏层:**中间的所有层称为隐藏层。
**输出层:**最后一层负责输出最后结果的层。

2.浅层神经网络的正向传播

以下图为例,首先分别计算第一层的每一个神经元的a,其中上标[]里的数字表示第几层,下标数字表示该层中的第几个神经元。
在这里插入图片描述
计算公式如下所示
在这里插入图片描述
此例子中的隐藏层的神经元个数为4个,但是当神经元个数较多时需要用向量的形式计算:
第一层:
在这里插入图片描述
第二层:
在这里插入图片描述
此例子中输入为单样本,当进行多样本输入训练时,
在这里插入图片描述
由此计算出 成本J,完成了依此正向传播。

3.反向传播

在这里插入图片描述
首先计算第二层的相关偏导数,与单神经元网络一致:
在这里插入图片描述
之后再计算第一层相关偏导数,由于第一层没有与损失函数直接相邻,只能通过链式法则。计算第一层相关偏导数时,首先需要计算出dZ[1],dW[1],db[1]都可以通过dZ[1]求得。
在这里插入图片描述
之后再进行向量化,最终得到反向传播后计算的相关偏导数如下所示
在这里插入图片描述

二、浅层神经网络代码实例

此次实例采用代码生成的虚拟数据集来演示,这个数据集由400个样本组成。这400个样本是400个颜色点。输入特征X是点的横纵坐标,标签Y是点的颜色标签(0表示红色,1表示蓝色)。
该样本点如下图所示:
在这里插入图片描述
此次的目标就是通过训练一个神经网络来通过坐标值判断在上图坐标系中某一点可能的颜色,例如坐标(-4,2)的点可能是什么颜色,(-4,3)最可能是什么颜色。将红色和蓝色的点区分出来。

import numpy as np
import matplotlib.pyplot as plt
import sklearn  # 其它库之前我们都介绍过了。这个新库是用于数据挖掘,数据分析和机器学习的库,例如它里面就内置了很多人工智能函数
import sklearn.datasets
import sklearn.linear_model


# 生成数据集函数
def load_planar_dataset():
    np.random.seed(1)
    m = 400  # number of examples
    N = int(m / 2)  # number of points per class
    D = 2  # dimensionality
    X = np.zeros((m, D))  # data matrix where each row is a single example
    Y = np.zeros((m, 1), dtype='uint8')  # labels vector (0 for red, 1 for blue)
    a = 4  # maximum ray of the flower

    for j in range(2):
        ix = range(N * j, N * (j + 1))
        t = np.linspace(j * 3.12, (j + 1) * 3.12, N) + np.random.randn(N) * 0.2  # theta
        r = a * np.sin(4 * t) + np.random.randn(N) * 0.2  # radius
        X[ix] = np.c_[r * np.sin(t), r * np.cos(t)]
        Y[ix] = j

    X = X.T
    Y = Y.T

    return X, Y


# 画图函数
def plot_decision_boundary(model, X, y):
    # Set min and max values and give it some padding
    x_min, x_max = X[0, :].min() - 1, X[0, :].max() + 1
    y_min, y_max = X[1, :].min() - 1, X[1, :].max() + 1
    h = 0.01
    # Generate a grid of points with distance h between them
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
    # Predict the function value for the whole grid
    Z = model(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    # Plot the contour and training examples
    plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
    plt.ylabel('x2')
    plt.xlabel('x1')
    plt.scatter(X[0, :], X[1, :], c=y, cmap=plt.cm.Spectral)


# 激活函数
def sigmoid(x):
    """
    Compute the sigmoid of x

    Arguments:
    x -- A scalar or numpy array of any size.

    Return:
    s -- sigmoid(x)
    """
    s = 1 / (1 + np.exp(-x))
    return s


# 初始化参数w和b函数
def initialize_parameters(n_x, n_h, n_y):
    """
    参数:
    n_x -- 输入层的神经元个数
    n_h -- 隐藏层的神经元个数
    n_y -- 输出层的神经元个数
    """

    np.random.seed(2)

    # 随机初始化第一层(隐藏层)相关的参数w.
    # 每一个隐藏层神经元都与输入层的每一个神经元相连。每一个相连都会有一个对应的参数w。
    # 所以W1的维度是(n_h, n_x),表示(隐藏层的神经元个数,输入层神经元个数)
    W1 = np.random.randn(n_h, n_x) * 0.01

    # 将第一层的参数b赋值为0,因为w已经非0了,所以b可以为0
    # 因为每一个神经元只有一个对应的b,所以b1的维度是(n_h, 1),表示(隐藏层神经元个数,1)
    b1 = np.zeros(shape=(n_h, 1))

    # 同理,初始化第二层的w和b
    W2 = np.random.randn(n_y, n_h) * 0.01
    b2 = np.zeros(shape=(n_y, 1))

    # 将初始化好的参数放入一个字典变量中
    parameters = {"W1": W1,
                  "b1": b1,
                  "W2": W2,
                  "b2": b2}

    return parameters


# 前向传播函数
def forward_propagation(X, parameters):
    """
    参数:
    X -- 输入特征,维度是 (横纵坐标, 样本数)
    parameters -- 参数w和b

    Returns:
    A2 -- The sigmoid output of the second activation
    cache -- a dictionary containing "Z1", "A1", "Z2" and "A2"
    """

    m = X.shape[1]  # 获取样本数
    # print("样本数:" + str(m))

    # 从字典中取出参数
    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']

    # 实现前向传播算法
    Z1 = np.dot(W1, X) + b1
    A1 = np.tanh(Z1)  # 第一层的激活函数我们使用tanh。numpy库里面已经帮我们实现了tanh工具函数
    Z2 = np.dot(W2, A1) + b2
    A2 = sigmoid(Z2)  # 第二层我们使用sigmoid,因为我们要解决的这个问题属于二分问题。这个函数是我们自己在planar_utils里面实现的。

    # 将这些前向传播时得出的值保存起来,因为在后面进行反向传播计算时会用到他们。
    cache = {"Z1": Z1,
             "A1": A1,
             "Z2": Z2,
             "A2": A2}

    return A2, cache


# 这个函数被用来计算成本
def compute_cost(A2, Y, parameters):
    """
    参数:
    A2 -- 神经网络最后一层的输出结果
    Y -- 数据的颜色标签
    """

    m = Y.shape[1]

    logprobs = np.multiply(np.log(A2), Y) + np.multiply((1 - Y), np.log(1 - A2))
    cost = - np.sum(logprobs) / m

    return cost


# 然后就是反向传播
def backward_propagation(parameters, cache, X, Y):
    """
    参数:
    parameters -- 参数w和b
    cache -- 前向传播时保存起来的一些数据
    X -- 输入特征
    Y -- 标签
    """
    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  # 返回计算得到的梯度


# 用上面得到的梯度来进行梯度下降(更新参数w和b,使其更优化)
def update_parameters(parameters, grads, learning_rate=1.2):
    """
    参数:
    parameters -- 参数w和b
    grads -- 梯度
    """

    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 nn_model(X, Y, n_h, num_iterations=10000, print_cost=True):
    """
    Arguments:
    X -- 输入特征
    Y -- 标签
    n_h -- 隐藏层的神经元个数
    num_iterations -- 训练多少次
    print_cost -- 是否打印出成本
    """

    np.random.seed(3)
    n_x = X.shape[0]  # 根据输入特征的维度得出输入层的神经元个数
    n_y = Y.shape[0]  # 根据标签的维度得出输出层的神经元个数

    # 初始化参数
    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(0, 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)

        # 将本次训练的成本打印出来
        if print_cost and i % 1000 == 0:
            print("在训练%i次后,成本是: %f" % (i, cost))

    return parameters


# 我们已经可以通过上面的函数来进行参数训练。
# 这个函数可以利用上面学习到的参数来对新数据进行预测
def predict(parameters, X):
    """
    参数:
    parameters -- 训练得出的参数(学习到的参数)
    X -- 预测数据
    """

    # 预测其实就是简单地执行一次前向传播
    A2, cache = forward_propagation(X, parameters)
    predictions = np.round(A2)  # 对结果进行四舍五入,小于0.5就是0,否则就是1

    return predictions


np.random.seed(1)  # 设置一个随机数种子,来保证后面我的代码产生的随机数与你们电脑上产生的一样,这样我的结果才能和你们运行的结果一样
X, Y = load_planar_dataset()

# 将训练集送入模型中,并设置隐藏层数为4层,训练次数为1000次
parameters = nn_model(X, Y, n_h=50, num_iterations=20000,print_cost=True)
# 然后用训练得出的参数进行预测。
predictions = predict(parameters, X)
print('预测准确率是: %d' % float((np.dot(Y, predictions.T) + np.dot(1 - Y, 1 - predictions.T)) / float(Y.size) * 100) + '%')
plot_decision_boundary(lambda x: predict(parameters, x.T), X, Y.ravel())
plt.show()

在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

入门神经网络——浅层神经网络 的相关文章

随机推荐

  • 外部中断EXTI

    项目场景 STM32外部中断 EXTI10 15 中断线挂起无法清除问题 问题描述 按键为PD14 输入模式 外部中断 进中断服务函数处理完后仍再次进入中断服务函数 无法退出 中断服务函数已加入清除中断线函数 检查引脚配置 输入模式 RCC
  • Javav中危险字符过滤工具类

    在进行网站开发时 为了避免网站遭到SQL语句的注入式攻击 应该考虑到过滤字符串中的危险字符 在该实例中 可以过滤 lt gt 等字符时 在处理页面中会把这些字符过滤掉 该示例主要利用String的replaceAll方法 public St
  • [spark]计算商品相似度

    一 商品相似度定义 基于物品的协同过滤算法是业界应用最多的算法 它的思想是给用户推荐那些和他们喜欢的物品相似的物品 主要分为两个步骤 一 计算物品之间的相似度 二 根据物品相似度和用户的历史行为给用户生成推荐列表 物品i和物品j的相似度可定
  • 创建工程文件(完整流程)

    创建并完成一个简单的工程的流程 添加文件 创建文件 此时 文件就添加完毕了 设置字体 设置Table的空格字数为4个 书写代码 拷贝的正点原子的例程 点击综合 生成设计后的原理图 第一种方法 进行I O引脚的分配 需要查看电路板的原理图分配
  • 【SSD-Caffe】安装使用教程

    1 下载镜像 参考我的另一篇博客 docker使用教程 我下载的是 docker pull bvlc caffe gpu 这个镜像 2 安装ssd caffe 下载之后这并不是ssd caffe 的环境 是较为原始版本的环境 所以还需要安装
  • 抓取iframe内数据(C#)

    当时企图抓取这iframe数据还费了不少劲 早就想记录下来 但是由于自身懒得让人惊叹 结果一直拖到现在 需求是要获取到一些网站上的大批数据 这些数据都是分很多页的 最初思路就是用web程序一页一页抓取 保存到Excel中 通常情况下用以下代
  • 5大指标:评估RPA项目的ROI,实现投资回报最大化

    ROI 投资回报率 通常是RPA项目中的一个关键指标 在企业步入自动化的早期阶段 关注RPA的投资回报率非常重要 这将影响到一个RPA项目是否值得去做 对企业运营者 尤其是COO 首席运营官 而言 RPA若实施得当 将为企业降本增效带来无与
  • 机器学习苹果识别——python+opencv实现物体特征提取

    以水果为例 要用机器学习来实现水果识别 无论是训练还是识别阶段都需要提取图片中水果的特征值 本篇将讲述如何提取水果的周长 面积 颜色 长度 宽度7个特征值 cv findContours cv findContours将图片中识别到的轮廓返
  • 如何用matlab去修改图像尺寸

    img imread test1 jpg 这里为原始图像 i imresize img 567 390 imwrite i 1 jpg 这里为修改后图像 imread imresize和imwrite 1 imread 读取图像信息 A i
  • 查看VSCode版本

    背景 想要查看一下visual studio code的版本 方法 在vscode菜单栏 帮助 gt 发行说明 Help gt Release Notes 版本为1 36
  • C++auto_ptr的用法

    文章目录 一 auto ptr是什么 二 auto ptr需要包含的头文件 三 auto ptr用法 一 auto ptr是什么 auto ptr 是C 标准库提供的类模板 auto ptr对象通过初始化指向由new创建的动态内存 它是这块
  • TCP 协议(四)重传与超时

    1 TCP 协议中的计时器 TCP 中有四种计时器 Timer 分别为 重传计时器 Retransmission Timer 持久计时器 Persistent Timer 保活计时器 Keeplive Timer 等待计时器 Timer W
  • gdb+gdbserver远程调试技术

    首先声明 此文是在别人的基础上添加一些自己的体会 之前做嵌入式开发的时候 弄过一段时间gdb gdbserver远程调试 最后无果而终 只好将就用printf 首先感谢这篇刘品的文章 看着整洁清楚 http www cnblogs com
  • 目标检测之YOLOv3算法分析

    基本原理 特征网络 输入输出 输入 416 416 3 416 416 3 416 416 3大小的图片 不唯一 但图片大小必为32的倍数 输出3个尺度的feature map 分别为
  • 虹科分享

    说到应用程序和软件 关键词是 更多 在数字经济需求的推动下 从简化业务运营到创造创新的新收入机会 企业越来越依赖应用程序 云本地应用程序开发更是火上浇油 然而 情况是双向的 这些应用程序通常更复杂 使用的开放源代码比以往任何时候都包含更多的
  • 在Linux中使用线程

    我并不假定你会使用Linux的线程 所以在这里就简单的介绍一下 如果你之前有过多线程方面的编程经验 完全可以忽略本文的内容 因为它非常的初级 首先说明一下 在Linux编写多线程程序需要包含头文件pthread h 也就是说你在任何采用多线
  • printf()和cout的区别

    printf 和cout的区别 printf is a function that takes a variable number of arguments the first argument being a format string
  • Ubuntu使用内网穿透实现外网ssh远程登录

    Ubuntu使用内网穿透实现外网ssh远程登录 想要远程Ubuntu可以使用ssh网络协议进行远程登录 那什么时ssh呢 SSH 为 Secure Shell的缩写 由 IETF 的网络小组 Network Working Group 所制
  • Windows-tomcat 部署Java项目

    windows 通过 tomcat 部署项目 部署环境准备 JDK下载安装及配置 进入 Oracle官网 的 Java 界面 Oracle官网地址 https www oracle com java 1 JDK下载 1 1 在网站页面滚动鼠
  • 入门神经网络——浅层神经网络

    文章目录 一 基础知识 1 浅层神经网络介绍 2 浅层神经网络的正向传播 3 反向传播 二 浅层神经网络代码实例 一 基础知识 1 浅层神经网络介绍 此次构件浅层神经网络 相比于单神经元 浅层神经网络拥有多个神经元 因此又可以称为多神经元网