# Drawing BasicEntanglerLayer circuit

**URL:** https://discuss.pennylane.ai/t/drawing-basicentanglerlayer-circuit/1726
**Category:** PennyLane Help
**Created:** [March 15, 2022, 11:02am UTC](https://discuss.pennylane.ai/t/drawing-basicentanglerlayer-circuit/1726 "2022-03-15T11:02:58Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![Muhammad\_Kashif](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/muhammad_kashif/32/558_2.png) [@Muhammad\_Kashif](https://discuss.pennylane.ai/u/Muhammad_Kashif)
#### Post date: [March 15, 2022, 11:02am UTC](https://discuss.pennylane.ai/t/drawing-basicentanglerlayer-circuit/1726/1 "2022-03-15T11:02:58Z")

</div>

Hello,

I am unable to print/draw the circuit when using `BasicEntanglerLayer`.  
Can anyone help me with that. Below is a sample code;

```
import pennylane as qml

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

@qml.qnode(dev)
def qnode(inputs,weights):
    for i in range(n_qubits):
        qml.Hadamard(wires=i)
    qml.AngleEmbedding(inputs, wires=range(n_qubits))
    qml.BasicEntanglerLayers(weights, wires=range(n_qubits))
    return [qml.expval(qml.PauliZ(wires=i)) for i in range(n_qubits)]

n_layers = 6
weight_shapes = {"weights": (n_layers, n_qubits)}

X=[1,2]

qml.draw_mpl(qnode)(X,weight_shapes)

```

When we are able to draw the above circuit, is it possible to print the inner structure of `AngleEmbedding` instead of a block and same for `BasicEntanglerLayer`.

Thanks in advacne

---

<div class="post-metadata">

### Author: ![josh](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/josh/32/100_2.png) [@josh](https://discuss.pennylane.ai/u/josh)
#### Post date: [March 15, 2022, 12:14pm UTC](https://discuss.pennylane.ai/t/drawing-basicentanglerlayer-circuit/1726/2 "2022-03-15T12:14:29Z")

</div>

Hi @Muhammad_Kashif! This is because the drawer is not taking into account the device gate set when drawing the QNode. To force it to decompose gates to match the device, we must specify `expansion_strategy="device"`:

```python
import pennylane as qml

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

@qml.qnode(dev)
def qnode(inputs, weights):
 for i in range(n_qubits):
     qml.Hadamard(wires=i)
 qml.AngleEmbedding(inputs, wires=range(n_qubits))
 qml.BasicEntanglerLayers(weights, wires=range(n_qubits))
 return [qml.expval(qml.PauliZ(wires=i)) for i in range(n_qubits)]

n_layers = 6
weights = np.random.random([n_layers, n_qubits])
X = [1, 2]

```

```auto
>>> print(qml.draw(qnode, expansion_strategy="device")(X, weights))
0: ──H──RX(1.00)──RX(0.42)─╭C──RX(0.29)─╭C──RX(0.50)─╭C──RX(0.25)─╭C──RX(0.06)─╭C──RX(0.51)─╭C─┤ <Z>
1: ──H──RX(2.00)──RX(0.57)─╰X──RX(0.19)─╰X──RX(0.54)─╰X──RX(0.66)─╰X──RX(0.18)─╰X──RX(0.60)─╰X─┤ <Z>

```

---

<div class="post-metadata">

### Author: ![Muhammad\_Kashif](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/muhammad_kashif/32/558_2.png) [@Muhammad\_Kashif](https://discuss.pennylane.ai/u/Muhammad_Kashif)
#### Post date: [March 15, 2022, 1:11pm UTC](https://discuss.pennylane.ai/t/drawing-basicentanglerlayer-circuit/1726/3 "2022-03-15T13:11:47Z")

</div>

hi @josh,

Thank you for answering.  
May I please ask, why can’t we draw the circuit when we use weight\_shapes like `weight_shapes = {"weights": (n_layers, n_qubits)} `, taken from QNN tutorial [here](https://pennylane.ai/qml/demos/tutorial_qnn_module_tf.html)

In the above example (you rectified for drawing the circuit) `RX` (from `Angle Encoding`) encodes the input `X` and the parametrized gate of`BasicEntanglerLayer' takes the weight. In QNN (tutorial referenced above) context shouldnt parametrized gates after encoding takes the value of encoded data instead of weights? How can we draw the circuit in that case when we only tell the `weight\_shapes`?

Thanks

---

<div class="post-metadata">

### Author: ![CatalinaAlbornoz](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/catalinaalbornoz/32/1196_2.png) [@CatalinaAlbornoz](https://discuss.pennylane.ai/u/CatalinaAlbornoz)
#### Post date: [March 16, 2022, 1:20pm UTC](https://discuss.pennylane.ai/t/drawing-basicentanglerlayer-circuit/1726/4 "2022-03-16T13:20:06Z")

</div>

Hi @Muhammad_Kashif, good question.

Notice that in the example you’re referencing, `weight_shapes` is passed into a Keras layer, not directly into the `BasicEntanglerLayers`. If you check the [docs for BasicEntanglerLayers](https://pennylane.readthedocs.io/en/stable/code/api/pennylane.BasicEntanglerLayers.html) you will notice that the input for “weights” must be a tensor.

Let me know if this answers your question!

---

<div class="post-metadata">

### Author: ![Muhammad\_Kashif](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/muhammad_kashif/32/558_2.png) [@Muhammad\_Kashif](https://discuss.pennylane.ai/u/Muhammad_Kashif)
#### Post date: [March 17, 2022, 1:14pm UTC](https://discuss.pennylane.ai/t/drawing-basicentanglerlayer-circuit/1726/5 "2022-03-17T13:14:37Z")

</div>

Hi @CatalinaAlbornoz,

Thank you for the answer, however I am still a little confused like how the KerasLayer treats these weight\_shapes or what actually are the weights (to optimize in QNNs). I get that the `weight_shapes` tells the `KerasLayer` about the shape of weights like if `weight_shapes = (1,2)`, the `weight_shapes` will be 1 (parameter) for two `parametrized gates` (number of qubits).  
Now, for instance, in case of `AngleEmbedding` the input data is encoded into `RX, RY` or `RZ` rotations, clear so far. The next we have for instance `BasicEntanglerLayer` circuit containing rotations (`RX, RY` or `RZ`) and entanglements.  
The question is:

1. The rotations here in `BasicEntanglerLayer` circuit takes the values of weights which we can `print and see` if we pass actual values (of `weights`) instead of `weight_shapes` but we can not print the circuit and see the corresponding parameters of rotations in `BasicEntanglerLayer`, so we don’t know what `parameters` or `weights` would be passed after the `embedding` step.
2. 

Shouldn’t the `parametrized gates` after the `embedding` the should take the the `embedded features` as parameters instead of `weights`, I am not sure if this is happening in case of `weight_shapes` passed to `KerasLayer`.

Can you please guide with that.  
Thanks

---

<div class="post-metadata">

### Author: ![CatalinaAlbornoz](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/catalinaalbornoz/32/1196_2.png) [@CatalinaAlbornoz](https://discuss.pennylane.ai/u/CatalinaAlbornoz)
#### Post date: [March 17, 2022, 11:13pm UTC](https://discuss.pennylane.ai/t/drawing-basicentanglerlayer-circuit/1726/6 "2022-03-17T23:13:24Z")

</div>

Hi @Muhammad_Kashif, I’m not sure that I understand your question.

A few messages above, Josh showed that by using `expansion_strategy="device"` you can show the parameters of your BasicEntanglerLayers. These parameters are effectively one-parameter single-qubit rotations, where the rotation angle is given by a particular weight. Basically the weight, parameter and rotation angle are the same in this case.  
We can’t use `weight_shapes` because what we need is the actual parameters (the weights).

If you look closely at the [QNN demo](https://pennylane.ai/qml/demos/tutorial_qnn_module_tf.html) you will notice that the weight shapes are necessary to create the quantum layer, but what goes into the qnode are the weights themselves.

About your second question I sense there might be some confusion. When we refer to features we refer to your data, which is not trainable. This data is embedded into your quantum circuit using `AngleEmbedding`. You then need an ansatz with parametrized gates and in this case we use `BasicEntanglerLayers`. So basically `BasicEntanglerLayers` takes parameters in the form of weights, and it’s `AngleEmbedding` that actually embeds your features (your data) into the circuit.

I hope this is clear. Please let me know if this helps!

---

<div class="post-metadata">

### Author: ![Muhammad\_Kashif](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/muhammad_kashif/32/558_2.png) [@Muhammad\_Kashif](https://discuss.pennylane.ai/u/Muhammad_Kashif)
#### Post date: [March 18, 2022, 1:17pm UTC](https://discuss.pennylane.ai/t/drawing-basicentanglerlayer-circuit/1726/7 "2022-03-18T13:17:15Z")

</div>

Hi @CatalinaAlbornoz,

Thanks for the clarification. One last thing the `expansion_strategy ="device` does show the internal structure of `Template Layer` but as you rightly said, for that we need to pass the actual values of `weights` and not `weight_shapes`. Let me try and explain my confusion with an example;  
For instance, if I have 2 qubits and my `data points` =`[a,b]` and `weights` = `[c,d]`,. My QNode contains the `AngleEmbedding` layer which takes data points `[a,b]` and make them trainable for the following variational circuit, which lets say is `BasicEntanglerLayer` in this case. Now the parameters for `parametrized gates` in my variational circuit should be the embedded datapoints but instead they take the `weights ([c,d])`, as defined above, so how does data embedding play the role here or where does the embedded data go?  
I am assuming that, in QNN context we only tell the `weight_shapes` while converting `Qnode` to `KerasLayer` and not the actual weights because in this case the weights will actually be the embedded data points/features, am I right?

I hope I have made my question clear.  
Thanks

---

<div class="post-metadata">

### Author: ![CatalinaAlbornoz](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/catalinaalbornoz/32/1196_2.png) [@CatalinaAlbornoz](https://discuss.pennylane.ai/u/CatalinaAlbornoz)
#### Post date: [March 18, 2022, 9:50pm UTC](https://discuss.pennylane.ai/t/drawing-basicentanglerlayer-circuit/1726/8 "2022-03-18T21:50:54Z")

</div>

Hi @Muhammad_Kashif,

I believe there’s still some confusion as to what a data point is, what a weight is and how the embedding and templates work. I’ll revert to a basic example. Another very good explanation is detailed in this [blog post on how to start learning quantum machine learning](https://pennylane.ai/blog/2021/10/how-to-start-learning-quantum-machine-learning/) (I strongly encourage you to read the blog post.)

I want to predict the change in value of a house based on the distance to the city centre. I have this information for a few houses that are at X = 0, 1, 2, 3, 4, and 5 km from the city centre. Their respective change in value are Y = 0, 0.84, 0.91, 0.14, -0.76 and -0.96.

I want to use a quantum circuit to predict the change in value located at any distance from the city centre. What do I do?

I first create a qnode

```
@qml.qnode(dev)
def circuit(some inputs):
    #I'll add something here
    return something

```

What inputs will my circuit need? It will need the distance from the city centre, which is my datapoint. Notice that this data is fixed, I don’t train over it. I will also need some parameters that I can put into my circuit, and which I can modify after each iteration, hoping to get a better model for my data.

My return value will be an expectation value, which will give me a prediction for the change in value of a house at the particular distance specified by the input datapoint.

This is how the qnode will be looking:

```
@qml.qnode(dev)
 def circuit(distance, parameters):
        # something that takes the distance
        # something that takes some trainable parameters
        return qml.expval(qml.PauliZ(0))

```

Now how do we put a distance into a quantum circuit? We put the classical data points into the quantum circuit by using an embedding. In this case we can use the angle embedding to plug my data into my circuit. This will basically create a rotation for every one of my features. In this case I only have one feature which is distance. But I could have had other features such as area of the house, number of bedrooms, and others.

And where do the trainable parameters go? I can put them into my circuit as angles in rotation gates, where these angles can in fact change. I can also add other gates such as CNOTs and Hadamards to add more complexity to my circuit. I can use BasicEntanglerLayers to do this in an easy way. But what about the weights? My parameters are the weights!

So now we have

```
@qml.qnode(dev)
 def circuit(distance, parameters):
        qml.AngleEmbedding(distance, wires=range(n_qubits))
        qml.BasicEntanglerLayers(parameters, wires=range(n_qubits))
        return qml.expval(qml.PauliZ(0))

```

Now lets get some initial values for the distance and parameters and draw the circuit:

```
n_qubits = 2
dev = qml.device('lightning.qubit',wires=n_qubits)
@qml.qnode(dev)
def circuit(distance, parameters):
    qml.AngleEmbedding(distance, wires=range(n_qubits))
    qml.BasicEntanglerLayers(parameters, wires=range(n_qubits))
    return qml.expval(qml.PauliZ(0))

n_layers = 6
weights = np.random.random([n_layers, n_qubits])
X = [1.5]

qml.draw_mpl(circuit,expansion_strategy="device",decimals=1)(X,weights)

```

As you can see I have a 2-qubit circuit where the first RX rotation is the embedding or encoding of my data (the distance) and then I have 6 layers of parametrized rotations and CNOTs.

I encourage you to first try out variational circuits without using Keras and then you can try adding Keras Layers into the mix.

Please let me know if this explanation was helpful or if you have other questions.

---

<div class="post-metadata">

### Author: ![kevinkawchak](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/kevinkawchak/32/1801_2.png) [@kevinkawchak](https://discuss.pennylane.ai/u/kevinkawchak)
#### Post date: [December 10, 2023, 5:34pm UTC](https://discuss.pennylane.ai/t/drawing-basicentanglerlayer-circuit/1726/9 "2023-12-10T17:34:20Z")

</div>

Thank you. Please also note that qml.BasicEntanglerLayers documentation should state:

rotation (pennylane.ops.Operation) – one-parameter single-qubit gate to use, if None, qml.RX is used as default

instead of:

rotation (pennylane.ops.Operation) – one-parameter single-qubit gate to use, if None, RX is used as default
