Input argument in keras layer

hi,
If I’m going to use a quantum layer inside a classical NN, what should be the “input” argument?
I’m a bit confused about this since I know we should define inputs to avoid computing their gradients.

Thanks

Hi @kareem_essafty,

For a QNode to work with KerasLayer it must satisfy the conditions mentioned in the Usage Details part of the documentation page. Importantly, the QNode must have an argument called inputs which will be where data from preceding Keras layers or raw input data is passed to.

For example, a valid QNode would be:

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

@qml.qnode(dev)
def qnode(inputs, weights):
    qml.RX(inputs[0], wires=0)
    qml.RX(inputs[1], wires=1)
    qml.CNOT(wires=[0, 1])
    qml.Rot(*weights[0], wires=0)
    qml.Rot(*weights[1], wires=1)
    qml.CNOT(wires=[0, 1])
    return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))

This QNode can be converted to a Keras Layer that takes 2D data and outputs 2D data with trainable weights given by weights:

weight_shapes = {"weights": (2, 3)}
qlayer = qml.qnn.KerasLayer(qnode, weight_shapes, output_dim=2)

In this example, we have an inputs argument and within the QNode it is used to embed the input data into the quantum circuit. Now, in the signature of the QNode, inputs can either be: (1) a positional argument

def qnode(inputs, weights):

or, (2) it can be a keyword argument:

def qnode(weights, inputs=None):

This results in the following:

  1. If inputs is a positional argument, PennyLane will be able to differentiate the QNode with respect to inputs. This is crucial if there will be Keras Layers placed before the quantum one, since accessing the gradient with respect to those layers depends on the gradient from the QNode. For example, we would need inputs to be a positional argument if we have:
model = tf.keras.models.Sequential([clayer1, qlayer, clayer2])

since we want to also optimize the trainable weights in clayer1.

  1. If inputs is a keyword argument, PennyLane will not include inputs in the gradient calculation. This means that the quantum Keras Layer must be the first layer, so that inputs is the raw input data that we do not differentiate. For example, we could have inputs be a keyword argument with:
model = tf.keras.models.Sequential([qlayer, clayer])

since it is the first layer in the model.

In general, you can leave inputs as a positional argument. Setting it to be a keyword argument adds restrictions but might produce a minor speed improvement.

I hope this helps, you can also share your code and I can give specific feedback.

Thanks!
Tom

1 Like

Thanks a lot for your clarification :slight_smile: