神经网络推导

本文详细介绍了一个单变量版本的BP神经网络算法,包括网络结构定义、前向传播过程及反向传播原理。通过数学公式推导,展示了如何通过梯度下降法调整权重与偏置,实现网络训练。

BP神经网络算法(单变量版本)

网络结构定义

输入变量XmXm,其中m=1,2,3,...,Ninputm=1,2,3,...,Ninput
要预测的变量tmtm,其中m=1,2,3,...,Ninputm=1,2,3,...,Ninput
设置三层网络结构,前两层为隐藏层,最后一层为输出层
第一层共有I个神经元,第二层共有J个神经元,第三层共有K个神经元。

前向传播

第一层

WimWim,表示 第一层神经网络第ii个神经元和第m个输入变量之前的权重。
bibi,表示 第一层神经网络第ii个神经元的偏置。
neti(1)=m=1NinputWimXm+bi,其中net(1)ineti(1)表示第一层神经网络中第ii个神经元的输出。
第一层的激活函数设为f(1),则经过激活函数激活后第ii个神经元的输出为

yi(1)=f(1)(neti(1))

第二层

WjiWji,表示 第二层神经网络第jj个神经元和第i个第一层神经网络的神经元输出之间的权重。
bjbj,表示 第二层神经网络第jj个神经元的偏置。
netj(2)=i=1IWjiyi(1)+bj,其中net(2)jnetj(2)表示第二层神经网络中第jj个神经元的输出。
第二层的激活函数设为f(2),则经过激活函数激活后第jj个神经元的输出为

yj(2)=f(2)(netj(2))

第三层(输出层)

WkjWkj,表示 第三层神经网络第kk个神经元和第j个第二层神经网络的神经元输出之间的权重。
bkbk,表示 第三层神经网络第kk个神经元的偏置。
netk(3)=j=1JWkjyj(2)+bk,其中net(3)knetk(3)表示第三层神经网络中第kk个神经元的输出。
第三层的激活函数设为f(3),则经过激活函数激活后第kk个神经元的输出为

yk(3)=f(3)(netk(3))

经过前向传播已经可以用来输出结果了。
但是怎么来训练这个神经网络呢?这里就要用到神经网络的反向传播!!

反向传播(Back-Propagation)-求导

要使用反向传播首先需要定义损失函数(loss function)。现在针对不同的领域损失函数的定义有非常多,这里用到最简单的均方差(Mean squared error-MSE)来训练分类任务的神经网络
均方差的定义

1ll=1nt(y(3)ktk)21l∑l=1nt(yk(3)−tk)2

nt表示分类任务最后类别的数目。如果是抛硬币那么nt=2(正面和反面)。
PS:如果是分类问题,需要将这里的t_m进行one-hot编码。并且输出层神经元的个数与nt的大小相同。

输出层推导

根据链式法则(chain-rule),求权重的导数

lossWkj=lossnet(3)knet(3)kWkj=lossnet(3)ky(2)j∂loss∂Wkj=∂loss∂netk(3)⋅∂netk(3)∂Wkj=∂loss∂netk(3)⋅yj(2)

lossnet(3)k=net(3)k(1llnt(y(3)ktk)2)=1lnet(3)k(lnt(f(3)(net(3)k)tk)2)∂loss∂netk(3)=∂∂netk(3)(1l∑lnt(yk(3)−tk)2)=1l∂∂netk(3)(∑lnt(f(3)(netk(3))−tk)2)

=1lnet(3)k((f(3)(net(3)k)tk)2)=2l(f(3)(net(3)k)tk)(f(3)(net(3)k)1)=1l∂∂netk(3)((f(3)(netk(3))−tk)2)=2l(f(3)(netk(3))−tk)⋅(f(3)′(netk(3))⋅1)

其中设lossnet(3)k=δ(3)=2l(f(3)(net(3)k)tk)(f(3)(net(3)k)1)∂loss∂netk(3)=δ(3)=2l(f(3)(netk(3))−tk)⋅(f(3)′(netk(3))⋅1)

lossWkj=δ(3)y(2)j→∂loss∂Wkj=δ(3)⋅yj(2)

