طبقه بندی MNIST

مشاهده در TensorFlow.org در Google Colab اجرا شود مشاهده منبع در GitHub دانلود دفترچه یادداشت

این آموزش یک شبکه عصبی کوانتومی (QNN) برای طبقه بندی یک نسخه ساده شده از MNIST، مشابه رویکرد مورد استفاده در فرهی و همکاران، می سازد. عملکرد شبکه عصبی کوانتومی در این مشکل داده کلاسیک با یک شبکه عصبی کلاسیک مقایسه شده است.

برپایی

pip install tensorflow==2.7.0

TensorFlow Quantum را نصب کنید:

pip install tensorflow-quantum
# Update package resources to account for version changes.
import importlib, pkg_resources
importlib.reload(pkg_resources)
<module 'pkg_resources' from '/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/pkg_resources/__init__.py'>

اکنون TensorFlow و وابستگی های ماژول را وارد کنید:

import tensorflow as tf
import tensorflow_quantum as tfq

import cirq
import sympy
import numpy as np
import seaborn as sns
import collections

# visualization tools
%matplotlib inline
import matplotlib.pyplot as plt
from cirq.contrib.svg import SVGCircuit
2022-02-04 12:29:39.759643: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected

1. داده ها را بارگذاری کنید

در این آموزش شما یک طبقه بندی کننده باینری برای تمایز بین ارقام 3 و 6 با پیروی از فرهی و همکاران می سازید. این بخش مدیریت داده ها را پوشش می دهد که:

  • داده های خام را از Keras بارگیری می کند.
  • مجموعه داده را فقط به 3 و 6 فیلتر می کند.
  • تصاویر را کاهش می دهد تا بتوانند در یک کامپیوتر کوانتومی جا شوند.
  • نمونه های متناقض را حذف می کند.
  • تصاویر باینری را به مدارهای Cirq تبدیل می کند.
  • مدارهای Cirq را به مدارهای کوانتومی TensorFlow تبدیل می کند.

1.1 داده های خام را بارگیری کنید

مجموعه داده MNIST توزیع شده با Keras را بارگیری کنید.

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

# Rescale the images from [0,255] to the [0.0,1.0] range.
x_train, x_test = x_train[..., np.newaxis]/255.0, x_test[..., np.newaxis]/255.0

print("Number of original training examples:", len(x_train))
print("Number of original test examples:", len(x_test))
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 0s 0us/step
11501568/11490434 [==============================] - 0s 0us/step
Number of original training examples: 60000
Number of original test examples: 10000

مجموعه داده را فیلتر کنید تا فقط 3 و 6 باقی بماند، کلاس‌های دیگر را حذف کنید. در همان زمان، برچسب y را به بولی تبدیل کنید: True برای 3 و False برای 6.

def filter_36(x, y):
    keep = (y == 3) | (y == 6)
    x, y = x[keep], y[keep]
    y = y == 3
    return x,y
x_train, y_train = filter_36(x_train, y_train)
x_test, y_test = filter_36(x_test, y_test)

print("Number of filtered training examples:", len(x_train))
print("Number of filtered test examples:", len(x_test))
Number of filtered training examples: 12049
Number of filtered test examples: 1968

مثال اول را نشان دهید:

print(y_train[0])

plt.imshow(x_train[0, :, :, 0])
plt.colorbar()
True
<matplotlib.colorbar.Colorbar at 0x7fac6ad4bd90>

png

1.2 مقیاس تصاویر را کاهش دهید

اندازه تصویر 28x28 برای کامپیوترهای کوانتومی فعلی بسیار بزرگ است. اندازه تصویر را به 4x4 کاهش دهید:

x_train_small = tf.image.resize(x_train, (4,4)).numpy()
x_test_small = tf.image.resize(x_test, (4,4)).numpy()

مجدداً، اولین مثال آموزشی را نمایش دهید - بعد از تغییر اندازه:

print(y_train[0])

plt.imshow(x_train_small[0,:,:,0], vmin=0, vmax=1)
plt.colorbar()
True
<matplotlib.colorbar.Colorbar at 0x7fabf807fe10>

png

1.3 حذف نمونه های متناقض

از بخش 3.3 آموزش برای تشخیص ارقام فرهی و همکاران. ، مجموعه داده را فیلتر کنید تا تصاویری را که به عنوان متعلق به هر دو کلاس برچسب گذاری شده اند حذف کنید.

این یک روش استاندارد یادگیری ماشینی نیست، اما برای دنبال کردن مقاله گنجانده شده است.

def remove_contradicting(xs, ys):
    mapping = collections.defaultdict(set)
    orig_x = {}
    # Determine the set of labels for each unique image:
    for x,y in zip(xs,ys):
       orig_x[tuple(x.flatten())] = x
       mapping[tuple(x.flatten())].add(y)

    new_x = []
    new_y = []
    for flatten_x in mapping:
      x = orig_x[flatten_x]
      labels = mapping[flatten_x]
      if len(labels) == 1:
          new_x.append(x)
          new_y.append(next(iter(labels)))
      else:
          # Throw out images that match more than one label.
          pass

    num_uniq_3 = sum(1 for value in mapping.values() if len(value) == 1 and True in value)
    num_uniq_6 = sum(1 for value in mapping.values() if len(value) == 1 and False in value)
    num_uniq_both = sum(1 for value in mapping.values() if len(value) == 2)

    print("Number of unique images:", len(mapping.values()))
    print("Number of unique 3s: ", num_uniq_3)
    print("Number of unique 6s: ", num_uniq_6)
    print("Number of unique contradicting labels (both 3 and 6): ", num_uniq_both)
    print()
    print("Initial number of images: ", len(xs))
    print("Remaining non-contradicting unique images: ", len(new_x))

    return np.array(new_x), np.array(new_y)

شمارش های به دست آمده دقیقاً با مقادیر گزارش شده مطابقت ندارند، اما روش دقیق آن مشخص نشده است.

همچنین در اینجا شایان ذکر است که اعمال فیلتر کردن مثال‌های متناقض در این مرحله به طور کامل از دریافت نمونه‌های آموزشی متناقض مدل جلوگیری نمی‌کند: مرحله بعدی داده‌ها را باینریزه می‌کند که باعث برخورد بیشتر می‌شود.

x_train_nocon, y_train_nocon = remove_contradicting(x_train_small, y_train)
Number of unique images: 10387
Number of unique 3s:  4912
Number of unique 6s:  5426
Number of unique contradicting labels (both 3 and 6):  49

Initial number of images:  12049
Remaining non-contradicting unique images:  10338

1.4 داده ها را به عنوان مدارهای کوانتومی رمزگذاری کنید

فرهی و همکاران برای پردازش تصاویر با استفاده از کامپیوتر کوانتومی. پیشنهاد نشان دادن هر پیکسل با یک کیوبیت، با وضعیت بسته به مقدار پیکسل. اولین مرحله تبدیل به کدگذاری باینری است.

THRESHOLD = 0.5

x_train_bin = np.array(x_train_nocon > THRESHOLD, dtype=np.float32)
x_test_bin = np.array(x_test_small > THRESHOLD, dtype=np.float32)

اگر بخواهید در این مرحله تصاویر متناقض را حذف کنید، تنها 193 عکس خواهید داشت که احتمالا برای آموزش موثر کافی نیست.

_ = remove_contradicting(x_train_bin, y_train_nocon)
Number of unique images: 193
Number of unique 3s:  80
Number of unique 6s:  69
Number of unique contradicting labels (both 3 and 6):  44

Initial number of images:  10338
Remaining non-contradicting unique images:  149

کیوبیت‌ها در شاخص‌های پیکسلی با مقادیری که از یک آستانه فراتر می‌روند، از طریق یک گیت \(X\) .

def convert_to_circuit(image):
    """Encode truncated classical image into quantum datapoint."""
    values = np.ndarray.flatten(image)
    qubits = cirq.GridQubit.rect(4, 4)
    circuit = cirq.Circuit()
    for i, value in enumerate(values):
        if value:
            circuit.append(cirq.X(qubits[i]))
    return circuit


x_train_circ = [convert_to_circuit(x) for x in x_train_bin]
x_test_circ = [convert_to_circuit(x) for x in x_test_bin]

در اینجا مدار ایجاد شده برای مثال اول است (نمودارهای مدار کیوبیت ها را با دروازه های صفر نشان نمی دهند):

SVGCircuit(x_train_circ[0])
findfont: Font family ['Arial'] not found. Falling back to DejaVu Sans.

svg

