我正在使用keras(带有TensorFlow后端的版本2.0.6)用于简单的神经网络:
model = Sequential()
model.add(LSTM(32, return_sequences=True, input_shape=(100, 5)))
model.add(LSTM(32, return_sequences=True))
model.add(TimeDistributed(Dense(5)))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
这只是对我的一次测试,我正在使用以下虚拟数据“训练”模型。
x_train = np.array([
[[0,0,0,0,1], [0,0,0,1,0], [0,0,1,0,0]],
[[1,0,0,0,0], [0,1,0,0,0], [0,0,1,0,0]],
[[0,1,0,0,0], [0,0,1,0,0], [0,0,0,1,0]],
[[0,0,1,0,0], [1,0,0,0,0], [1,0,0,0,0]],
[[0,0,0,1,0], [0,0,0,0,1], [0,1,0,0,0]],
[[0,0,0,0,1], [0,0,0,0,1], [0,0,0,0,1]]
])
y_train = np.array([
[[0,0,0,0,1], [0,0,0,1,0], [0,0,1,0,0]],
[[1,0,0,0,0], [0,1,0,0,0], [0,0,1,0,0]],
[[0,1,0,0,0], [0,0,1,0,0], [0,0,0,1,0]],
[[1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0]],
[[1,0,0,0,0], [0,0,0,0,1], [0,1,0,0,0]],
[[1,0,0,0,0], [0,0,0,0,1], [0,0,0,0,1]]
])
然后我做:
model.fit(x_train, y_train, batch_size=2, epochs=50, shuffle=False)
print(model.predict(x_train))
结果是:
[[[ 0.11855114 0.13603994 0.21069065 0.28492314 0.24979511]
[ 0.03013871 0.04114409 0.16499813 0.41659597 0.34712321]
[ 0.00194826 0.00351031 0.06993906 0.52274817 0.40185428]]
[[ 0.17915446 0.19629011 0.21316603 0.22450975 0.18687972]
[ 0.17935558 0.1994358 0.22070852 0.2309722 0.16952793]
[ 0.18571526 0.20774922 0.22724937 0.23079531 0.14849086]]
[[ 0.11163659 0.13263632 0.20109797 0.28029731 0.27433187]
[ 0.02216373 0.03424517 0.13683401 0.38068131 0.42607573]
[ 0.00105937 0.0023865 0.0521594 0.43946937 0.50492537]]
[[ 0.13276921 0.15531689 0.21852671 0.25823513 0.23515201]
[ 0.05750636 0.08210614 0.22636817 0.3303588 0.30366054]
[ 0.01128351 0.02332032 0.210263 0.3951444 0.35998878]]
[[ 0.15303896 0.18197381 0.21823004 0.23647803 0.21027911]
[ 0.10842207 0.15755147 0.23791778 0.26479205 0.23131666]
[ 0.06472684 0.12843341 0.26680911 0.28923658 0.25079405]]
[[ 0.19560908 0.20663913 0.21954383 0.21920268 0.15900527]
[ 0.22829761 0.22907974 0.22933882 0.20822221 0.10506159]
[ 0.27179539 0.25587022 0.22594844 0.18308094 0.063305 ]]]
好的,它有效,但它只是一个测试,我真的不关心准确性等。我想了解我如何使用不同大小的输出。
例如:传递一个序列(numpy.array),如:
[[0,0,0,0,1], [0,0,0,1,0], [0,0,1,0,0]]
我想将4维输出作为预测:
[[..first..], [..second..], [..third..], [..four..]]
这有可能吗?尺寸可能会有所不同我会用不同的标签训练模型,这些标签可以有不同的N维度。
由于
答案 0 :(得分:2)
我不认识Keras,但从实践和理论的角度来看,这绝对是可能的。
这个想法是你有一个输入序列和一个输出序列。通常,每个序列的开始和结束由一些特殊符号界定(例如,字符序列“cat”被翻译成具有开始符号“^”和结束符号“#”的“^ cat#”)。然后用另一个特殊符号填充序列,最多最大序列长度(例如“^ cat#$$$$$$”,填充符号为“$”)。
如果填充符号对应于零向量,则它对您的训练没有影响。
您的输出序列现在可以假设任何长度达到最大长度,因为实际长度是从开始到结束符号位置的长度。
换句话说,您将始终具有相同的输入和输出序列长度(即最大值),但实际长度是起始符号和结束符号之间的长度。
(显然,在输出序列中,在丢失函数中不应考虑结束符号之后的任何内容)
答案 1 :(得分:2)
这个答案是针对不同的维度,但对于不同的维度,Giuseppe的答案中的填充想法似乎是可行的方法,可能借助于提出的"Masking"在Keras文档中。
Keras的输出形状完全取决于"单位/神经元/细胞的数量"你放在最后一层,当然还有层的类型。
我可以看到您的数据与您的问题中的代码不匹配,这是不可能的,但是,假设您的代码是正确的,并暂时忘记数据。
LSTM图层中的输入形状(100,5)表示形状(None, 100, 5)
的张量,这是
None
是批量大小。您的数据的第一维保留给您拥有的数量。 (X和Y必须具有相同数量的示例)。 sequence with 100 time steps
5-dimension vector
。 同一LSTM层中的 32个单元意味着生成的向量将从5维向量变为32维向量。使用return_sequences=True
时,所有100个时间步都将出现在结果中。所以第一层的结果形状是(None, 100, 32)
:
return_sequences=True
) 现在第二个LSTM图层完全相同。保持100个步骤,因为它还有32个单元格,保留32维向量,所以输出也是(None, 100, 32)
最后,分布式密集层的时间也将保持100次步长(因为TimeDistributed
),并再次将向量更改为5维向量(因为{{1} }),导致5 units
。
如您所见,您不能直接使用循环图层更改时间步数,您需要使用其他图层来更改这些尺寸。而这样做的方式完全取决于你,有无限的方法可以做到这一点。
但是在所有这些中,您需要摆脱时间步长并使用其他形状重建数据。
来自我的建议(这只是一种可能性)是重塑你的结果,并应用另一个密集层来实现最终的形状。
假设您想要(None, 100, 5)
这样的结果(永远不要忘记,您的数据的第一个维度是示例的数量,它可以是任何数字,但您必须将其考虑在内当你整理数据时)。我们可以通过将数据重新整形为第二维中包含4的形状来实现这一目标:
(None, 4, 5)
这将为您提供4个时间步长(因为Reshape之后的尺寸为:(None,4,125),每个步骤都是5维向量(因为Dense(5))。
使用#after the Dense layer:
model.add(Reshape((4,125)) #the batch size doesn't appear here,
#just make sure you have 500 elements, which is 100*5 = 4*125
model.add(TimeDistributed(Dense(5))
#this layer could also be model.add(LSTM(5,return_sequences=True)), for instance
#continue to the "Activation" layer
命令查看每个图层输出的形状。
答案 2 :(得分:0)
似乎有两种方法可以对序列进行排序方法,您需要进行描述。第一个直接使用keras使用this example(下面的代码)
from keras.layers import Input, LSTM, RepeatVector
from keras.models import Model
inputs = Input(shape=(timesteps, input_dim))
encoded = LSTM(latent_dim)(inputs)
decoded = RepeatVector(timesteps)(encoded)
decoded = LSTM(input_dim, return_sequences=True)(decoded)
sequence_autoencoder = Model(inputs, decoded)
encoder = Model(inputs, encoded)
重复向量重复初始时间序列n次以匹配输出向量的时间戳数。这仍然意味着您需要在输出向量中使用固定数量的时间步长,但是,可能有一种方法可以填充时间戳比最大时间步长少的向量。
或者你可以使用基于keras构建的seq2seq模块。