Hey @Double_Fan! I can’t seem to reproduce your error. Here is the code that I’m running and the outputs:
import pennylane as qml
import tensorflow as tf
from pennylane import numpy as np
print(qml.__version__) # 0.24.0 for me
print(tf.__version__) # 2.9.1 for me
dev = qml.device("default.mixed", wires=1)
@qml.qnode(dev, interface="tf")
def qcircuit(params, x):
qml.Rot(0, x[0], 0, wires=0)
qml.Rot(params[0],params[1],params[2], wires=0)
return qml.expval(qml.PauliZ(0))
class Circuit(tf.keras.layers.Layer):
def __init__(self):
super(Circuit, self).__init__()
theta_init = tf.random_uniform_initializer(minval=0.0, maxval=np.pi)
self.params = tf.Variable(initial_value=theta_init(shape=(3,), dtype="float32"), trainable=True, name="thetas")
def call(self, inputs):
preds = []
for i in range(inputs.shape[0]):
pred = qcircuit(self.params, inputs[i])
preds.append([pred])
return tf.convert_to_tensor(preds, dtype=tf.float32)
class Circuit(tf.keras.layers.Layer):
def __init__(self):
super(Circuit, self).__init__()
theta_init = tf.random_uniform_initializer(minval=0.0, maxval=np.pi)
self.params = tf.Variable(initial_value=theta_init(shape=(3,), dtype="float32"), trainable=True, name="thetas")
def call(self, inputs):
preds = []
for i in range(inputs.shape[0]):
pred = qcircuit(self.params, inputs[i])
preds.append([pred])
return tf.convert_to_tensor(preds, dtype=tf.float32)
class Model():
def __init__(self, n_layers=20, **kwargs):
super().__init__(**kwargs)
self.circuit = Circuit()
self.train_op = tf.keras.optimizers.Adam(learning_rate=0.001)
self.x_extra = tf.Variable(x_extra, trainable = False)
def run(self, X):
return self.circuit(X)
def get_loss(self, X, Y):
predicts = self.run(X)
loss1 = tf.math.reduce_mean(tf.math.square(predicts-Y))
with tf.GradientTape(persistent=True) as tape:
tape.watch(self.x_extra)
y_extra = self.run(self.x_extra)
dx = tape.gradient(y_extra, self.x_extra)
dx2 = tape.gradient(dx, self.x_extra)
print(dx2)
return loss1
def get_grad(self,X,Y):
with tf.GradientTape(persistent=True) as tape:
tape.watch(self.circuit.variables)
L = self.get_loss(X,Y)
g = tape.gradient(L, self.circuit.variables)
return g
def network_learn(self,X,Y):
g = self.get_grad(X,Y)
print(g)
self.train_op.apply_gradients(zip(g, self.circuit.variables))
x = np.array([[0.5]])
y = np.array([[0.5]])
x_extra = np.array([[0.5]])
model= Model()
model.network_learn(x,y)
"""
Outputs:
From print(dx2):
tf.Tensor([[-0.88553823]], shape=(1, 1), dtype=float64)
From print(g):
[<tf.Tensor: shape=(3,), dtype=float32, numpy=array([ 5.7883937e-02, -1.7684884e-02, 3.4694470e-18], dtype=float32)>] # print(g)
"""