【问题标题】:How to reshape tensor flattened to a LSTM?如何将张量展平为 LSTM?
【发布时间】:2019-01-23 13:57:01
【问题描述】:

在这里,我在 Keras 中编码时遇到了一些问题。我需要用两种嵌入来处理两个顺序输入,一种是词嵌入,另一种是 doc2vec 嵌入,都是dim=300。然后我将把这两个向量连接成一个更长的向量,因为我想从中获得一些堆叠的特征。然而,这两个嵌入可能在不同的空间中,所以我必须使用nn.flatten() 将这两个向量映射到同一个向量中。然后我需要将输出向量从 flatten 输入到 LSTM 模型。但是编译器抱怨Input 0 is incompatible with lstm_1: expected ndim=3, found ndim=2,我根本没有设置ndim=3,我不知道如何将向量重塑为具有正确形状的新输入。 请帮助解决这个问题。

n_hidden = 50

batch_size = 64

def classification_softmax(left, right):
''' Helper function for the similarity estimate of the LSTMs outputs'''
return K.abs(left - right)
embedding_layer = Embedding(len(embeddings), 300, weights=[embeddings], input_length=max_seq_length,
                            trainable=False)


embedding_cfg_layer =  Embedding(len(cfg_embedding_matrix), 300, weights=[cfg_embedding_matrix], input_length=1,
                            trainable=False)


#cfg_embedding_l=krs.layers.Flatten()(embedding_cfg_layer(cfg_left_input))
#cfg_embedding_r=krs.layers.Flatten()(embedding_cfg_layer(cfg_right_input))
#encoded_left = krs.layers.Concatenate(axis=1)([krs.layers.Flatten()(embedding_layer(left_input)),cfg_embedding_l])
#encoded_right = krs.layers.Concatenate(axis=1)([krs.layers.Flatten()(embedding_layer(right_input)), cfg_embedding_r])

encoded_left = encoded_left
encoded_right = encoded_right
# Since this is a siamese network, both sides share the same LSTM
shared_lstm = LSTM(n_hidden,return_sequences=True)

#encoded_left=krs.layers.Reshape((2,))(encoded_left)
#encoded_right=krs.layers.Reshape((2,))(encoded_right)
left_output = shared_lstm(encoded_left)
right_output = shared_lstm(encoded_right)
    cfg_embedding_l=embedding_cfg_layer(cfg_left_input)
cfg_embedding_r=embedding_cfg_layer(cfg_right_input)
encoded_left = krs.layers.Concatenate(axis=0)([(embedding_layer(left_input),cfg_embedding_l])
encoded_right = krs.layers.Concatenate(axis=0)(embedding_layer(right_input), cfg_embedding_r])
...   
dist = Lambda(lambda x: classification_softmax(x[0], x[1]))([left_output, right_output])
classify = Dense(5, activation=softMaxAxis1)(dist)
# Pack it all up into a model
malstm = Model([left_input, right_input,cfg_left_input,cfg_right_input], [classify])

optimizer = Adadelta(clipnorm=gradient_clipping_norm)

# malstm.compile(loss='mean_squared_error', optimizer='adam', metrics= 
['accuracy', f1, recall,precision])
malstm.compile(loss='categorical_crossentropy', optimizer='adam', metrics= 
[categorical_accuracy])#, f1, recall, precision])

# Start training
training_start_time = time()

malstm_trained = malstm.fit(
[X_train['left'], X_train['right'], X_train['cfg_A'], X_train['cfg_B']],
krs.utils.to_categorical(Y_train, 5),
batch_size=batch_size, nb_epoch=n_epoch,
#callbacks=[metrics],
validation_data=(
    [X_validation['left'], X_validation['right'], 
X_validation['cfg_A'],X_validation['cfg_B']],
    krs.utils.to_categorical(Y_validation, 5)))

【问题讨论】:

    标签: python keras


    【解决方案1】:

    我无法从您的示例代码中分辨出您输入的确切形状,因此我无法给出确切形状的答案,但在这种情况下,您应该使用Reshape 层。

    我将进行逻辑飞跃,您的形状将是 (batch_size, 300 * max_seq_length + 300),因为第一个 Embedding 层输出一个 (max_seq_length, 300) 张量,第二个输出一个 (1, 300) 张量,然后您将其展平并连接他们。

    您想将您的 2D (batch_size, 300 * max_seq_length + 300) 重塑为像 (batch_size, 300 * max_seq_length + 300, 1) 这样的 3D 形状。使用您的目标形状添加Reshape 层:

    reshape = keras.layers.Reshape(300 * max_seq_length + 300, 1)
    
    encoded_left = reshape(encoded_left)
    encoded_right = reshape(encoded_right)
    

    然后将它们传递到您的 LSTM。

    【讨论】:

    • @ Primusa 非常感谢您的回答,它看起来是正确的。我尝试了您的解决方案,然后又遇到了另一个运行时错误:“预计 dense_1 有 3 个维度,但得到了形状为 (24000,5) 的数组” . 24000是单热数组形式的列表Y_validation的长度。分类 = Dense(5, activation=softMaxAxis1)(dist) 可以看到我想将数据分类为 5 类。所以我在 [0,1,2,3,4....] 这样的列表中有 Y_value 并且我使用 keras.utils.to_categorical(Y_validation,5) 来获得一个热矩阵作为 Y。有人说我需要设置LSTM(hidden,return_Sequences=False),但它从记忆中消失了。
    • 输出中单个样本的形状是什么?
    • 你的意思是预测值 Y 对吗?它是列表中的 Y_value,例如 [[0],[1],[2],[3],[4],[0],[0],....],它只是一个数字 [0,4 ] 代表一类。数字作为 Y_value 存储在列表中,我将列表传递给函数 keras.utils.to_categorical(Y_validation,5)。输入样本包含两部分:一个句子(例如,最大长度为 1000)和一个图形表示。两者都是通过输入层输入的。我更新代码sn-p来查看上下文
    • 请发布您的完整模型和一些虚拟输入和输出数据(不是实际数据,相同形状的假数据,即np.random.rand(10, 32, 300))。这样我就能更好地帮助你。
    • 我更新了帖子中的代码。我正在尝试打印样本的输入和输出形状。但是我发现我可以在模型中犯的错误:batchmax_length dimension =64(batch)*24000(max_length)*300 in flattened vector,它可能太大而无法计算。我可能需要在 LSTM 之后连接两个部分
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    • 2022-01-14
    • 1970-01-01
    • 2021-11-13
    • 2020-05-26
    • 2019-08-16
    • 2021-03-14
    相关资源
    最近更新 更多