我想在我的tensorflow 图执行模型中使用预先训练好的句子嵌入。这些嵌入可以通过函数调用动态获得,该函数接收一个句子数组并输出一个句子嵌入数组。该函数使用预先训练好的pytorch模型,因此必须与我正在训练的tensorflow 模型保持分离:
def get_pretrained_embeddings(sentences):
return pretrained_pytorch_model.encode(sentences)
我的tensorflow 模型如下所示:
class SentenceModel(tf.keras.Model):
def __init__(self):
super().__init__()
def call(self, sentences):
embedding_layer = tf.keras.layers.Embedding(
10_000,
256,
embeddings_initializer=tf.keras.initializers.Constant(get_pretrained_embeddings(sentences)),
trainable=False,
)
sentence_text_embedding = tf.keras.Sequential([
embedding_layer,
tf.keras.layers.GlobalAveragePooling1D(),
])
return sentence_text_embedding,
但是当我尝试用
cached_train = train.shuffle(100_000).batch(1024)
model.fit(cached_train)
我的embeddings_initializer调用得到错误:
OperatorNotAllowedInGraphError: iterating over `tf.Tensor` is not allowed: AutoGraph did convert this function. This might indicate you are trying to use an unsupported feature.
我认为这是因为tensorflow试图使用符号数据编译图形。我如何才能让依赖于当前训练数据批的外部函数使用tensorflow的图形训练?
1条答案
按热度按时间u1ehiz5o1#
Tensorflow会在执行实际训练过程之前将模型编译为执行图。一个明显的副作用是,如果我们在
call()
方法中有一个常规的Pythonprint()
语句,它只会执行一次,因为Tensorflow会在您的代码中运行以构建执行图,然后将其转换为本机代码。这样做的另一个副作用是,在训练时不能使用任何非某种描述的Tensor。这里的“Tensor”,可以将以下所有内容视为Tensor:
call()
方法的输入值(很明显)tf.Sequential
tf.keras.Model
/tf.keras.layers.Layer
子类SparseTensor
tf.constant()
为此,您需要将PyTorch模型转换为Tensorflow模型,以便能够在
tf.keras.Model
/tf.keras.layers.Layer
的子类中引用它。顺便说一句,如果你 * 确实 * 发现需要迭代一个Tensor,你应该只能够在第一维(即批量大小)上迭代它,如下所示:
如果你想在其他维度上迭代,我建议你先执行
tf.unstack(some_tensor, axis=AXIS_NUMBER_HERE)
,然后在结果上迭代。