Skip to content

Conversation

@eggerdj
Copy link
Contributor

@eggerdj eggerdj commented May 12, 2021

Summary

This PR implements a

  • SVD node and an IQ averaging node for the data processor,
  • a data processor training mechanism,
  • run-time options that can be given to a data processor, and
  • an error propagation mechanism.

Details and comments

The SVD allows the user to project the IQ data on the main axis of the data. This also means that this axis must be determined before using the SVD. Furthermore, this training is not done on a single datum but either on all the data or a subset of the data (the data processing calibration data).

DataProcessors can now be trained one node at a time using the train method. Each node has a is_trained property which by default is True. Nodes that require a training process must overwrite this property.

The error propagation and run-time options are implemented by changing the signature of DataAction calls from

def __call__(self, data: Any) -> Any:

to

def __call__(self, data: Any, error: Optional[Any] = None, **options) -> Tuple[Any, Any]:

and making the required changes in DataProcessor.

TODO:

  • DataProcessor training mechanisme
  • IQ averaging node
  • Run-time options
  • Error propagation for SVD

* Added tests.
* Added train method to DataAction.
@eggerdj eggerdj mentioned this pull request May 12, 2021
@eggerdj
Copy link
Contributor Author

eggerdj commented May 12, 2021

This is needed for #31

@eggerdj eggerdj mentioned this pull request May 13, 2021
eggerdj added 7 commits May 13, 2021 21:06
* Added SVD training test.
* Added required dimension to SVD.
* Added error propagation mechanisme to the data processor.
* Added optional outcome to Probability.
* Added AverageIDData Node.
* Added averaging and SVD test.
@blakejohnson
Copy link
Contributor

Can we have an option to "self-train" this from the data source? This is often good enough if your data set has a reasonable mixture of 0s and 1s.

@eggerdj
Copy link
Contributor Author

eggerdj commented May 16, 2021

In #22 we decided to have the data processor apply to an individual datum, i.e. processor(experiment_data.data(index)). It therefore only sees one point of the data at the time. Self-fitting is thus done in the analysis class, see e.g. #46. This also gives us the possibility to train on either all or part of the data. E.g. an experiment might include a few ground-state and excited-state calibration circuits (which we can single out for training) before measuring the actual thing. PR #48 introduces a mechanism that allows nodes and data processors to self train on the data they are given.

@eggerdj eggerdj changed the title [WIP] SVD data processing SVD data processing May 16, 2021
Copy link
Collaborator

@nkanazawa1989 nkanazawa1989 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks good.

Copy link
Collaborator

@chriseclectic chriseclectic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about the changes to the base class here which seem to be very tied to this specific SVD function. Training doesn't seem like it is a general enough property for the base class.

Also do we need to allow runtime options for these objects, or can we take it in a direction of specifically setting options for node and data processors at initialization or using set_options? Passing generic kwargs through the entire processing chain might lead to some issues later on similar to the current issues in experiment classes with the various layers of options.

@eggerdj
Copy link
Contributor Author

eggerdj commented May 18, 2021

Here is some rational for the current implementation. Consider the case of spectroscopy. When running spectroscopy you have no pi-pulse and cannot run any calibrations. Therefore, you need to train your SVD (or whatever projection method you use) on the data you measure in the spectroscopy experiment. Therefore the data processor needs to self train on the data it is given. This would look like this:

processor = DataProcessor("memory", [SVD()])

processor.train(experiment_data.data())

y_sigmas = np.array([processor(datum) for datum in experiment_data.data()])

Copy link
Collaborator

@nkanazawa1989 nkanazawa1989 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Collaborator

@chriseclectic chriseclectic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks better with the subclasses. One question is does is_trained need to be an abstract method? Or can the object just have an attribute like self._trained = False that this property returns, and the subclasses should set this to True as part of the train abstract method implementation?

@eggerdj
Copy link
Contributor Author

eggerdj commented May 19, 2021

One advantage with the abstract property is that it forces the person implementing the node to carefully think about what it means for the node to be trained.

@eggerdj eggerdj merged commit fbe19dd into qiskit-community:main May 19, 2021
@eggerdj eggerdj deleted the svd-processing-node branch May 19, 2021 16:55
@coruscating coruscating added this to the Release 0.1 milestone Jun 16, 2021
paco-ri pushed a commit to paco-ri/qiskit-experiments that referenced this pull request Jul 11, 2022
* * First draft of SVD node.
* Added tests.
* Added train method to DataAction.

* * Added node and data processor training functionality.

* * Fixed bug in _call_internal.
* Added SVD training test.
* Added required dimension to SVD.

* * Added run-time options to data processor
* Added error propagation mechanisme to the data processor.
* Added optional outcome to Probability.
* Added AverageIDData Node.
* Added averaging and SVD test.

* * Added error propagation for SVD node and tests.
* Black and lint.

* * Added call to super().setUp()

* * Removed redundent setUp

* * Made the averaging node independent of IQData.

* * Docstring.

* * Black

* * Lint

* * Black.

* * Fix docstring.

* Update qiskit_experiments/data_processing/data_processor.py

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>

* * Made means a function to improve readability.

* * Removed RealAvg and ImagAvg.

* * Added TrainableDataAction as a subclass of DataAction.

* * Removed _required_dimension.

* * Removed **options from data processing.

* * Used the property

* * Removed raises in SVD.

* * Made scale default to 1.0

Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants