Python 在tf.function中创建具有不同形状的变量

Python 在tf.function中创建具有不同形状的变量,python,tensorflow,Python,Tensorflow,我试图训练一个网络,在这个网络中,从一个时代到另一个时代,我的可训练变量的形状将发生变化。我的训练步骤是这样的 @tf.function def训练步骤(输入:tf.张量, 标签:tf.张量, 可培训内容:列表[tf.张量], 优化器:tf.optimizers.optimizer, 损失:可赎回, 激活:可调用): def f(x,可培训人员): #算算 返回结果 使用tf.GradientTape()作为磁带: 磁带、手表(样品) yhat=激活(tf.矢量化映射(lambda vec:f(

我试图训练一个网络,在这个网络中,从一个时代到另一个时代,我的可训练变量的形状将发生变化。我的训练步骤是这样的

@tf.function
def训练步骤(输入:tf.张量,
标签:tf.张量,
可培训内容:列表[tf.张量],
优化器:tf.optimizers.optimizer,
损失:可赎回,
激活:可调用):
def f(x,可培训人员):
#算算
返回结果
使用tf.GradientTape()作为磁带:
磁带、手表(样品)
yhat=激活(tf.矢量化映射(lambda vec:f(vec,可培训对象),输入))
损耗=损耗(标签,yhat)
梯度=磁带梯度(损失,可培训)
优化器。应用_梯度(zip(梯度,可训练))
退货损失,可培训人员
当我第一次运行它时,没有问题,所以第一个历元运行得很好,但是在第二个历元开始时,我想应用一些张量分解,它可以改变可训练变量的形状。因此,在第二个历元中,我得到了如下预期的错误

ValueError: tf.function-decorated function tried to create variables on non-first call.
这是由这一行生成的:
optimizer.apply_梯度(zip(梯度,可培训内容))
。其中说
tf.function
decorator不允许以不同的形状运行,这是出于效率原因可以理解的。但有没有办法在必要时强制它工作或重新编译

其中的PS表示存在类似的bug问题,但我不认为我的问题与bug有关,因为我没有使用常规的
模型
模块,而是简单地创建一个包含张量的
tf.Variable
列表,然后我将其插入这个
培训步骤

谢谢

  • Python 3.6
  • Tensorflow 2.4.1
  • 操作系统:macOS Big Sur v11.1(也在Debian中试用过,同一版本)

最简单的方法可能是将
tf.function
用作函数,而不是装饰器。例如

def train_step():
    ...


some_variables = ...
train_step_compiled = tf.function(train_step)
train_step_compiled(some_variables, other_stuff)

some_variables = stuff_that_modifies_variable_shapes(some_variables)

train_step_compiled = tf.function(train_step)
train_step_compiled(some_variables, other_stuff)
我希望这种“口语化”的伪代码能够让人明白这一点——基本上,只要需要,您就可以显式地调用
tf.function
,例如,在更改变量之后,这样就可以用修改过的形状重新编译它。对函数调用
tf.function
,并使用返回的函数与将其用作装饰器是一样的