I'm trying to train a network where from one epoch to another the shapes of my trainable variables will change. So my training step looks like this
@tf.function
def training_step(inputs: tf.Tensor,
labels: tf.Tensor,
trainables: List[tf.Tensor],
optimizer: tf.optimizers.Optimizer,
loss: Callable,
activation: Callable):
def f(x, trainables):
# do some calculation
return result
with tf.GradientTape() as tape:
tape.watch(samples)
yhat = activation(tf.vectorized_map(lambda vec: f(vec, trainables), inputs))
loss = loss(labels,yhat)
gradients = tape.gradient(loss, trainables)
optimizer.apply_gradients(zip(gradients, trainables))
return loss, trainables
When I run this for the first time, there is no problem so the first epoch runs nicely but at the beginning of the second epoch, I would like to apply some tensor decomposition which can change the shape of the trainable variables. Hence in the second epoch, I get the following error as expected
ValueError: tf.function-decorated function tried to create variables on non-first call.
which is generated by this line: optimizer.apply_gradients(zip(gradients, trainables)). In this discussion it says that tf.function decorator doesn't allow running with different shapes which is understandable for efficiency reasons. But is there a way to force it to work or recompile when necessary?
PS in this link it says there is a similar bug issue but I don't think my problem is related to a bug since I'm not using regular Model module, instead, I'm simply creating a list of tf.Variable which has the tensors and then I plug it in this training_step.
Thanks
- Python 3.6
- Tensorflow 2.4.1
- OS: macOS Big Sur v11.1 (also tried in Debian, same issue)