python - 无法在多模式 seq2seq 中计算输出 KerasTensor
问题描述
我正在尝试使用帖子的图像、标题和源 subreddit从 subreddit 帖子生成评论。
如果您不知道 subreddit 是什么,只需将其视为帖子的一个类别,例如猫、狗、汽车
我将 CNN 用于图像,一个简单的神经网络用于 subreddits,LSTM 用于标题,最后将 LSTM 用于评论生成。
我让它工作了,但推理部分很难编码,所以我重构了它,所以最终模型的每个组件都是一个小模型。但是,当我尝试将所有内容放在一起时,出现如下所示的错误。
我该如何解决它,问题的原因是什么?
错误
AssertionError Traceback (most recent call last)
/tmp/ipykernel_42/2610877267.py in <module>
5 inputs = encoder.inputs
6
----> 7 result = decoder(decoder_target, encoder(inputs))
/opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py in __call__(self, *args, **kwargs)
950 if _in_functional_construction_mode(self, inputs, args, kwargs, input_list):
951 return self._functional_construction_call(inputs, args, kwargs,
--> 952 input_list)
953
954 # Maintains info about the `Layer.call` stack.
/opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py in _functional_construction_call(self, inputs, args, kwargs, input_list)
1089 # Check input assumptions set after layer building, e.g. input shape.
1090 outputs = self._keras_tensor_symbolic_call(
-> 1091 inputs, input_masks, args, kwargs)
1092
1093 if outputs is None:
/opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py in _keras_tensor_symbolic_call(self, inputs, input_masks, args, kwargs)
820 return nest.map_structure(keras_tensor.KerasTensor, output_signature)
821 else:
--> 822 return self._infer_output_signature(inputs, args, kwargs, input_masks)
823
824 def _infer_output_signature(self, inputs, args, kwargs, input_masks):
/opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py in _infer_output_signature(self, inputs, args, kwargs, input_masks)
861 # TODO(kaftan): do we maybe_build here, or have we already done it?
862 self._maybe_build(inputs)
--> 863 outputs = call_fn(inputs, *args, **kwargs)
864
865 self._handle_activity_regularization(inputs, outputs)
/opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/engine/functional.py in call(self, inputs, training, mask)
423 """
424 return self._run_internal_graph(
--> 425 inputs, training=training, mask=mask)
426
427 def compute_output_shape(self, input_shape):
/opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/engine/functional.py in _run_internal_graph(self, inputs, training, mask)
567 for x in self.outputs:
568 x_id = str(id(x))
--> 569 assert x_id in tensor_dict, 'Could not compute output ' + str(x)
570 output_tensors.append(tensor_dict[x_id].pop())
571
AssertionError: Could not compute output KerasTensor(type_spec=TensorSpec(shape=(None, 80, 5000), dtype=tf.float32, name=None), name='dense_25/truediv:0', description="created by layer 'dense_25'")
标题编码器
获取嵌入它的帖子的标记化标题并返回 LSTM 的状态。
def build_title_embeddings():
encoder_inputs = Input(shape=(max_title_len), name='Post title')
encoder_emb = Embedding(vocab_size, title_embedding_size)(encoder_inputs)
encoder = LSTM(title_hidden_size, return_state=True)
_, state_h, state_c = encoder(encoder_emb)
return Model(inputs=encoder_inputs, outputs=[state_h, state_c], name="Title encoder")
美国有线电视新闻网
Cnn 在 imagenet 上预训练keras.applications.EfficientNetB3
def build_cnn():
cnn = EfficientNetB3(include_top=False, input_shape=(300,300,3), pooling="avg")
cnn.trainable = False
return Model(inputs=cnn.inputs, outputs=cnn.outputs, name="cnn")
子版块嵌入
将一个热编码向量作为输入。它的目的是减少输入的维度
def build_subreddit_embeddings():
input_subreddit = Input(shape=(num_subreddits), name='One hot encoded subreddit')
sub_emb = Dense(subreddit_embedding_size, activation='relu')(input_subreddit)
return Model(inputs=input_subreddit, outputs=sub_emb, name="Subreddit embedding")
最终编码器
获取上述所有内容并为解码器生成初始状态
def build_final_encoder():
cnn = build_cnn()
subreddit_embeddings = build_subreddit_embeddings()
title_embeddings = build_title_embeddings()
merged = Concatenate()([cnn.output, subreddit_embeddings.output, *title_embeddings.output])
intermediate_layer = Dense(intermediate_layer_size, activation='relu')(merged)
state1 = Dense(decoder_hidden_size, activation='relu')(intermediate_layer)
state2 = Dense(decoder_hidden_size, activation='relu')(intermediate_layer)
return Model(inputs=[cnn.inputs, subreddit_embeddings.inputs, title_embeddings.inputs], outputs=[state1,state2], name="post_encoder")
解码器
作为最终编码器的输入输出并生成评论标记。
解码器的输入是自己预测的先前标记
def build_decoder():
decoder_inputs = Input(shape=(max_decoder_len,), name="Decoder inputs")
state_inputs1 = Input(shape=(decoder_hidden_size,), name="Decoder state input 1")
state_inputs2 = Input(shape=(decoder_hidden_size,), name="Decoder state input 2")
decoder_emb = Embedding(vocab_size, decoder_embedding_size)(decoder_inputs)
decoder_lstm = LSTM(decoder_hidden_size, return_sequences=True, return_state=True, name="decoder_lstm")
decoder_outputs, _, _ = decoder_lstm(decoder_emb, initial_state=[state_inputs1, state_inputs2])
decoder_outputs = Dense(vocab_size, activation="softmax")(decoder_outputs)
return Model(inputs=[decoder_inputs, [state_inputs1,state_inputs2]], outputs=decoder_outputs, name="final_decoder")
尝试将所有东西放在一起
解码器目标是正确的令牌 id 在训练期间移动了一个,在推理期间是先前的预测
例如在训练期间
解码器目标 -['<start_of_sentence_token>','I','like','pizza']
正确答案 -['I','like','pizza','<end_of_sentence_token>']
decoder_target = Input(shape=(max_decoder_len,), name="Decoder target")
encoder = build_final_encoder()
decoder = build_decoder()
inputs = encoder.inputs
result = decoder(decoder_target, encoder(inputs)) # Errors happen here
解决方案
推荐阅读
- graphics - 更快地绘制具有比例和 alpha 通道的 tbitmap
- javascript - javascript俄罗斯方块中的重启功能
- java - 如何在Java应用程序中的方法期间禁止按键?
- postgresql - PostgreSQL 逻辑复制 - 创建订阅挂起
- .net - 如何从 DB (Oracle) 正确刷新 DataTable
- r - 更改 R 雷达图中的标签颜色
- javascript - 在 Leaflet 中悬停地图时获取图层信息
- google-analytics - 如何在报告数据中包含未设置或空指标?
- excel - 类型不匹配错误将 10 秒添加到前一个单元格的值
- sql-server - 没有浏览器的 SQL Server 配置 32 位和 64 位客户端 TCP/IP 配置