keras 在tensorflow 图执行期间访问训练数据

hof1towb  于 2022-11-30  发布在  其他
关注(0)|答案(1)|浏览(153)

我想在我的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的图形训练?

u1ehiz5o

u1ehiz5o1#

Tensorflow会在执行实际训练过程之前将模型编译为执行图。一个明显的副作用是,如果我们在call()方法中有一个常规的Python print()语句,它只会执行一次,因为Tensorflow会在您的代码中运行以构建执行图,然后将其转换为本机代码。
这样做的另一个副作用是,在训练时不能使用任何非某种描述的Tensor。这里的“Tensor”,可以将以下所有内容视为Tensor:

  • call()方法的输入值(很明显)
  • 一个tf.Sequential
  • 一个tf.keras.Model/tf.keras.layers.Layer子类
  • A × SparseTensor
  • 一个tf.constant()
  • ....可能还有更多我没有在这里列出的。

为此,您需要将PyTorch模型转换为Tensorflow模型,以便能够在tf.keras.Model/tf.keras.layers.Layer的子类中引用它。
顺便说一句,如果你 * 确实 * 发现需要迭代一个Tensor,你应该只能够在第一维(即批量大小)上迭代它,如下所示:

for part in some_tensor:
    pass

如果你想在其他维度上迭代,我建议你先执行tf.unstack(some_tensor, axis=AXIS_NUMBER_HERE),然后在结果上迭代。

相关问题