You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

复现SkimLit论文时Bidirectional层初始化及特征拼接报错求助

复现SkimLit论文时的模型构建错误与特征拼接问题

问题背景

正在复现SkimLit论文,尝试拼接token级、字符级嵌入以及行号、总行号特征时遇到错误,参考相关issue后问题仍未解决。

数据预处理代码

# 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'")

解决方案

1. 修复Bidirectional层初始化错误

报错核心是把LSTM层的输出张量传给了Bidirectional,而Bidirectional需要接收Layer实例,同时存在变量名拼写错误:char_embeddings应为char_embedding。修正后的字符分支代码:

# 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)
# 先实例化LSTM层传入Bidirectional,再调用处理输入张量
char_bi_lstm = layers.Bidirectional(layers.LSTM(24))(char_embedding)
char_model = tf.keras.Model(char_inputs, char_bi_lstm)

2. 修正变量名拼写与输入维度错误

  • 行号分支:line_numbers_inputs应为line_number_inputs,且输入维度需匹配one-hot后的20维,修改为shape=(20,)
  • 特征拼接:total_lines_model.ouput拼写错误,改为total_lines_model.output
  • 最终模型输入:total_line_model.input改为total_lines_model.input

3. 整合所有特征到数据集

当前数据集仅包含token和char数据,缺少行号、总行号特征,需整合后才能匹配模型输入:

# 训练集整合所有特征:(token, char, line_num, total_lines)
train_all_data = tf.data.Dataset.from_tensor_slices((train_sentences, train_chars, train_line_numbers_one_hot, train_total_lines_one_hot))
train_all_labels = tf.data.Dataset.from_tensor_slices(train_labels_one_hot)
train_dataset = tf.data.Dataset.zip((train_all_data, train_all_labels))
train_dataset = train_dataset.batch(32).prefetch(tf.data.AUTOTUNE)

# 验证集同理
val_all_data = tf.data.Dataset.from_tensor_slices((val_sentences, val_chars, val_line_numbers_one_hot, val_total_lines_one_hot))
val_all_labels = tf.data.Dataset.from_tensor_slices(val_labels_one_hot)
val_dataset = tf.data.Dataset.zip((val_all_data, val_all_labels))
val_dataset = val_dataset.batch(32).prefetch(tf.data.AUTOTUNE)

4. 完整修正后的模型代码

# 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_embedding)
char_model = tf.keras.Model(char_inputs, char_bi_lstm)

# 3. Line number feature
line_number_inputs = layers.Input(shape=(20,), dtype=tf.float32, name="line_number_inputs")
x = layers.Dense(32, activation="relu")(line_number_inputs)
line_number_model = tf.keras.Model(line_number_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.output,
                                                                              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=[token_model.input,
                                char_model.input,
                                line_number_model.input,
                                total_lines_model.input],
                        outputs=output_layer)

内容的提问来源于stack exchange,提问作者Frederic Strand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 00:32:01