How can I use density as output and build my QNN model

Hello! If applicable, put your complete code example down below. Make sure that your code:

  • is 100% self-contained — someone can copy-paste exactly what is here and run it to
    reproduce the behaviour you are observing
  • includes comments
@qml.qnode(dev, diff_method="backprop")
def circuit(weights, gammas, x):
    global num_qubits
    FRQI(x, num_qubits, gammas)

    for W in weights:
        layer(W)

    density = qml.density_matrix(wires=[0,1])

    return density

If you want help with diagnosing an error, please put the full error message below:

TypeError: Grad only applies to real scalar-output functions. Try jacobian, elementwise_grad or holomorphic_grad.

And, finally, make sure to include the versions of your packages. Specifically, show us the output of qml.about().

Hey @Pride-Huang! Welcome to the forum :rocket:!

Since I don’t have access to your layer and FRQI quantum functions, here’s a minimal example that reproduces the error you get:

import pennylane as qml
from pennylane import numpy as np

dev = qml.device("default.qubit", wires=2)

@qml.qnode(dev, diff_method="backprop")
def circuit(x):
    qml.RX(x, 0)
    qml.Hadamard(0)

    return qml.density_matrix(wires=[0, 1])

x = np.array(0.1, requires_grad=True)
qml.grad(circuit)(x)

'''
TypeError: Grad only applies to real scalar-output functions. Try jacobian, elementwise_grad or holomorphic_grad.
'''

As the error suggests, the grad function only applies to QNodes that return a scalar (e.g., qml.expval(qml.PauliZ(0))). Here, you’re returning tensor. To differentiate this circuit, you can use jacobian, noting that we only support differentiation of states when they’re separated into their real and imaginary parts:

dev = qml.device("default.qubit", wires=2)

@qml.qnode(dev)
def circuit(x):
    qml.RX(x, 0)
    qml.Hadamard(1)
    return qml.density_matrix(wires=[0, 1])

def realcircuit(x):
    return qml.math.real(circuit(x))

x = np.array(0.1, requires_grad=True)
print(qml.jacobian(realcircuit)(x))

def complexcircuit(x):
    return qml.math.imag(circuit(x))

print(qml.jacobian(complexcircuit)(x))

Hope this helps!

Thanks for your reply. I have know how to compute the Jacobian matrix now. However, how can.I.use it to update my parameters. Are there any optimizer? I will appreciate for your reply.

No optimizers come to mind that do that :thinking:… The Jacobian is a tensor object — an update rule that directly uses a Jacobian isn’t entirely obvious to me. Do you have a specific application in mind? Maybe a gradient-based method is best here?