Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2019, 2021.
# (C) Copyright IBM 2019, 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand All @@ -14,22 +14,10 @@
Discriminator
"""

import logging
from qiskit.exceptions import MissingOptionalLibraryError
import qiskit_machine_learning.optionals as _optionals

logger = logging.getLogger(__name__)

try:
if _optionals.HAS_TORCH:
import torch
from torch import nn
except ImportError:
if logger.isEnabledFor(logging.INFO):
EXC = MissingOptionalLibraryError(
libname="Pytorch",
name="DiscriminatorNet",
pip_install="pip install 'qiskit-machine-learning[torch]'",
)
logger.info(str(EXC))

# torch 1.6.0 fixed a mypy error about not applying contravariance rules
# to inputs by defining forward as a value, rather than a function. See also
Expand All @@ -39,6 +27,7 @@
# The pylint disable=abstract-method fixes it.


@_optionals.HAS_TORCH.require_in_instance
class DiscriminatorNet(torch.nn.Module): # pylint: disable=abstract-method
"""
Discriminator
Expand All @@ -54,6 +43,9 @@ def __init__(self, n_features: int = 1, n_out: int = 1) -> None:
"""

super().__init__()
# pylint: disable=import-error
from torch import nn

self.n_features = n_features

self.hidden0 = nn.Sequential(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2019, 2021.
# (C) Copyright IBM 2019, 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand Down Expand Up @@ -274,7 +274,7 @@ def load_model(self, load_dir):
Load discriminator model

Args:
load_dir (str): file with stored pytorch discriminator model to be loaded
load_dir (str): file with stored PyTorch discriminator model to be loaded
"""
self._discriminator.architecture = np.load(
os.path.join(load_dir, "np_discriminator_architecture.csv")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2019, 2021.
# (C) Copyright IBM 2019, 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand All @@ -17,20 +17,12 @@
from typing import Dict, Any, Iterable, Optional, Sequence, cast
import os
import numpy as np
from qiskit.exceptions import MissingOptionalLibraryError
from qiskit.utils import QuantumInstance
import qiskit_machine_learning.optionals as _optionals
from .discriminative_network import DiscriminativeNetwork

try:
import torch
from torch import nn, optim
from torch.autograd.variable import Variable

_HAS_TORCH = True
except ImportError:
_HAS_TORCH = False


@_optionals.HAS_TORCH.require_in_instance
class PyTorchDiscriminator(DiscriminativeNetwork):
"""
Discriminator based on PyTorch
Expand All @@ -41,17 +33,10 @@ def __init__(self, n_features: int = 1, n_out: int = 1) -> None:
Args:
n_features: Dimension of input data vector.
n_out: Dimension of the discriminator's output vector.

Raises:
MissingOptionalLibraryError: Pytorch not installed
"""
super().__init__()
if not _HAS_TORCH:
raise MissingOptionalLibraryError(
libname="Pytorch",
name="PyTorchDiscriminator",
pip_install="pip install 'qiskit-meachine-learning[torch]'",
)
# pylint: disable=import-outside-toplevel
from torch import optim

self._n_features = n_features
self._n_out = n_out
Expand All @@ -73,6 +58,8 @@ def set_seed(self, seed: int):
Args:
seed: seed
"""
import torch

torch.manual_seed(seed)

def save_model(self, snapshot_dir: str):
Expand All @@ -82,15 +69,19 @@ def save_model(self, snapshot_dir: str):
Args:
snapshot_dir: directory path for saving the model
"""
import torch

torch.save(self._discriminator, os.path.join(snapshot_dir, "discriminator.pt"))

def load_model(self, load_dir: str):
"""
Load discriminator model

Args:
load_dir: file with stored pytorch discriminator model to be loaded
load_dir: file with stored PyTorch discriminator model to be loaded
"""
import torch

self._discriminator = torch.load(load_dir)

@property
Expand Down Expand Up @@ -118,11 +109,14 @@ def get_label(self, x, detach=False): # pylint: disable=arguments-differ
Returns:
torch.Tensor: Discriminator output, i.e. data label
"""

# pylint: disable=not-callable, no-member
import torch

if isinstance(x, torch.Tensor):
pass
else:
from torch.autograd.variable import Variable

x = torch.tensor(x, dtype=torch.float32)
x = Variable(x)

Expand All @@ -143,6 +137,8 @@ def loss(self, x, y, weights=None):
Returns:
torch.Tensor: Loss w.r.t to the generated data points.
"""
from torch import nn

if weights is not None:
loss_funct = nn.BCELoss(weight=weights, reduction="sum")
else:
Expand All @@ -164,9 +160,13 @@ def gradient_penalty(self, x, lambda_=5.0, k=0.01, c=1.0):
torch.Tensor: Gradient penalty.
"""
# pylint: disable=not-callable, no-member
import torch

if isinstance(x, torch.Tensor):
pass
else:
from torch.autograd.variable import Variable

x = torch.tensor(x, dtype=torch.float32)
x = Variable(x)
# pylint: disable=no-member
Expand Down Expand Up @@ -207,6 +207,9 @@ def train(
"""
# pylint: disable=E1101
# pylint: disable=E1102
import torch
from torch.autograd.variable import Variable

# Reset gradients
self._optimizer.zero_grad()
real_batch = cast(Sequence, data)[0]
Expand Down
15 changes: 8 additions & 7 deletions qiskit_machine_learning/algorithms/objective_functions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
# (C) Copyright IBM 2021, 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
Expand All @@ -17,9 +17,14 @@

import numpy as np

try:
import qiskit_machine_learning.optionals as _optionals
from qiskit_machine_learning.neural_networks import NeuralNetwork
from qiskit_machine_learning.utils.loss_functions import Loss

if _optionals.HAS_SPARSE:
# pylint: disable=import-error
from sparse import SparseArray
except ImportError:
else:

class SparseArray: # type: ignore
"""Empty SparseArray class
Expand All @@ -29,10 +34,6 @@ class SparseArray: # type: ignore
pass


from qiskit_machine_learning.neural_networks import NeuralNetwork
from qiskit_machine_learning.utils.loss_functions import Loss


class ObjectiveFunction:
"""An abstract objective function. Provides methods for computing objective value and
gradients for forward and backward passes."""
Expand Down
33 changes: 9 additions & 24 deletions qiskit_machine_learning/connectors/torch_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,17 @@

from typing import Tuple, Any, Optional, cast, Union
import numpy as np
from qiskit.exceptions import MissingOptionalLibraryError

try:
from sparse import SparseArray, COO

_HAS_SPARSE = True
except ImportError:
_HAS_SPARSE = False

import qiskit_machine_learning.optionals as _optionals
from ..neural_networks import NeuralNetwork
from ..exceptions import QiskitMachineLearningError
from ..deprecation import deprecate_property

try:
if _optionals.HAS_TORCH:
from torch import Tensor, sparse_coo_tensor, einsum
from torch.autograd import Function
from torch.nn import Module, Parameter as TorchParam
except ImportError:
else:

class Function: # type: ignore
"""Empty Function class
Expand All @@ -50,17 +43,12 @@ class Tensor: # type: ignore
class Module: # type: ignore
"""Empty Module class
Replacement if torch.nn.Module is not present.
Always fails to initialize
"""

def __init__(self) -> None:
raise MissingOptionalLibraryError(
libname="Pytorch",
name="TorchConnector",
pip_install="pip install 'qiskit-machine-learning[torch]'",
)
pass


@_optionals.HAS_TORCH.require_in_instance
class TorchConnector(Module):
"""Connects a Qiskit (Quantum) Neural Network to PyTorch."""

Expand Down Expand Up @@ -88,7 +76,6 @@ def forward( # type: ignore

Raises:
QiskitMachineLearningError: Invalid input data.
MissingOptionalLibraryError: sparse not installed.
"""

# validate input shape
Expand All @@ -109,12 +96,10 @@ def forward( # type: ignore
input_data.detach().cpu().numpy(), weights.detach().cpu().numpy()
)
if neural_network.sparse and sparse:
if not _HAS_SPARSE:
raise MissingOptionalLibraryError(
libname="sparse",
name="COO",
pip_install="pip install 'qiskit-machine-learning[sparse]'",
)
_optionals.HAS_SPARSE.require_now("COO")
# pylint: disable=import-error
from sparse import SparseArray, COO

result = cast(COO, cast(SparseArray, result).asformat("coo"))
result_tensor = sparse_coo_tensor(result.coords, result.data)
else:
Expand Down
26 changes: 8 additions & 18 deletions qiskit_machine_learning/datasets/ad_hoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@

import numpy as np
import scipy
from qiskit.utils import algorithm_globals
from qiskit.exceptions import MissingOptionalLibraryError
from qiskit.utils import algorithm_globals, optionals

from qiskit_machine_learning.datasets.dataset_helper import (
features_and_labels_transform,
Expand Down Expand Up @@ -167,14 +166,9 @@ def ad_hoc_data(
}

if plot_data:
try:
import matplotlib.pyplot as plt
except ImportError as ex:
raise MissingOptionalLibraryError(
libname="Matplotlib",
name="ad_hoc_data",
pip_install="pip install matplotlib",
) from ex
optionals.HAS_MATPLOTLIB.require_now("ad_hoc_data")
# pylint: disable=import-error
import matplotlib.pyplot as plt

plt.show()
fig2 = plt.figure()
Expand Down Expand Up @@ -260,14 +254,10 @@ def ad_hoc_data(
}

if plot_data:
try:
import matplotlib.pyplot as plt
except ImportError as ex:
raise MissingOptionalLibraryError(
libname="Matplotlib",
name="ad_hoc_data",
pip_install="pip install matplotlib",
) from ex
optionals.HAS_MATPLOTLIB.require_now("ad_hoc_data")
# pylint: disable=import-error
import matplotlib.pyplot as plt

sample_total_a = np.asarray(sample_total_a)
sample_total_b = np.asarray(sample_total_b)
x_1 = sample_total_a[:, 0]
Expand Down
14 changes: 5 additions & 9 deletions qiskit_machine_learning/datasets/breast_cancer.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.decomposition import PCA
from qiskit.exceptions import MissingOptionalLibraryError
from qiskit.utils import optionals
from .dataset_helper import features_and_labels_transform
from ..deprecation import deprecate_function

Expand Down Expand Up @@ -68,14 +68,10 @@ def breast_cancer(training_size, test_size, n, plot_data=False, one_hot=True):
)

if plot_data:
try:
import matplotlib.pyplot as plt
except ImportError as ex:
raise MissingOptionalLibraryError(
libname="Matplotlib",
name="breast_cancer",
pip_install="pip install matplotlib",
) from ex
optionals.HAS_MATPLOTLIB.require_now("breast_cancer")
# pylint: disable=import-error
import matplotlib.pyplot as plt

for k in range(0, 2):
plt.scatter(
sample_train[label_train == k, 0][:training_size],
Expand Down
Loading