我正在查看Keras LSTM背后的代码,发现有些奇怪的东西。
假设我们正在输入大小为(batch_size, time_steps, input_dim)
的输入
batch_size
是微型批次中的示例数量,time_steps
是回溯的时间步数(即窗口大小)input_dim
是输入变量的数量。假设我们要输入大小为batch_size
= 5,time_steps
= 2和input_dim
= 1的迷你批。
也就是说,我们有一个单变量时间序列,每个小批量有五个示例,并且我们使用时间序列的前两个值来预测下一个值。
假设我们要使用大小为3的LSTM(即隐藏单元数和输出单元数)来完成此操作。将此大小称为units
。
在the code here的1871-1995行中,正在构建LSTM。我很困惑的方程式是在1989-1990行上,它对应于输入门的计算:
i = self.recurrent_activation(x_i + K.dot(h_tm1_i, self.recurrent_kernel_i))
变量x_i
的计算公式为:
x_i = K.dot(inputs_i, self.kernel_i)
其中
inputs_i
=时间i的输入,其形状为(batch_size, time_steps, input_dim)
,在我们的示例中为形状(5, 2, 1)
self.kernel_i
=权重矩阵乘以时间t的当前输入,并具有形状(input_dim,单位),在我们的情况下,形状为(1, 3)
我知道此点积是通过广播完成的,最终形状为(batch_size, time_steps, units)
,在我们的情况下为(5, 2, 3)
。
现在让我们检查点积:
K.dot(h_tm1_i, self.recurrent_kernel_i))
其中
h_tm1_i
=时间i
时的重复隐藏状态,根据295行的形状等于(batch_size, units)
。在我们的例子中,这就是(5, 3)
< / p>
self.recurrent_kernel
=权重矩阵乘以先前的隐藏状态,并具有形状(units, units)
,在我们的情况下为(3, 3)
。
通过广播魔术,点乘积以(5, 3)
的形式呈现出某种形状
我们只需要添加x_i
和K.dot(h_tm1_i, self.recurrent_kernel_i))
,它们的形状分别为(5, 2, 3)
和(5, 3)
。当我尝试在tensorflow中自己执行此操作时,出现错误:
ValueError: Dimensions must be equal, but are 2 and 5 for 'add_1' (op: 'Add') with input shapes: [5,2,3], [5,3].
很明显,我在某处做错了,但看不到逻辑错误。有人可以帮忙吗?
编辑:重现该错误:
>>> import tensorflow as tf
>>> import keras
>>> from keras import backend as K
>>> inputs_i = tf.ones([5, 2, 1])
>>> kernel_i = tf.ones([1,3])
>>> h_tm1_i = tf.ones([5,3])
>>> rec_i = tf.ones([3,3])
>>> x_i = K.dot(inputs_i, kernel_i)
>>> x_i
<tf.Tensor 'Reshape_9:0' shape=(5, 2, 3) dtype=float32>
>>> K.dot(h_tm1_i, rec_i)
<tf.Tensor 'MatMul_4:0' shape=(5, 3) dtype=float32>
>>> x_i + K.dot(h_tm1, rec_i) #Raises ValueError
编辑:基于答案here,我认为我误解了隐藏状态(h_tm1_i
)的大小。为了使乘法有效,大小必须为(batch_size, time_steps, units)
,此处为(5, 2, 3)
。如果这样做,数学就可以算出。但是,我无法仅通过查看代码就知道这实际上是否是隐藏状态的大小。有人可以确认吗?