این مدار را با شاخص هایی که مقدار تصویر از آستانه فراتر می رود مقایسه کنید:

bin_img = x_train_bin[0,:,:,0]
indices = np.array(np.where(bin_img)).T
indices
array([[2, 2],
       [3, 1]])

این مدارهای Cirq را به تانسور برای tfq :

x_train_tfcirc = tfq.convert_to_tensor(x_train_circ)
x_test_tfcirc = tfq.convert_to_tensor(x_test_circ)

2. شبکه عصبی کوانتومی

راهنمایی کمی برای ساختار مدار کوانتومی که تصاویر را طبقه بندی می کند وجود دارد. از آنجایی که طبقه بندی بر اساس انتظار کیوبیت بازخوانی است، فرهی و همکاران. پیشنهاد استفاده از دو دروازه کیوبیت، با کیوبیت بازخوانی همیشه بر اساس عمل می شود. این از برخی جهات شبیه اجرای یک RNN واحد کوچک در سراسر پیکسل ها است.

2.1 مدار مدل را بسازید

این مثال زیر این رویکرد لایه ای را نشان می دهد. هر لایه از n نمونه از یک گیت استفاده می کند که هر یک از کیوبیت های داده روی کیوبیت بازخوانی عمل می کنند.

با یک کلاس ساده شروع کنید که لایه ای از این گیت ها را به مدار اضافه می کند:

class CircuitLayerBuilder():
    def __init__(self, data_qubits, readout):
        self.data_qubits = data_qubits
        self.readout = readout

    def add_layer(self, circuit, gate, prefix):
        for i, qubit in enumerate(self.data_qubits):
            symbol = sympy.Symbol(prefix + '-' + str(i))
            circuit.append(gate(qubit, self.readout)**symbol)

یک لایه مدار نمونه بسازید تا ببینید چگونه به نظر می رسد:

demo_builder = CircuitLayerBuilder(data_qubits = cirq.GridQubit.rect(4,1),
                                   readout=cirq.GridQubit(-1,-1))

circuit = cirq.Circuit()
demo_builder.add_layer(circuit, gate = cirq.XX, prefix='xx')
SVGCircuit(circuit)

svg

اکنون یک مدل دو لایه بسازید که با اندازه مدار داده مطابقت داشته باشد و عملیات آماده سازی و بازخوانی را نیز شامل شود.

def create_quantum_model():
    """Create a QNN model circuit and readout operation to go along with it."""
    data_qubits = cirq.GridQubit.rect(4, 4)  # a 4x4 grid.
    readout = cirq.GridQubit(-1, -1)         # a single qubit at [-1,-1]
    circuit = cirq.Circuit()

    # Prepare the readout qubit.
    circuit.append(cirq.X(readout))
    circuit.append(cirq.H(readout))

    builder = CircuitLayerBuilder(
        data_qubits = data_qubits,
        readout=readout)

    # Then add layers (experiment by adding more).
    builder.add_layer(circuit, cirq.XX, "xx1")
    builder.add_layer(circuit, cirq.ZZ, "zz1")

    # Finally, prepare the readout qubit.
    circuit.append(cirq.H(readout))

    return circuit, cirq.Z(readout)
model_circuit, model_readout = create_quantum_model()

2.2 مدار مدل را در مدل tfq-keras بپیچید

مدل کراس را با اجزای کوانتومی بسازید. این مدل از "داده های کوانتومی" از x_train_circ می کند که داده های کلاسیک را رمزگذاری می کند. برای آموزش مدار مدل بر روی داده های کوانتومی، از یک لایه مدار کوانتومی پارامتریزه شده، tfq.layers.PQC استفاده می کند.

برای طبقه بندی این تصاویر، فرهی و همکاران. دریافت انتظار یک کیوبیت بازخوانی در یک مدار پارامتری شده را پیشنهاد کرد. انتظار مقداری بین 1 و -1 برمی گرداند.

# Build the Keras model.
model = tf.keras.Sequential([
    # The input is the data-circuit, encoded as a tf.string
    tf.keras.layers.Input(shape=(), dtype=tf.string),
    # The PQC layer returns the expected value of the readout gate, range [-1,1].
    tfq.layers.PQC(model_circuit, model_readout),
])

سپس، با استفاده از روش compile ، روند آموزش را برای مدل توضیح دهید.

