前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文速学-让神经网络不再神秘,一天速学神经网络基础-前向传播

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

原创
作者头像
fanstuck
发布2024-03-18 10:24:33
21500
代码可运行
发布2024-03-18 10:24:33
举报
运行总次数:0
代码可运行

前言

深度学习的内容不是那么好掌握的,包含大量的数学理论知识以及大量的计算公式原理需要推理。且如果不进行实际操作很难够理解我们写的代码究极在神经网络计算框架中代表什么作用。

不过我会尽可能将知识简化,转换为我们比较熟悉的内容,我将尽力让大家了解并熟悉神经网络框架,保证能够理解通畅以及推演顺利的条件之下,尽量不使用过多的数学公式和专业理论知识。以一篇文章快速了解并实现该算法,以效率最高的方式熟练这些知识。此专栏的目的就是为了让零基础快速使用各类数学模型、机器学习和深度学习以及代码,每一篇文章都包含实战项目以及可运行代码。博主紧跟各类数模比赛,每场数模竞赛博主都会将最新的思路和代码写进此专栏以及详细思路和完全代码。希望有需求的小伙伴不要错过笔者精心打造的专栏。

前向传播

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

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

从输入到隐藏层

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

  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$ 中,得到隐藏层神经元的输出,常见的激活函数包括 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还是有差距的,若是权重设定不合适会导致更差的结果,这个时候就需要使用到反向传播来使预测值更加接近真实值。当然如果是输入层较多,隐藏层比较复杂,我们一般是使用矩阵来进行,例如:

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

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

代码语言:python
代码运行次数:0
复制
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)  #最终输出结果

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

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

代码语言:python
代码运行次数:0
复制
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)

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 前向传播
    • 从输入到隐藏层
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
    http://www.vxiaotou.com