一文速学-让神经网络不再神秘,一天速学神经网络基础-前向传播(三)


前言

思索了很久到底要不要出深度学习内容,毕竟在数学建模专栏里边的机器学习内容还有一大半算法没有更新,很多坑都没有填满,而且现在深度学习的文章和学习课程都十分的多,我考虑了很久决定还是得出神经网络系列文章,不然如果以后数学建模竞赛或者是其他更优化模型如果用上了神经网络(比如利用LSTM进行时间序列模型预测),那么就更好向大家解释并且阐述原理了。但是深度学习的内容不是那么好掌握的,包含大量的数学理论知识以及大量的计算公式原理需要推理。且如果不进行实际操作很难够理解我们写的代码究极在神经网络计算框架中代表什么作用。不过我会尽可能将知识简化,转换为我们比较熟悉的内容,我将尽力让大家了解并熟悉神经网络框架,保证能够理解通畅以及推演顺利的条件之下,尽量不使用过多的数学公式和专业理论知识。以一篇文章快速了解并实现该算法,以效率最高的方式熟练这些知识。

现在很多竞赛虽然没有限定使用算法框架,但是更多获奖的队伍都使用到了深度学习算法,传统机器学习算法日渐式微。比如2022美国大学生数学建模C题,参数队伍使用到了深度学习网络的队伍,获奖比例都非常高,现在人工智能比赛和数据挖掘比赛都相继增多,对神经网络知识需求也日渐增多,因此十分有必要掌握各类神经网络算法。

博主专注建模四年,参与过大大小小数十来次数学建模,理解各类模型原理以及每种模型的建模流程和各类题目分析方法。此专栏的目的就是为了让零基础快速使用各类数学模型、机器学习和深度学习以及代码,每一篇文章都包含实战项目以及可运行代码。博主紧跟各类数模比赛,每场数模竞赛博主都会将最新的思路和代码写进此专栏以及详细思路和完全代码。希望有需求的小伙伴不要错过笔者精心打造的专栏。
 


前向传播

上两篇文章讲述了神经网络的基本架构和各类常用的激活函数,那么我们知道,在神经网络中每个神经元都与其前后层的每个神经元相互连接,那么神经网络要怎么通过输入的数据又是经过何种计算到输出层的呢?我们现在就来看看它的工作原理。

神经网络的传递过程可以描述为四个关键的步骤:

从输入到隐藏层

神经网络从输入层到隐藏层的计算方式涉及权重和偏置的线性组合,然后将结果传递给激活函数。

  1. 输入信号: 输入层接收外部输入的数据,这些数据可以是图像、文本、数字等。每个输入都对应着网络中的一个输入神经元。假设输入层有n^{(0)}个神经元,分别为a_1^{(0)}, a_2^{(0)}, ..., a_{n^{(0)}}^{(0)},它们分别表示第1个到第n^{(0)}个输入神经元的输出。
  2. 权重和偏置: 隐藏层包含多个神经元,每个神经元与输入层的每个神经元都有一个连接,连接上有一个权重w_{ji}^{(1)}。其中,$j$ 表示隐藏层中的神经元索引,i表示输入层中的神经元索引。每个隐藏层神经元还有一个偏置 b_j^{(1)}
  3. 线性组合: 对于隐藏层中的第j个神经元,其输入信号将与权重相乘并加上偏置,得到线性组合的值z_j^{(1)}

  4. 激活函数: 对于线性组合的值z_j^{(1)},将其输入激活函数 $f$ 中,得到隐藏层神经元的输出a_j^{(1)},常见的激活函数包括 sigmoid、ReLU、tanh 等,它们引入非线性性质,使得神经网络能够学习更复杂的函数。
  5. 逐层传递: 上述步骤在每个隐藏层中的每个神经元都会重复进行。每个隐藏层神经元的输出将成为下一层神经元的输入。

 这个计算过程将重复在每一层的每个神经元中,直到得到隐藏层的输出。这些隐藏层的输出将成为下一层的输入,以此类推,直到达到输出层。通过这种逐层计算的方式,神经网络可以从输入数据中提取并表示更高级别的特征。

 如果理解上述文字描述感觉抽象吃力的话,我们可以根据有一个小例子来具体理解神经网络的前向传递过程:

 如上图所示为一个神经网络基本结构,我们设定两个输入节点X_{1}=0.4,X_{2}=-0.6,Y为实际真值情况Y=0.1,那么我们设定权重:W_{1}=0.3,W_{2}=-0.6,W_{3}=0.9,W_{4}=-0.4,W_{5}=0.4,W_{6}=0.7

对输入层到隐藏层的节点进行加权求和,结果分别如下:

节点1的值为:X_{1}*W_{1}+X_{2}*W_{3}=0.4*0.3+-0.6*0.9=-0.42

节点2的值为:X_{1}*W_{2}+X_{2}*W_{4}=0.4*-0.6+-0.6*-0.4=0

 接着对隐藏层的节点的值执行Sigmoid激活,sigmoid函数在我上篇文章有详细讲述,直接进行计算即可:

