循环神经网络(RNN)相关知识
文章目录
- RNN概述
- 前向传播公式
- 通过时间反向传播(BPTT)
- RNN确定序列长度方式
- 其他RNN结构
- 基于RNN的应用
- 1,序列数据的分析
- 2,序列数据的转换
- 3,序列数据的生成
- RNN的不足
- 1,从隐藏变量h角度来看
- 2,从梯度传播角度来看
RNN概述
循环神经网络(RNN)是用于处理序列数据的神经网络,该序列在时刻 t(从1 到 τ)包含向量 x(t)x^{(t) }x(t)。典型的网络结构如下图所示:
RNN每个时间步都需要将 x 值的输入序列映射到输出值 o 的对应序列。其中 o 是未归一化的对数概率,并且在损失函数 L 内部计算 y^=softmax(x)\hat y = softmax(x)y^=softmax(x)。损失函数 L 用于衡量每个 o 与相应的训练目标 y 的距离。
RNN输入到隐含单元的连接由权重矩阵 U 参数化,隐含单元与隐含单元连接由权重矩阵 W 参数化,隐含单元到输出节点的连接由权重矩阵 V 参数化。从上面的图中也可以看出,与CNN类似,在RNN中同样有参数共享的思想(共享了参数W,U,VW,U,VW,U,V等)。这使得模型的泛化能力更强,因为模型不会依赖于特定位置上的输入xxx。例如考虑这两句话:“I went to Nepal in 2009’’ 和 “In 2009, I went to Nepal.” ,他们表达的意思完全相同,但是时间2009出现在不同的地方,RNN的参数共享机制可以更有效的提取到这个时间信息。参数共享也允许模型泛化到没有见过的序列长度,并且训练模型所需的训练样本远远少于不带参数共享的模型。
当训练循环网络根据过去的信息去预测未来的信息时,网络通常要使用隐含状态 h (t) 来表示时刻 t 之前的序列信息:
h(t)=g(t)(x(t),x(t−1),x(t−2),…,x(2),x(1))=f(h(t−1),x(t);θ).\begin{aligned} h^{(t)} &=g^{(t)}(x^{(t)},x^{(t-1)},x^{(t-2)},\dots,x^{(2)}, x^{(1)}) \\ & = f(h^{(t-1)}, x^{(t)} ; \theta) . \end{aligned} h(t)=g(t)(x(t),x(t−1),x(t−2),…,x(2),x(1))=f(h(t−1),x(t);θ).
函数g(t)g^{(t)}g(t)将过去的序列(x(t),x(t−1),x(t−2),…,x(2),x(1))(x^{(t)},x^{(t-1)}, x^{(t-2)},\dots,x^{(2)}, x^{(1)})(x(t),x(t−1),x(t−2),…,x(2),x(1))作为输入来生成当前的隐含状态h(t)h(t)h(t)。实际上,我们可以递归调用函数fff来完成隐含状态的计算。这么做主要有两个优点:
- 无论序列的长度如何,模型始终具有相同的输入数据。因为它只关注给定输x(t)x^{(t)}x(t)后,从一种状态h(t−1)h(t-1)h(t−1)到另一种状态h(t)h(t)h(t)的转移, 而不是在可变长度的历史输入数据x(t−1),x(t−2),…,x(2),x(1)x^{(t-1)},x^{(t-2)},\dots,x^{(2)}, x^{(1)}x(t−1),x(t−2),…,x(2),x(1)上的操作。
- 我们可以在每个时间步(ttt时刻)使用相同参数的状态转移函数fff。
在不同的NLP场景中,h(t) 需要保存的信息也不同。例如在词性标注任务中,h(t) 更多的是要保存前一个单词的信息;而在机器翻译任务中,则需要保存输入序列的所有信息。
前向传播公式
上面的图中没有指明激活函数,假设使用tanhtanhtanh作为激活函数,并且假设输出值是离散的,例如用于预测类别。一种表示离散变量的方式是:把输出 o 作为离散变量每种可能值的非标准化对数概率。然后,我们可以应用 softmax 函数获得标准化后概率的输出向量y^\hat yy^。
RNN从特定的初始状态 h (0) 开始前向传播。从 t = 1 到 t = τ 的每个时间步,我们应用以下更新方程:
a(t)=b+Wh(t−1)+Ux(t)h(t)=tanh(a(t))o(t)=c+Vh(t)\begin{aligned} &\mathbf a^{(t)} = \mathbf b + \mathbf W \mathbf h^{(t-1)} + \mathbf U \mathbf x^{(t)} \\ &\mathbf h^{(t)} = \tanh(\mathbf a^{(t)}) \\ &\mathbf o^{(t)} = \mathbf c + \mathbf V \mathbf h^{(t)} \\ \end{aligned} a(t)=b+Wh(t−1)+Ux(t)h(t)=tanh(a(t))o(t)=c+Vh(t)
y^(t)=softmax(o(t))=eo(t)∑t=1τeo(t)\hat {\mathbf y} ^{(t)} = softmax(\mathbf o^{(t)}) = \frac{e^{o^{(t)}}}{\sum_{t=1}^\tau e^{o^{(t)}}} \\ y^(t)=softmax(o(t))=∑t=1τeo(t)eo(t)
其中的参数的偏置向量 b 和 c 连同权重矩阵 U、V 和 W,分别对应于输入到隐藏单元、
隐藏单元到输出和隐藏单元到隐藏单元的连接。这个循环网络将一个输入序列映射到相同长度的输出序列。与 x 序列配对的 y 的总损失就是所有时间步的损失之和,例如定义损失L为所有时间步的负对数似然函数:
L({x(1),…,x(τ)},{y(1),…,y(τ)})=∑tL(t)=−∑tlogPmodel(y(t)∣{x(1),…,x(τ)})\begin{aligned} &L(\{x^{(1)},\ldots,x^{(\tau)}\},\{y^{(1)},\ldots,y^{(\tau)}\}) \\ &= \sum_{t} L^{(t)} \\ &= -\sum_{t} \log P_{model}(y^{(t)}|\{x^{(1)},\ldots,x^{(\tau)}\}) \end{aligned} L({x(1),…,x(τ)},{y(1),…,y(τ)})=t∑L(t)=−t∑logPmodel(y(t)∣{x(1),…,x(τ)})
了解正向传播的计算内容之后,就可以讨论通过时间反向传播算法来更新网络参数了。
通过时间反向传播(BPTT)
回顾之前的计算图:
对于每一个节点 N,我们需要先 N 后面的节点的梯度,然后递归地计算梯度 ∇NL∇ _N L∇NL。我们从最后一个节点开始递归:
∂L∂L(t)=1\frac{\partial L}{\partial L^{(t)}} = 1 ∂L(t)∂L=1
观察正向传播的计算公式,不难发现 L(t)L^{(t)}L(t)是关于y^(t)\hat {\mathbf y} ^{(t)}y^(t)的函数,y^(t)\hat {\mathbf y} ^{(t)}y^(t)是softmaxsoftmaxsoftmax的结果, 而softmaxsoftmaxsoftmax是关于 o(t)o^{(t)}o(t)的函数。求LLL对非标准化对数概率 o(t)o^{(t)}o(t)求偏导(相关求导过程可以参考Softmax求导),得到:
(∇o(t)L)i=∂L∂oi(t)=∂L∂L(t)∂L(t)∂y^i(t)∂y^i(t)∂oi(t)={y^i(t)−1,yi(t)=labely^i(t)−0,yi(t)≠label\begin{aligned} (\nabla_{\mathbf o^{(t)}} L)_i &= \frac{\partial L}{\partial o_{i}^{(t)}}\\ &= \frac{\partial L}{\partial L^{(t)}} \frac{\partial L^{(t)}}{\partial \hat {\mathbf y} ^{(t)}_i} \frac{\partial \hat {\mathbf y} ^{(t)}_i}{\partial o_{i}^{(t)}} \\ &= \begin{cases} \hat {y}_i ^{(t)} - 1 , \qquad {y}_i ^{(t)} =label\\ \hat {y}_i ^{(t)} - 0, \qquad {y}_i ^{(t)} \ne label \end{cases} \end{aligned} (∇o(t)L)i=∂oi(t)∂L=∂L(t)∂L∂y^i(t)∂L(t)∂oi(t)∂y^i(t)={y^i(t)−1,yi(t)=labely^i(t)−0,yi(t)=label
从序列的末尾开始,反向进行计算。在最后的时间步 τ,只有 o (τ) 依赖于h (τ) ,不存在h (τ+1)依赖于h (τ) ,因此这个梯度很简单。由o(t)=c+Vh(t)\mathbf o^{(t)} = \mathbf c + \mathbf V \mathbf h^{(t)}o(t)=c+Vh(t),可以知道:
∇h(τ)L=∂o(τ)∂h(τ)∇o(τ)L=VT∇o(τ)L\nabla_{\mathbf h^{(\tau)}}L = \frac{\partial o^{(\tau)}}{\partial h^{(\tau)}}\nabla_{\mathbf o^{(\tau)}} L = \mathbf V^T \nabla_{\mathbf o^{(\tau)}} L ∇h(τ)L=∂h(τ)∂o(τ)∇o(τ)L=VT∇o(τ)L
然后我们可以从时刻 t = τ − 1 到 t = 1 反向迭代,通过时间反向传播梯度。由下面的式子:
a(t)=b+Wh(t−1)+Ux(t)h(t)=tanh(a(t))o(t)=c+Vh(t)\mathbf a^{(t)} = \mathbf b + \mathbf W \mathbf h^{(t-1)} + \mathbf U \mathbf x^{(t)} \\ \mathbf h^{(t)} = \tanh(\mathbf a^{(t)}) \\ \mathbf o^{(t)} = \mathbf c + \mathbf V \mathbf h^{(t)} a(t)=b+Wh(t−1)+Ux(t)h(t)=tanh(a(t))o(t)=c+Vh(t)
不难发现当t < τ时, o (t) 和 h (t+1) 都依赖于h (t) 。因此,它的梯度由两个部分组成:
∇h(t)L=(∂h(t+1)∂h(t))⊤(∇h(t+1)L)+(∂o(t)∂h(t))⊤(∇o(t)L)=W⊤(∇h(t+1)L)diag(1−(h(t+1))2)+V⊤(∇o(t)L)\begin{array}{l} \nabla_{h^{(t)}} L=\left(\frac{\partial \boldsymbol{h}^{(t+1)}}{\partial \boldsymbol{h}^{(t)}}\right)^{\top}\left(\nabla_{\boldsymbol{h}^{(t+1)}} L\right)+\left(\frac{\partial \boldsymbol{o}^{(t)}}{\partial \boldsymbol{h}^{(t)}}\right)^{\top}\left(\nabla_{\boldsymbol{o}^{(t)}} L\right) \\ =\boldsymbol{W}^{\top}\left(\nabla_{\boldsymbol{h}^{(t+1)}} L\right) \operatorname{diag}\left(1-\left(\boldsymbol{h}^{(t+1)}\right)^{2}\right)+\boldsymbol{V}^{\top}\left(\nabla_{\boldsymbol{o}^{(t)}} L\right) \end{array} ∇h(t)L=(∂h(t)∂h(t+1))⊤(∇h(t+1)L)+(∂h(t)∂o(t))⊤(∇o(t)L)=W⊤(∇h(t+1)L)diag(1−(h(t+1))2)+V⊤(∇o(t)L)
其中:
tanh′(x)=1−(tanh(x))2\tanh'(x) = 1- (tanh(x))^2 tanh′(x)=1−(tanh(x))2
∂h(t+1)∂h(t)=∂tanh(b+Wh(t)+Ux(t+1))∂h(t)=WTdiag(1−(h(t+1))2)\begin{aligned} \frac{\partial \boldsymbol{h}^{(t+1)}}{\partial\boldsymbol{h}^{(t)}} &= \frac{\partial \tanh(\mathbf b + \mathbf W \boldsymbol h^{(t)} + \mathbf U \mathbf x^{(t+1)} )}{\partial\boldsymbol{h}^{(t)}} \\ &= \mathbf W^T diag(1-(\boldsymbol h^{(t+1)})^2) \end{aligned} ∂h(t)∂h(t+1)=∂h(t)∂tanh(b+Wh(t)+Ux(t+1))=WTdiag(1−(h(t+1))2)
基于前面的步骤,接下来进行参数的跟新:
∇cL=∑t(∂o(t)∂c)⊤∇o(t)L=∑t∇o(t)L∇bL=∑t(∂h(t)∂b(t))⊤∇h(t)L=∑tdiag(1−(h(t))2)∇h(t)L∇VL=∑t∑i(∂L∂oi(t))∇Voi(t)=∑t(∇o(t)L)h(t)⊤∇W=∑t∑i(∂L∂hi(t))∇W(t)hi(t)=∑tdiag(1−(h(t))2)(∇h(t)L)h(t−1)⊤∇UL=∑t∑i(∂L∂hi(t))∇U(t)hi(t)=∑tdiag(1−(h(t))2)(∇h(t)L)x(t)⊤\begin{aligned} \nabla_{c} L &=\sum_{t}\left(\frac{\partial \boldsymbol{o}^{(t)}}{\partial \boldsymbol{c}}\right)^{\top} \nabla_{\boldsymbol{o}^{(t)}} L=\sum_{t} \nabla_{\boldsymbol{o}^{(t)}} L \\ \nabla_{\boldsymbol{b}} L &=\sum_{t}\left(\frac{\partial \boldsymbol{h}^{(t)}}{\partial \boldsymbol{b}^{(t)}}\right)^{\top} \nabla_{\boldsymbol{h}^{(t)}} L=\sum_{t} \operatorname{diag}\left(1-\left(\boldsymbol{h}^{(t)}\right)^{2}\right) \nabla_{\boldsymbol{h}^{(t)}} L \\ \nabla_{\boldsymbol{V}} L &=\sum_{t} \sum_{i}\left(\frac{\partial L}{\partial o_{i}^{(t)}}\right) \nabla_{\boldsymbol{V}} o_{i}^{(t)}=\sum_{t}\left(\nabla_{o^{(t)}} L\right) \boldsymbol{h}^{(t)^{\top}} \\ \nabla_{\boldsymbol{W}} &=\sum_{t} \sum_{i}\left(\frac{\partial L}{\partial h_{i}^{(t)}}\right) \nabla_{\boldsymbol{W}^{(t)}} h_{i}^{(t)} \\ &=\sum_{t} \operatorname{diag}\left(1-\left(\boldsymbol{h}^{(t)}\right)^{2}\right)\left(\nabla_{\boldsymbol{h}^{(t)}} L\right) \boldsymbol{h}^{(t-1)^{\top}} \\ \nabla_{U} L &=\sum_{t} \sum_{i}\left(\frac{\partial L}{\partial h_{i}^{(t)}}\right) \nabla_{\boldsymbol{U}^{(t)}} h_{i}^{(t)} \\ &=\sum_{t} \operatorname{diag}\left(1-\left(\boldsymbol{h}^{(t)}\right)^{2}\right)\left(\nabla_{\boldsymbol{h}^{(t)}} L\right) \boldsymbol{x}^{(t)^{\top}} \end{aligned} ∇cL∇bL∇VL∇W∇UL=t∑(∂c∂o(t))⊤∇o(t)L=t∑∇o(t)L=t∑(∂b(t)∂h(t))⊤∇h(t)L=t∑diag(1−(h(t))2)∇h(t)L=t∑i∑(∂oi(t)∂L)∇Voi(t)=t∑(∇o(t)L)h(t)⊤=t∑i∑(∂hi(t)∂L)∇W(t)hi(t)=t∑diag(1−(h(t))2)(∇h(t)L)h(t−1)⊤=t∑i∑(∂hi(t)∂L)∇U(t)hi(t)=t∑diag(1−(h(t))2)(∇h(t)L)x(t)⊤
RNN确定序列长度方式
第一种是添加一个表示序列末端的特殊符号。在训练集中,我们将该符号作为序列的一个额外成员,即紧跟每个训练样本 x (τ) 之后。
第二种选择是在模型中引入一个额外的Bernoulli输出,表示在每个时间步决定继续或停止。相比向词汇表增加一个额外符号,这种方法更普遍,因为它适用于任何RNN。在这种方法中,sigmoid被训练为最大化正确预测的对数似然,即在每个时间步序列决定结束或继续。
第三种是将一个额外的输出添加到模型并预测整数 τ 本身。模型可以预测 τ 的值,然后使用 τ 步有价值的数据。这种方法需要在每个时间步的循环更新中增加一个额外输入,使得循环更新知道它是否是靠近所产生序列的末尾。
其他RNN结构
除了上面介绍的RNN结构,还有一些其他结构:
1, 每个时间步都产生一个输出,但是只有当前时刻的输出 o 与下个时刻的隐藏单元之间有连接的RNN:
这样的RNN没有最开始介绍的 RNN 那样强大,上图中的RNN被训练为将特定输出值放入 o 中,并且 o 是允许传播到未来的唯一信息。此处没有从 h 前向传播的直接连接。之前的 h 仅通过产生的预测间接地连接到当前。o 通常缺乏过去的重要信息,除非它非常高维且内容丰富。这使得该图中的RNN不那么强大,但是它更容易训练,因为每个时间步可以与其他时间步分离训练,允许训练期间更多的并行化。
2, 隐藏单元之间存在循环连接,但读取整个序列后只在最后一个时间步产生单个输出的RNN:
这样的网络可以用于概括序列,并产生一个向量 o 用于表示整个输入序列,然后可以对 o 进行进一步的处理。例如在翻译任务中,先输入原始输入的句子,得到句子的向量表示 o ,然后对 o 展开进一步的翻译任务。
3,包含上下文的RNN:
此RNN包含从前一个输出到当前状态的连接。这些连接允许RNN在给定 x 的序列后,对相同长度的 y 序列上的任意分布建模。
4,双向RNN
在许多应用中,我们要输出的 y (t) 的预测可能依赖于整个输入序列。例如,在语音识别中,当前声音作为音素的正确解释可能取决于未来几个音素,甚至可能取决于未来的几个词,因为词与附近的词之间的存在语义依赖。双向RNN结构如下:
隐藏状态变量 h 在时间上向前传播信息(向右),而隐藏状态变量 g 在时间上向后传播信息(向左)。因此在每个点 t,输出单元 o (t) 可以受益于输入 h (t) 中关于过去的相关信息以及输入 g (t) 中关于未来的相关信息。
5,编码—解码结构(序列到序列)的RNN
编码—解码结构的RNN支持将输入序列映射到不一定等长的输出序列,结构如下图所示:
这在许多场景中都有应用,如语音识别、机器翻译或问答,其中训练集的输入和输出序列的长度通常不相同。它由读取输入序列的编码器RNN以及生成输出序列的解码器RNN组成。编码器RNN的最终隐藏状态用于计算一般为固定大小的上下文向量 C,C 表示输入序列的语义概要信息并且作为解码器RNN的输入。
基于RNN的应用
RNN通常用于处理序列形式的输入数据,如文本,语音等。输出也可以是序列或者某个预测值。常见的应用如下:
1,序列数据的分析
例如情感分析,输入一句话的每个字的向量表示,输出其情感的预测标签。网络结构如下:
2,序列数据的转换
例如机器翻译,输入是某种语言的字序列,输出是翻译后的字序列。网络结构如下:
再如,词性标注,输入是字的向量表示,输出是每个字对应的词性标注信息,常见网络结构如下:
3,序列数据的生成
例如,图片描述生成,输入是一张图片的向量表示,输出图片的描述信息。网络结构如下:
RNN的不足
RNN很难解决长依赖问题,即经过许多个时间步的传播之后,梯度值倾向于0或者无穷大,这样的现象称之为梯度消失和梯度爆炸。
1,从隐藏变量h角度来看
为了简化说明,我们认为:
h(t)=WTh(t−1)\boldsymbol h^{(t)} = \boldsymbol W^T \boldsymbol h^{(t-1)} h(t)=WTh(t−1)
根据递推关系,可以转换为:
h(t)=(Wt)Th(0)\boldsymbol h^{(t)} = (\boldsymbol W^t)^T \boldsymbol h^{(0)} h(t)=(Wt)Th(0)
当W\boldsymbol WW 符合下列形式的特征分解:
W=QΣQT\boldsymbol W = \boldsymbol Q \boldsymbol \Sigma \boldsymbol Q^T W=QΣQT
其中Q\boldsymbol QQ是正交矩阵。于是有:
h(t)=QTΣtQh(0)\boldsymbol h^{(t)} = \boldsymbol Q^T \boldsymbol \Sigma^t \boldsymbol Q \boldsymbol h^{(0)} h(t)=QTΣtQh(0)
经过多个阶段的传播后,如果$ \boldsymbol \Sigma^t中的特征值小于1,特征值将衰减到零。如果特征值大于1,经过中的特征值小于1,特征值将衰减到零。如果特征值大于1,经过中的特征值小于1,特征值将衰减到零。如果特征值大于1,经过t次相乘后,特征值将激增。任何不与最大特征向量对齐的次相乘后,特征值将激增。任何不与最大特征向量对齐的次相乘后,特征值将激增。任何不与最大特征向量对齐的\boldsymbol h^{(0)}$的部分将最终被丢弃,无法做到长期依赖。
2,从梯度传播角度来看
梯度的反向传播过程如下图所示:
不难得到:
∂J∂y0=∂J∂h3∂h3∂h2∂h2∂h1∂h1∂y0\frac{\partial J}{\partial y_0} = \frac{\partial J}{\partial h_3}\frac{\partial h_3}{\partial h_2} \frac{\partial h_2}{\partial h_1} \frac{\partial h_1}{\partial y_0} ∂y0∂J=∂h3∂J∂h2∂h3∂h1∂h2∂y0∂h1
上面的式子是多个偏导数的累乘,如果每个偏导数的值都小于1,那么传播到 t=0t=0t=0 时刻的梯度几乎等于0了,也就是梯度消失了。梯度消失意味着只有靠近输出的几层才真正起到学习的作用,无法通过加深网络层数来提升预测效果,这样RNN很难学习到输入序列中的长距离依赖关系。
反之,如果每个偏导数的值都大于1,那么传播到 t=0t=0t=0 时刻的梯度被指数倍放大,也就是梯度爆炸了。可以通过梯度裁剪来缓解,即当梯度的范式大于某个给定值的时候,对梯度进行等比缩放。
为了能学习到更长的依赖关系,需要对RNN网络加以改进,下一篇文章提到的LSTM模型可以一定程度上得到改善。
参考文章:
《深度学习》
RNN详解
循环神经网络(RNN)相关知识相关推荐
- 循环神经网络(RNN)知识入门
循环神经网络(RNN)知识入门 原创:方云 一. RNN的发展历史 1986年,Elman等人提出了用于处理序列数据的循环神经网络(Recurrent Neural Networks).如同卷积神经网 ...
- 【NLP】 深度学习NLP开篇-循环神经网络(RNN)
从这篇文章开始,有三AI-NLP专栏就要进入深度学习了.本文会介绍自然语言处理早期标志性的特征提取工具-循环神经网络(RNN).首先,会介绍RNN提出的由来:然后,详细介绍RNN的模型结构,前向传播和 ...
- [Python人工智能] 十二.循环神经网络RNN和LSTM原理详解及TensorFlow编写RNN分类案例
从本专栏开始,作者正式开始研究Python深度学习.神经网络及人工智能相关知识.前一篇讲解了TensorFlow如何保存变量和神经网络参数,通过Saver保存神经网络,再通过Restore调用训练好的 ...
- 「NLP」 深度学习NLP开篇-循环神经网络(RNN)
https://www.toutiao.com/a6714260714988503564/ 从这篇文章开始,有三AI-NLP专栏就要进入深度学习了.本文会介绍自然语言处理早期标志性的特征提取工具-循环 ...
- 深度学习~循环神经网络RNN, LSTM
目录 1. 循环神经网络RNN 1.1 RNN出现背景 1.2 RNN概念 2. LSTM 2.1 LSTM出现背景 2.2 LSTM结构 参考 1. 循环神经网络RNN 1.1 RNN出现背景 pr ...
- 循环神经网络(RNN, Recurrent Neural Networks)介绍
循环神经网络(RNN, Recurrent Neural Networks)介绍 循环神经网络(Recurrent Neural Networks,RNNs)已经在众多自然语言处理(Natural ...
- 第六章_循环神经网络(RNN)
文章目录 第六章 循环神经网络(RNN) CNN和RNN的对比 http://www.elecfans.com/d/775895.html 6.1 为什么需要RNN? 6.1 RNN种类? RNN t ...
- 使用循环神经网络(RNN)实现影评情感分类
最近由于做论文的补充实验,需要在rnn上做一下算法验证.找了一下这个博客写的挺好的,但是也有一些bug,暂时先记录一下. 使用循环神经网络(RNN)实现影评情感分类 作为对循环神经网络的实践,我用循环 ...
- 循环神经网络RNN 2—— attention注意力机制(附代码)
attention方法是一种注意力机制,很明显,是为了模仿人的观察和思维方式,将注意力集中到关键信息上,虽然还没有像人一样,完全忽略到不重要的信息,但是其效果毋庸置疑,本篇我们来总结注意力机制的不同方 ...
最新文章
- AsyncTask使用详解
- Material Design入门(三)
- Qt/C++工作笔记-vector与QVector的拷贝复制(区别与联系)
- Mysql 日志管理详解
- 负载均衡实现 --- LVS的介绍、调度算法、NAT模式的搭建
- uniapp 小程序生成二维码 (兼容H5、微信小程序)
- vue 点击图片放大预览
- git 拉取最新代码
- Xcode各种运行报错及解决方法
- 节日大全c语言程序,C语言 程序设计 节日查询及任务提醒系统-万年历.doc
- kafka-集群搭建
- 2023年江苏专转本志愿填报辅导(22上岸南工程学长辅导手册)
- 2019CVPR单目深度估计综述
- 想要改变客户态度 这些销售话术需掌握
- Vertica常用语法
- 弹性伸缩,轻松上云-华为云弹性云服务器 ECS
- 【你好,windows】Windows 10 X64 20H2 19042.868 纯净版2021.3.17
- 华为鸿蒙2系统harmonyOS,华为鸿蒙HarmonyOS 2.0Beta版官方
- 【Java】据给出的英文短文,作如下统计
- 让群晖“文本编辑器”支持更多文件扩展名
热门文章
- seaborn绘图后得到分布参数
- 红黑树 删除某节点后 旋转3次 举例
- windows下mysql中文乱码_windows下mysql中文乱码, 配置解决方法
- 云服务器的操作系统是什么,服务器操作系统是什么?云服务器的操作系统怎么选择...
- MySql---数据库笔记(功能齐全)
- 如何制作可以在 MaxCompute 上使用的 crcmod
- 2019/01/29-Linux常用指令
- python json.loads json.dumps(ensure_ascii = False) 汉字乱码问题解决
- Mybatis基于XML配置SQL映射器(二)
- Spring Cloud自定义Hystrix请求命令