同理可得

lossbk=lossnet(3)knet(3)kbk=lossnet(3)k=δ(3)∂loss∂bk=∂loss∂netk(3)⋅∂netk(3)∂bk=∂loss∂netk(3)=δ(3)

这里就求得了最后一层相关权重和偏置的导数了。

第二层隐藏层推导

与输出层的求导非常相似,也是使用链式法则(chain-rule),求第二层隐藏层权重的导数

lossWji=lossnet(2)jnet(2)jWji=lossnet(2)jy(1)i∂loss∂Wji=∂loss∂netj(2)⋅∂netj(2)∂Wji=∂loss∂netj(2)⋅yi(1)

lossnet(2)j=net(2)j(1llnt(y(3)ktk)2)=1lnet(2)j(lnt(f(3)(net(3)k)tk)2)∂loss∂netj(2)=∂∂netj(2)(1l∑lnt(yk(3)−tk)2)=1l∂∂netj(2)(∑lnt(f(3)(netk(3))−tk)2)

=1lnet(2)j((f(3)(net(3)k)tk)2)=1lnet(2)j(f(3)(j=1JWkjy(2)j+bk)tk)2=1l∂∂netj(2)((f(3)(netk(3))−tk)2)=1l∂∂netj(2)(f(3)(∑j=1JWkjyj(2)+bk)−tk)2

=1lnet(2)j(f(3)(j=1JWkjf(2)(net(2)j)+bk)tk)2=1l∂∂netj(2)(f(3)(∑j=1JWkjf(2)(netj(2))+bk)−tk)2

=2lf(3)(j=1JWkjf(2)(net(2)j)+bk)tk)f(3)(j=1JWkjf(2)(net(2)j)+bk)j=1JWkjf(2)(net(2)j)1=2l⋅f(3)(∑j=1JWkjf(2)(netj(2))+bk)−tk)⋅f(3)′(∑j=1JWkjf(2)(netj(2))+bk)⋅∑j=1JWkjf(2)′(netj(2))⋅1

=δ(3)kj=1JWkjf(2)(net(2)j)=j=1J(Wkjδ(3)k)f(2)(net(2)j)=δk(3)⋅∑j=1JWkjf(2)′(netj(2))=∑j=1J(Wkj⋅δk(3))⋅f(2)′(netj(2))

!!!注意δ(3)kJj=1Wkjf(2)(net(2)j)δk(3)⋅∑j=1JWkjf(2)′(netj(2))这个式子 (************还需要配图说明)
其中设lossnet(2)j=δ(2)=Jj=1(Wkjδ(3)k)f(2)(net(2)j)∂loss∂netj(2)=δ(2)=∑j=1J(Wkj⋅δk(3))⋅f(2)′(netj(2))

lossWji=δ(2)y(1)i→∂loss∂Wji=δ(2)⋅yi(1)

同理可得

lossbj=lossnet(2)jnet(2)jbj=lossnet(2)j=δ(2)∂loss∂bj=∂loss∂netj(2)⋅∂netj(2)∂bj=∂loss∂netj(2)=δ(2)
第一层隐藏层推导

与第二层隐藏层推导一样,也是使用链式法则(chain-rule),求第一层隐藏层权重的导数

lossWim=lossnet(1)inet(1)iWim=lossnet(1)iXm∂loss∂Wim=∂loss∂neti(1)⋅∂neti(1)∂Wim=∂loss∂neti(1)⋅Xm

其中设lossnet(1)i=δ(1)=Ii=1(Wjiδ(2)j)f(1)(net(1)i)∂loss∂neti(1)=δ(1)=∑i=1I(Wji⋅δj(2))⋅f(1)′(neti(1))

lossWim=δ(1)Xm→∂loss∂Wim=δ(1)⋅Xm

同理可得

lossbi=lossnet(1)inet(1)ibi=lossnet(1)i=δ(1)∂loss∂bi=∂loss∂neti(1)⋅∂neti(1)∂bi=∂loss∂neti(1)=δ(1)

神经网络中所有需要求解的导数都已经完成。接下来只要进行反向传播更新便可以训练该神经网络了。

