问题
一直很苦恼深度学习对GPU的依赖,也很羡慕那些土豪玩家动不动几十张N卡训练各种复杂网络模型
各种打比赛,各种刷论文
可是身为草根屌丝的我,积累了N年也只有一个capability为4的显卡,难道就没办法玩复杂模型了吗?
于是我便开始不断琢磨使用更少量的计算和结构而能达到深度学习同样效果的方法
发现
近期看到TensorFlow峰会介绍TFQ中实现了量子神经网络
https://www.bilibili.com/video/BV1Q54y1R7aS?from=search&seid=1236825802957325049
其中benchmark的效果让我眼前一亮
如上图,其中黄色和蓝色的部分是QNN迭代的结果,绿色是传统神经网络迭代的结果
于是开始恶补量子计算,想验证下
该文中描述的量子计算大致原理,使用一堆量子比特来描述某个问题集合发生的概率
思想有点类似于贝叶斯网络,只不过这里网络的节点换成了量子比特
但文中有一些关键点没有交代清楚:
1.“量子操作”具体该怎么操作?预先就知道答案了,对其中的候选量子进行加权,岂不是多此一举?
2.重复次数是怎么得到的?
于是,在好奇心的驱使下,我下载了TFQ的源码看看它是如何实现的?
分析
这里找到了TFQ官方公布的源码:
https://github.com/tensorflow/quantum/blob/master/docs/tutorials/mnist.ipynb
前面数据准备部分就不看了,关键部分就是将图像数据编码成量子电路:
qubits = cirq.GridQubit.rect(4, 4)
这里,我理解就是用16个量子比特来表征4*4的图像数据
再看看QNN量子神经网络是怎么搭建的:
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)
从源码上看,这里其实和传统神经网络结构也没什么差异
也是构建了很多层,只是将网络节点替换成了量子比特
继续往下看,从模型选择的损失函数和优化器来看
说明QNN也并未抛弃传统神经网络BP的策略
model.compile(
loss=tf.keras.losses.Hinge(),
optimizer=tf.keras.optimizers.Adam(),
metrics=[hinge_accuracy])
那么,它凭什么就比传统神经网络收敛的快呢?
从代码分析来看,我初步得到以下一些推断(以下观点仅代表个人理解):
1.量子比特的粒度比CNN的卷积更细,卷积和池化层为了减少运算降低了精度,而在QNN中一个量子比特就能对应一个图像像素点;
2.量子比特的概率不是随机产生,而是通过样本数据不断累加,累加值就是最优值,所以从逼近凸函数的角度来看,QNN是从平面不断接近,而CNN是从凹凸不平的随机面不断接近,从宏观上看,从平面出发就会快一些。
结论
细看了QNN的实现过程后,也揭开了最开始我的两点疑惑:
1.“量子操作”在QNN中,其实就是根据已知测量的结果,增加一个Q比特(量子比特)输出某一状态的概率
举个简单的例子:
图像中某个在人脸范围内的Q比特,它的颜色值取[黄色|非黄色]
那么随着训练(测量)次数不断叠加,它取黄色的概率就越来越大
换句话说,这里Q比特的概率其实就可以看做节点权重
2.重复次数,我并未找到QNN中体现量子搜索次数的代码,可能在量子框架cirq的更底层API中实现了,有兴趣的同学可以去研究下
在QNN中还是会根据传统神经网络的epoch来不断迭代
所以,由上分析可以发现,QNN可以看做CNN的一种简化版结构,只是受到了量子叠加态这个现象的启发而进行的改进
感受
雾里看花,刚看觉得高大上,细看过后自然又有一丝失望和惆怅
想想,测试集只是MNIST,还好数据量不大,如果换成更复杂的图像和视频,又会是怎样的体验?
当然,无论如何QNN量子叠加的思想还是值得鼓励和继续关注的
好了,看来QNN在目前还不是草根的菜,我还得继续寻觅,期待未来能真正出现革命性的进步!