标准RNN的推导

1.RNN前向计算:对于如下结构,x是输入,s为隐层,o为输出,U,W,V为不同层的权值,同一类型的权连接权值相同

则ot可表示为

其中,g,f为输出层,隐层的激活函数,f一般选择tanh函数,若RNN用于分类的话,g选择softmax函数

2.RNN反向传播:BPTT算法,本质还是BP算法,因为RNN处理序列数据,所以在原有基础上增加了序列维度反向传播。BPTT的中心思想与BP算法相同,沿着需要优化的参数的负梯度方向不断寻找更优的点直至收敛。其中RNN损失为各个时间点的损失之和,故各个梯度的变化为各个时间点梯度变化之和

 

 

从上图可以看出,反向传播每计算一个隐层,都会与一个激活函数的导数相乘,而激活函数的累乘会导致梯度消失或梯度爆炸的现象发生

3.常用的几个激活函数

(1)sigmoid函数

从图中可以看出,函数的导数取值范围为(0,0.025],反向传播时每多一个一层,梯度变化都会至少缩小四倍,传到神经网络前部很容易造成梯度消失。同时,sigmoid函数的输出不是中心对称,均大于0,称为偏移现象,这就导致后一层的神经元 将上一层输出的非0均值的信号也学习到作为此层的输入,易学习到噪声。

(2)tanh函数

从图中可以看出,tanh函数的输出关于零点中心对称,网络收敛性更好,同时,tanh函数的导数范围为(0,1],反向传播每经过一层,梯度变化较sigmoid函数慢,也就是梯度消失的速度更慢

(3)Relu函数

relu函数的导数左侧为0,右侧为1,在一定程度上避免了梯度消失的问题,但是与激活函数相乘的另一个因子在反向传播中呈现增长的趋势,则恒为1的导数容易引起梯度爆炸,而恒为0的导数有可能把神经元学死,设置合适的步长可有效避免这个问题的发生

解决梯度消失或梯度爆炸的方法主要有:

1. 选择更适合的激活函数

2.改变传播结构

### RNN 时间复杂度分析 循环神经网络(Recurrent Neural Network, RNN)是一种用于处理序列数据的神经网络模型。其时间复杂度取决于多个因素,包括输入序列长度 \( T \),隐藏层单元数 \( n_h \),以及每一步操作的具体实现。 #### 输入序列长度的影响 对于一个标准的单向 RNN,在每次前向传播过程中,当前时刻的状态依赖于上一时刻的状态。因此,整个序列的计算需要遍历每一个时间步。假设输入序列为长度 \( T \),则时间复杂度至少为 \( O(T) \)[^1]。 #### 隐藏状态更新的操作成本 在每个时间步中,RNN 的核心运算涉及矩阵乘法和激活函数的应用。具体来说: - 假设输入维度为 \( d_x \),隐藏层大小为 \( n_h \),权重矩阵分别为 \( W_{hx} \in \mathbb{R}^{n_h \times d_x} \) 和 \( W_{hh} \in \mathbb{R}^{n_h \times n_h} \)。 - 对于每一时间步 \( t \),隐藏状态的更新公式如下: \[ h_t = f(W_{hx}x_t + W_{hh}h_{t-1} + b) \] 其中 \( h_t \) 是第 \( t \) 步的隐藏状态,\( x_t \) 是该步的输入,\( f(\cdot) \) 表示激活函数(如 tanh 或 ReLU),\( b \) 是偏置项。 上述公式的计算主要包括两个矩阵乘法: 1. \( W_{hx}x_t \): 复杂度为 \( O(n_h \cdot d_x) \)[^3]。 2. \( W_{hh}h_{t-1} \): 复杂度为 \( O(n_h^2) \)。 综合来看,每个时间步的总复杂度为 \( O(n_h^2 + n_h \cdot d_x) \)。考虑到共有 \( T \) 个时间步,整体的时间复杂度可表示为: \[ O(T \cdot (n_h^2 + n_h \cdot d_x)) \] #### 双向 RNN 的扩展 双向 RNN (Bidirectional RNN, Bi-RNN)引入了反向传递机制,分别从前到后和从后到前计算两次隐藏状态。这种设计使得最终的时间复杂度加倍,即: \[ O(2T \cdot (n_h^2 + n_h \cdot d_x)) = O(T \cdot (2n_h^2 + 2n_h \cdot d_x)) \][^1]。 --- ### Python 实现中的递归方程求解 如果采用递归来模拟 RNN 的计算过程,则可以通过递归方程进一步推导时间复杂度。例如,定义递归关系式为: \[ C(t) = C(t-1) + c_0 \] 其中 \( C(t) \) 表示第 \( t \) 步所需的计算量,\( c_0 \) 是固定开销。展开此递归方程并累加得到总的计算量为 \( O(T \cdot c_0) \)[^2]。结合前述矩阵运算的成本,可以得出一致的结果。 --- ### 总结 综上所述,标准单向 RNN 的时间复杂度为 \( O(T \cdot (n_h^2 + n_h \cdot d_x)) \),而双向 RNN 则为 \( O(T \cdot (2n_h^2 + 2n_h \cdot d_x)) \)。这些结论表明,随着隐藏层数目增加或输入序列变长,计算负担显著提升,需谨慎选择架构以平衡性能与效率[^1]^。 ```python def rnn_time_complexity(T, n_h, d_x): """ 计算标准单向 RNN 的时间复杂度 :param T: 序列长度 :param n_h: 隐藏层大小 :param d_x: 输入特征维度 :return: 时间复杂度表达式 """ complexity = T * (n_h**2 + n_h * d_x) return complexity # 示例调用 print(rnn_time_complexity(100, 512, 64)) # 输出理论复杂度数值 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值