class_docstr: Converts a :class:`~.QNode` to a Torch layer.
  
  The result can be used within the ``torch.nn``
  `Sequential <https://pytorch.org/docs/stable/nn.html#sequential>`__ or
  `Module <https://pytorch.org/docs/stable/nn.html#module>`__ classes for
  creating quantum and hybrid models.
  
  Args:
      qnode (qml.QNode): the PennyLane QNode to be converted into a Torch layer
      weight_shapes (dict[str, tuple]): a dictionary mapping from all weights used in the QNode to
          their corresponding shapes
      init_method (Union[Callable, Dict[str, Union[Callable, torch.Tensor]], None]): Either a
          `torch.nn.init <https://pytorch.org/docs/stable/nn.init.html>`__ function for
          initializing all QNode weights or a dictionary specifying the callable/value used for
          each weight. If not specified, weights are randomly initialized using the uniform
          distribution over :math:`[0, 2 \pi]`.
  
  **Example**
  
  First let's define the QNode that we want to convert into a Torch layer:
  
  .. code-block:: python
  
      n_qubits = 2
      dev = qml.device("default.qubit", wires=n_qubits)
  
      @qml.qnode(dev)
      def qnode(inputs, weights_0, weight_1):
          qml.RX(inputs[0], wires=0)
          qml.RX(inputs[1], wires=1)
          qml.Rot(*weights_0, wires=0)
          qml.RY(weight_1, wires=1)
          qml.CNOT(wires=[0, 1])
          return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))
  
  The signature of the QNode **must** contain an ``inputs`` named argument for input data,
  with all other arguments to be treated as internal weights. We can then convert to a Torch
  layer with:
  
  >>> weight_shapes = {"weights_0": 3, "weight_1": 1}
  >>> qlayer = qml.qnn.TorchLayer(qnode, weight_shapes)
  
  The internal weights of the QNode are automatically initialized within the
  :class:`~.TorchLayer` and must have their shapes specified in a ``weight_shapes`` dictionary.
  It is then easy to combine with other neural network layers from the
  `torch.nn <https://pytorch.org/docs/stable/nn.html>`__ module and create a hybrid:
  
  >>> clayer = torch.nn.Linear(2, 2)
  >>> model = torch.nn.Sequential(qlayer, clayer)
  
  .. details::
      :title: Usage Details
  
      **QNode signature**
  
      The QNode must have a signature that satisfies the following conditions:
  
      - Contain an ``inputs`` named argument for input data.
      - All other arguments must accept an array or tensor and are treated as internal
        weights of the QNode.
      - All other arguments must have no default value.
      - The ``inputs`` argument is permitted to have a default value provided the gradient with
        respect to ``inputs`` is not required.
      - There cannot be a variable number of positional or keyword arguments, e.g., no ``*args``
        or ``**kwargs`` present in the signature.
  
      **Output shape**
  
      If the QNode returns a single measurement, then the output of the ``KerasLayer`` will have
      shape ``(batch_dim, *measurement_shape)``, where ``measurement_shape`` is the output shape
      of the measurement:
  
      .. code-block::
  
          def print_output_shape(measurements):
              n_qubits = 2
              dev = qml.device("default.qubit", wires=n_qubits, shots=100)
  
              @qml.qnode(dev)
              def qnode(inputs, weights):
                  qml.templates.AngleEmbedding(inputs, wires=range(n_qubits))
                  qml.templates.StronglyEntanglingLayers(weights, wires=range(n_qubits))
                  if len(measurements) == 1:
                      return qml.apply(measurements[0])
                  return [qml.apply(m) for m in measurements]
  
              weight_shapes = {"weights": (3, n_qubits, 3)}
              qlayer = qml.qnn.TorchLayer(qnode, weight_shapes)
  
              batch_dim = 5
              x = torch.zeros((batch_dim, n_qubits))
              return qlayer(x).shape
  
      >>> print_output_shape([qml.expval(qml.PauliZ(0))])
      torch.Size([5])
      >>> print_output_shape([qml.probs(wires=[0, 1])])
      torch.Size([5, 4])
      >>> print_output_shape([qml.sample(wires=[0, 1])])
      torch.Size([5, 100, 2])
  
      If the QNode returns multiple measurements, then the measurement results will be flattened
      and concatenated, resulting in an output of shape ``(batch_dim, total_flattened_dim)``:
  
      >>> print_output_shape([qml.expval(qml.PauliZ(0)), qml.probs(wires=[0, 1])])
      torch.Size([5, 5])
      >>> print_output_shape([qml.probs([0, 1]), qml.sample(wires=[0, 1])])
      torch.Size([5, 204])
  
      **Initializing weights**
  
      If ``init_method`` is not specified, weights are randomly initialized from the uniform
      distribution on the interval :math:`[0, 2 \pi]`.
  
      Alternative a): The optional ``init_method`` argument of :class:`~.TorchLayer` allows for the initialization
      method of the QNode weights to be specified. The function passed to the argument must be
      from the `torch.nn.init <https://pytorch.org/docs/stable/nn.init.html>`__ module. For
      example, weights can be randomly initialized from the normal distribution by passing:
  
      .. code-block::
  
          init_method = torch.nn.init.normal_
  
      Alternative b): Two dictionaries ``weight_shapes`` and ``init_method`` are passed, whose ``keys`` match the ``args`` of the qnode.
  
      .. code-block::
  
          @qml.qnode(dev)
          def qnode(inputs, weights_0, weights_1, weights_2, weight_3, weight_4):
              qml.templates.AngleEmbedding(inputs, wires=range(n_qubits))
              qml.templates.StronglyEntanglingLayers(weights_0, wires=range(n_qubits))
              qml.templates.BasicEntanglerLayers(weights_1, wires=range(n_qubits))
              qml.Rot(*weights_2, wires=0)
              qml.RY(weight_3, wires=1)
              qml.RZ(weight_4, wires=1)
              qml.CNOT(wires=[0, 1])
              return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))
  
  
          weight_shapes = {
              "weights_0": (3, n_qubits, 3),
              "weights_1": (3, n_qubits),
              "weights_2": 3,
              "weight_3": 1,
              "weight_4": (1,),
          }
  
          init_method = {
              "weights_0": torch.nn.init.normal_,
              "weights_1": torch.nn.init.uniform,
              "weights_2": torch.tensor([1., 2., 3.]),
              "weight_3": torch.tensor(1.),  # scalar when shape is not an iterable and is <= 1
              "weight_4": torch.tensor([1.]),
          }
  
          qlayer = qml.qnn.TorchLayer(qnode, weight_shapes=weight_shapes, init_method=init_method)
  
      **Model saving**
  
      Instances of ``TorchLayer`` can be saved using the usual ``torch.save()`` utility:
  
      .. code-block::
  
          qlayer = qml.qnn.TorchLayer(qnode, weight_shapes=weight_shapes)
          torch.save(qlayer.state_dict(), SAVE_PATH)
  
      To load the layer again, an instance of the class must be created first before calling ``torch.load()``,
      as required by PyTorch:
  
      .. code-block::
  
          qlayer = qml.qnn.TorchLayer(qnode, weight_shapes=weight_shapes)
          qlayer.load_state_dict(torch.load(SAVE_PATH))
          qlayer.eval()
  
      .. note::
  
          Currently ``TorchLayer`` objects cannot be saved using the ``torch.save(qlayer, SAVE_PATH)``
          syntax. In order to save a ``TorchLayer`` object, the object's ``state_dict`` should be
          saved instead.
  
      PyTorch modules that contain ``TorchLayer`` objects can also be saved and loaded.
  
      Saving:
  
      .. code-block::
  
          qlayer = qml.qnn.TorchLayer(qnode, weight_shapes=weight_shapes)
          clayer = torch.nn.Linear(2, 2)
          model = torch.nn.Sequential(qlayer, clayer)
          torch.save(model.state_dict(), SAVE_PATH)
  
      Loading:
  
      .. code-block::
  
          qlayer = qml.qnn.TorchLayer(qnode, weight_shapes=weight_shapes)
          clayer = torch.nn.Linear(2, 2)
          model = torch.nn.Sequential(qlayer, clayer)
          model.load_state_dict(torch.load(SAVE_PATH))
          model.eval()
  
      **Full code example**
  
      The code block below shows how a circuit composed of templates from the
      :doc:`/introduction/templates` module can be combined with classical
      `Linear <https://pytorch.org/docs/stable/nn.html#linear>`__ layers to learn
      the two-dimensional `moons <https://scikit-learn.org/stable/modules/generated/sklearn
      .datasets.make_moons.html>`__ dataset.
  
      .. code-block:: python
  
          import numpy as np
          import pennylane as qml
          import torch
          import sklearn.datasets
  
          n_qubits = 2
          dev = qml.device("default.qubit", wires=n_qubits)
  
          @qml.qnode(dev)
          def qnode(inputs, weights):
              qml.templates.AngleEmbedding(inputs, wires=range(n_qubits))
              qml.templates.StronglyEntanglingLayers(weights, wires=range(n_qubits))
              return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))
  
          weight_shapes = {"weights": (3, n_qubits, 3)}
  
          qlayer = qml.qnn.TorchLayer(qnode, weight_shapes)
          clayer1 = torch.nn.Linear(2, 2)
          clayer2 = torch.nn.Linear(2, 2)
          softmax = torch.nn.Softmax(dim=1)
          model = torch.nn.Sequential(clayer1, qlayer, clayer2, softmax)
  
          samples = 100
          x, y = sklearn.datasets.make_moons(samples)
          y_hot = np.zeros((samples, 2))
          y_hot[np.arange(samples), y] = 1
  
          X = torch.tensor(x).float()
          Y = torch.tensor(y_hot).float()
  
          opt = torch.optim.SGD(model.parameters(), lr=0.5)
          loss = torch.nn.L1Loss()
  
      The model can be trained using:
  
      .. code-block:: python
  
          epochs = 8
          batch_size = 5
          batches = samples // batch_size
  
          data_loader = torch.utils.data.DataLoader(list(zip(X, Y)), batch_size=batch_size,
                                                    shuffle=True, drop_last=True)
  
          for epoch in range(epochs):
  
              running_loss = 0
  
              for x, y in data_loader:
                  opt.zero_grad()
  
                  loss_evaluated = loss(model(x), y)
                  loss_evaluated.backward()
  
                  opt.step()
  
                  running_loss += loss_evaluated
  
              avg_loss = running_loss / batches
              print("Average loss over epoch {}: {:.4f}".format(epoch + 1, avg_loss))
  
      An example output is shown below:
  
      .. code-block:: rst
  
          Average loss over epoch 1: 0.5089
          Average loss over epoch 2: 0.4765
          Average loss over epoch 3: 0.2710
          Average loss over epoch 4: 0.1865
          Average loss over epoch 5: 0.1670
          Average loss over epoch 6: 0.1635
          Average loss over epoch 7: 0.1528
          Average loss over epoch 8: 0.1528
