# Making a one layer neural network

**URL:** <https://discuss.pennylane.ai/t/making-a-one-layer-neural-network/504>\
**Category:** PennyLane Help\
**Created:** [August 6, 2020, 10:40am UTC](https://discuss.pennylane.ai/t/making-a-one-layer-neural-network/504 "2020-08-06T10:40:06Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Shawn](https://avatars.discourse-cdn.com/v4/letter/s/f6c823/32.png) [@Shawn](https://discuss.pennylane.ai/u/Shawn)\
**Post date:** [August 6, 2020, 10:40am UTC](https://discuss.pennylane.ai/t/making-a-one-layer-neural-network/504/1 "2020-08-06T10:40:06Z")

</div>

Hey everyone,

I am using the CVNN at the moment and I would like to simplify it and just use a one layer neural network:

```
out_dim = 4
wires = 1
n_quantum_layers = 2

dev = qml.device("strawberryfields.fock", wires=wires, cutoff_dim=30)

@qml.qnode(dev)
def layer(inputs, w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10):
    qml.templates.DisplacementEmbedding(inputs, wires=range(wires))
    qml.templates.CVNeuralNetLayers(w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, wires=range(wires))
    return [qml.expval(qml.X(wires=i)) for i in range(wires)]

weights = qml.init.cvqnn_layers_all(n_quantum_layers, wires)#, seed=0)
weight_shapes = {"w{}".format(i): w.shape for i, w in enumerate(weights)}
qlayer = qml.qnn.KerasLayer(layer, weight_shapes, output_dim=wires)
clayer_in = tf.keras.layers.Dense(wires)
clayer_out = tf.keras.layers.Dense(out_dim)
model = tf.keras.models.Sequential([clayer_in, qlayer, clayer_out])
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate = 0.00012), loss = 'mse')

```

And I would like to for example just use a simple displacement layer:

```
dev = qml.device("strawberryfields.fock", wires=wires, cutoff_dim=30)

@qml.qnode(dev)
def layer(inputs, x):
    qml.templates.DisplacementEmbedding(inputs, wires=range(wires))
    qml.Displacement(x, 0, wires=range(wires)
    return [qml.expval(qml.X(wires=i)) for i in range(wires)]

```

but am unsure what to put for the weights and the weight\_shapes for

```
qlayer = qml.qnn.KerasLayer(layer, weight_shapes, output_dim=wires)

```

Any insight is appreciated!

---

<div class="post-metadata">

**Author:** ![jmarrazola](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/jmarrazola/32/255_2.png) [@jmarrazola](https://discuss.pennylane.ai/u/jmarrazola)\
**Post date:** [August 6, 2020, 10:25pm UTC](https://discuss.pennylane.ai/t/making-a-one-layer-neural-network/504/2 "2020-08-06T22:25:20Z")

</div>

Hi Shawn,

As far as I understand, the variational parameters of your quantum circuit are the displacements, which you call `x` in the code. These are 1-dimensional parameters. Then you are applying a displacement for each wire. So if you have `n` wires, these parameters are just an array of dimension `n`.

I haven’t used the KerasLayer before, but reading the documentation, I believe in your case you should simply set `weight_shapes = {"x": wires}`.

Let me know if that works!

---

<div class="post-metadata">

**Author:** ![Shawn](https://avatars.discourse-cdn.com/v4/letter/s/f6c823/32.png) [@Shawn](https://discuss.pennylane.ai/u/Shawn)\
**Post date:** [August 7, 2020, 6:35pm UTC](https://discuss.pennylane.ai/t/making-a-one-layer-neural-network/504/3 "2020-08-07T18:35:57Z")

</div>

Thanks @jmarrazola it worked!

---

<div class="post-metadata">

**Author:** ![Shawn](https://avatars.discourse-cdn.com/v4/letter/s/f6c823/32.png) [@Shawn](https://discuss.pennylane.ai/u/Shawn)\
**Post date:** [August 8, 2020, 7:06am UTC](https://discuss.pennylane.ai/t/making-a-one-layer-neural-network/504/4 "2020-08-08T07:06:52Z")

</div>

Hi @jmarrazola one more question 🙂

I’m trying to get this to work:

```
def layer(inputs, w, x, y, z):
    qml.templates.DisplacementEmbedding(inputs, wires=range(wires))
    qml.Interferometer(np.array([w]), wires=range(wires))
    qml.Displacement(x, 0, wires=range(wires))
    qml.Rotation(y, wires=range(wires))
    qml.Kerr(z, wires=range(wires))
    return [qml.expval(qml.X(wires=i)) for i in range(wires)]
a = ["x","y","z","w"]
weight_shapes = {a[i]: wires for i in range(len(a))}

```

But I keep getting errors. Can anyone tell me what’s wrong with the layer or the `weight_shapes`?

---

<div class="post-metadata">

**Author:** ![Tom\_Bromley](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/tom_bromley/32/129_2.png) [@Tom\_Bromley](https://discuss.pennylane.ai/u/Tom_Bromley)\
**Post date:** [August 10, 2020, 11:51am UTC](https://discuss.pennylane.ai/t/making-a-one-layer-neural-network/504/5 "2020-08-10T11:51:26Z")

</div>

Hey @Shawn,

There are three things causing a problem here:

- Inside the circuit, you are using single mode gates on multiple wires (e.g., `Displacement`, `Rotation`, `Kerr`).

- You should use `qml.templates.Interferometer`, which applies the interferometer according to some trainable angles. The `qml.Interferometer` you were using requires an input unitary.

- The interferometer should be fed three variables and the shape of each should be declared in `weight_shapes`. Their shapes are not simply `wires`, you can find them [here](https://pennylane.readthedocs.io/en/stable/code/api/pennylane.templates.subroutines.Interferometer.html).

Your code should look something more like this:

```python
def layer(inputs, theta, phi, varphi, x, y, z):
    qml.templates.DisplacementEmbedding(inputs, wires=range(wires))
    qml.templates.Interferometer(theta, phi, varphi, wires=range(wires))
    for i in range(wires):
        qml.Displacement(x[i], 0, wires=i)
        qml.Rotation(y[i], wires=i)
        qml.Kerr(z[i], wires=i)
    return [qml.expval(qml.X(wires=i)) for i in range(wires)]

interferometer_shape = int(wires * (wires - 1) / 2)

weight_shapes = {
    "theta": interferometer_shape,
    "phi": interferometer_shape,
    "varphi": wires,
    "x": wires,
    "y": wires,
    "z": wires,
}

```

As a quick test, this makes a usable Keras layer:

```python
dev = qml.device("strawberryfields.fock", wires=wires, cutoff_dim=4)
qnode = qml.QNode(layer, dev)
qlayer = qml.qnn.KerasLayer(qnode, weight_shapes, wires)

import numpy as np
x = np.random.random((10, wires))
qlayer(x)

```

---

<div class="post-metadata">

**Author:** ![Shawn](https://avatars.discourse-cdn.com/v4/letter/s/f6c823/32.png) [@Shawn](https://discuss.pennylane.ai/u/Shawn)\
**Post date:** [August 10, 2020, 12:39pm UTC](https://discuss.pennylane.ai/t/making-a-one-layer-neural-network/504/6 "2020-08-10T12:39:16Z")

</div>

Hi @Tom_Bromley thanks a lot for the help. When running the code I am getting the following error:

```
WARNING:tensorflow:Layer keras_layer is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2. The layer has dtype float32 because it's dtype defaults to floatx.

If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.

To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.

Traceback (most recent call last):
  File "froz_versuch.py", line 40, in <module>
    qlayer(x)
ValueError: wrong shape of weight input(s) detected
```

---

<div class="post-metadata">

**Author:** ![Tom\_Bromley](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/tom_bromley/32/129_2.png) [@Tom\_Bromley](https://discuss.pennylane.ai/u/Tom_Bromley)\
**Post date:** [August 10, 2020, 12:51pm UTC](https://discuss.pennylane.ai/t/making-a-one-layer-neural-network/504/7 "2020-08-10T12:51:30Z")

</div>

Hey @Shawn, that’s odd.

Here is the full code that I managed to get working:

```python
import pennylane as qml

wires = 4

def layer(inputs, theta, phi, varphi, x, y, z):
    qml.templates.DisplacementEmbedding(inputs, wires=range(wires))
    qml.templates.Interferometer(theta, phi, varphi, wires=range(wires))
    for i in range(wires):
        qml.Displacement(x[i], 0, wires=i)
        qml.Rotation(y[i], wires=i)
        qml.Kerr(z[i], wires=i)
    return [qml.expval(qml.X(wires=i)) for i in range(wires)]

interferometer_shape = int(wires * (wires - 1) / 2)

weight_shapes = {
    "theta": interferometer_shape,
    "phi": interferometer_shape,
    "varphi": 4,
    "x": wires,
    "y": wires,
    "z": wires,
}

dev = qml.device("strawberryfields.fock", wires=wires, cutoff_dim=4)
qnode = qml.QNode(layer, dev)
qlayer = qml.qnn.KerasLayer(qnode, weight_shapes, wires)

import numpy as np
x = np.random.random((10, wires))
qlayer(x)

```

If you copy/paste that, are you still getting an error?

---

<div class="post-metadata">

**Author:** ![Shawn](https://avatars.discourse-cdn.com/v4/letter/s/f6c823/32.png) [@Shawn](https://discuss.pennylane.ai/u/Shawn)\
**Post date:** [August 10, 2020, 1:01pm UTC](https://discuss.pennylane.ai/t/making-a-one-layer-neural-network/504/8 "2020-08-10T13:01:44Z")

</div>

Hi @Tom_Bromley, it seems to only work when wires = 3,4,5,6,7 (8 and beyond I get a space error so I would assume it works also for 8 and onward). For wires = 1,2 the error occurs. Could it be that `interferometer_shape` needs to be bigger than 1?

---

<div class="post-metadata">

**Author:** ![Tom\_Bromley](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/tom_bromley/32/129_2.png) [@Tom\_Bromley](https://discuss.pennylane.ai/u/Tom_Bromley)\
**Post date:** [August 11, 2020, 12:31pm UTC](https://discuss.pennylane.ai/t/making-a-one-layer-neural-network/504/9 "2020-08-11T12:31:10Z")

</div>

Yes, the `MemoryError` for increasing wire number should be due to representing the `cutoff ** wires` dimensional state in the Fock basis.

For `wires=2`, try replacing this line:  
`qml.templates.Interferometer([theta], [phi], varphi, wires=range(wires))`  
This is needed because the `theta` and `phi` are one-dimensional for `wires=2` and end up getting internally flattened from an array to a float.

For `wires=1`, you could just swap out the interferometer with a `qml.Rotation()` gate.

---

<div class="post-metadata">

**Author:** ![Shawn](https://avatars.discourse-cdn.com/v4/letter/s/f6c823/32.png) [@Shawn](https://discuss.pennylane.ai/u/Shawn)\
**Post date:** [August 11, 2020, 1:06pm UTC](https://discuss.pennylane.ai/t/making-a-one-layer-neural-network/504/10 "2020-08-11T13:06:53Z")

</div>

Thank you @Tom_Bromley! Both of them are working.
