# QNode inside Keras layer

**URL:** https://discuss.pennylane.ai/t/qnode-inside-keras-layer/335
**Category:** PennyLane Help
**Created:** [February 7, 2020, 4:57pm UTC](https://discuss.pennylane.ai/t/qnode-inside-keras-layer/335 "2020-02-07T16:57:17Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Matthias\_Rosenkranz](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/matthias_rosenkranz/32/151_2.png) [@Matthias\_Rosenkranz](https://discuss.pennylane.ai/u/Matthias_Rosenkranz)
#### Post date: [February 7, 2020, 4:57pm UTC](https://discuss.pennylane.ai/t/qnode-inside-keras-layer/335/1 "2020-02-07T16:57:17Z")

</div>

Hi,

I’ve recently started using pennylane. Thanks for the great tool!

I am trying (unsuccessfully) to build a custom Keras layer in TensorFlow 2 that includes a QNode. The goal is to use QNodes in a “standard” TensorFlow 2 workflow, i.e. define a Keras model, compile and fit. The Keras model should first process input data via a classical NN, then feed it into the parameters of a quantum circuit (all inside the model).

My first attempt failed due to `AttributeError: 'Tensor' object has no attribute 'numpy'`, which seems to be related to pennylane assuming eager mode but Keras assuming that layers can be both executed as a graph and in eager.

Then I tried using `dynamic=True` in the layer init to tell Keras that the layer only works with eager, but this fails with `NotImplementedError:` in Keras.

My attempts are on Colab:  
[https://colab.research.google.com/drive/1OFxeEG2RSXyoX56lnhL7h7Pj4MzYFDCC](https://colab.research.google.com/drive/1OFxeEG2RSXyoX56lnhL7h7Pj4MzYFDCC)

Would you mind having a look? I am not sure if I am doing something wrong or if my use case is just not supported.

Many thanks,  
Matthias

---

<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: [February 8, 2020, 2:36am UTC](https://discuss.pennylane.ai/t/qnode-inside-keras-layer/335/2 "2020-02-08T02:36:04Z")

</div>

Hi @Matthias_Rosenkranz! You’re right that PennyLane only currently works with TensorFlow eager (not autograph), so `dynamic=True` is currently required when using Keras.

I haven’t used PennyLane with Keras personally, however I can link you a few resources that have:

- [https://towardsdatascience.com/classifying-documents-with-quantum-enhanced-transfer-learning-8ee6d04f3ccd](https://towardsdatascience.com/classifying-documents-with-quantum-enhanced-transfer-learning-8ee6d04f3ccd)

- [https://github.com/rdisipio/qnlp](https://github.com/rdisipio/qnlp)

- One of our researchers, @Tom_Bromley, has also used Keras with PennyLane: [https://github.com/XanaduAI/qml/issues/28#issuecomment-574889614](https://github.com/XanaduAI/qml/issues/28#issuecomment-574889614)

On our [tutorials page](https://pennylane.ai/qml/implementations.html), we have quite a few tutorials using PyTorch and TensorFlow directly, but none using Keras so far, this would be a great addition if you wanted to add a demonstration once your code is working!

---

<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: [February 8, 2020, 2:43am UTC](https://discuss.pennylane.ai/t/qnode-inside-keras-layer/335/3 "2020-02-08T02:43:02Z")

</div>

Having a look at @Tom_Bromley’s code, I note that the error message in your colab notebook disappears if you add a `compute_output_shape` method:

```python
class QuantumLayer(tf.keras.layers.Layer):
 def __init__ (self, num_outputs, qnode, **kwargs):
   super(QuantumLayer, self). __init__ (**kwargs)
   self.num_outputs = num_outputs
   self.qnode = qnode

 def call(self, inputs):
   outputs = []
   for input in inputs:
     outputs.append(self.qnode(input))
   return tf.reshape(outputs, shape=(inputs.shape[0], self.num_outputs))

 def compute_output_shape(self, input_shape):
   return input_shape

```

I’m not too familiar with Keras, but perhaps this needs to always be defined if `dynamic=True`.

---

<div class="post-metadata">

### Author: ![Matthias\_Rosenkranz](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/matthias_rosenkranz/32/151_2.png) [@Matthias\_Rosenkranz](https://discuss.pennylane.ai/u/Matthias_Rosenkranz)
#### Post date: [February 10, 2020, 8:08am UTC](https://discuss.pennylane.ai/t/qnode-inside-keras-layer/335/4 "2020-02-10T08:08:03Z")

</div>

Thanks @josh! Defining `compute_output_shape` made it work.

---

<div class="post-metadata">

### Author: ![Matthias\_Rosenkranz](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/matthias_rosenkranz/32/151_2.png) [@Matthias\_Rosenkranz](https://discuss.pennylane.ai/u/Matthias_Rosenkranz)
#### Post date: [February 10, 2020, 11:59am UTC](https://discuss.pennylane.ai/t/qnode-inside-keras-layer/335/5 "2020-02-10T11:59:33Z")

</div>

For reference, here is a working Colab including the Keras-style training via `compile` and `fit`. It’s not a very useful model in itself as it just fits a classical NN to output a parameter for `R_y` that flips the initial |0\rangle state.

[https://colab.research.google.com/drive/1gKcSyiZ4pHuA1UEXhCz-C5YLhbn1Bho9](https://colab.research.google.com/drive/1gKcSyiZ4pHuA1UEXhCz-C5YLhbn1Bho9)

Btw, also works with the newly released pennylane 0.8 :).

---

<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: [May 19, 2020, 8:37pm UTC](https://discuss.pennylane.ai/t/qnode-inside-keras-layer/335/6 "2020-05-19T20:37:53Z")

</div>

Hi @Matthias_Rosenkranz,

We have now added a new [KerasLayer](https://pennylane.readthedocs.io/en/latest/code/api/pennylane.qnn.KerasLayer.html) feature to PennyLane that converts QNodes to a Keras Layer. This should make it easy to interface more with other elements of Keras.

You can access this feature by installing the latest version of PennyLane:

```python
pip install pennylane --upgrade

```
