I tried to modify the quantum kernel Demo, but the following problem occurred. I haven’t played Pennylane for a long time, and I didn’t even know that the parameters (“params” in code) now have dimensions. It has always been a one-dimensional vector before. There is also no documentation for the current parameter explaining why it automatically becomes a multidimensional vector. Please give a reasonable explanation of the custom parameter dimension.
def QuantumKernel(x, params, wires):
"""The embedding ansatz"""
i = 0
for j, wire in enumerate(wires):
qml.RZ(params[j], wires=[wire])
qml.Hadamard(wires=[wire])
qml.U1(2*x[i], wires=[wire])
i += 1
for i in range(len(x)):
for j in np.arange(i + 1, len(x), 1):
qml.CNOT(wires=[i,j])
qml.U1(2*(np.pi - x[i])*(np.pi - x[j]), wires=j)
qml.CNOT(wires=[i,j])
init_params = random_params(num_wires=X.shape[1], num_layers=1)
print(init_params, init_params.dtype)
kernel_value = kernel(X[0], X[0], init_params)
print(kernel_value)
qml.drawer.use_style('black_white')
fig, ax = qml.draw_mpl(kernel_circuit, show_all_wires=True)(X[0], X[0], init_params)
fig.set_size_inches((10, 5))
#print(f"The kernel value between the first and second datapoint is {kernel_value:.3f}")
init_kernel = lambda x1, x2: kernel(x1, x2, init_params)
print(X)
K_init = qml.kernels.square_kernel_matrix(X, init_kernel, assume_normalized_kernel=True)
with np.printoptions(precision=3, suppress=True):
print(K_init)
[[[5.79224151 0.81098457 1.42666494]
[3.92941447 0.87498623 4.73891606]]] float64ValueError Traceback (most recent call last)
Input In [102], in <cell line: 3>()
1 init_params = random_params(num_wires=X.shape[1], num_layers=1)
2 print(init_params, init_params.dtype)
----> 3 kernel_value = kernel(X[0], X[0], init_params)
4 print(kernel_value)
5 qml.drawer.use_style(‘black_white’)Input In [100], in kernel(x1, x2, params)
42 def kernel(x1, x2, params):
—> 43 return kernel_circuit(x1, x2, params)[0]File d:\miniconda3\lib\site-packages\pennylane\qnode.py:610, in QNode.call(self, *args, **kwargs)
607 set_shots(self._original_device, override_shots)(self._update_gradient_fn)()
609 # construct the tape
→ 610 self.construct(args, kwargs)
612 cache = self.execute_kwargs.get(“cache”, False)
613 using_custom_cache = (
614 hasattr(cache, “getitem”)
615 and hasattr(cache, “setitem”)
616 and hasattr(cache, “delitem”)
617 )File d:\miniconda3\lib\site-packages\pennylane\qnode.py:525, in QNode.construct(self, args, kwargs)
522 self._tape = qml.tape.QuantumTape()
524 with self.tape:
→ 525 self._qfunc_output = self.func(*args, **kwargs)
526 self._tape._qfunc_output = self._qfunc_output
528 params = self.tape.get_parameters(trainable_only=False)Input In [100], in kernel_circuit(x1, x2, params)
36 @qml.qnode(dev)
37 def kernel_circuit(x1, x2, params):
—> 38 QuantumKernel(x1, params, wires)
39 adjoint_ansatz(x2, params, wires)
40 return qml.probs(wires=wires)Input In [100], in QuantumKernel(x, params, wires)
8 i = 0
9 for j, wire in enumerate(wires):
—> 10 qml.RZ(params[j], wires=[wire])
11 qml.Hadamard(wires=[wire])
12 qml.U1(2*x[i], wires=[wire])File d:\miniconda3\lib\site-packages\pennylane\ops\qubit\parametric_ops.py:253, in RZ.init(self, phi, wires, do_queue, id)
252 def init(self, phi, wires, do_queue=True, id=None):
→ 253 super().init(phi, wires=wires, do_queue=do_queue, id=id)File d:\miniconda3\lib\site-packages\pennylane\operation.py:1521, in Operation.init(self, wires, do_queue, id, *params)
1518 def init(self, *params, wires=None, do_queue=True, id=None):
1520 self._inverse = False
→ 1521 super().init(*params, wires=wires, do_queue=do_queue, id=id)
1523 # check the grad_recipe validity
1524 if self.grad_recipe is None:
1525 # Make sure grad_recipe is an iterable of correct length instead of NoneFile d:\miniconda3\lib\site-packages\pennylane\operation.py:894, in Operator.init(self, wires, do_queue, id, *params)
888 if self.num_wires not in {AllWires, AnyWires} and len(self._wires) != self.num_wires:
889 raise ValueError(
890 f"{self.name}: wrong number of wires. "
891 f"{len(self._wires)} wires given, {self.num_wires} expected."
892 )
→ 894 self._check_batching(params)
896 self.data = list(params) #: list[Any]: parameters of the operator
898 if do_queue:File d:\miniconda3\lib\site-packages\pennylane\operation.py:935, in Operator.check_batching(self, params)
930 ndims_matches = [
931 (ndim == exp_ndim, ndim == exp_ndim + 1)
932 for ndim, exp_ndim in zip(ndims, self.ndim_params)
933 ]
934 if not all(correct or batched for correct, batched in ndims_matches):
→ 935 raise ValueError(
936 f"{self.name}: wrong number(s) of dimensions in parameters. "
937 f"Parameters with ndims {ndims} passed, {self.ndim_params} expected."
938 )
940 first_dims = [
941 qml.math.shape(p)[0] for (, batched), p in zip(ndims_matches, params) if batched
942 ]
943 if not qml.math.allclose(first_dims, first_dims[0]):ValueError: RZ: wrong number(s) of dimensions in parameters. Parameters with ndims (2,) passed, (0,) expected.