## update: <br>2023.4.28<br>

### 目标工作：尝试去解决“预测模型收敛速度”方面的问题
- 问题：按照原有思路，通过QAT from scratch获得前5/10/15/20个epoch的loss下降量和训练梯度相似度进行拟合。但根据qat.py得到的数据结果并不太好。<br>主要有两个方面的问题：<br>(1)出现了距离(即 相似度的差异性)过大、且变化过大(出现了显著的数量级差异，且规律与预期不符)的问题。<br>(2) 对不同量化方式的数据，loss的下降量有正有负，换言之，没有一个明显的loss在减小的趋势，数值较为随机。<br>
- 实验：针对上述问题，我进行了一系列观察、思考、实验，修改了qat.py中可能存在的问题，得到new_qat.py，还新增了model_foldbn.py, 修改了module.py.<br>

### 分析与实验：

1. 问题与方案：
- 量化模型中将BN fold进了Conv，因此我尝试仿照量化中的fold过程，在全精度模型训练时也将BN fold进Conv，具体的代码在module.py和model_foldbn.py中。我对fold后的全精度模型进行了训练验证，其可以正常更新权值参数，提升推理精度，但训练的收敛速度明显变慢了(ResNet18_foldbn在80个epoch时acc才40%)。
- qat.py中model和model_ptq都使用了同一个optimizer，在new_qat.py将其改为两个optimizer，分别为两个model的参数进行优化。
- 在实验中发现如果使用Adam优化器，得到的梯度会比较不稳定，我该用了SGD后稳定性提高了，趋势更显著。
- 对full_grad...等字典存储的是epoch上限时的各组梯度数据，如果直接用于与各个epoch节点的量化模型梯度数据去计算相似度，在大部分情况下是没有对应上的。这里我在实验中暂时只训练5个epoch，还没处理该问题。
- 对lr和momentum进行了一系列调整，但效果不明显。

2. 修改后的效果：
- 在INT量化中，随着量化位宽增大，量化模型的训练梯度与全精度模型的训练梯度的数量级逐渐接近至相同(但具体数值上仍有明显差异)。
- 得到明显改善的js_grad, loss_delta...等数据 （不过与预期仍不相符）

3. 还存在的问题与我的猜想：
- 对于INT量化，随着位宽增加，只有最开始出现了训练梯度相似度上升的趋势，后续呈现了波动趋势。且根据我对梯度数据的观察，他们并没有随着量化位宽增加而呈现出一致性，仅仅是数量级接近了，但具体数值仍有很大的差异。我猜想这是因为QAT from scratch较难，他们没有能有效的训练。也有可能是代码中还有一些未发现的bug。
- 在INT量化中，loss_delta(loss的减小量)也没有随着位宽增加而呈显著一致的增大，只有在位宽较小时有一段增大趋势，后续则呈现了较为随机的波动。
- 尝试进行了QAT from scratch训练，80个epoch左右没能看到明显的训练效果，可能这也是为什么出现上述问题的原因之一。

<br>(注：具体数据可见于ResNet18qat_result.xlsx中)

4. 尝试进行的拟合
loss_delta - js_grad  (loss的下降量 - 第5个epoch的训练梯度加权相似度)
<img src = "fig/grad_delta.png" class="h-90 auto">
可以看到拟合效果非常差。
loss_avg - js_grad_avg (loss平均值 - 前5epoch的平均训练梯度的加权相似度)
<img src = "fig/qat.png" class="h-90 auto">
可以看到他们存在一个线性趋势，但这仅仅说明训练梯度相似度越大，loss越大，而loss的大小与训练收敛速度间并不能建立合理的逻辑关系。loss很大说明当前模型的效果很差，导致了loss大。

## update: <br>2023.4.24<br>
补充了一些数据和拟合图<br>
尝试将ResNet18,ResNet50,ResNet152,MobileNetV2四个模型的数据点拟合在同一张图上，效果还不错。不过考虑到这四个模型的结构较为相似，暂不确定与其他的结构差异较大的模型的数据点在一起拟合效果如何。
1. ResNet50:
<img src = "fig/50_flops_f.png" class="h-90 auto">
<img src = "fig/50_params_F.png" class="h-90 auto">
2. ResNet152:
<img src = "fig/152_flops_f.png" class="h-90 auto">
<img src = "fig/152_params_f.png" class="h-90 auto">
3. 综合了ResNet18,ResNet50,ResNet152,MobileNetV2的数据点的拟合图
<img src = "fig/total_flops.png" class="h-90 auto">
<img src = "fig/total_params.png" class="h-90 auto">
## update: <br>2023.4.24<br>
- 解决的问题：
1. PoT拟合异常 <br>
2. 曲线拟合效果较差
- 思路记录<br>
在解决MobileNetV2遇到的js散度，曲线拟合问题时，发现了F.normalize对相似度计算的影响很大，其虽然能够帮助把量化后的权值参数调整成与全精度模型相同的scale，但是导致数据分布改变过大，进而导致了出现了反常的关系和拟合结果。具体思路和分析可见MobileNetV2的readme，此处同样也使用了fakefreeze来将量化后的权值参数dequantize，使其与全精度模型的权值参数处于相同的scale，再直接用js散度计算距离。
<br>
在ResNet系列上进行了重新实验，ResNet50，152的数据和曲线待程序运行完后再补充. <br>
ResNet18:
<img src = "fig/18_flops_f.png" class="h-90 auto">
<img src = "fig/18_params_f.png" class="h-90 auto">
可以看到曲线拟合效果有了非常好的提升。

## update: <br>2023.4.23<br>
1. 本文件夹下的ResNet系列模型的Conv层不具有bias，与经典的ResNet一致。但在含有fold BN操作的ConvBN，ConvBNReLU后，Conv会具有bias，在代码中进行了相应修改以适配。
2. ResNet18的无bias的acc比有bias的略高。且无bias的情况下，训练速度明显增快。
3. 修正了一系列小bug
4. 一系列拟合图
(1) 有PoT:
resnet18:
<img src = "fig/18_flops_nobias.png" class="h-90 auto">
<img src = "fig/18_params_nobias.png" class="h-90 auto">
resnet50:
<img src = "fig/50_flops_nobias.png" class="h-90 auto">
<img src = "fig/50_params_nobias.png" class="h-90 auto">
resnet152:
<img src = "fig/152_flops_nobias.png" class="h-90 auto">
<img src = "fig/152_params_nobias.png" class="h-90 auto">
(2) 无PoT:

resnet18:
<img src = "fig/18_flops_nobias_nopot.png" class="h-90 auto">

resnet50:
<img src = "fig/50_flops_nobias_nopot.png" class="h-90 auto">

resnet152:
<img src = "fig/152_flops_nobias_nopot.png" class="h-90 auto">
