OriginQ / VQNET2.0-tutorial

9 stars 7 forks source link

关于混合量子经典的QUnet网络模型的一些问题 #10

Open cyx617 opened 2 years ago

cyx617 commented 2 years ago

您好!因为这个issue,我暂时还不能跑这个例子。但我浏览了一下代码,有几个问题想请教一下:

  1. 训练和保存模型段落,有如下代码:

    if PREPROCESS == True:
    print("Quantum pre-processing of train images:")
    q_train_images = QuantumDataPreprocessing(train_images)
    q_test_images = QuantumDataPreprocessing(test_images)
    q_train_label = QuantumDataPreprocessing(train_labels)
    q_test_label = QuantumDataPreprocessing(test_labels)

    这里面的QuantumDataPreprocessing,好像在前面没有定义。另外,这里面好像也把测试集的label也进行了量子处理。这点我不知道是否合理,因为在现实的应用阶段,我们不会事先知道新样本数据的label。而且模型训练的目标,也不应该是拟合量子处理后的分割图片。

  2. 数据可视化段落,有如下代码:

modela = load_parameters("./result/Q-Unet_End.model")
print("----------------PREDICT-------------")
model.train()

for i, (x1, y1) in enumerate(trainset):

我理解这里应该属于模型预测阶段,所以是否应该把model.train()改为model.eval(),而且选择的数据集应该是测试集而不是trainset。

  1. 从整体逻辑来看,这里的量子电路实际上没有可训练的参数,也没有参与实际的模型训练,应该算是个non-trainable quantum filter。所以我觉得是否可以略微说明一下,因为实际上也可以将量子电路做成一个trainable quantum filter,和UNET拼接成hybrid model,一起参与模型训练。
kevzos commented 2 years ago

@cyx617 你好,谢谢你指出文档的问题。 针对(1),我们这里的模型是使用Unet对经过量子卷积后的图像进行分割,如果不对label图像进行量子卷积,则无法正确进行Unet损失函数的计算。QuantumDataPreprocessing函数在文档中遗漏了,我们会在下个版本修改代码错误和笔误。 针对(2),由于模型含有BN层,BN层的行为在train()和eval()有较大差别,eval()模式下,BN层的均值和方差依赖于batchsize,不准确的计算导致模型效果远差于train()。故这里使用了model.train()。trainset 应该改为testset。我们会在下个版本码错误和笔误。 针对(3),我们这里的量子卷积模块作用在于把经典数据量子化,实际上没有可训练的参数,参考的是 Quanvolutional Neural Networks: Powering Image Recognition with QuantumCircuits这篇论文。至于可训练的卷积核模块,我们这里同样提供了QConv接口:https://vqnet20-tutorial.readthedocs.io/en/main/rst/qnn.html#qconv

cyx617 commented 2 years ago

@kevzos 感谢你的回复!

kevzos commented 2 years ago

@kevzos 感谢你的回复!

  • 对于(1),你的意思是,现有Unet的输出是64 x 64,而原始label是128 x 128,尺寸不匹配,所以不能计算损失函数是吗?这个可能是由于我们额外引入了一个量子卷积层导致的。那我们是否可以在Unet的最后再添加一个上采样层(也或者在Unet的最前面减少一个下采样层),这样Unet就可以输出128 x 128的分割图像了。因为从机器学习角度来看,我们不能改变这个任务的本质,即输入一张原始尺寸为128 x 128的图像,输出一张尺寸为128 x 128的分割图像。如果我们不对当前的QUnet进行改变,那该模型输出的尺寸将一直是输入的一半。
  • 对于(2),的确,BN层的行为在train()和eval()有较大差别。一般在eval()模式下,batchsize较小,甚至为1,不适合BN层对均值和方差的估算。我觉得可以参考BN原始论文的思想,在eval()阶段,采用训练集数据的均值和方差(无偏估计的);或者参考像TensorFlow这样的经典DL框架的逻辑,采用训练时候所有batch数据的均值和方差的移动平均,来进行BN层的计算。也或者,可以尝试把Unet中的BN层换成Layernorm层,也许可以解决小batchsize的问题。
  • 对于(3),我理解你的意思,咱们的教程确实和那篇经典之作的思路非常类似,只不过没有加上随机电路或者随机初始化的参数,只是单纯做了angle encoding + entanglement。

@cyx617 你好。针对问题(1):你说的尺寸不统一是第一个问题。你所说的加入反卷积层也是一种方法,但考虑到我们预先对图像进行量子线路的预处理,反卷积能否达到逆运算的目的是存疑的。因此我们这里将图像都经过量子线路的预处理,所以我们理所应当的对标签进行了同样的预处理,本质上,该示例是使用Unet对量子线路编码后的图像进行分割。 针对问题(2),在BN层中我们同样缓存了”均值和方差的移动平均“,使用eval模式可以达到你所说的使用训练阶段历史均值和方差进行估计的作用,下次版本的文档我们会改成eval()。