از آنجایی که بازخوانی مورد انتظار در محدوده [-1,1] است، بهینه سازی افت لولا تا حدودی یک تناسب طبیعی است.

برای استفاده از افت لولا در اینجا باید دو تنظیم کوچک انجام دهید. ابتدا برچسب‌ها، y_train_nocon را از boolean به [-1,1] تبدیل کنید، همانطور که از دست دادن لولا انتظار می‌رود.

y_train_hinge = 2.0*y_train_nocon-1.0
y_test_hinge = 2.0*y_test-1.0

دوم، از یک متریک hinge_accuracy استفاده کنید که [-1, 1] به‌عنوان آرگومان y_true labels به درستی مدیریت می‌کند. tf.losses.BinaryAccuracy(threshold=0.0) انتظار دارد که y_true یک Boolean باشد و بنابراین نمی توان با از دست دادن لولا از آن استفاده کرد.

def hinge_accuracy(y_true, y_pred):
    y_true = tf.squeeze(y_true) > 0.0
    y_pred = tf.squeeze(y_pred) > 0.0
    result = tf.cast(y_true == y_pred, tf.float32)

    return tf.reduce_mean(result)
model.compile(
    loss=tf.keras.losses.Hinge(),
    optimizer=tf.keras.optimizers.Adam(),
    metrics=[hinge_accuracy])
print(model.summary())
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 pqc (PQC)                   (None, 1)                 32        
                                                                 
=================================================================
Total params: 32
Trainable params: 32
Non-trainable params: 0
_________________________________________________________________
None

آموزش مدل کوانتومی

اکنون مدل را آموزش دهید - این حدود 45 دقیقه طول می کشد. اگر نمی‌خواهید آنقدر صبر کنید، از یک زیرمجموعه کوچک از داده‌ها استفاده کنید (مجموعه NUM_EXAMPLES=500 ، در زیر). این واقعاً بر پیشرفت مدل در طول آموزش تأثیر نمی گذارد (فقط 32 پارامتر دارد و برای محدود کردن آنها به داده های زیادی نیاز ندارد). استفاده از نمونه‌های کمتر، آموزش را زودتر به پایان می‌رساند (5 دقیقه)، اما به اندازه‌ای طول می‌کشد که نشان دهد در گزارش‌های اعتبارسنجی پیشرفت می‌کند.

EPOCHS = 3
BATCH_SIZE = 32

NUM_EXAMPLES = len(x_train_tfcirc)
x_train_tfcirc_sub = x_train_tfcirc[:NUM_EXAMPLES]
y_train_hinge_sub = y_train_hinge[:NUM_EXAMPLES]

آموزش این مدل برای همگرایی باید به دقت بیش از 85 درصد در مجموعه آزمایشی دست یابد.

qnn_history = model.fit(
      x_train_tfcirc_sub, y_train_hinge_sub,
      batch_size=32,
      epochs=EPOCHS,
      verbose=1,
      validation_data=(x_test_tfcirc, y_test_hinge))

qnn_results = model.evaluate(x_test_tfcirc, y_test)
Epoch 1/3
324/324 [==============================] - 68s 207ms/step - loss: 0.6745 - hinge_accuracy: 0.7719 - val_loss: 0.3959 - val_hinge_accuracy: 0.8004
Epoch 2/3
324/324 [==============================] - 68s 209ms/step - loss: 0.3964 - hinge_accuracy: 0.8291 - val_loss: 0.3498 - val_hinge_accuracy: 0.8997
Epoch 3/3
324/324 [==============================] - 66s 204ms/step - loss: 0.3599 - hinge_accuracy: 0.8854 - val_loss: 0.3395 - val_hinge_accuracy: 0.9042
62/62 [==============================] - 3s 41ms/step - loss: 0.3395 - hinge_accuracy: 0.9042

3. شبکه عصبی کلاسیک

در حالی که شبکه عصبی کوانتومی برای این مسئله ساده شده MNIST کار می کند، یک شبکه عصبی کلاسیک پایه می تواند به راحتی از QNN در این کار بهتر عمل کند. پس از یک دوره واحد، یک شبکه عصبی کلاسیک می‌تواند به دقت بیش از 98 درصد در مجموعه نگهدارنده دست یابد.

