CharlesTao0926
CharlesTao0926
@ricky40403 Thanks for your hard and great work. I copied the DSQConv.py into my project and used DSQConv instead of nn.conv2d except the first and the last layers. However during...
@csyhhu: 感谢您的杰出工作。 我对您的MetaQuant技术很感兴趣,仔细研读了您的论文和代码。我的理解,您的核心思想是要解决量化网络在梯度反传时量化函数不可导问题。解决的办法是:反向传播时,通过meta-net获得meta-grad,再结合calibration,从而获得更加准确的梯度。在训练过程中,每一次迭代的过程主要分为4步 (以dorefa和MultiFC为例): 步骤1. 对于非首次迭代,使用上次迭代产生的layer.quantized_grad和layer.pre_quantized_weight来生成meta-grad 步骤2. 执行base-net前向 步骤3. 计算base-net损失,执行base-net的反向传播 步骤4. 对于非首次迭代,a) 使用步骤1生成的meta-grad,并结合layer.calibration,更新weight梯度, b)对weight梯度执行refinement, c)用refinement后的梯度更新base-net参数。 我仔细研究了您的代码实现,代码可以正常运行,Cifar10上获得了89%的准确率。但是,我也发现了几处不太匹配的地方,分析如下。如果是我理解不当,还请您不吝赐教,非常感谢! 第一次迭代过程: 因为是第1次迭代,所以会跳过上述步骤1和步骤4,只执行步骤2和步骤3。此时,base-net完成了一次前向和反向的过程。前向过程中,由于Function_STE.apply的使用,反向结束后,layer.weight.grad保存的将是STE的结果。并且,第一次迭代结束时,不立即更新参数,从而在第二次迭代开始时base-net参数仍然是第一次迭代时的参数。 第二次迭代过程(依序执行步骤1~4): 执行步骤1:计算meta-grad:layer.pre_quantized_weight和layer.quantized_grad中分别对应于第一次迭代前向过程中保存的量化前权重和反向过程中回传的梯度,根据此两个值,计算并返回meta-grad。 执行步骤2:在base-net的前向过程中,首先根据layer.weight计算layer.calibration(该layer.calibration将用于后续的步骤4), 接着计算layer.calibrated_grad, 然后更新layer.meta_weight. 问题是,layer.meta_weight的实际计算使用的是self.weight - lr * self.weight.grad, (尽管代码中使用的是 self.weight...