مشاهده در 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>
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>
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.
این مدار را با شاخص هایی که مقدار تصویر از آستانه فراتر می رود مقایسه کنید:
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)
اکنون یک مدل دو لایه بسازید که با اندازه مدار داده مطابقت داشته باشد و عملیات آماده سازی و بازخوانی را نیز شامل شود.
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:>