跳转至

NNFidelityEstimator

QuICT.qcda.utility.fidelity_estimator.nn_fidelity_estimator.ShallowFidelityNN

ShallowFidelityNN(input_size, hidden_size)

Bases: Module

A simple NN for quantum circuit fidelity estimation.

Parameters:

  • input_size(int)

    input size of NN

  • hidden_size(int)

    hidden size of NN

Source code in QuICT/qcda/utility/fidelity_estimator/nn_fidelity_estimator.py
def __init__(self, input_size, hidden_size):
    """
    Args:
        input_size(int): input size of NN
        hidden_size(int): hidden size of NN
    """

    output_size = 1
    super(ShallowFidelityNN, self).__init__()
    self.fc1 = nn.Linear(input_size, hidden_size)
    self.relu1 = nn.ReLU()
    self.fc2 = nn.Linear(hidden_size, hidden_size)
    self.relu2 = nn.ReLU()
    self.fc3 = nn.Linear(hidden_size, hidden_size)
    self.relu3 = nn.ReLU()
    self.fc4 = nn.Linear(hidden_size, output_size)
    self.tanh = nn.Tanh()

forward

forward(x)

Parameters:

  • x(torch.Tensor)

    input tensor

Returns:

  • torch.Tensor: output tensor

Source code in QuICT/qcda/utility/fidelity_estimator/nn_fidelity_estimator.py
def forward(self, x):
    """
    Args:
        x(torch.Tensor): input tensor

    Returns:
        torch.Tensor: output tensor
    """

    x = self.fc1(x)
    x = self.relu2(x)
    x = self.fc2(x)
    x = self.relu2(x)
    x = self.fc3(x)
    x = self.relu3(x)
    x = self.fc4(x)
    x = self.tanh(x)
    return x

QuICT.qcda.utility.fidelity_estimator.nn_fidelity_estimator.NNFidelityEstimator

NNFidelityEstimator(vqm: VirtualQuantumMachine, hidden_size=200, use_vqm=False)

NN based fidelity estimator.

Parameters:

  • vqm(VirtualQuantumMachine)

    target machine

  • hidden_size(int)

    hidden size of NN

  • use_vqm(bool)

    whether to use vqm information when estimating

Source code in QuICT/qcda/utility/fidelity_estimator/nn_fidelity_estimator.py
def __init__(self, vqm: VirtualQuantumMachine, hidden_size=200, use_vqm=False):
    """
    Args:
        vqm(VirtualQuantumMachine): target machine
        hidden_size(int): hidden size of NN
        use_vqm(bool): whether to use vqm information when estimating
    """

    self.vqm = vqm
    self.hidden_size = hidden_size
    self.use_vqm = use_vqm
    self.scaler = StandardScaler()

    feature = self._compute_features(Circuit(vqm.qubit_number), vqm)
    self.model = ShallowFidelityNN(len(feature), hidden_size)

estimate_fidelity

estimate_fidelity(circ: Circuit, vqm: VirtualQuantumMachine = None, mapping: List[int] = None)

Estimate the fidelity of a given circuit.

Parameters:

  • circ(Circuit)

    given circuit

  • vqm(VirtualQuantumMachine)

    given vqm, use default vqm if not given

  • mapping(List[int])

    Mapping of the circuit. Identity if None.

Returns:

  • float

    fidelity

Source code in QuICT/qcda/utility/fidelity_estimator/nn_fidelity_estimator.py
def estimate_fidelity(self, circ: Circuit, vqm: VirtualQuantumMachine = None, mapping: List[int] = None):
    """
    Estimate the fidelity of a given circuit.

    Args:
        circ(Circuit): given circuit
        vqm(VirtualQuantumMachine): given vqm, use default vqm if not given
        mapping(List[int]): Mapping of the circuit. Identity if None.

    Returns:
        float: fidelity
    """

    circ.flatten()
    feature = self._compute_features(circ, vqm, mapping)
    feature = self.scaler.transform(np.array([feature]))
    inputs = torch.from_numpy(feature).float()
    outputs = self.model(inputs)
    return self.label_to_fidelity(outputs.item())

fit