class_docstr_tok: ["Converts","a",":","class",":","`","~.QNode","`","to","a","Torch","layer",".","The","result","can","be","used","within","the","``","torch.nn","``","`","Sequential","<","https",":","\/\/pytorch.org\/docs\/stable\/nn.html","#","sequential",">","`","__","or","`","Module","<","https",":","\/\/pytorch.org\/docs\/stable\/nn.html","#","module",">","`","__","classes","for","creating","quantum","and","hybrid","models",".","Args",":","qnode","(","qml.QNode",")",":","the","PennyLane","QNode","to","be","converted","into","a","Torch","layer","weight_shapes","(","dict","[","str",",","tuple","]",")",":","a","dictionary","mapping","from","all","weights","used","in","the","QNode","to","their","corresponding","shapes","init_method","(","Union","[","Callable",",","Dict","[","str",",","Union","[","Callable",",","torch.Tensor","]","]",",","None","]",")",":","Either","a","`","torch.nn.init","<","https",":","\/\/pytorch.org\/docs\/stable\/nn.init.html",">","`","__","function","for","initializing","all","QNode","weights","or","a","dictionary","specifying","the","callable\/value","used","for","each","weight",".","If","not","specified",",","weights","are","randomly","initialized","using","the","uniform","distribution","over",":","math",":","`","[","0",",","2","\\pi","]","`",".","*","*","Example","*","*","First","let","'s","define","the","QNode","that","we","want","to","convert","into","a","Torch","layer",":","..","code-block",":",":","python","n_qubits","=","2","dev","=","qml.device","(","``","default.qubit","''",",","wires=n_qubits",")","@","qml.qnode","(","dev",")","def","qnode","(","inputs",",","weights_0",",","weight_1",")",":","qml.RX","(","inputs","[","0","]",",","wires=0",")","qml.RX","(","inputs","[","1","]",",","wires=1",")","qml.Rot","(","*","weights_0",",","wires=0",")","qml.RY","(","weight_1",",","wires=1",")","qml.CNOT","(","wires=","[","0",",","1","]",")","return","qml.expval","(","qml.PauliZ","(","0",")",")",",","qml.expval","(","qml.PauliZ","(","1",")",")","The","signature","of","the","QNode","*","*","must","*","*","contain","an","``","inputs","``","named","argument","for","input","data",",","with","all","other","arguments","to","be","treated","as","internal","weights",".","We","can","then","convert","to","a","Torch","layer","with",":",">",">",">","weight_shapes","=","{","``","weights_0","''",":","3",",","``","weight_1","''",":","1","}",">",">",">","qlayer","=","qml.qnn.TorchLayer","(","qnode",",","weight_shapes",")","The","internal","weights","of","the","QNode","are","automatically","initialized","within","the",":","class",":","`","~.TorchLayer","`","and","must","have","their","shapes","specified","in","a","``","weight_shapes","``","dictionary",".","It","is","then","easy","to","combine","with","other","neural","network","layers","from","the","`","torch.nn","<","https",":","\/\/pytorch.org\/docs\/stable\/nn.html",">","`","__","module","and","create","a","hybrid",":",">",">",">","clayer","=","torch.nn.Linear","(","2",",","2",")",">",">",">","model","=","torch.nn.Sequential","(","qlayer",",","clayer",")","..","details",":",":",":","title",":","Usage","Details","*","*","QNode","signature","*","*","The","QNode","must","have","a","signature","that","satisfies","the","following","conditions",":","-","Contain","an","``","inputs","``","named","argument","for","input","data",".","-","All","other","arguments","must","accept","an","array","or","tensor","and","are","treated","as","internal","weights","of","the","QNode",".","-","All","other","arguments","must","have","no","default","value",".","-","The","``","inputs","``","argument","is","permitted","to","have","a","default","value","provided","the","gradient","with","respect","to","``","inputs","``","is","not","required",".","-","There","can","not","be","a","variable","number","of","positional","or","keyword","arguments",",","e.g.",",","no","``","*","args","``","or","``","*","*","kwargs","``","present","in","the","signature",".","*","*","Output","shape","*","*","If","the","QNode","returns","a","single","measurement",",","then","the","output","of","the","``","KerasLayer","``","will","have","shape","``","(","batch_dim",",","*","measurement_shape",")","``",",","where","``","measurement_shape","``","is","the","output","shape","of","the","measurement",":","..","code-block",":",":","def","print_output_shape","(","measurements",")",":","n_qubits","=","2","dev","=","qml.device","(","``","default.qubit","''",",","wires=n_qubits",",","shots=100",")","@","qml.qnode","(","dev",")","def","qnode","(","inputs",",","weights",")",":","qml.templates.AngleEmbedding","(","inputs",",","wires=range","(","n_qubits",")",")","qml.templates.StronglyEntanglingLayers","(","weights",",","wires=range","(","n_qubits",")",")","if","len","(","measurements",")","==","1",":","return","qml.apply","(","measurements","[","0","]",")","return","[","qml.apply","(","m",")","for","m","in","measurements","]","weight_shapes","=","{","``","weights","''",":","(","3",",","n_qubits",",","3",")","}","qlayer","=","qml.qnn.TorchLayer","(","qnode",",","weight_shapes",")","batch_dim","=","5","x","=","torch.zeros","(","(","batch_dim",",","n_qubits",")",")","return","qlayer","(","x",")",".shape",">",">",">","print_output_shape","(","[","qml.expval","(","qml.PauliZ","(","0",")",")","]",")","torch.Size","(","[","5","]",")",">",">",">","print_output_shape","(","[","qml.probs","(","wires=","[","0",",","1","]",")","]",")","torch.Size","(","[","5",",","4","]",")",">",">",">","print_output_shape","(","[","qml.sample","(","wires=","[","0",",","1","]",")","]",")","torch.Size","(","[","5",",","100",",","2","]",")","If","the","QNode","returns","multiple","measurements",",","then","the","measurement","results","will","be","flattened","and","concatenated",",","resulting","in","an","output","of","shape","``","(","batch_dim",",","total_flattened_dim",")","``",":",">",">",">","print_output_shape","(","[","qml.expval","(","qml.PauliZ","(","0",")",")",",","qml.probs","(","wires=","[","0",",","1","]",")","]",")","torch.Size","(","[","5",",","5","]",")",">",">",">","print_output_shape","(","[","qml.probs","(","[","0",",","1","]",")",",","qml.sample","(","wires=","[","0",",","1","]",")","]",")","torch.Size","(","[","5",",","204","]",")","*","*","Initializing","weights","*","*","If","``","init_method","``","is","not","specified",",","weights","are","randomly","initialized","from","the","uniform","distribution","on","the","interval",":","math",":","`","[","0",",","2","\\pi","]","`",".","Alternative","a",")",":","The","optional","``","init_method","``","argument","of",":","class",":","`","~.TorchLayer","`","allows","for","the","initialization","method","of","the","QNode","weights","to","be","specified",".","The","function","passed","to","the","argument","must","be","from","the","`","torch.nn.init","<","https",":","\/\/pytorch.org\/docs\/stable\/nn.init.html",">","`","__","module",".","For","example",",","weights","can","be","randomly","initialized","from","the","normal","distribution","by","passing",":","..","code-block",":",":","init_method","=","torch.nn.init.normal_","Alternative","b",")",":","Two","dictionaries","``","weight_shapes","``","and","``","init_method","``","are","passed",",","whose","``","keys","``","match","the","``","args","``","of","the","qnode",".","..","code-block",":",":","@","qml.qnode","(","dev",")","def","qnode","(","inputs",",","weights_0",",","weights_1",",","weights_2",",","weight_3",",","weight_4",")",":","qml.templates.AngleEmbedding","(","inputs",",","wires=range","(","n_qubits",")",")","qml.templates.StronglyEntanglingLayers","(","weights_0",",","wires=range","(","n_qubits",")",")","qml.templates.BasicEntanglerLayers","(","weights_1",",","wires=range","(","n_qubits",")",")","qml.Rot","(","*","weights_2",",","wires=0",")","qml.RY","(","weight_3",",","wires=1",")","qml.RZ","(","weight_4",",","wires=1",")","qml.CNOT","(","wires=","[","0",",","1","]",")","return","qml.expval","(","qml.PauliZ","(","0",")",")",",","qml.expval","(","qml.PauliZ","(","1",")",")","weight_shapes","=","{","``","weights_0","''",":","(","3",",","n_qubits",",","3",")",",","``","weights_1","''",":","(","3",",","n_qubits",")",",","``","weights_2","''",":","3",",","``","weight_3","''",":","1",",","``","weight_4","''",":","(","1",",",")",",","}","init_method","=","{","``","weights_0","''",":","torch.nn.init.normal_",",","``","weights_1","''",":","torch.nn.init.uniform",",","``","weights_2","''",":","torch.tensor","(","[","1.",",","2.",",","3",".","]",")",",","``","weight_3","''",":","torch.tensor","(","1",".",")",",","#","scalar","when","shape","is","not","an","iterable","and","is","<","=","1","``","weight_4","''",":","torch.tensor","(","[","1",".","]",")",",","}","qlayer","=","qml.qnn.TorchLayer","(","qnode",",","weight_shapes=weight_shapes",",","init_method=init_method",")","*","*","Model","saving","*","*","Instances","of","``","TorchLayer","``","can","be","saved","using","the","usual","``","torch.save","(",")","``","utility",":","..","code-block",":",":","qlayer","=","qml.qnn.TorchLayer","(","qnode",",","weight_shapes=weight_shapes",")","torch.save","(","qlayer.state_dict","(",")",",","SAVE_PATH",")","To","load","the","layer","again",",","an","instance","of","the","class","must","be","created","first","before","calling","``","torch.load","(",")","``",",","as","required","by","PyTorch",":","..","code-block",":",":","qlayer","=","qml.qnn.TorchLayer","(","qnode",",","weight_shapes=weight_shapes",")","qlayer.load_state_dict","(","torch.load","(","SAVE_PATH",")",")","qlayer.eval","(",")","..","note",":",":","Currently","``","TorchLayer","``","objects","can","not","be","saved","using","the","``","torch.save","(","qlayer",",","SAVE_PATH",")","``","syntax",".","In","order","to","save","a","``","TorchLayer","``","object",",","the","object","'s","``","state_dict","``","should","be","saved","instead",".","PyTorch","modules","that","contain","``","TorchLayer","``","objects","can","also","be","saved","and","loaded",".","Saving",":","..","code-block",":",":","qlayer","=","qml.qnn.TorchLayer","(","qnode",",","weight_shapes=weight_shapes",")","clayer","=","torch.nn.Linear","(","2",",","2",")","model","=","torch.nn.Sequential","(","qlayer",",","clayer",")","torch.save","(","model.state_dict","(",")",",","SAVE_PATH",")","Loading",":","..","code-block",":",":","qlayer","=","qml.qnn.TorchLayer","(","qnode",",","weight_shapes=weight_shapes",")","clayer","=","torch.nn.Linear","(","2",",","2",")","model","=","torch.nn.Sequential","(","qlayer",",","clayer",")","model.load_state_dict","(","torch.load","(","SAVE_PATH",")",")","model.eval","(",")","*","*","Full","code","example","*","*","The","code","block","below","shows","how","a","circuit","composed","of","templates","from","the",":","doc",":","`","\/introduction\/templates","`","module","can","be","combined","with","classical","`","Linear","<","https",":","\/\/pytorch.org\/docs\/stable\/nn.html","#","linear",">","`","__","layers","to","learn","the","two-dimensional","`","moons","<","https",":","\/\/scikit-learn.org\/stable\/modules\/generated\/sklearn",".datasets.make_moons.html",">","`","__","dataset",".","..","code-block",":",":","python","import","numpy","as","np","import","pennylane","as","qml","import","torch","import","sklearn.datasets","n_qubits","=","2","dev","=","qml.device","(","``","default.qubit","''",",","wires=n_qubits",")","@","qml.qnode","(","dev",")","def","qnode","(","inputs",",","weights",")",":","qml.templates.AngleEmbedding","(","inputs",",","wires=range","(","n_qubits",")",")","qml.templates.StronglyEntanglingLayers","(","weights",",","wires=range","(","n_qubits",")",")","return","qml.expval","(","qml.PauliZ","(","0",")",")",",","qml.expval","(","qml.PauliZ","(","1",")",")","weight_shapes","=","{","``","weights","''",":","(","3",",","n_qubits",",","3",")","}","qlayer","=","qml.qnn.TorchLayer","(","qnode",",","weight_shapes",")","clayer1","=","torch.nn.Linear","(","2",",","2",")","clayer2","=","torch.nn.Linear","(","2",",","2",")","softmax","=","torch.nn.Softmax","(","dim=1",")","model","=","torch.nn.Sequential","(","clayer1",",","qlayer",",","clayer2",",","softmax",")","samples","=","100","x",",","y","=","sklearn.datasets.make_moons","(","samples",")","y_hot","=","np.zeros","(","(","samples",",","2",")",")","y_hot","[","np.arange","(","samples",")",",","y","]","=","1","X","=","torch.tensor","(","x",")",".float","(",")","Y","=","torch.tensor","(","y_hot",")",".float","(",")","opt","=","torch.optim.SGD","(","model.parameters","(",")",",","lr=0.5",")","loss","=","torch.nn.L1Loss","(",")","The","model","can","be","trained","using",":","..","code-block",":",":","python","epochs","=","8","batch_size","=","5","batches","=","samples","\/\/","batch_size","data_loader","=","torch.utils.data.DataLoader","(","list","(","zip","(","X",",","Y",")",")",",","batch_size=batch_size",",","shuffle=True",",","drop_last=True",")","for","epoch","in","range","(","epochs",")",":","running_loss","=","0","for","x",",","y","in","data_loader",":","opt.zero_grad","(",")","loss_evaluated","=","loss","(","model","(","x",")",",","y",")","loss_evaluated.backward","(",")","opt.step","(",")","running_loss","+=","loss_evaluated","avg_loss","=","running_loss","\/","batches","print","(","``","Average","loss","over","epoch","{","}",":","{",":",".4f","}","''",".format","(","epoch","+","1",",","avg_loss",")",")","An","example","output","is","shown","below",":","..","code-block",":",":","rst","Average","loss","over","epoch","1",":","0.5089","Average","loss","over","epoch","2",":","0.4765","Average","loss","over","epoch","3",":","0.2710","Average","loss","over","epoch","4",":","0.1865","Average","loss","over","epoch","5",":","0.1670","Average","loss","over","epoch","6",":","0.1635","Average","loss","over","epoch","7",":","0.1528","Average","loss","over","epoch","8",":","0.1528"]
docstr: Initialize and register the weights with the given init_method. If init_method is not
  specified, weights are randomly initialized from the uniform distribution on the interval
  [0, 2π].
  
  Args:
      weight_shapes (dict[str, tuple]): a dictionary mapping from all weights used in the QNode to
          their corresponding shapes
      init_method (Union[Callable, Dict[str, Union[Callable, torch.Tensor]], None]): Either a
          `torch.nn.init <https://pytorch.org/docs/stable/nn.init.html>`__ function for
          initializing the QNode weights or a dictionary specifying the callable/value used for
          each weight. If not specified, weights are randomly initialized using the uniform
          distribution over :math:`[0, 2 \pi]`.
