请使用“tf.keras.layers.Layer”实例初始化“双向”层

Please initialize `Bidirectional` layer with a `tf.keras.layers.Layer` instance

提问人:Frederic Strand 提问时间:11/16/2023 更新时间:11/16/2023 访问量:20

问:

我正在尝试重新创建 SkimLit 论文 (https://arxiv.org/abs/1612.05251),但在尝试连接标记和字符级嵌入以及行号和总行号时遇到了麻烦。我见过其他人遇到这个问题,但他们的解决方案对我不起作用。下面是一个示例:https://github.com/keras-team/tf-keras/issues/556。如果有人能帮助一个迷失的灵魂,我将不胜感激。

这只是对数据进行热编码并预取数据,以便运行得更快。

# Combine chars and tokens into a dataset
train_token_char_data = tf.data.Dataset.from_tensor_slices((train_sentences, train_chars))
train_char_token_labels = tf.data.Dataset.from_tensor_slices(train_labels_one_hot)
train_char_token_dataset = tf.data.Dataset.zip((train_token_char_data, train_char_token_labels))

# Prefetch and batch train data

train_char_token_dataset = train_char_token_dataset.batch(32).prefetch(tf.data.AUTOTUNE)

# Combine chars and tokens into a dataset

val_token_char_data = tf.data.Dataset.from_tensor_slices((val_sentences, val_chars))
val_char_token_labels = tf.data.Dataset.from_tensor_slices(val_labels_one_hot)
val_char_token_dataset = tf.data.Dataset.zip((val_token_char_data, val_char_token_labels))

# Prefetch and batch train data

val_char_token_dataset = val_char_token_dataset.batch(32).prefetch(tf.data.AUTOTUNE)\`

# Use tensorflow to create one-hot-encoded tensors of our "line_number" column
train_line_numbers_one_hot = tf.one_hot(train_df["line_number"].to_numpy(), depth=20)
val_line_numbers_one_hot = tf.one_hot(val_df["line_number"].to_numpy(), depth=20)
test_line_numbers_one_hot = tf.one_hot(test_df["line_number"].to_numpy(), depth=20)
train_line_numbers_one_hot[:5], train_line_numbers_one_hot.shape

# Use tensorflow to create one-hot encoded tensors of our "total_lines" feature
train_total_lines_one_hot = tf.one_hot(train_df["total_lines"].to_numpy(), depth=20)
val_total_lines_one_hot = tf.one_hot(val_df["total_lines"].to_numpy(), depth=20)
test_total_lines_one_hot = tf.one_hot(test_df["total_lines"].to_numpy(), depth=20)
train_total_lines_one_hot[:2], train_total_lines_one_hot.shape`

现在对于实际模型:

# 1. Token inputs
token_inputs = layers.Input(shape=[], dtype=tf.string, name="token_inputs")
token_embeddings = tf_hub_embedding_layer(token_inputs)
token_outputs = layers.Dense(128, activation="relu")(token_embeddings)
token_model = tf.keras.Model(token_inputs,token_outputs)

# 2. Char inputs
char_inputs = layers.Input(shape=(1,), dtype=tf.string, name="char_inputs")
char_vectors = char_vectorizer(char_inputs)
char_embedding = char_embed(char_vectors)
char_bi_lstm = layers.Bidirectional(layers.LSTM(24)(char_embeddings))
char_model = tf.keras.Model(char_inputs, char_bi_lstm)

# 3. Line number feature
line_number_inputs = layers.Input(shape=[], dtype=tf.float32, name="line_number_inputs")
x = layers.Dense(32, activation="relu")(line_numbers_inputs)
line_number_model = tf.keras.Model(line_numbers_inputs, x)

# 4. Total line number feature
total_lines_inputs = layers.Input(shape=(20,), dtype=tf.float32, name="total_lines_inputs")
y = layers.Dense(32, activation="relu")(total_lines_inputs)
total_lines_model = tf.keras.Model(total_lines_inputs, y)

# 5. Combine token and char embeddings into a hybrid embedding
combined_embeddings = layers.Concatenate(name="char_token_hybrid_embedding")([token_model.output,
                                                                             char_model.output])

z = layers.Dense(256, activation="relu")(combined_embeddings)
z = layers.Dropout(0.5)(z)

# 6. Combine positional embedding with combined token and char embeddings
tribrid_embeddings = layers.Concatenate(name="char_token_tribrid_embedding")([line_number_model.output,
 total_lines_model.ouput,
 z])

# 7. Create output layer
output_layer = layers.Dense(5, activation="softmax", name="output_layer")(tribrid_embeddings)

# 8. Put together model with all kinds of inputs
model_5 = tf.keras.Model(inputs=[line_number_model.input,
                                total_line_model.input,
                                token_model.input,
                                char_model.input],
                        outputs=output_layer)

我收到此错误:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[123], line 11
      9 char_vectors = char_vectorizer(char_inputs)
     10 char_embedding = char_embed(char_vectors)
---> 11 char_bi_lstm = layers.Bidirectional(layers.LSTM(24)(char_embeddings))
     12 char_model = tf.keras.Model(char_inputs, char_bi_lstm)
     14 # 3. Line number feature

File ~/Desktop/skimLit/env/lib/python3.10/site-packages/keras/src/layers/rnn/bidirectional.py:118, in Bidirectional.__init__(self, layer, merge_mode, weights, backward_layer, **kwargs)
    109 def __init__(
    110     self,
    111     layer,
   (...)
    115     **kwargs,
    116 ):
    117     if not isinstance(layer, Layer):
--> 118         raise ValueError(
    119             "Please initialize `Bidirectional` layer with a "
    120             f"`tf.keras.layers.Layer` instance. Received: {layer}"
    121         )
    122     if backward_layer is not None and not isinstance(backward_layer, Layer):
    123         raise ValueError(
    124             "`backward_layer` need to be a `tf.keras.layers.Layer` "
    125             f"instance. Received: {backward_layer}"
    126         )

ValueError: Please initialize `Bidirectional` layer with a `tf.keras.layers.Layer` instance. Received: KerasTensor(type_spec=TensorSpec(shape=(None, 24), dtype=tf.float32, name=None), name='lstm_19/PartitionedCall:0', description="created by layer 'lstm_19'")
TensorFlow 机器学习 Keras

评论

0赞 Dr. Snoopy 11/16/2023
你不是在传递一个层,而是在传递一个层的输出,以某种方式混合了顺序和函数式 API,这是行不通的。
0赞 Frederic Strand 11/16/2023
我解决了这个问题。我在整个代码中有一些错别字,但主要问题出在这一行:line_number_inputs = 层。Input(shape=[], dtype=tf.float32, name=“line_number_inputs”) 这里的形状也应该是 shape=(1,)。

答: 暂无答案