fit(data, have_vqm=False, num_epochs=50000)

Fit the fidelity estimator with given data.

Parameters:

  • data(list)

    list of tuples (circ, vqm, fidelity)

  • have_vqm(bool)

    whether the data contains vqm

  • num_epochs(int)

    number of epochs to train

Source code in QuICT/qcda/utility/fidelity_estimator/nn_fidelity_estimator.py
def fit(self, data, have_vqm=False, num_epochs=50000):
    """
    Fit the fidelity estimator with given data.

    Args:
        data(list): list of tuples (circ, vqm, fidelity)
        have_vqm(bool): whether the data contains vqm
        num_epochs(int): number of epochs to train
    """

    # use default vqm if not given
    if not have_vqm:
        data = [[circ, None, f] for circ, f in data]

    features = []
    labels = []
    for circ, vqm, f in data:
        feature = self._compute_features(circ, vqm)
        features.append(feature)
        labels.append(self.fidelity_to_label(f))

    X = self.scaler.fit_transform(np.array(features))
    X = torch.tensor(X, dtype=torch.float32)

    y = torch.tensor(np.array(labels).reshape(-1, 1), dtype=torch.float32)
    criterion = nn.MSELoss()
    optimizer = optim.SGD(self.model.parameters(), lr=0.01)

    for epoch in range(num_epochs):
        outputs = self.model(X)
        optimizer.zero_grad()
        loss = criterion(outputs, y)
        loss.backward()
        optimizer.step()
        if epoch % 100 == 0:
            print('epoch {}, loss {}'.format(epoch, loss.item()))

from_target_machine classmethod

from_target_machine(target_machine)

Load default fidelity estimator from given target_machine. See NNFidelityEstimator.SUPPORTED_MACHINE for supported machines.

Parameters:

  • target_machine(str)

    target machine

Returns:

  • NNFidelityEstimator

    fidelity estimator

Source code in QuICT/qcda/utility/fidelity_estimator/nn_fidelity_estimator.py
@classmethod
def from_target_machine(cls, target_machine):
    """
    Load default fidelity estimator from given target_machine.
    See NNFidelityEstimator.SUPPORTED_MACHINE for supported machines.

    Args:
        target_machine(str): target machine

    Returns:
        NNFidelityEstimator: fidelity estimator
    """

    if target_machine not in cls.SUPPORTED_MACHINE:
        raise ValueError(f'Unsupported machine: {target_machine}')

    dir_path = os.path.join(os.path.dirname(__file__), 'models', f'{target_machine}')
    return cls.load(dir_path)

load classmethod

load(path)

Load a fidelity estimator from a given path.

Parameters:

  • path(str)

    path to the estimator

Returns:

  • NNFidelityEstimator

    fidelity estimator

Source code in QuICT/qcda/utility/fidelity_estimator/nn_fidelity_estimator.py
@classmethod
def load(cls, path):
    """
    Load a fidelity estimator from a given path.

    Args:
        path(str): path to the estimator

    Returns:
        NNFidelityEstimator: fidelity estimator
    """

    scaler = pkl.load(open(os.path.join(path, 'scaler.pkl'), 'rb'))
    params = pkl.load(open(os.path.join(path, 'params.pkl'), 'rb'))

    fe = cls(*params)
    fe.scaler = scaler
    fe.model.load_state_dict(torch.load(os.path.join(path, 'model.pt')))
    fe.model.eval()
    return fe

save

save(path)

Save the fidelity estimator to a given path.

Parameters:

  • path(str)

    path to save the estimator

Source code in QuICT/qcda/utility/fidelity_estimator/nn_fidelity_estimator.py
def save(self, path):
    """
    Save the fidelity estimator to a given path.

    Args:
        path(str): path to save the estimator
    """

    if not os.path.exists(path):
        os.makedirs(path)
    torch.save(self.model.state_dict(), os.path.join(path, 'model.pt'))
    pkl.dump(self.scaler, open(os.path.join(path, 'scaler.pkl'), 'wb'))
    params = (self.vqm, self.hidden_size, self.use_vqm)
    pkl.dump(params, open(os.path.join(path, 'params.pkl'), 'wb'))