docstr_tok: ["Initialize","and","register","the","weights","with","the","given","init_method",".","If","init_method","is","not","specified",",","weights","are","randomly","initialized","from","the","uniform","distribution","on","the","interval","[","0",",","2\u03c0","]",".","Args",":","weight_shapes","(","dict","[","str",",","tuple","]",")",":","a","dictionary","mapping","from","all","weights","used","in","the","QNode","to","their","corresponding","shapes","init_method","(","Union","[","Callable",",","Dict","[","str",",","Union","[","Callable",",","torch.Tensor","]","]",",","None","]",")",":","Either","a","`","torch.nn.init","<","https",":","\/\/pytorch.org\/docs\/stable\/nn.init.html",">","`","__","function","for","initializing","the","QNode","weights","or","a","dictionary","specifying","the","callable\/value","used","for","each","weight",".","If","not","specified",",","weights","are","randomly","initialized","using","the","uniform","distribution","over",":","math",":","`","[","0",",","2","\\pi","]","`","."]
code: def _init_weights(
      self,
      weight_shapes: Dict[str, tuple],
      init_method: Union[
          Callable, Dict[str, Union[Callable, Any]], None
      ],
  ):
      r"""Initialize and register the weights with the given init_method. If init_method is not
      specified, weights are randomly initialized from the uniform distribution on the interval
      [0, 2π].
  
      Args:
          weight_shapes (dict[str, tuple]): a dictionary mapping from all weights used in the QNode to
              their corresponding shapes
          init_method (Union[Callable, Dict[str, Union[Callable, torch.Tensor]], None]): Either a
              `torch.nn.init <https://pytorch.org/docs/stable/nn.init.html>`__ function for
              initializing the QNode weights or a dictionary specifying the callable/value used for
              each weight. If not specified, weights are randomly initialized using the uniform
              distribution over :math:`[0, 2 \pi]`.
      """
  
      def init_weight(
          weight_name: str, weight_size: tuple
      ) -> torch.Tensor:
          """Initialize weights.
  
          Args:
              weight_name (str): weight name
              weight_size (tuple): size of the weight
  
          Returns:
              torch.Tensor: tensor containing the weights
          """
          if init_method is None:
              init = functools.partial(
                  torch.nn.init.uniform_, b=2 * math.pi
              )
          elif callable(init_method):
              init = init_method
          elif isinstance(init_method, dict):
              init = init_method[weight_name]
              if isinstance(init, torch.Tensor):
                  if tuple(init.shape) != weight_size:
                      raise ValueError(
                          f"The Tensor specified for weight '{weight_name}' doesn't have the "
                          + "appropiate shape."
                      )
                  return init
          return (
              init(torch.Tensor(*weight_size))
              if weight_size
              else init(torch.Tensor(1))[0]
          )
  
      for name, size in weight_shapes.items():
          self.qnode_weights[name] = torch.nn.Parameter(
              init_weight(weight_name=name, weight_size=size)
          )
  
          self.register_parameter(name, self.qnode_weights[name])
  
file_path: pennylane/pennylane/qnn/torch.py
imports: import contextlib
  import functools
  import inspect
  import math
  from collections.abc import Iterable
  from typing import Callable, Dict, Union, Any
  from pennylane import QNode
label_desc: Use image node_id 8 for calling the TorchLayer obj's underlying member method code with example usage: obj._init_weights(weight_shapes, init_method) and returns: unknown, init