QNN circuit draw and specs

weight_shapes = {"weights": (num_layers,n_qubits,3)}

# Model

input_m = tf.keras.layers.Input(shape=(2 ** n_qubits,), name = "input_0")

print(input_m)

keras_1 = qml.qnn.KerasLayer(circuit, weight_shapes, output_dim=n_qubits, name = "keras_1")(input_m)

print(keras_1)

output = tf.keras.layers.Dense(num_classes_q, activation='softmax', name = "dense_1")(keras_1)

I have a circuit defined here, and I am creating a qnn model here. Is there a way to print the circuit and the specs? qml.draw() needs arguments weights, but using keras that’s predefined.

@ CatalinaAlbornoz

Hi @VQX,

If you want to draw the quantum circuit you can use qml.draw() or qml.draw_mpl() with a random set of weights.

You could use something like numpy.random.random with size=weight_shapes to generate the weights for drawing. You can then use the weights defined by Keras for training.

Similarly for qml.specs().

Let me know if you run into any issues.

w = np.random.random(size=weight_shapes.get('weights'))

print(w)

qml.draw(circuit)(w)

Output:

[[[0.41919451 0.6852195 0.20445225]
[0.87811744 0.02738759 0.67046751]
[0.4173048 0.55868983 0.14038694]
[0.19810149 0.80074457 0.96826158]
[0.31342418 0.69232262 0.87638915]
[0.89460666 0.08504421 0.03905478]]

[[0.16983042 0.8781425 0.09834683]
[0.42110763 0.95788953 0.53316528]
[0.69187711 0.31551563 0.68650093]
[0.83462567 0.01828828 0.75014431]
[0.98886109 0.74816565 0.28044399]
[0.78927933 0.10322601 0.44789353]]

[[0.9085955 0.29361415 0.28777534]
[0.13002857 0.01936696 0.67883553]
[0.21162812 0.26554666 0.49157316]
[0.05336255 0.57411761 0.14672857]
[0.58930554 0.69975836 0.10233443]
[0.41405599 0.69440016 0.41417927]]

[[0.04995346 0.53589641 0.66379465]
[0.51488911 0.94459476 0.58655504]
[0.90340192 0.1374747 0.13927635]
[0.80739129 0.39767684 0.1653542 ]
[0.92750858 0.34776586 0.7508121 ]
[0.72599799 0.88330609 0.62367221]]

[[0.75094243 0.34889834 0.26992789]
[0.89588622 0.42809119 0.96484005]
[0.6634415 0.62169572 0.11474597]
[0.94948926 0.44991213 0.57838961]
[0.4081368 0.23702698 0.90337952]
[0.57367949 0.00287033 0.61714491]]

[[0.3266449 0.5270581 0.8859421 ]
[0.35726976 0.90853515 0.62336012]
[0.01582124 0.92943723 0.69089692]
[0.99732285 0.17234051 0.13713575]
[0.93259546 0.69681816 0.06600017]
[0.75546305 0.75387619 0.92302454]]

[[0.71152476 0.12427096 0.01988013]
[0.02621099 0.02830649 0.24621107]
[0.86002795 0.53883106 0.55282198]
[0.84203089 0.12417332 0.27918368]
[0.58575927 0.96959575 0.56103022]
[0.01864729 0.80063267 0.23297427]]

[[0.8071052 0.38786064 0.86354185]
[0.74712164 0.55624023 0.13645523]
[0.05991769 0.12134346 0.04455188]
[0.10749413 0.22570934 0.71298898]
[0.55971698 0.01255598 0.07197428]
[0.96727633 0.56810046 0.20329323]]]

ValueError Traceback (most recent call last)
in
3 print(w)
4 # print(qml.specs(circuit))
----> 5 qml.draw(circuit)(w)
6
7 # print(model.get_layer(“keras_1”).get_weights()[0])

4 frames
/usr/local/lib/python3.8/dist-packages/pennylane/templates/state_preparations/mottonen.py in init(self, state_vector, wires, do_queue, id)
300
301 if len(shape) != 1:
→ 302 raise ValueError(
303 f"State vectors must be one-dimensional; vector {i} has shape {shape}."
304 )

ValueError: State vectors must be one-dimensional; vector 0 has shape ().

This is the circuit


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

@qml.qnode(dev, diff_method='adjoint')
def circuit(weights, inputs=None):
  ''' Quantum QVC Circuit'''

  
   


  # print(weights)

  weights_each_layer = tf.split(weights, num_or_size_splits=num_layers, axis=0)
  


 
  inputs_1 = inputs / np.sqrt(max(np.sum(inputs ** 2, axis=-1), 0.001))
  

  for i, W in enumerate(weights):
  
    if i % 2 == 0:
      MottonenStatePreparation(inputs_1, wires = range(n_qubits))
    
 
    StronglyEntanglingLayers(weights_each_layer[i], wires=range(n_qubits))
  


  return [qml.expval(qml.PauliZ(i)) for i in range(n_qubits)] 

Hi @VQX, I think the issue is that you weren’t specifying the “inputs” argument to your circuit.
I couldn’t replicate your error exactly but I could create a version of the code that works.

import pennylane as qml
import numpy as np
import tensorflow as tf

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

@qml.qnode(dev, diff_method='adjoint')
def circuit(weights, inputs=None):
    ''' Quantum QVC Circuit'''
    # print(weights)
    weights_each_layer = tf.split(weights, num_or_size_splits=num_layers, axis=0)
    for i, W in enumerate(weights):
        if i % 2 == 0:
            qml.MottonenStatePreparation(inputs, wires = range(n_qubits))
            qml.StronglyEntanglingLayers(weights_each_layer[i], wires=range(n_qubits))
    return [qml.expval(qml.PauliZ(i)) for i in range(n_qubits)] 

weight_shapes = {"weights": (num_layers,n_qubits,3)}
w = np.random.random(size=weight_shapes.get('weights'))
state = np.array([1, 2j, 3, 4j, 5, 6j, 7, 8j])
state = state / np.linalg.norm(state)

print(w)

print(qml.draw(circuit)(w,state))
fig,ax = qml.draw_mpl(circuit)(w,state)
fig.show()
1 Like