در مثال زیر، یک شبکه عصبی کلاسیک برای مسئله طبقه بندی 3-6 با استفاده از کل تصویر 28x28 به جای نمونه برداری فرعی از تصویر استفاده شده است. این به راحتی به دقت نزدیک به 100٪ مجموعه تست همگرا می شود.

def create_classical_model():
    # A simple model based off LeNet from https://keras.io/examples/mnist_cnn/
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Conv2D(32, [3, 3], activation='relu', input_shape=(28,28,1)))
    model.add(tf.keras.layers.Conv2D(64, [3, 3], activation='relu'))
    model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
    model.add(tf.keras.layers.Dropout(0.25))
    model.add(tf.keras.layers.Flatten())
    model.add(tf.keras.layers.Dense(128, activation='relu'))
    model.add(tf.keras.layers.Dropout(0.5))
    model.add(tf.keras.layers.Dense(1))
    return model


model = create_classical_model()
model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              optimizer=tf.keras.optimizers.Adam(),
              metrics=['accuracy'])

model.summary()
Model: "sequential_1"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 26, 26, 32)        320       
                                                                 
 conv2d_1 (Conv2D)           (None, 24, 24, 64)        18496     
                                                                 
 max_pooling2d (MaxPooling2D  (None, 12, 12, 64)       0         
 )                                                               
                                                                 
 dropout (Dropout)           (None, 12, 12, 64)        0         
                                                                 
 flatten (Flatten)           (None, 9216)              0         
                                                                 
 dense (Dense)               (None, 128)               1179776   
                                                                 
 dropout_1 (Dropout)         (None, 128)               0         
                                                                 
 dense_1 (Dense)             (None, 1)                 129       
                                                                 
=================================================================
Total params: 1,198,721
Trainable params: 1,198,721
Non-trainable params: 0
_________________________________________________________________
model.fit(x_train,
          y_train,
          batch_size=128,
          epochs=1,
          verbose=1,
          validation_data=(x_test, y_test))

cnn_results = model.evaluate(x_test, y_test)
95/95 [==============================] - 3s 31ms/step - loss: 0.0400 - accuracy: 0.9842 - val_loss: 0.0057 - val_accuracy: 0.9970
62/62 [==============================] - 0s 3ms/step - loss: 0.0057 - accuracy: 0.9970

مدل فوق نزدیک به 1.2M پارامتر دارد. برای مقایسه منصفانه تر، یک مدل 37 پارامتری را روی تصاویر زیر نمونه امتحان کنید:

def create_fair_classical_model():
    # A simple model based off LeNet from https://keras.io/examples/mnist_cnn/
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Flatten(input_shape=(4,4,1)))
    model.add(tf.keras.layers.Dense(2, activation='relu'))
    model.add(tf.keras.layers.Dense(1))
    return model


model = create_fair_classical_model()
model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              optimizer=tf.keras.optimizers.Adam(),
              metrics=['accuracy'])

model.summary()
Model: "sequential_2"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 flatten_1 (Flatten)         (None, 16)                0         
                                                                 
 dense_2 (Dense)             (None, 2)                 34        
                                                                 
 dense_3 (Dense)             (None, 1)                 3         
                                                                 
=================================================================
Total params: 37
Trainable params: 37
Non-trainable params: 0
_________________________________________________________________
model.fit(x_train_bin,
          y_train_nocon,
          batch_size=128,
          epochs=20,
          verbose=2,
          validation_data=(x_test_bin, y_test))

