Tensorflow Keras 多输入模型
Posted
技术标签:
【中文标题】Tensorflow Keras 多输入模型【英文标题】:Tensorflow Keras multiple input model 【发布时间】:2021-12-26 01:00:20 【问题描述】:我需要将此模型调整为两列文本输入(而不是一列)
tfhub_handle_encoder = \
"https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-512_A-8/1"
tfhub_handle_preprocess = \
"https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3"
def build_classifier_model():
text_input = tf.keras.layers.Input(
shape=(), dtype=tf.string, name='text')
preprocessing_layer = hub.KerasLayer(
tfhub_handle_preprocess, name='preprocessing')
encoder_inputs = preprocessing_layer(text_input)
encoder = hub.KerasLayer(
tfhub_handle_encoder, trainable=True, name='BERT_encoder')
outputs = encoder(encoder_inputs)
net = outputs['pooled_output']
net = tf.keras.layers.Dropout(0.1)(net)
net = tf.keras.layers.Dense(
6, activation='softmax', name='classifier')(net)
model = tf.keras.Model(text_input, net)
loss = tf.keras.losses.CategoricalCrossentropy(from_logits=False) # (from_logits=True)
metric = tf.metrics.CategoricalAccuracy('accuracy')
optimizer = Adam(
learning_rate=5e-05, epsilon=1e-08, decay=0.01, clipnorm=1.0)
model.compile(
optimizer=optimizer, loss=loss, metrics=metric)
model.summary()
return model
history = classifier_model.fit(
x=X_train['f'].values,
y=y_train_c,
validation_data=(X_valid['f'].values, y_valid_c),
epochs=15)
似乎这是教程中的模型:https://www.tensorflow.org/text/tutorials/classify_text_with_bert
我尝试修改两个输入层的代码,但由于连接后张量维度错误而出错:
def build_classifier_model():
input1 = tf.keras.layers.Input(
shape=(), dtype=tf.string, name='text')
input2 = tf.keras.layers.Input(
shape=(), dtype=tf.string, name='text1')
text_input = tf.keras.layers.concatenate([input1, input2], axis=-1)
preprocessing_layer = hub.KerasLayer(
tfhub_handle_preprocess, name='preprocessing')
encoder_inputs = preprocessing_layer(text_input)
encoder = hub.KerasLayer(
tfhub_handle_encoder, trainable=True, name='BERT_encoder')
outputs = encoder(encoder_inputs)
net = outputs['pooled_output']
net = tf.keras.layers.Dropout(0.1)(net)
net = tf.keras.layers.Dense(
6, activation='softmax', name='classifier')(net)
model = tf.keras.Model([input1, input2], net)
loss = tf.keras.losses.CategoricalCrossentropy(from_logits=False) # (from_logits=True)
metric = tf.metrics.CategoricalAccuracy('accuracy')
optimizer = Adam(
learning_rate=5e-05, epsilon=1e-08, decay=0.01, clipnorm=1.0)
model.compile(
optimizer=optimizer, loss=loss, metrics=metric)
model.summary()
return model
错误:
InvalidArgumentError: logits and labels must be broadcastable: logits_size=[64,6] labels_size=[32,6]
[[node categorical_crossentropy/softmax_cross_entropy_with_logits (defined at tmp/ipykernel_39/1837193519.py:5) ]] [Op:__inference_train_function_271676]
如果使用与另一个维度连接,则模型不会编译
【问题讨论】:
警告消息表明标签问题而不是输入端问题。你检查过吗? 但是只有一个输入层,一切都很好。错误,因为我连接了两个输入层 这似乎是两个输入 (32 + 32) 样本的批量大小和一个输入的标签 - 32 个样本。您可以通过 colab 链接分享可重现的代码吗? 我做了colab notebook colab.research.google.com/drive/… 【参考方案1】:奇怪的是,在你的模型中用tf.strings.join
替换你的Concatenation
层似乎有效:
def build_classifier_model():
input1 = tf.keras.layers.Input(
shape=(), dtype=tf.string, name='text')
input2 = tf.keras.layers.Input(
shape=(), dtype=tf.string, name='text1')
text_input = tf.strings.join([input1, input2])
preprocessing_layer = hub.KerasLayer(
tfhub_handle_preprocess, name='preprocessing')
encoder_inputs = preprocessing_layer(text_input)
encoder = hub.KerasLayer(
tfhub_handle_encoder, trainable=True, name='BERT_encoder')
outputs = encoder(encoder_inputs)
net = outputs['pooled_output']
net = tf.keras.layers.Dropout(0.1)(net)
output = tf.keras.layers.Dense(
6, activation='softmax', name='classifier')(net)
model = tf.keras.Model([input1, input2], output)
loss = tf.keras.losses.CategoricalCrossentropy(from_logits=False) # (from_logits=True)
metric = tf.metrics.CategoricalAccuracy('accuracy')
optimizer = Adam(
learning_rate=5e-05, epsilon=1e-08, decay=0.01, clipnorm=1.0)
model.compile(
optimizer=optimizer, loss=loss, metrics=metric)
model.summary()
return model
Epoch 1/5
497/1094 [============>.................] - ETA: 2:14 - loss: 1.8664 - accuracy: 0.1641
您也可以考虑简单地做text_input = input1 + input2
,因为Concatenation
层似乎搞乱了批处理维度。或者您可以将每个输入提供给您的encoder
,然后将结果连接起来:
def build_classifier_model():
input1 = tf.keras.layers.Input(
shape=(), dtype=tf.string, name='text')
input2 = tf.keras.layers.Input(
shape=(), dtype=tf.string, name='text1')
preprocessing_layer = hub.KerasLayer(
tfhub_handle_preprocess, name='preprocessing')
encoder_input1 = preprocessing_layer(input1)
encoder_input2 = preprocessing_layer(input2)
encoder = hub.KerasLayer(
tfhub_handle_encoder, trainable=True, name='BERT_encoder')
output1 = encoder(encoder_input1)
output2 = encoder(encoder_input2)
net = tf.keras.layers.Concatenate(axis=-1)([output1['pooled_output'], output2['pooled_output']])
net = tf.keras.layers.Dropout(0.1)(net)
output = tf.keras.layers.Dense(
6, activation='softmax', name='classifier')(net)
model = tf.keras.Model([input1, input2], output)
loss = tf.keras.losses.CategoricalCrossentropy(from_logits=False) # (from_logits=True)
metric = tf.metrics.CategoricalAccuracy('accuracy')
optimizer = Adam(
learning_rate=5e-05, epsilon=1e-08, decay=0.01, clipnorm=1.0)
model.compile(
optimizer=optimizer, loss=loss, metrics=metric)
model.summary()
return model
【讨论】:
我尝试将两个带有文本的 pandas 列合并为一个,但模型准确率下降 嗯,很有趣,因为tf.strings.join
很简单地以元素方式连接字符串
这个型号应该没问题。因为我使用 catboost 模型,2 列得到 0.3,1 列得到 0.21。使用 keras bert 我有 0.27 一列和 0.21 两列。
谢谢,每个输入带有两个独立编码器的选项会更好
是的,我也这么认为。以上是关于Tensorflow Keras 多输入模型的主要内容,如果未能解决你的问题,请参考以下文章
具有推理功能的 TensorFlow + Keras 多 GPU 模型
Keras + Tensorflow 和 Python 中的多处理
在 Tensorflow 中加载文本分类模型时出现 ValueError
当我在 Tensorflow 上使用 Keras API 连接两个模型时,模型的输入张量必须来自 `tf.layers.Input`
(已解决)Tensorflow 联合 | tff.learning.from_keras_model() 具有具有 DenseFeature 层和多个输入的模型