[英]How to increase the rank (ndim) of input of BERT keras hub layer for learning-to-rank
我正在尝试使用 tensorflow 集线器上可用的预训练 BERT 来实现学习排序 model。 我正在使用 ListNet loss function 的变体,它要求每个训练实例都是与查询相关的几个排名文档的列表。 I need the model to be able to accept data in a shape (batch_size, list_size, sentence_length), where the model loops over the 'list_size' axis in each training instance, returns the ranks and passes them to the loss function. 在仅由密集层组成的简单 model 中,这很容易通过增加输入层的尺寸来完成。 例如:
from tensorflow.keras.layers import Dense, Input
from tensorflow.keras import Model
input = Input([6,10])
x = Dense(20,activation='relu')(input)
output = Dense(1, activation='sigmoid')(x)
model = Model(inputs=input, outputs=output)
...现在 model 将在计算损失和更新梯度之前对长度为 10 的向量执行 6 次前向传递。
我正在尝试对 BERT model 及其预处理层做同样的事情:
import tensorflow as tf
import tensorflow_hub as hub
import tensorflow_text as text
bert_preprocess_model = hub.KerasLayer('https://tfhub.dev/tensorflow/small_bert/bert_en_uncased_L-4_H-512_A-8/1')
bert_model = hub.KerasLayer('https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3')
text_input = tf.keras.layers.Input(shape=(), dtype=tf.string, name='text')
processed_input = bert_preprocess_model(text_input)
output = bert_model(processed_input)
model = tf.keras.Model(text_input, output)
但是,当我尝试将“text_input”的形状更改为(6)或以任何方式干预它时,它总是会导致相同类型的错误:
ValueError: Could not find matching function to call loaded from the SavedModel. Got:
Positional arguments (3 total):
* Tensor("inputs:0", shape=(None, 6), dtype=string)
* False
* None
Keyword arguments: {}
Expected these arguments to match one of the following 4 option(s):
Option 1:
Positional arguments (3 total):
* TensorSpec(shape=(None,), dtype=tf.string, name='sentences')
* False
* None
Keyword arguments: {}
....
As per https://www.tensorflow.org/hub/api_docs/python/hub/KerasLayer , it seems like you can configure the input shape of hub.KerasLayer via tf.keras.layers.InputSpec. 就我而言,我想它会是这样的:
bert_preprocess_model.input_spec = tf.keras.layers.InputSpec(ndim=2)
bert_model.input_spec = tf.keras.layers.InputSpec(ndim=2)
当我运行上面的代码时,属性确实发生了变化,但是在尝试构建 model 时,出现了同样的错误。
有没有什么方法可以轻松解决这个问题而无需创建自定义训练循环?
假设您有一批 B 个示例,每个示例恰好有 N 个文本字符串,这构成了一个形状为 [B, N] 的二维张量。 使用tf.reshape() ,您可以将其转换为形状为 [B*N] 的一维张量,通过 BERT(保留输入顺序)将其发送,然后将其重新整形为 [B,N]。 (还有tf.keras.layers.Reshape ,但这对您隐藏了批次维度。)
如果每次都不完全是 N 个文本字符串,则您必须在旁边做一些簿记(例如,将输入存储在tf.RaggedTensor中,在其.values
上运行 BERT,并构造一个具有相同.row_splits
的新 RaggedTensor结果。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.