### RNN神经网络的数学推导过程 #### 背景与核心概念 循环神经网络(Recurrent Neural Network, RNN)是一种用于处理序列数据的强大工具。其基本思想是利用隐藏状态 \( h_t \) 来捕捉输入序列的历史信息,并将其传递到下一个时间步。这种机制使得RNN能够建模具有时间依赖性的复杂模式。 #### 数学表示 假设我们有一个长度为 \( T \) 的输入序列 \( x_1, x_2, ..., x_T \),其中每个 \( x_t \in \mathbb{R}^d \) 表示在时间步 \( t \) 处的一个向量输入。RNN的状态更新方程如下: \[ h_t = f(W_{hh} h_{t-1} + W_{xh} x_t + b_h) \] 这里, - \( h_t \in \mathbb{R}^m \) 是时间步 \( t \) 的隐藏状态; - \( W_{hh} \in \mathbb{R}^{m \times m} \) 和 \( W_{xh} \in \mathbb{R}^{m \times d} \) 分别是从上一时刻隐藏状态和当前时刻输入到隐藏状态的权重矩阵; - \( b_h \in \mathbb{R}^m \) 是偏置项; - \( f(\cdot) \) 是激活函数,通常采用 tanh 或 ReLU 函数[^1]。 对于输出部分,如果我们在每个时间步都希望得到一个预测,则可以通过以下公式计算输出: \[ y_t = g(W_{hy} h_t + b_y) \] 这里, - \( y_t \in \mathbb{R}^k \) 是时间步 \( t \) 的输出; - \( W_{hy} \in \mathbb{R}^{k \times m} \) 是从隐藏状态到输出的权重矩阵; - \( b_y \in \mathbb{R}^k \) 是偏置项; - \( g(\cdot) \) 是输出层的激活函数,通常是 softmax 函数以适应分类任务的需求[^4]。 #### 训练方法:沿时间反向传播 (BPTT) 为了训练RNN模型,我们需要最小化损失函数 \( L(y, \hat{y}) \),该函数衡量了真实标签 \( y \) 与模型预测值 \( \hat{y} \) 之间的差异。常用的损失函数包括交叉熵损失或均方误差损失。 通过链式法则,我们可以求得关于各参数的梯度。具体来说,在某个时间步 \( t \),隐藏状态相对于前一时刻隐藏状态的变化由下式给出: \[ \frac{\partial h_t}{\partial h_{t-1}} = \text{diag}(f'(z_t)) W_{hh} \] 其中 \( z_t = W_{hh} h_{t-1} + W_{xh} x_t + b_h \) 是线性变换的结果,\( f'(\cdot) \) 是激活函数的导数[^3]。 进一步地,整个序列上的梯度可通过累积各个时间步的影响来获得。例如,针对权重矩阵 \( W_{hh} \) 的梯度可写成: \[ \frac{\partial L}{\partial W_{hh}} = \sum_{t=1}^T \left( \frac{\partial L}{\partial h_t} \right)^T \frac{\partial h_t}{\partial W_{hh}} \] 这里的每一项都可以通过递归方式逐步计算出来。最终,这些梯度被用来更新模型参数,从而完成一次完整的训练迭代[^5]。 ```python import numpy as np def rnn_step_forward(x, prev_h, W_xh, W_hh, b_h): """ 单步RNN正向传播。 参数: x: 当前时间步的输入 (batch_size, input_dim) prev_h: 上一时间步的隐藏状态 (batch_size, hidden_dim) W_xh: 输入到隐藏状态的权重矩阵 (input_dim, hidden_dim) W_hh: 隐藏状态间的权重矩阵 (hidden_dim, hidden_dim) b_h: 偏置项 (hidden_dim,) 返回: next_h: 下一时间步的隐藏状态 (batch_size, hidden_dim) """ z = np.dot(prev_h, W_hh) + np.dot(x, W_xh) + b_h next_h = np.tanh(z) cache = (x, prev_h, W_xh, W_hh, b_h, z) return next_h, cache ``` 上述代码展示了单步RNN正向传播的具体实现,它基于前面提到的数学表达式进行了编码[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值