5-隐藏层:神经网络为什么working

声明

本文章基于哔哩哔哩付费课程《小白也能听懂的人工智能原理》。仅供学习记录、分享,严禁他用!!如有侵权,请联系删除

目录

一、知识引入

(一)隐藏层

(二)泛化

(三)深度神经网络

二、编程实验

(一)输入x与第一层

(二)上一层的输出结果与第二层

(三)计算前向传播

(四)计算反向传播

(五)完整代码


一、知识引入

        小蓝海底的豆豆发生了进化,毒性变得忽大忽小,与豆豆的大小不再有明显的关系,就需要一个有多样单调性的函数来预测,而不是只具有单一不变的单调性。

        将神经元组成一个网络:

        第一个神经元:先通过线性函数计算,再通过激活函数得到最终的输出,利用梯度下降算法,将输出调整为sigmoid式的样子;

        第二个神经元也同样,调整为sigmoid式的样子;

        将两个神经元的最终输出作为第三个神经元的输入,先通过第三个神经元的线性函数计算,再通过激活函数+梯度下降算法

        即,将输入分为两个部分,然后分别对两个部分进行调节,然后再送入最后一个神经元,让整体的神经网络形成一个单调性不唯一的更多变函数。从而具备了解决更加复杂问题的能力

        添加一个神经元后,相当于增加了一个抽象的维度把输入放进不同的维度中,每个维度通过不断地调整权重并进行激活,从而产生对输入的不同理解。最后再把这些抽象维度中的输出合并、降维,得到输出。这个输入数据由于在多个抽象维度中被产生不同的解读,从而让输出得到了更多可能。

        当环境中的豆豆毒性发生更多可能的时候,同样可以采取类似的方法:通过增加对输入更多的抽象维度,产生更多的解读,从而实现更加复杂的分类效果。

(一)隐藏层

        中间新增添加的神经元节点--“隐藏层”。

        正是因为隐藏层的存在,才让神经网络能够在复杂情况下仍旧working。

        显而易见,隐藏层的神经元数量越多,就可以产生越复杂的组合,解决越复杂的问题。当然计算量也随之越来越大。

(二)泛化

        我们采集的训练数据越充足,那么最后训练得到的模型也就能越好的去预测新的问题。因为越充足的训练数据,就在越大程度上蕴藏了问题的规律特征。新的问题数据也就越难以逃脱这些规律的约束。

        所以总说,机器学习神经网络的根基是:海量数据。

        一个训练后,拟合适当的模型,进而在遇到新的问题数据时,也能大概率产生正确预测。成为“模型的泛化”。泛化能力也是神经网络追求的核心问题。

(三)深度神经网络

        隐藏层超过3层的网络。

二、编程实验

(一)输入x与第一层

# 第一层
# 第一个神经元
w11_1 = np.random.rand() # _后表示第几层,11表示第1个输入和第1个神经元
b1_1 = np.random.rand() # _后表示第几层,1表示第一个神经元权重的偏置项

# 第二个神经元
w12_1 = np.random.rand() # _后表示第几层,12表示第1个输入和第2个神经元
b2_1 = np.random.rand() # _后表示第几层,2表示第二个神经元权重的偏置项

(二)上一层的输出结果与第二层

# 第二层
w11_2 = np.random.rand() # _后表示第几层,11表示第1个输入和第1个神经元
w21_2 = np.random.rand() # _后表示第几层,21表示第2个输入和第1个神经元
b1_2 = np.random.rand() # _后表示第几层,1表示第一个神经元权重的偏置项

(三)计算前向传播

# 计算前向传播
# 第一层
z1_1 = w11_1 * xs + b1_1
a1_1 = sigmoid(z1_1)
z2_1 = w21_1 * xs + b2_1
a2_1 = sigmoid(z2_1)

# 第二层
# 第一层的输出作为输入
z1_2 = w11_2 * a1_1 + w21_2 * a2_1 + b1_2
a1_2 = sigmoid(z1_2)

(四)计算反向传播

# 先来一次前向传播
z1_1, a1_1, z2_1, a2_1, z1_2, a1_2 = forward_propagation(x)
# 反向传播
# 代价函数e
e = (y - a1_2)**2

# 代价函数对最终输出求导
deda1_2 = -2 * (y - a1_2)
# 第二层神经元的激活函数求导
da1_2dz1_2 = a1_2 * (1 - a1_2)
# z1_2对两个输入神经元的权重求导,即线性函数的导数
dz1_2dw11_2 = a1_1
dz1_2dw21_2 = a2_1
# 链式法则,得到损失函数e对第二层神经元的两个输入的导数
dedw11_2 = deda1_2 * da1_2dz1_2 * dz1_2dw11_2
dedw21_2 = deda1_2 * da1_2dz1_2 * dz1_2dw21_2
# 第二层神经元的偏置项
dz1_2db1_2 = 1
dedb1_2 = deda1_2 * da1_2dz1_2 *dz1_2db1_2