fair_nn_results = model.evaluate(x_test_bin, y_test)
Epoch 1/20
81/81 - 1s - loss: 0.6678 - accuracy: 0.6546 - val_loss: 0.6326 - val_accuracy: 0.7358 - 503ms/epoch - 6ms/step
Epoch 2/20
81/81 - 0s - loss: 0.6186 - accuracy: 0.7654 - val_loss: 0.5787 - val_accuracy: 0.7515 - 98ms/epoch - 1ms/step
Epoch 3/20
81/81 - 0s - loss: 0.5629 - accuracy: 0.7861 - val_loss: 0.5247 - val_accuracy: 0.7764 - 104ms/epoch - 1ms/step
Epoch 4/20
81/81 - 0s - loss: 0.5150 - accuracy: 0.8301 - val_loss: 0.4825 - val_accuracy: 0.8196 - 103ms/epoch - 1ms/step
Epoch 5/20
81/81 - 0s - loss: 0.4762 - accuracy: 0.8493 - val_loss: 0.4490 - val_accuracy: 0.8293 - 97ms/epoch - 1ms/step
Epoch 6/20
81/81 - 0s - loss: 0.4438 - accuracy: 0.8527 - val_loss: 0.4216 - val_accuracy: 0.8298 - 99ms/epoch - 1ms/step
Epoch 7/20
81/81 - 0s - loss: 0.4169 - accuracy: 0.8555 - val_loss: 0.3986 - val_accuracy: 0.8313 - 98ms/epoch - 1ms/step
Epoch 8/20
81/81 - 0s - loss: 0.3951 - accuracy: 0.8595 - val_loss: 0.3794 - val_accuracy: 0.8313 - 105ms/epoch - 1ms/step
Epoch 9/20
81/81 - 0s - loss: 0.3773 - accuracy: 0.8596 - val_loss: 0.3635 - val_accuracy: 0.8328 - 98ms/epoch - 1ms/step
Epoch 10/20
81/81 - 0s - loss: 0.3620 - accuracy: 0.8611 - val_loss: 0.3499 - val_accuracy: 0.8333 - 97ms/epoch - 1ms/step
Epoch 11/20
81/81 - 0s - loss: 0.3488 - accuracy: 0.8714 - val_loss: 0.3382 - val_accuracy: 0.8720 - 98ms/epoch - 1ms/step
Epoch 12/20
81/81 - 0s - loss: 0.3372 - accuracy: 0.8831 - val_loss: 0.3279 - val_accuracy: 0.8720 - 95ms/epoch - 1ms/step
Epoch 13/20
81/81 - 0s - loss: 0.3271 - accuracy: 0.8831 - val_loss: 0.3187 - val_accuracy: 0.8725 - 97ms/epoch - 1ms/step
Epoch 14/20
81/81 - 0s - loss: 0.3181 - accuracy: 0.8832 - val_loss: 0.3107 - val_accuracy: 0.8725 - 96ms/epoch - 1ms/step
Epoch 15/20
81/81 - 0s - loss: 0.3101 - accuracy: 0.8833 - val_loss: 0.3035 - val_accuracy: 0.8725 - 96ms/epoch - 1ms/step
Epoch 16/20
81/81 - 0s - loss: 0.3030 - accuracy: 0.8833 - val_loss: 0.2972 - val_accuracy: 0.8725 - 105ms/epoch - 1ms/step
Epoch 17/20
81/81 - 0s - loss: 0.2966 - accuracy: 0.8833 - val_loss: 0.2913 - val_accuracy: 0.8725 - 104ms/epoch - 1ms/step
Epoch 18/20
81/81 - 0s - loss: 0.2908 - accuracy: 0.8928 - val_loss: 0.2861 - val_accuracy: 0.8725 - 104ms/epoch - 1ms/step
Epoch 19/20
81/81 - 0s - loss: 0.2856 - accuracy: 0.8955 - val_loss: 0.2816 - val_accuracy: 0.8725 - 99ms/epoch - 1ms/step
Epoch 20/20
81/81 - 0s - loss: 0.2809 - accuracy: 0.8952 - val_loss: 0.2773 - val_accuracy: 0.8725 - 101ms/epoch - 1ms/step
62/62 [==============================] - 0s 895us/step - loss: 0.2773 - accuracy: 0.8725

4. مقایسه

ورودی وضوح بالاتر و مدل قدرتمندتر این مشکل را برای CNN آسان می کند. در حالی که یک مدل کلاسیک با قدرت مشابه (~32 پارامتر) در کسری از زمان به دقت مشابهی آموزش می‌دهد. به هر حال، شبکه عصبی کلاسیک به راحتی از شبکه عصبی کوانتومی بهتر عمل می کند. برای داده های کلاسیک، شکست دادن یک شبکه عصبی کلاسیک دشوار است.

qnn_accuracy = qnn_results[1]
cnn_accuracy = cnn_results[1]
fair_nn_accuracy = fair_nn_results[1]

sns.barplot(["Quantum", "Classical, full", "Classical, fair"],
            [qnn_accuracy, cnn_accuracy, fair_nn_accuracy])
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/seaborn/_decorators.py:43: FutureWarning: Pass the following variables as keyword args: x, y. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation.
  FutureWarning
<AxesSubplot:>

png