【问题标题】:Concatenate BERT and CNN连接 BERT 和 CNN
【发布时间】:2020-06-07 16:02:01
【问题描述】:

我正在尝试将两个模型合并为一个。 我有一个 BERT 模型和 EfficientNet 模型。

input_text = model_Bert.inputs[:2]
text = model_Bert(input_text)
input_img = model_EfNet.layers[0].input
img = model_EfNet(input_img)
concatenated = layers.concatenate([text, img], axis=1) #same dimension
dense = layers.Dense(512, activation='relu')(concatenated)
dense = layers.Dense(128, activation='relu')(dense)
dense = layers.Dropout(0.3)(dense)
outputs = layers.Dense(2, activation='softmax', name = 'real_output')(dense)

model_Multimodal = keras.models.Model(inputs=[input_text, input_img], outputs=outputs)

但是我收到了这个错误:


ValueError Traceback(最近一次调用最后一次) 在 9 个输出 = layers.Dense(2, activation='softmax', name = 'real_output')(dense) 10 ---> 11 model_Multimodal = keras.models.Model(inputs=[input_text, input_img], outputs=outputs)

~/anaconda3/lib/python3.7/site-packages/keras/legacy/interfaces.py 在 wrapper(*args, **kwargs) 89 warnings.warn('更新你的' + object_name + '调用'+ 90 'Keras 2 API: ' + 签名,stacklevel=2) ---> 91 返回函数(*args,**kwargs) 92 包装器._original_function = func 93 返回包装器

~/anaconda3/lib/python3.7/site-packages/keras/engine/network.py in init(self, *args, **kwargs) kwargs 中的 92 个“输入”和 kwargs 中的“输出”): 93 # 图网络 ---> 94 self._init_graph_network(*args, **kwargs) 95 其他: 96 # 子类网络

~/anaconda3/lib/python3.7/site-packages/keras/engine/network.py in _init_graph_network(self, inputs, outputs, name, **kwargs) 167 '必须来自keras.layers.Input。 ' 168 '收到:' + str(x) + --> 169 '(缺少上一层元数据)。') 170 # 检查 x 是否是输入张量。 171层,node_index,tensor_index = x._keras_history

ValueError: Input tensors to a Model must come from `keras.layers.Input`. Received: [<tf.Tensor 'Input-Token_1:0' shape=(None, 128) dtype=float32>, <tf.Tensor 'Input-Segment_1:0' shape=(None, 128) dtype=float32>] (missing previous layer metadata).

【问题讨论】:

  • 我已经尝试像这样修改第 2,4 行:text = model_Bert.layers[105].output img = model_EfNet.layers[11].output 但错误是一样的。
  • 请问你解决了吗?

标签: python tensorflow keras deep-learning keras-layer


【解决方案1】:

如果不知道您用于 BERT 的实现,很难从您的代码中分辨出来。特别是,它是无头模型吗?我的理解(可能不正确)是没有头部的 BERT 提供了形状为 (batch_size, seq_length, embedding_dim) 的输出。换句话说,输出形状随输入大小而变化。因此,我看不出您的图像嵌入将如何始终与转换器的输出具有相同的形状。

我正在使用transformerslibrary 和预训练的 CNN 以大致以下方式创建双峰语言模型:

def call(encoded_sentences, img_embeddings, **transformer_kwargs):

        outputs = transformer(encoded_sentences, **transformer_kwargs)
        last_hidden_state, *_ = outputs
        batch_size, batch_seq_len, last_hidden_dim = last_hidden_state.shape

        # reshape and repeat image embeddings
        batch_size, *img_emb_shape = img_embeddings.shape
        img_emb_flattened = tf.reshape(img_embeddings, 
                                       (batch_size, np.prod(img_emb_shape)))
        emb_flattened_reps = tf.repeat(tf.expand_dims(img_emb_flattened, 1), 
                                       batch_seq_len, axis=1)

        # concatenate the language and image embeddings
        embs_concat = tf.concat([last_hidden_state, emb_flattened_reps], 2)

        # generate mlm predictions over input sequence
        training = transformer_kwargs.get('training', False)
        prediction_scores = mlm_head(embs_concat, training=training)

        # Add hidden states and attention if they are here
        outputs = (prediction_scores,) + outputs[2:]

        return outputs

在我的例子中,transformerTFAlbertModelmlm_headTFAlbertMLMHead(如果这段代码看起来有点混乱,因为我已经从 tf.keras.Model 中的类方法改编它) .另外,请记住,encoded_sentences 已通过标记器,img_embeddings 是从预训练的 CNN 中提取的。

请参阅 this repository 了解我的笔记本探索这种图像字幕的方法。

【讨论】:

  • 现在我尝试解释我的工作:我正在尝试用相应的图像对句子的情绪进行分类。为了改善我的结果,我决定开发三个管道:一个仅用于文本,一个仅用于图像,一个用于两者。我使用所有模型 BERT。问题是我无法获取层 BERT 的输出(768)(不是最终输出)。我的想法是获取这个输出,将它与 conv 层的输出(可以是 1280 或 768)连接并进行分类。
猜你喜欢
  • 2021-04-03
  • 1970-01-01
  • 2020-09-28
  • 2018-01-25
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多