刚开始使用TensorFlow为多类分类构建LSTM网络
给定如下所示的结构:A RNN model假设每个节点A代表TensorFlow BasicLSTMcell .
根据网上发现的一些流行的例子,培训的输入准备为[batch_size,timeStep_size,feature_size]
让我们假设timeStep_size = 5,feature_size = 2,num_class = 4,给定一个训练集:(虚拟数据)
t = t0 t1 t2 t3 t4
x = [ [1] [2] [2] [5] [2] ]
[ [2] [3] [3] [1] [2] ]
y = [ [0] [1] [1] [0] [0] ]
[ [1] [0] [0] [0] [0] ]
[ [0] [0] [0] [0] [1] ]
[ [0] [0] [0] [1] [0] ]
根据流行的用法:
...
# 1-layer LSTM with n_hidden units.
rnn_cell = rnn.BasicLSTMCell(n_hidden)
# generate prediction
outputs, states = rnn.static_rnn(rnn_cell, x, dtype=tf.float32)
return tf.matmul(outputs[-1], weights['out']) + biases['out']
在我看来,LSTM细胞的训练没有利用y的所有五个输出(y在t0-t3) . 当与输出[-1]比较时,仅在时间t4使用y来计算损耗 .
问题1:LSTM是否自行计算/近似y_t0,并输入t1计算y_t1,依此类推......直到计算出y_t4?
如果是这种情况,
问题2:如果t-1的y非常重要怎么办?
例:
t = t-1 t0 t1 t2 t3 t4
x = [ [1] [2] [2] [2] [2] [2]]
[ [1] [2] [2] [2] [2] [2]]
y = [ [0] [1] [1] [1] [1] [1]]
[ [1] [0] [0] [0] [0] [0]]
[ [0] [0] [0] [0] [0] [0]]
[ [0] [0] [0] [0] [0] [0]]
VS:
t = t-1 t0 t1 t2 t3 t4
x = [ [3] [2] [2] [2] [2] [2]]
[ [3] [2] [2] [2] [2] [2]]
y = [ [0] [0] [0] [0] [0] [0]]
[ [0] [0] [0] [0] [0] [0]]
[ [1] [0] [0] [0] [0] [0]]
[ [0] [1] [1] [1] [1] [1]]
这意味着即使从t0到t4的输入特征相同,输出y也是不同的,因为先前的输出(y_t-1)是不同的 .
那怎么处理这种情况呢?在t0计算输出时,TensorFlow如何设置t-1的输出?
我想过增加timeStep_Size,但实际情况可能非常大,所以我有点困惑......
任何指针都非常感谢!
先感谢您 .
=================更新===============================
回复:jdehesa,再次感谢 .
一些额外的背景:我的意图是对一系列长x进行分类,如下所示:
t = t0 t1 t2 t3 t4 t5 t6 t7 ...
x = [ [3] [2] [2] [2] [2] [2] [1] [2] [2] [2] [2] [2] ...]
[ [3] [2] [2] [2] [2] [2] [1] [2] [2] [2] [2] [2] ...]
y = [ c3 c2 c2 c2 c2 c2 c1 c4 c4 c4 c4 c4 ...]
Note: c1: class 1, c2: class2 c3: class 3, c4: class 4
这篇文章背后的主要困惑是有一些已知的手动分类规则 . 以上面的虚拟数据为例,假设有规则
-
如果前一个特征x是第3类([3,3]),那么所有后面的[2,2]将是第2类,直到达到第1类 .
-
如果前一个x是1级([1,1]),那么所有后面的[2,2]将是4级,直到达到3级 .
在这种情况下,如果LSTM只看到[5乘2]特征向量(x)与t1到t4相同,那么网络将完全丢失,并将其分类为2级或4级 . 所以我的意思是不仅仅是那些5个时间步的特征很重要,前一个时间步的输出/标签也很重要 .
所以重申一下这个问题:如果现在训练集是t1到t5,那么除了x [batch_size,t1:t5,2]之外,如何在t0处涉及标签/类y .
以下是我对你答案的回应 .
考虑我使用GRU而不是LSTM,其中单元格输出和单元格状态都由"h"表示,如understandign LSTM .
-
关于initial_state参数:我刚刚发现dynamic_rnn和static_rnn采用了你指出的参数:D . 如果我要解决刚刚提到的问题,我可以使用在训练之前将之前的类/标签(y在t0)分配给initial_state参数,而不是使用zeros_state .
-
我突然觉得自己完全迷失了LSTM内存的时间 Span . 我一直在想内存的时间 Span 仅受timeStep_size的限制 . 如果timeStep_size = 5,网络最多只能回调4步,因为每次训练我们只提供[5 x 2] x特征向量 . 如果我错了,请纠正我 .
再次,谢谢你
1 回答
通常,LSTM单元或RNN单元具有在处理每个时间步之后更新的内部状态 . 显然,你无法及时回归,所以你必须从某个时刻开始 . 一般惯例是从一个充满零的单元状态开始;实际上,TensorFlow中的RNN单元具有
zero_state
方法,该方法针对每种特定的单元类型和大小返回这种状态 . 如果你对这个起点不满意(例如,因为你已经处理了半个序列,现在你想要处理另一半,那么你可以选择相同的状态),你可以将initial_state
参数传递给tf.nn.dynamic_rnn .关于培训,我完全取决于你 . 我处理的问题是我每次都有一个标签样本,因此我的输出与输入的大小相同 . 但是,在许多情况下,您只需要整个序列的标签(例如"this sentence is positive/negative"),因此您只需查看最后一个输出 . 无论如何,所有先前的输入当然都很重要,因为它们定义了与最后一个输入组合使用的最后一个单元状态,以确定最终输出 . 例如,如果你采取像"That's cool, man"这样的句子并且逐字处理它,最后一个单词"man"可能不会告诉你很多关于它本身是正面还是负面的句子,但是在这一点上,单元格处于这样一种状态:它确定它是一个正面的句子(也就是说,之后需要一个明显的负面输入才能产生"negative"输出 .
我不确定你对t-1的意思是什么......我的意思是如果你的输入从t0开始并且你从未见过t-1,你就无法做到这一点(例如,如果你只得到了输入"really like this food"但事实证明整个原始句子是"not really like this food",你只会完全错误) . 但是,如果您确实有输入,那么如果确实很重要,网络将学会将其考虑在内 . LSTM细胞的重点在于它们能够记住过去很远的事物(即内部状态的输入效果可以达到很长的时间 Span ) .
更新:
关于您的其他评论 .
当然,您可以使用任何您想要的输入状态 . 但是,即使使用GRU,内部状态通常也不会与输出标签匹配 . 通常,在循环单元之后使用sigmoid或softmax激活,然后产生与标签相当的输出 .
关于时间 Span . 使用具有小时间步长的输入将限制循环单元学习长期依赖性(以在较长序列中找到模式)的能力是正确的 . 正如我所提到的,如果在下一次运行中将周期性单位的最后状态作为初始状态提供,则可以“模拟”更长的时间步长 . 但是,无论你是否这样做,LSTM单位过去都不会“记不起”事情并不准确 . 即使您使用时间步长5进行训练,如果您随后使用大小为100的序列运行网络,则最后输入的输出将(可能)受到所有99个先前输入的影响;你根本无法分辨出它们的影响程度,因为这是你在训练期间没有的情况 .