# Pytorch interface for models

**URL:** <https://discuss.pennylane.ai/t/pytorch-interface-for-models/160>\
**Category:** PennyLane Help\
**Created:** [June 12, 2019, 2:58pm UTC](https://discuss.pennylane.ai/t/pytorch-interface-for-models/160 "2019-06-12T14:58:01Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![barthelemymp](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/barthelemymp/32/58_2.png) [@barthelemymp](https://discuss.pennylane.ai/u/barthelemymp)\
**Post date:** [June 12, 2019, 2:58pm UTC](https://discuss.pennylane.ai/t/pytorch-interface-for-models/160/1 "2019-06-12T14:58:01Z")

</div>

Hello

I’m trying to make a neural networks using the interface Pytorch Pennylane. To do so I have to build a complex pytorch which will have to to have some actions on the device.

I firstly just tried to recode the rotation tutorial but using a model and I end up with an error I can not understand.

```
import pennylane as qml
import torch
import torch.autograd
import torch.nn as nn
import torch.nn.functional as F

class test_Rot(nn.Module):
    def __init__ (self, n_wire):
        super(test_Rot, self). __init__ ()
        self.n_wire = n_wire
        self.phi = torch.tensor(0.011, requires_grad = True)
        self.theta = torch.tensor(0.012, requires_grad = True)
        
    def forward(self,):
        print(self.phi,self.theta)
        qml.RX(self.phi, wires=0)
        qml.RY(self.theta, wires=0)
        

dev1 = qml.device('default.qubit', wires=1)
testcl = test_Rot(dev1,1)

@qml.qnode(dev1, interface='torch')
def circuit(classifier):
    classifier()
    return qml.expval.PauliZ(0)

print('testcircuit')
print(circuit(testcl))

```

That’s where it stop, even if the rest of the code should be :

```
def cost(classifier):
    return(circuit() - 1)
        

opt = torch.optim.Adam([testcl.phi, testcl.theta], lr = 0.1) 

for i in range(400):
    print(i)
    opt.zero_grad()
    loss = cost(testcl)
    loss.backward()
    opt.step()

```

My error message is:

```
testcircuit
Traceback (most recent call last):
  File "tests.py", line 43, in <module>
    print(circuit(testcl))
  File "C:\Users\barthelemy\.conda\envs\penny\lib\site-packages\pennylane\interfaces\torch.py", line 390, in custom_apply
    return _TorchQNode.apply(keyword_values, *args)
  File "C:\Users\barthelemy\.conda\envs\penny\lib\site-packages\pennylane\interfaces\torch.py", line 307, in forward
    res = qnode(*ctx.args, **ctx.kwargs)
  File "C:\Users\barthelemy\.conda\envs\penny\lib\site-packages\pennylane\qnode.py", line 457, in __call__
    return self.evaluate(args, **kwargs) # args as one tuple
  File "C:\Users\barthelemy\.conda\envs\penny\lib\site-packages\autograd\tracer.py", line 48, in f_wrapped
    return f_raw(*args, **kwargs)
  File "C:\Users\barthelemy\.conda\envs\penny\lib\site-packages\pennylane\qnode.py", line 471, in evaluate
    self.construct(args, **kwargs)
  File "C:\Users\barthelemy\.conda\envs\penny\lib\site-packages\pennylane\qnode.py", line 274, in construct
    variables = unflatten(temp, args)
  File "C:\Users\barthelemy\.conda\envs\penny\lib\site-packages\pennylane\utils.py", line 99, in unflatten
    res, tail = _unflatten(np.asarray(flat), model)
  File "C:\Users\barthelemy\.conda\envs\penny\lib\site-packages\pennylane\utils.py", line 88, in _unflatten
    val, flat = _unflatten(flat, x)
  File "C:\Users\barthelemy\.conda\envs\penny\lib\site-packages\pennylane\utils.py", line 92, in _unflatten
    raise TypeError('Unsupported type in the model: {}'.format(type(model)))
TypeError: Unsupported type in the model: <class ' __main__.test_Rot'>

```

I have put a print at the entrance of the circuit function, the error comes before that.

I’m not sure to see what I did wrong.

Best regards

Barthélémy

---

<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:** [June 12, 2019, 3:56pm UTC](https://discuss.pennylane.ai/t/pytorch-interface-for-models/160/2 "2019-06-12T15:56:05Z")

</div>

Hi @barthelemymp. Great question!

One thing to keep in mind is that:

- a PyTorch `nn` module _can_ include quantum operations, **but** they must be contained within QNodes

- A QNode itself cannot contain anything other than quantum operations, so you cannot place a `nn` module inside a QNode.

I’ve rearranged your example to satisfy the above:

```python
import pennylane as qml
import torch
import torch.autograd
import torch.nn as nn
import torch.nn.functional as F

dev1 = qml.device('default.qubit', wires=1)

# define neural network

class NeuralNet(nn.Module):
    def __init__ (self, classifier, n_wire):
        super(NeuralNet, self). __init__ ()
        self.classifier = classifier
        self.n_wire = n_wire
        self.phi = torch.tensor(0.011, requires_grad = True)
        self.theta = torch.tensor(0.012, requires_grad = True)
        
    def forward(self):
        print(self.phi,self.theta)

        @qml.qnode(dev1, interface='torch')
        def circuit(*params):
            self.classifier(*params)
            return qml.expval.PauliZ(0)

        return circuit(self.phi, self.theta)

# define custom classifiers

def test_rot(phi, theta):
    qml.RX(phi, wires=0)
    qml.RY(theta, wires=0)

# perform the optimization

testcl = NeuralNet(test_rot, 1)
opt = torch.optim.Adam([testcl.phi, testcl.theta], lr = 0.1) 

for i in range(400):
    opt.zero_grad()
    output = testcl()
    loss = output - 1
    loss.backward()
    opt.step()

```

Note that the QNode is now defined and executed inside the `nn.forward` method. You could even use more than one QNode here, or mix a combination of QNode and classical layers.

Hope this helps!

---

<div class="post-metadata">

**Author:** ![barthelemymp](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/barthelemymp/32/58_2.png) [@barthelemymp](https://discuss.pennylane.ai/u/barthelemymp)\
**Post date:** [June 12, 2019, 6:18pm UTC](https://discuss.pennylane.ai/t/pytorch-interface-for-models/160/3 "2019-06-12T18:18:23Z")

</div>

Thank you Josh for this Quick answer.  
However in my example my classifier was the forward of the nn.Module I was creating (so it can not be used to initalize itself).

My goal was to decompose my circuit in 2 pyTorch NeuralNet, defining qml operation in their forward, and then having only one circuit(Qnode decorated) that use my two neuralNet

example I define 2 NeuralNet which are supposed to act on my quantumstate when I call their forward.

```
class NeuralNet1(nn.Module):
    def __init__ (self, ...):
        super(NeuralNet, self). __init__ ()

    def forward(self):
        qml.operations...

class NeuralNet2(nn.Module):
    def __init__ (self, ...):
        super(NeuralNet2, self). __init__ ()

    def forward(self):
        qml.operations...

```

and then make my Qnode

```
NN1 = NeuralNet1(...)
NN2 = NeuralNet2(...)

@qml.qnode(dev1, interface='torch')
def circuit(*params):
     NN1() #make the operations of the forward of the NN1
     NN2() #make the operations of the forward of the NN2 on the same device (it continues the operations made by NN1)
return qml.expval...

```

The probleme is that if I define the qnode inside the forward, I will need to use differents QNode in a row, which seems a bit tricky because I want my second qnode to act on the state of the device after the first QNode, and not to restart from the default |0000000\> state.

There is a lot of questions in one, and I hope it is understandable…

Thank you again for your help!

b

---

<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:** [June 12, 2019, 6:38pm UTC](https://discuss.pennylane.ai/t/pytorch-interface-for-models/160/4 "2019-06-12T18:38:29Z")

</div>

Hi @barthelemymp, unfortunately that pattern will not work, as you cannot place a PyTorch neural network inside a QNode. PyTorch neural networks are designed for classical processing, and cannot be run on quantum hardware or simulators.

Instead of using the `nn` module, is there any reason why you can’t create custom functions? For example, like:

```python
def NeuralNet1(params):
    qml.operations...

def NeuralNet2(params):
    qml.operations...

@qml.qnode(dev1, interface='torch')
def circuit(params):
    layer1, layer2 = params
    NeuralNet1(layer1) #make the operations of the forward of the NN1
    NeuralNet2(layer2) #make the operations of the forward of the NN2 on the same device (it continues the operations made by NN1)
    return qml.expval...

```

---

<div class="post-metadata">

**Author:** ![barthelemymp](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/barthelemymp/32/58_2.png) [@barthelemymp](https://discuss.pennylane.ai/u/barthelemymp)\
**Post date:** [June 18, 2019, 3:45pm UTC](https://discuss.pennylane.ai/t/pytorch-interface-for-models/160/5 "2019-06-18T15:45:44Z")

</div>

Thank you,

I just wanted to have a nice architecture that could work with the Pytorch dataLoader.

But the trick of defining my circuits inside the forward path works.

Thank you again,

barthélémy

---

<div class="post-metadata">

**Author:** ![cubicgate](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/cubicgate/32/56_2.png) [@cubicgate](https://discuss.pennylane.ai/u/cubicgate)\
**Post date:** [August 16, 2019, 2:32pm UTC](https://discuss.pennylane.ai/t/pytorch-interface-for-models/160/6 "2019-08-16T14:32:59Z")

</div>

> [@josh](#):
>
> import pennylane as qml import torch import torch.autograd import torch.nn as nn import torch.nn.functional as F dev1 = qml.device(‘default.qubit’, wires=1) # define neural network class NeuralNet(nn.Module): def **init** (self, classifier, n\_wire): super(NeuralNet, self). **init** () self.classifier = classifier self.n\_wire = n\_wire self.phi = torch.tensor(0.011, requires\_grad = True) self.theta = torch.tensor(0.012, requires\_grad = True) def forward(self): print(self.phi,self.theta) @qml.qnode(dev1, interface=‘torch’) def circuit(\*params): self.classifier(\*params) return qml.expval.PauliZ(0) return circuit(self.phi, self.theta) # define custom classifiers def test\_rot(phi, theta): qml.RX(phi, wires=0) qml.RY(theta, wires=0) # perform the optimization testcl = NeuralNet(test\_rot, 1) opt = torch.optim.Adam([testcl.phi, testcl.theta], lr = 0.1) for i in range(400): opt.zero\_grad() output = testcl() loss = output - 1 loss.backward() opt.step()

Hi @josh, I cannot run your code, and I got this error:  
Traceback (most recent call last):  
File “torch\_model.py”, line 42, in   
output = testcl()  
File “C:\Users\wei\AppData\Local\Programs\Python\Python36\lib\site-packages\torch\nn\modules\module.py”, line 489, in **call**  
result = self.forward(\*input, \*\*kwargs)  
File “torch\_model.py”, line 27, in forward  
return circuit(self.phi, self.theta)  
File “C:\Users\wei\AppData\Local\Programs\Python\Python36\lib\site-packages\pennylane\interfaces\torch.py”, line 390, in custom\_apply  
return \_TorchQNode.apply(keyword\_values, \*args)  
File “C:\Users\wei\AppData\Local\Programs\Python\Python36\lib\site-packages\pennylane\interfaces\torch.py”, line 307, in forward  
res = qnode(\*ctx.args, \*\*ctx.kwargs)  
File “C:\Users\wei\AppData\Local\Programs\Python\Python36\lib\site-packages\pennylane\qnode.py”, line 514, in **call**  
return self.evaluate(args, \*\*kwargs) # args as one tuple  
File “C:\Users\wei\AppData\Local\Programs\Python\Python36\lib\site-packages\autograd\tracer.py”, line 48, in f\_wrapped  
return f\_raw(\*args, \*\*kwargs)  
File “C:\Users\wei\AppData\Local\Programs\Python\Python36\lib\site-packages\pennylane\qnode.py”, line 591, in evaluate  
ret = self.device.execute(self.queue, self.ev)  
File “C:\Users\wei\AppData\Local\Programs\Python\Python36\lib\site-packages\pennylane\_device.py”, line 208, in execute  
self.apply(operation.name, operation.wires, operation.parameters)  
File “C:\Users\wei\AppData\Local\Programs\Python\Python36\lib\site-packages\pennylane\operation.py”, line 389, in parameters  
return \_unflatten(temp\_val, self.params)[0]  
File “C:\Users\wei\AppData\Local\Programs\Python\Python36\lib\site-packages\pennylane\utils.py”, line 89, in \_unflatten  
val, flat = \_unflatten(flat, x)  
File “C:\Users\wei\AppData\Local\Programs\Python\Python36\lib\site-packages\pennylane\utils.py”, line 93, in \_unflatten  
raise TypeError(‘Unsupported type in the model: {}’.format(type(model)))  
TypeError: Unsupported type in the model: \<class ‘pennylane.variable.Variable’\>

---

<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:32pm UTC](https://discuss.pennylane.ai/t/pytorch-interface-for-models/160/7 "2020-05-19T20:32:05Z")

</div>

Hi @barthelemymp and @cubicgate,

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

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

```python
pip install git+https://github.com/XanaduAI/pennylane.git#egg=pennylane

```
