def validate_output_shape(self, qnn: OpflowQNN, test_data: List[np.ndarray]) -> None: """ Asserts that the opflow qnn returns results of the correct output shape. Args: qnn: QNN to be tested test_data: list of test input arrays Raises: QiskitMachineLearningError: Invalid input. """ # get weights weights = np.random.rand(qnn.num_weights) # iterate over test data and validate behavior of model for x in test_data: # evaluate network forward_shape = qnn.forward(x, weights).shape grad = qnn.backward(x, weights) backward_shape_input = grad[0].shape backward_shape_weights = grad[1].shape # derive batch shape form input batch_shape = x.shape[:-len(qnn.output_shape)] if len(batch_shape) == 0: batch_shape = (1,) # compare results and assert that the behavior is equal self.assertEqual(forward_shape, (*batch_shape, *qnn.output_shape)) self.assertEqual(backward_shape_input, (*batch_shape, *qnn.output_shape, qnn.num_inputs)) self.assertEqual(backward_shape_weights, (*batch_shape, *qnn.output_shape, qnn.num_weights))
def test_composed_op(self): """Tests OpflowQNN with ComposedOp as an operator.""" qc = QuantumCircuit(1) param = Parameter("param") qc.rz(param, 0) h_1 = PauliSumOp.from_list([("Z", 1.0)]) h_2 = PauliSumOp.from_list([("Z", 1.0)]) h_op = ListOp([h_1, h_2]) op = ~StateFn(h_op) @ StateFn(qc) # initialize QNN qnn = OpflowQNN(op, [], [param]) # create random data and weights for testing input_data = np.random.rand(2, qnn.num_inputs) weights = np.random.rand(qnn.num_weights) qnn.forward(input_data, weights) qnn.backward(input_data, weights)
class TestOpflowQNN(QiskitMachineLearningTestCase): """Opflow QNN Tests.""" def setUp(self): super().setUp() # specify "run configuration" backend = Aer.get_backend('statevector_simulator') quantum_instance = QuantumInstance(backend) # specify how to evaluate expected values and gradients expval = PauliExpectation() gradient = Gradient() # construct parametrized circuit params = [Parameter('input1'), Parameter('weight1')] qc = QuantumCircuit(1) qc.h(0) qc.ry(params[0], 0) qc.rx(params[1], 0) qc_sfn = StateFn(qc) # construct cost operator cost_operator = StateFn(PauliSumOp.from_list([('Z', 1.0), ('X', 1.0)])) # combine operator and circuit to objective function op = ~cost_operator @ qc_sfn # define QNN self.qnn = OpflowQNN(op, [params[0]], [params[1]], expval, gradient, quantum_instance=quantum_instance) def test_opflow_qnn1(self): """ Opflow QNN Test """ input_data = np.zeros(self.qnn.num_inputs) weights = np.zeros(self.qnn.num_weights) # test forward pass result = self.qnn.forward(input_data, weights) self.assertEqual(result.shape, (1, *self.qnn.output_shape)) # test backward pass result = self.qnn.backward(input_data, weights) self.assertEqual(result[0].shape, (1, self.qnn.num_inputs, *self.qnn.output_shape)) self.assertEqual(result[1].shape, (1, self.qnn.num_weights, *self.qnn.output_shape))