\frac{1}{1+e^{-0.42}}=0.4,\frac{1}{1+e^{0}}=0.5

然后对隐藏层的输出到输出节点进行加权求和:

-0.42*0.4+0.5*0.7=0.18

最后我们发现0.18和真值0.1还是有差距的,若是权重设定不合适会导致更差的结果,这个时候就需要使用到反向传播来使预测值更加接近真实值。当然如果是输入层较多,隐藏层比较复杂,我们一般是使用矩阵来进行,例如:

我们可以使用矩阵运算来表达:

\begin{pmatrix} w11&w21 \\ w12&w22 \end{pmatrix}*\begin{pmatrix} x1\\x2 \end{pmatrix}=\begin{pmatrix} w11*x1+w21*x2\\ w12*x1+w22*x2 \end{pmatrix}

现在假设输入数据源是[0.9,0.1,0.8],我们再进行一次计算:

import numpy as np
def _sigmoid(in_data):
    return 1/(1+np.exp(-in_data))
#输入层
x = np.array([0.9,0.1,0.8])
#隐藏层:需要计算输入层到中间隐藏层每个节点的组合,中间隐藏层的每个节点都与输入层相连,所以w1是一个3*3的矩阵
#因此每个节点都会得到输入信号的部分信息
#第一个输入节点与中间隐藏层第一个节点之间的权重w11=0.9,输入的第二个节点与隐藏层之间的连接的权重为w22=0.8
w1 = np.array([[0.9,0.3,0.4],
              [0.2,0.8,0.2],
              [0.1,0.5,0.6]]
             )
#因为输出层包含了3个节点,所以w2也是一个3x3的矩阵
w2 = np.array([
    [0.3,0.7,0.5],
    [0.6,0.5,0.2],
    [0.8,0.1,0.9]
])

Xhidden = _sigmoid(w1.dot(x))
print(Xhidden)
Xoutput = w2.dot(Xhidden)
print(Xoutput)  #最终输出结果

 

 下面再来看一个更加复杂的例子:

 这个案例我们增加一层隐藏层再来看看如何运算:

def _sigmoid(in_data):
    return 1/(1+np.exp(-in_data))

def init_network():
    network={}
    network['w1']=np.array([[0.1,0.3,0.5],[0.2,0.4,0.6]])
    network['b1']=np.array([0.1,0.2,0.3])
    network['w2']=np.array([[0.1,0.4],[0.2,0.5],[0.3,0.6]])
    network['b2']=np.array([0.1,0.2])
    network['w3']=np.array([[0.1,0.3],[0.2,0.4]])
    network['b3']=np.array([0.1,0.2])
    
    return network
    
def forward(network,x):
    w1,w2,w3 = network['w1'],network['w2'],network['w3']
    b1,b2,b3 = network['b1'],network['b2'],network['b3']
    a1 = x.dot(w1) + b1
    z1 = _sigmoid(a1)
    a2 = z1.dot(w2) + b2
    z2 = _sigmoid(a2)
    a3 = z2.dot(w3)+b3
    y=a3
    return y

network = init_network()
x = np.array([1.0,0.5])
y = forward(network,x)
print(y)

 

那么前向传播到这里就全部讲完了,没有很复杂的内容,线性计算就可以,下一章我们将着重讲述一下输出层的计算和功能。


 

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

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

相关文章

——滑动窗口

