如何将这些模型保存下来. 换句话说, 你剪枝完了之后, 你得到了一个mask的掩码, 不管是结构化还是非结构化, 这个新的模型你要怎么样才能导出呢? 试想一下, 如果只是得到这么一个掩码, 你在推理的时候, 只是这一部分权重为零而已, 你推理的长宽高啥的都么有改变, so, 速度会变得更快吗?
这位老哥发现, 他尝试不管是结构化剪枝还是非结构化剪枝, 速度和模型的大小都没有变化. 然后另外一个老哥就告诉他真像了:
重要的是要了解非结构化修剪和结构化修剪之间的区别。
结构化修剪:通过删除张量的整行/列来减小重量张量的尺寸。这转化为去除神经元及其所有传入和传出连接(在密集层中)或整个卷积过滤器(在卷积层中)。
非结构化修剪:单个权重可以“去除”(归零),而不受最终张量形状的限制。这意味着删除神经元之间的单个连接(在密集层中)或删除卷积过滤器的单个权重(在卷积层中)。
请注意,生成的重量张量可以稀疏,但保持其原始形状。目前,torch.nn.utils.prune仅支持非结构化修剪,这几乎无法帮助降低推理成本,因为==GPU并未针对稀疏矩阵乘法进行优化==。虽然您可能希望减小权重张量的尺寸以减少浮点运算的数量,但非结构化修剪会产生带有许多零的权重张量,但不会自动减小此类张量的大小。仅当去除许多负担时,非结构化修剪才能帮助提高性能。在这种情况下,您可以依靠PyTorch稀疏操作,也可以尝试查找包含全零的行/列,因此可以将其删除。相反,如果要研究结构化修剪,可以看一下TorchPruner,这是我为研究目的而自行开发的一个库,它提供了实用程序来查找最不重要的神经元并相应地对重量张量进行切片。
所以, 这个部分我们也应该知道, 事实上pytorch的prune里面做的事情, 只是找到哪些层是可以置零的而已, 请注意, 这里的层指的不是某个layer, 而是一个卷积层矩阵里面的某一整行或者某一整列.
事实上pytorch的prune里面做的事情, 只是找到哪些层是可以置零的而已, 请注意, 这里的层指的不是某个layer, 而是一个卷积层矩阵里面的某一整行或者某一整列.
那么问题来了, 听起来我们要保存模型, 要得到速度加快, 模型变小的模型, 还需要再每一个prune的层里面找到某一被全置零的链接, 然后再拿来做推理.
可是这个怎么听起来这么复杂呢? 事实上在实际应用中应该怎么做呢? 这就引入了下一篇教程: 使用Distiller的工业应用模型剪枝教程.