我正在尝试在keras中创建一个状态的rnn,这是输入是嵌入和3个整数输入的串联。
以下是代码的简化版本,我添加了图层的尺寸作为注释,以使阅读
更容易input = Input(batch_shape=(1,3,10))
inputTag = Lambda(lambda x: x[:,:,0:1])(input)
inputMeta =Lambda(lambda x: x[:,:,7:10])(input)
inputTag.shape, inputMeta.shape
#(TensorShape([Dimension(1), Dimension(3), Dimension(1)]),
# TensorShape([Dimension(1), Dimension(3), Dimension(1), Dimension(3)]))
inputTagEnc = Embedding(tag_vocab_size,
tag_emb_output_dim,
input_length = 1)(inputTag)
inputTagEnc.shape
#TensorShape([Dimension(1), Dimension(3), Dimension(1), Dimension(4)])
encodings =[inputTagEnc, inputMeta]
encodedInput = Concatenate()(encodings)
#Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# File "C:UsersmarcoAnaconda3libsite-packageskerasenginetopology.py", line 521, in __call__
# self.build(input_shapes)
# File "C:UsersmarcoAnaconda3libsite-packageskeraslayersmerge.py", line 153, in build
# 'Got inputs shapes: %s' % (input_shape))
#ValueError: `Concatenate` layer requires inputs with matching shapes except for the concat axis. Got inputs shapes: [(1, 1, 4), (1, 3, 1, 3)]
rnn = LSTM(n_hidden,
dropout=0.0,
activation='relu',
recurrent_dropout=0.0,
stateful=True)(encodedInput)
output = Dense(3, activation='softmax')(rnn)
model = Model(inputs=[input], outputs=[encodedInput])
model.compile(loss='categorical_crossentropy', optimizer=Adam())
model.summary()
串联似乎正在失败,因为嵌入正在展开由于我的批量大小为3,但是整数输入正在尝试按原样处理。
现在,我尝试了一百万个重塑,变平和定时分配的变体,以使尺寸保持一致,但我仍然陷入困境。
有人可以解决这个问题吗?
我找到了解决这个问题的解决方案,尽管不是一个非常整洁的问题。使用自定义层,我可以在将张量馈入RNN之前手动刺激张量。该方法需要更多的工作才能使其动态,但这里是当前形式。
class WorkingConcat(Layer):
def __init__(self, **kwargs):
super(WorkingConcat, self).__init__(**kwargs)
def build(self, input_shape):
super(WorkingConcat, self).build(input_shape) # Be sure to call this somewhere!
def call(self, x):
encodings, inputMeta = x[0:len(x)-1], x[len(x)-1]
dd = K.reshape(inputMeta,(batch_size,3,1,3))
encodings.append(dd)
encodedInput = K.concatenate(encodings,axis=3)
#ff = Reshape((3,67))(encodedInput)
ff = K.reshape(encodedInput,(batch_size,3,67))
self.output_dim = ff.shape
return ff
def compute_output_shape(self, input_shape):
return (batch_size, 3, 67)
encodings =[inputTagEnc]
encodings.append(inputMeta)
reshapedFrame = WorkingConcat()(encodings)
自定义层只能采用张量或张量列表,因此该层在列表中找到的最后一个张量并重塑其张紧,然后将其与其余的张紧(在我的完整解决方案中,编码都有一堆相似尺寸的编码(