在有状态RNN中组合嵌入和整数输入

时间:2017-05-04 06:26:21

标签: keras

我正在尝试在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:\Users\marco\Anaconda3\lib\site-packages\keras\engine\topology.py", line 521, in __call__
#    self.build(input_shapes)
#  File "C:\Users\marco\Anaconda3\lib\site-packages\keras\layers\merge.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,但整数输入正在尝试按原样处理。

现在我尝试了一百万种形状变形,变平和时间分布试图让尺寸对齐,但我仍然卡住了。

有没有人能解决这个问题?

1 个答案:

答案 0 :(得分:0)

风滚草......

我找到了解决这个问题的方法,虽然不是很好。使用自定义图层,我可以在将它们送入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)

自定义图层只能采用张量或张量列表,因此图层会获取它在列表中找到的最后一个张量并对其进行重新整形,然后将其与其余部分进行对比(在我的完整解决方案中,编码有一堆类似大小的编码)