变分量子分类器(Variational Quantum Classifier,简称 VQC)是一种利用量子计算技术进行分类工作的机器学习算法。它属于量子机器学习算法家族,旨在利用量子计算机的计算能力,潜在地晋升经典机器学习办法的性能。
VQC 的根本思维是应用一个量子电路,也称为变分量子电路,将输出数据编码并映射到量子态上。而后,应用量子门和测量操作对这些量子态进行操作,以提取与分类工作相干的特色。最初,解决测量后果,并将其用于为输出数据调配类别标签。
VQC 将经典优化技术与量子计算相结合。在训练过程中,将变分量子电路在量子计算机或模拟器上反复执行,并将后果与训练数据的实在标签进行比拟。通过迭代地调整变分量子电路的参数,使其在预测标签与实在标签之间的差别上最小化代价函数。这个优化过程旨在找到最优的量子电路配置,从而最大化分类准确性。尽管看起来很简略,但这种混合计算体系结构存在很多的挑战。
特色映射是第一阶段,其中数据必须编码为量子位。有许多编码方法,因为特色映射是从一个向量空间到另一个向量空间的数学变换。所以钻研如何为每个问题找到最佳映射,就是一个待钻研的问题
有了映射,还要设计一个量子电路作为模型,这是第二阶段。在这里咱们能够随心所愿地施展创意,但必须思考到同样的旧规定依然很重要: 对于简略的问题,不要应用太多的参数来防止过拟合,也不能应用太少的参数来防止偏差,并且因为咱们正在应用量子计算,为了从量子计算范式中获得最佳成果,必须与叠加(superposition)和纠缠(entanglement)一起工作。
并且量子电路是线性变换,咱们还须要对其输入进行解决。比方非线性化的激活。
数据集和特色
这里咱们将基于泰坦尼克号数据集设计一个分类器,咱们的数据集有以下特色:
- PassengerID
- Passenger name
- Class (First, second or third)
- Gender
- Age
- SibSP (siblings and/or spouses aboard)
- Parch (parents or children aboard)
- Ticket
- Fare
- Cabin
- Embarked
- Survived
咱们要构建一个依据乘客的特色预测乘客是否幸存的分类器。所以咱们只抉择几个变量作为示例:
- is_child (if age <12)
- is_class1 (if person is in the first class)
- is_class2
- is_female
因为只有四个变量,所以咱们应用将应用 Basis Embedding。咱们只需将经典位转换为等效量子位。比方咱们的四个变量是 1010,这将被转换为 |1010>。
模型
咱们的模型是可参数化量子电路。这个电路必须具备肯定水平的叠加和纠缠,这样能力证实应用量子组件是正当的,咱们的模型如下:
这个模型可能看起来很简单,但他的想法相当简略。这是一个双层电路,因为外围构造反复了 2 次。首先,咱们为每个量子位绕 Z、Y 和 Z 轴旋转,这里的想法是别离在每个量子位上插入某种程度的叠加。这些旋转是参数化的,并且在算法的每次交互中,这些参数将由经典计算机更新。而后就是 Y 轴和 Z 轴上的旋转,因为量子位的矢量空间是一个球体(布洛赫球体)。RZ 只会扭转量子比特相位,RY 会影响量子比特与 |0> 和 |1> 的靠近水平。
每对量子位之间有四个受控非 (CNOT) 状态,这是一个量子门,依据另一个量子位(别离为指标和管制)的状态反转一个量子位状态。也就是说这个门纠缠了咱们电路中的所有量子位,当初所有状态都纠缠了。在第二层中,咱们利用了一组新的旋转,这不仅仅是第一层的逻辑反复,因为当初所有状态都纠缠在一起,这意味着旋转第一个量子比特也会影响其余量子比特!最初咱们有了一组新的 CNOT 门。
这是对咱们下面模型的非常简单的解释,上面代码会让这些内容变得更清晰。
优化器
我应用的是 Adam Optimizer,然而这个优化器是通过非凡解决的,咱们间接应用 pennylane 库。
代码实现
这里咱们间接应用 Pennylane 和 sklearn 实现代码。
importpennylaneasqml
frompennylaneimportnumpyasnp
frompennylane.optimizeimportAdamOptimizer
fromsklearn.model_selectionimporttrain_test_split
importpandasaspd
fromsklearn.metricsimportaccuracy_score
fromsklearn.metricsimportf1_score
fromsklearn.metricsimportprecision_score
fromsklearn.metricsimportrecall_score
importmath
num_qubits=4
num_layers=2
dev=qml.device("default.qubit", wires=num_qubits)
# quantum circuit functions
defstatepreparation(x):
qml.BasisEmbedding(x, wires=range(0, num_qubits))
deflayer(W):
qml.Rot(W[0, 0], W[0, 1], W[0, 2], wires=0)
qml.Rot(W[1, 0], W[1, 1], W[1, 2], wires=1)
qml.Rot(W[2, 0], W[2, 1], W[2, 2], wires=2)
qml.Rot(W[3, 0], W[3, 1], W[3, 2], wires=3)
qml.CNOT(wires=[0, 1])
qml.CNOT(wires=[1, 2])
qml.CNOT(wires=[2, 3])
qml.CNOT(wires=[3, 0])
@qml.qnode(dev, interface="autograd")
defcircuit(weights, x):
statepreparation(x)
forWinweights:
layer(W)
returnqml.expval(qml.PauliZ(0))
defvariational_classifier(weights, bias, x):
returncircuit(weights, x) +bias
defsquare_loss(labels, predictions):
loss=0
forl, pinzip(labels, predictions):
loss=loss+ (l-p) **2
loss=loss/len(labels)
returnloss
defaccuracy(labels, predictions):
loss=0
forl, pinzip(labels, predictions):
ifabs(l-p) <1e-5:
loss=loss+1
loss=loss/len(labels)
returnloss
defcost(weights, bias, X, Y):
predictions= [variational_classifier(weights, bias, x) forxinX]
returnsquare_loss(Y, predictions)
# preparaing data
df_train=pd.read_csv('train.csv')
df_train['Pclass'] =df_train['Pclass'].astype(str)
df_train=pd.concat([df_train, pd.get_dummies(df_train[['Pclass', 'Sex', 'Embarked']])], axis=1)
# I will fill missings with the median
df_train['Age'] =df_train['Age'].fillna(df_train['Age'].median())
df_train['is_child'] =df_train['Age'].map(lambdax: 1ifx<12else0)
cols_model= ['is_child', 'Pclass_1', 'Pclass_2', 'Sex_female']
X_train, X_test, y_train, y_test=train_test_split(df_train[cols_model], df_train['Survived'], test_size=0.10, random_state=42, stratify=df_train['Survived'])
X_train=np.array(X_train.values, requires_grad=False)
Y_train=np.array(y_train.values*2-np.ones(len(y_train)), requires_grad=False)
# setting init params
np.random.seed(0)
weights_init=0.01*np.random.randn(num_layers, num_qubits, 3, requires_grad=True)
bias_init=np.array(0.0, requires_grad=True)
opt=AdamOptimizer(0.125)
num_it=70
batch_size=math.floor(len(X_train)/num_it)
weights=weights_init
bias=bias_init
foritinrange(num_it):
# Update the weights by one optimizer step
batch_index=np.random.randint(0, len(X_train), (batch_size,))
X_batch=X_train[batch_index]
Y_batch=Y_train[batch_index]
weights, bias, _, _=opt.step(cost, weights, bias, X_batch, Y_batch)
# Compute accuracy
predictions= [np.sign(variational_classifier(weights, bias, x)) forxinX_train]
acc=accuracy(Y_train, predictions)
print("Iter: {:5d} | Cost: {:0.7f} | Accuracy: {:0.7f}".format(it+1, cost(weights, bias, X_train, Y_train), acc
)
)
X_test=np.array(X_test.values, requires_grad=False)
Y_test=np.array(y_test.values*2-np.ones(len(y_test)), requires_grad=False)
predictions= [np.sign(variational_classifier(weights, bias, x)) forxinX_test]
accuracy_score(Y_test, predictions)
precision_score(Y_test, predictions)
recall_score(Y_test, predictions)
f1_score(Y_test, predictions, average='macro')
最初失去的后果如下:
Accuracy: 78.89%
Precision: 76.67%
Recall: 65.71%
F1: 77.12%
为了比拟,咱们应用经典的逻辑回归作为比照,
Accuracy: 75.56%
Precision: 69.70%
Recall: 65.71%
F1: 74.00%
能够看到 VQC 比逻辑回归模型略微好一点! 这并不意味着 VQC 肯定更好,因为只是这个特定的模型和特定的优化过程体现得更好。但这篇文章的次要还是是展现构建一个量子分类器是很简略的,并且是无效的。
总结
VQC 算法须要同时利用经典资源和量子资源。经典局部解决优化和参数更新,而量子局部在量子态上执行计算。VQC 的性能和潜在劣势取决于诸如分类问题的复杂性、量子硬件的品质以及适合的量子特色映射和量子门的可用性等因素。
最重要的是:量子机器学习畛域仍处于晚期阶段,VQC 的理论实现和有效性目前受到构建大规模、纠错的量子计算机的挑战所限度。然而该畛域的钻研正在一直进行,量子硬件和算法的提高可能会在将来带来更弱小和高效的量子分类器。
https://avoid.overfit.cn/post/5c39cdddb6cb4111ab9e776f26d89ce5