# 对隐藏层的神经元进行操作
# 第一个神经元
# 对权重求导
dz1_2da1_1 = w11_2
# 激活函数求导
da1_1dz1_1 = a1_1 * (1 - a1_1)
# 对权重求导
dz1_1dw11_1 = x
# 链式法则
dedw11_1 = deda1_2 * da1_2dz1_2 * dz1_2da1_1 * da1_1dz1_1 * dz1_1dw11_1
# 对偏置项b求导
dz1_1db1_1 = 1
# 链式求导法则
dedb1_1 = deda1_2 * da1_2dz1_2 * dz1_2da1_1 * da1_1dz1_1 * dz1_1db1_1

# 对第二个神经元
# 对权重求导
dz1_2da2_1 = w21_2
# 激活函数求导
da2_1dz2_1 = a2_1 * (1 - a2_1)
# 对权重求导
dz2_1dw12_1 = x
dedw12_1 = deda1_2 * da1_2dz1_2 * dz1_2da1_1 * da2_1dz2_1 * dz2_1dw12_1
# 对偏置项b求导
dz2_1db2_1 = 1
# 链式求导法则
dedb2_1 = deda1_2 * da1_2dz1_2 * dz1_2da1_1 * da2_1dz2_1 * dz2_1db2_1

alpha = 0.03
# 更新参数
w11_1 = w11_1 - alpha * dedw11_1
w12_1 = w12_1 - alpha * dedw12_1
b1_1 = b1_1 - alpha * dedb1_1

w11_2 = w11_2 - alpha * dedw11_2
w21_2 = w21_2 - alpha * dedw21_2
b1_2 = b1_2 - alpha * dedb1_2

(五)完整代码

import dataset
import matplotlib
import numpy as np
from matplotlib import pyplot as plt
# 首先要知道 matplotlib 的 backend 使用的是默认配置 agg (agg不能显示绘制的图),要想显示绘制的图需要更改 agg 为 TkAgg
matplotlib.use('TkAgg')

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# 生成数据
xs, ys = dataset.get_beans(100)
num = 100

# 第一层
# 第一个神经元
w11_1 = np.random.rand() # _后表示第几层,11表示第1个输入和第1个神经元
b1_1 = np.random.rand() # _后表示第几层,1表示第一个神经元权重的偏置项
# 第二个神经元
w12_1 = np.random.rand() # _后表示第几层,12表示第1个输入和第2个神经元
b2_1 = np.random.rand() # _后表示第几层,2表示第二个神经元权重的偏置项

# 第二层
w11_2 = np.random.rand() # _后表示第几层,11表示第1个输入和第1个神经元
w21_2 = np.random.rand() # _后表示第几层,21表示第2个输入和第1个神经元
b1_2 = np.random.rand() # _后表示第几层,1表示第一个神经元权重的偏置项

# 计算前向传播
def forward_propagation(xs):
    # 第一层
    z1_1 = w11_1 * xs + b1_1
    a1_1 = sigmoid(z1_1)
    z2_1 = w12_1 * xs + b2_1
    a2_1 = sigmoid(z2_1)

    # 第二层
    # 第一层的输出作为输入
    z1_2 = w11_2 * a1_1 + w21_2 * a2_1 + b1_2
    a1_2 = sigmoid(z1_2)

    return z1_1, a1_1, z2_1, a2_1, z1_2, a1_2