滑动窗口 所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。也可以理解为一种双指针的做法。 leetcode76 class Solution {public String minWindow(String s, String t) {char[] schars s.toCharArray();char[] tc…

服务器部署前后端项目-SQL Father为例

hello~大家好哇,好久没更新博客了。现在来更新一波hhh 现在更新一下部署上的一些东西,因为其实有很多小伙伴跟我之前一样,很多时候只是开发了,本地前后端都能调通,也能用,但是没有部署到服务器试过&#x…

如果你觉得自己很失败,请观看此内容 视频学习

目录 什么是成功?​​​​​​​ How can we succeed in such an unfair world? 我们如何在这个不公平的地球上获得成功? 如何去找到自己的不公平优势呢? 最开始也有常有人跟她说你做视频是赚不到钱的 你做了,并不代表你做…

Spring版本与JDK版本演变

Java各版本变更核心API Java8 lambada表达式函数式接口方法引用默认方法Stream API 对元素流进行函数式操作Optional 解决NullPointerExceptionDate Time API重复注解 RepeatableBase64使用元空间Metaspace代替持久代(PermGen space) Java7 switch 支…

day3 c++d对话框及事件处理机制

1.文本编辑器 2.自由移动的球

手把手教你写出第一个C语言程序

Hello, World! 1. 前言2. 准备知识2.1 环境2.2 文件的分类2.3 注释2.3.1 注释的作用2.3.2 注释的两种风格2.3.2.1 C语言的注释风格2.3.2.2 C的注释风格 2.3.3 VS中注释和取消注释的快捷键 3. 开始演示3.1 创建项目3.2 创建源文件3.3 写代码3.4 编译链接运行 4. 代码解释4.1 写主…

QT DAY4

一、对话框 消息对话框、字体对话框、颜色对话框、文件对话框 1.1消息对话框 主要分为这四类对话及一种NoIcon无图标对话 而对话框也分为两种实现方式,一种为基于属性分开初始化的方式,这种方式更灵活,更多元,需要对exec的返回值…

SQLPro Studio for Mac:强大的SQL开发和管理工具

SQLPro Studio for Mac是一款强大的Mac上使用的SQL开发和管理工具,它支持各种数据库,包括MySQL,PostgreSQL,SQLite等。使用 SQLPro Studio,您可以轻松地连接和管理您的数据库,执行SQL查询和脚本&#xff0c…

c++11 标准模板(STL)(std::basic_ostringstream)(一)

定义于头文件 <sstream> template< class CharT, class Traits std::char_traits<CharT> > class basic_ostringstream;(C11 前)template< class CharT, class Traits std::char_traits<CharT>, class Allocator std::allo…

Windows安装Nginx及部署vue前端项目操作

先在nginx官网下载windows下安装的包&#xff0c;并解压&#xff0c;到ngnix目录下 双击nginx.exe,会有黑窗闪过。 用cmd命令窗口&#xff0c;cd 到nginx解压目录&#xff0c;./nginx启动。 在浏览器中访问http://localhost:80,出现以下界面说明启动成功(由于笔者电脑80端口被…

【核心复现】基于改进灰狼算法的并网交流微电网经济优化调度(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Nano编辑器安装使用指南

关于nano Nano编辑器是一个命令行文本编辑器&#xff0c;具有简单易用的界面和一些基本功能。 Nano小巧友好&#xff0c;提供许多额外的特性&#xff0c;例如交互式的查找和替换、定位到指定的行列、自动缩进、特性切换、国际化支持、文件名标记完成等。 Nano是为了代替闭源的…

【0901作业】QTday3 对话框、发布软件、事件处理机制,使用文件相关操作完成记事本的保存功能、处理键盘事件完成圆形的移动

目录 一、思维导图 二、作业 2.1 使用文件相关操作完成记事本的保存功能 2.2 处理键盘事件完成圆形的移动 一、思维导图 二、作业 2.1 使用文件相关操作完成记事本的保存功能 void Widget::on_saveBtn_clicked() {QString filename QFileDialog::getSaveFileName(this,&…

DVWA失效的访问控制

失效的访问控制&#xff0c;可以认为是系统对一些功能进行了访问或权限限制&#xff0c;但因为种种原因&#xff0c;限制并没有生效&#xff0c;造成失效的访问控制漏洞,比如越权等 这里以DVWA为例&#xff0c;先访问低难度的命令执行并抓包 删除cookie&#xff0c;并在请求头…

堆的基本存储(Java 实例代码)

堆的基本存储 一、概念及其介绍 堆(Heap)是计算机科学中一类特殊的数据结构的统称。 堆通常是一个可以被看做一棵完全二叉树的数组对象。 堆满足下列性质&#xff1a; 堆中某个节点的值总是不大于或不小于其父节点的值。堆总是一棵完全二叉树。 二、适用说明 堆是利用完…

【防火墙】防火墙NAT Server的配置

Web举例&#xff1a;公网用户通过NAT Server访问内部服务器 介绍公网用户通过NAT Server访问内部服务器的配置举例。 组网需求 某公司在网络边界处部署了FW作为安全网关。为了使私网Web服务器和FTP服务器能够对外提供服务&#xff0c;需要在FW上配置NAT Server功能。除了公网…

java八股文面试[多线程]——进程与线程的区别

定义 1、进程&#xff1a;进程是一个具有独立功能的程序关于某个数据集合的以此运行活动。 是系统进行资源分配和调度的独立单位&#xff0c;也是基本的执行单元。是一个动态的概念&#xff0c;是一个活动的实体。它不只是程序的代码&#xff0c;还包括当前的活动。 进程结构…

RunnerGo:提升性能测试效率的强大利器

在现代软件开发中&#xff0c;性能测试是确保应用程序在真实负载下正常运行的关键环节。为了满足不断增长的用户需求和保证应用程序的性能稳定性&#xff0c;这里给大家介绍RunnerGo&#xff0c;这是一款功能强大、易于使用的性能测试平台&#xff0c;能够极大地提升性能测试的…

NoSQL数据库介绍+Redis部署

目录 一、NoSQL概述 1、数据的高并发读写 2、海量数据的高效率存储和访问 3、数据库的高扩展和高可用 二、NoSQL的类别 1、键值存储数据库 2、列存储数据库 3、文档型数据库 4、图形化数据库 三、分布式数据库中的CAP原理 1、传统的ACID 1&#xff09;、A--原子性 …

9、Spring_事务管理

六、Spring 事务管理 1.Spring 事务简介 事务概述&#xff1a;保证数据库操作同时成功或者同时失败 Spring 事务的概述&#xff1a;在数据层保证数据库操作同时成功或者同时失败 2.转账案例分析 转账肯定有一个业务方法&#xff1a;给转出用户减钱&#xff0c;给转入用户加…