循环神经网络可以学习序列之间非常复杂的映射(与前馈网络不同,前馈网络只能转换固定大小的向量)。你真的只需要一个 RNN,它采用以下形式的序列(一个吨,b吨)作为输入(假设t ∈ { 1... T}你有序列。一个和b两者都有吨样本,您必须将这些信号分类为ķ类)。然后,您可以为采样运行以下过程(伪代码)(给定已训练的模型):
for t in (1..T) //loop over an input sequence
rnn.input[0] = a[t] //assign t-th point of the blue seq.
rnn.input[1] = b[t] //assign t-th point of the green seq.
rnn.forward() //make forward pass
rnn.output.normalize() //renormalize output probabilities
class_prob = rnn.output.max()
class = rnn.output.argmax()
例如,我们有以下长度为 4 的序列:
信号 A: {1, 3, 4, 6}
信号 B: {4, 3, 0, 1}
然后在第一个时间步中我们分配向量( 1 , 4 ) 到输入层,然后 ( 3 , 3 )等等。在每个时间步,我们将输入向前传播到网络,更新其隐藏状态,该隐藏状态负责记住过去的数据点。在每次前向传递之后,我们的神经网络会在输出层生成一个预测,这暂时不重要。这种波动的预测反映了 rnn 对我们数据集部分的信念——它只见过吨第一个输入向量。在我们传播了整个信号之后,我们可以进行分类。
你的 RNN 的输出层应该是ķ维及其一世-th 分量是信号蜂在类中的伪概率一世. 例如,您可以执行 argmax(采用预测最大的索引)或使用 softmax 分布进行采样。例如,如果你有课一个和班级b你的输出向量是( 5 , 15 )那么你的信号被归类为b. 或者如果你做softmax然后软件_ _t m a x ( 5 , 15 ) = ( 0.000045 , 0.999955 )所以你分配班级b几乎100%的概率。
训练 RNN 要复杂得多。我建议你使用一些现有的工具包,这些工具包已经实现了 RNN,例如 LSTM。为了训练递归神经网络,我们可以应用上述过程,但最后(在迭代序列之后)我们计算损失函数的梯度并进行反向传播。然而这种技术被称为时间反向传播(它实际上类似于普通的 FFN 反向传播,但我们必须及时“展开”出 RNN 以调整循环连接)。另请注意,如果您选择使用 softmax 输出单元,您的损失函数应该是交叉熵损失函数。
但是计算梯度损失的预期输出向量是什么?如果您的数据集包含ñ (绿-蓝)序列中的每一个 ķn 类,那么他们的预期输出向量就是 one-hot 向量 ( 0 ... , 1 , ... .0 ) 在哪里 1 位于 ķn仅 -th 组件。例如,如果您有一个序列分类为b,则其输出向量目标为 ( 0 , 1 ). @EDIT:假设在前面的例子中你的序列有类b 所以你希望看到向量 ( 0 , 1 ). 你现在接受网络的预测(比如说( 0.34 , 0.57 )) 并将误差函数计算为正常的 fe 平方误差或交叉熵。
您可以从karpathy和Hinton了解更多信息