# 在全部样本上做了5000次梯度下降
for _ in range(5000):
    for i in range(100):
        # 随机梯度下降算法,以单个为对象
        x = xs[i]
        y = ys[i]
        # 先来一次前向传播
        z1_1, a1_1, z2_1, a2_1, z1_2, a1_2 = forward_propagation(x)
        # 反向传播
        # 代价函数e
        e = (y - a1_2)**2

        # 代价函数对最终输出求导
        deda1_2 = -2 * (y - a1_2)
        # 第二层神经元的激活函数求导
        da1_2dz1_2 = a1_2 * (1 - a1_2)
        # z1_2对两个输入神经元的权重求导,即线性函数的导数
        dz1_2dw11_2 = a1_1
        dz1_2dw21_2 = a2_1
        # 链式法则,得到损失函数e对第二层神经元的两个输入的导数
        dedw11_2 = deda1_2 * da1_2dz1_2 * dz1_2dw11_2
        dedw21_2 = deda1_2 * da1_2dz1_2 * dz1_2dw21_2
        # 第二层神经元的偏置项
        dz1_2db1_2 = 1
        dedb1_2 = deda1_2 * da1_2dz1_2 *dz1_2db1_2

        # 对隐藏层的神经元进行操作
        # 第一个神经元
        # 对权重求导
        dz1_2da1_1 = w11_2
        # 激活函数求导
        da1_1dz1_1 = a1_1 * (1 - a1_1)
        # 对权重求导
        dz1_1dw11_1 = x
        # 链式法则
        dedw11_1 = deda1_2 * da1_2dz1_2 * dz1_2da1_1 * da1_1dz1_1 * dz1_1dw11_1
        # 对偏置项b求导
        dz1_1db1_1 = 1
        # 链式求导法则
        dedb1_1 = deda1_2 * da1_2dz1_2 * dz1_2da1_1 * da1_1dz1_1 * dz1_1db1_1

        # 对第二个神经元
        # 对权重求导
        dz1_2da2_1 = w21_2
        # 激活函数求导
        da2_1dz2_1 = a2_1 * (1 - a2_1)
        # 对权重求导
        dz2_1dw12_1 = x
        dedw12_1 = deda1_2 * da1_2dz1_2 * dz1_2da1_1 * da2_1dz2_1 * dz2_1dw12_1
        # 对偏置项b求导
        dz2_1db2_1 = 1
        # 链式求导法则
        dedb2_1 = deda1_2 * da1_2dz1_2 * dz1_2da1_1 * da2_1dz2_1 * dz2_1db2_1

        alpha = 0.03
        w11_1 = w11_1 - alpha * dedw11_1
        w12_1 = w12_1 - alpha * dedw12_1
        b1_1 = b1_1 - alpha * dedb1_1

        w11_2 = w11_2 - alpha * dedw11_2
        w21_2 = w21_2 - alpha * dedw21_2
        b1_2 = b1_2 - alpha * dedb1_2

    # 减少绘图的频率
    if _ % 50 == 0:
        # plt.clf()函数清除绘图窗口
        plt.clf()
        # 重新绘制散点图和预测曲线
        plt.scatter(xs, ys)
        z1_1, a1_1, z2_1, a2_1, z1_2, a1_2 = forward_propagation(xs)
        plt.plot(xs, a1_2)

        # 暂停0.01秒
        plt.pause(0.01)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/477615.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

UE4 Json事件设置Asset值(Asset如果都在同一目录下)

通过Json事件来设置,比如骨骼网格体(换皮)等等

202112青少年软件编程(Scratch图形化)等级考试试卷(三级)

第1题:【 单选题】 下列程序哪个可以实现: 按下空格键, 播放完音乐后说“你好! ” 2 秒? ( ) A: B: C: D: 【正确答案】: C 【试题解析】 : 第2题:【 单选题】 执行下列程序, 变量 N 的值不可能是? ( ) A:1 B:4 C:5 D:6 【正确答案】: D 【试题解析】…

Git进阶用法:Git分支轻松使用,配有图文

一、文章内容 git和分支相关的概念.git和分支有关的命令.git项目实战环节. 二、相关概念 分支:分支的概念好比树干的分支,每一跟分支都是从主干分出来的,营养是主干给的,所以在git里主干和分支也是如此,在git里主分…

day02_mysql-DDLDMLDQL_课后练习 - 参考答案

文章目录 day02_mysql_课后练习第1题第2题 day02_mysql_课后练习 第1题 案例: 1、创建数据库test02_library 2、创建表格books 字段名字段说明数据类型b_id书编号int(11)b_name书名varchar(50)authors作者varchar(100)price价格floatpub…

opengl 学习(六)-----坐标系统与摄像机

坐标系统与摄像机 分类引言坐标系统摄像机教程在CMake中使用全局定义预编译宏,来控制是否开启错误检查补充 分类 opengl c 引言 OpenGL希望在每次顶点着色器运行后,我们可见的所有顶点都为标准化设备坐标(Normalized Device Coordinate, NDC)。也就是说&#xff…

pcl采样:随机采样

pcl 随机采样,实际上就是抽稀 头文件 代码 结果

ubuntu系统下如何使用vscode编译和调试#小白入门#

编程环境:ubuntu系统为18.04.1,vscode版本为1.66.2 一、VSCode切换中文显示: 1、vscode安装完成后启动,在左侧externsions中搜索“简体中文”插件,并完成安装: 2、选择右下角齿轮形状的"Manage"&#xff…

【C++】弥补C语言的不足(①命名冲突问题)

Hello,这里是关于C的入门,C的命名冲突问题,如果你像我一样对命名空间满是疑惑,只知道using namespace std,那么可以看下这篇文章,我自己之前的一些疑惑以及一些形象的理解。 命名冲突问题与命名空间 🌻命名…

【图解物联网】第1章 物联网的基础知识

1.1 物联网入门 1.1.1 物联网 物联网的英语是Internet of Things,缩写为IoT,这里的“物”指的是我们身边一切能与网络相连的物品。只要能与网络相连,就都是物联网说的“物”。 物联网就是“物”之间通过连接互联网来共享信息并产生…

CSS 让元素根据内容自适应宽度

一、需求 点击链接跳转,只点击标红区域才跳转,右侧空白区域不要跳转 二、实现 宽度太宽,导致右侧空白区域也加了跳转效果,修改为 将元素的最大宽度设置为其内容所需的宽度。 方法一:建议方式 使用 display: inline…

MyBatis框架简述

作用 降低开发人员使用JDBC的难度降低开发人员进行Dao层的开发难度 MyBatis本质上就是对JDBC的封装,通过MyBatis完成CRUD。MyBatis在三层架构中负责持久层的,属于持久层框架。MyBatis的发展历程:【引用百度百科】 MyBatis本是apache的一个开…

数据结构—稀疏多项式相加

利用链表实现两个稀疏多项式相加。 代码 #include <iostream> using namespace std;// 定义多项式项结构体 typedef struct {int x; // 系数int y; // 指数 } Elemtype;// 定义链表节点结构体 typedef struct Node {Elemtype data;struct Node* next; } *LinkList, N…

C语言 自定义类型:联合和枚举

目录 前言 一、联合体 1.1 联合体的特点 1.2 联合体与结构体的区别 1.3 联合体的大小计算 1.4 联合体例子 1.5 联合体判断大小端 二、枚举 2.1 枚举类型定义 2.2 枚举类型的优点 2.3 枚举类型的使用 总结 前言 之前我们讲了C语言其中一个自定义类型结构体&#xff…

C++面试宝典第36题:骑士游历

题目 在国际象棋的棋盘上,使一个骑士遍历所有的格子一遍且仅一遍。对于任意给定的顶点,输出一条符合上述要求的路径。骑士的走法和中国象棋的马的走法一样,走日。 解析 本题是一个经典的回溯搜索问题,具体来说是求解国际象棋棋盘上骑士的遍历问题,也称为骑士巡游问题(Kni…

【链表】Leetcode 25. K 个一组翻转链表【困难】

K 个一组翻转链表 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。你不能只是单纯的改…

SAP前台处理:物料主数据创建<MM01>之会计视图

一、背景&#xff1a; 终于来到了物料主数据&#xff0c;我觉得物料账是SAP最重要的一项发明&#xff0c;也一直是SAP的一项重要优势&#xff0c;物料账记录了一个个物料的生生不息&#xff1b; 本章主要讲解物料主数据和财务相关的主要内容&#xff1a;这里特别提示由于作者…

脚本实现Ubuntu设置屏幕无人操作,自动黑屏

使用 xrandr 命令可以实现对屏幕的控制&#xff0c;包括调整分辨率、旋转屏幕以及关闭屏幕等。要实现 Ubuntu 设置屏幕在无人操作一段时间后自动黑屏&#xff0c;可以借助 xrandr 命令来关闭显示器。 首先&#xff0c;你需要找到系统中显示器的名称&#xff0c;可以通过运行 x…

联通短信平台有什么特点?

【直连优势&#xff0c;安全可靠】 中国联通A2P短信服务直连其内地短信通道&#xff0c;这意味着企业用户能够享受到更为直接的运营商连接服务&#xff0c;确保每一条短信都具有卓越的性能表现和无可挑剔的稳定性。这种点对点的通信模式极大地降低了信息延迟和丢失的风险&#…

[云] vmware: host: net: Net.CoaleseDefaultOn

https://communities.vmware.com/t5/Storage-Performance/Advanced-Networking-Performance-Options/ta-p/2792649 在vsphere client下的路径是&#xff1a; 选择使用的host -> 右键setting->configure-> system->advanced system setting->edit->Net.Coales…

哪些事是你当了领导才明白的?

哪些事是你当了领导才明白的&#xff1f; 毕业5年&#xff0c;17年开始带团队&#xff0c;确实很多事不做到管理这一层&#xff0c;就真的意识不到。 带着【执行者】和【管理者】这2个视角&#xff0c;再结合我毕业至今这5年的所有职场经历&#xff0c;聊聊“职场潜规则”。 …