Dynamic Network Surgery for Efficient DNNs 笔记
文章采用的记号与变量:
- 用 \(\left\{\mathbf{W}_{k}: 0 \leq k \leq C\right\}\) 中的 \(W_k\) 表示第 k 层的连接的矩阵,
- 对于一个有 \(p\) 维的输入与 \(q\) 维的输出, 矩阵 \(W_k\) 的维度为 \(q_{k} \times p_{k}\)
- 为了表示稀疏矩阵, 可以引入矩阵, \(T_k\) , 其中 \(T_k\) 是一个二进制的矩阵, 其中的数字表示网络连接的状态
- 对于卷积神经网络的卷积层, 我们讲核进行
剪枝的方法
剪枝的关键问题在于如何判断这个节点的重要性, 我们以第 \(k\) 层为例:
我们需要解决的优化问题如下面所示:
\[\min _{\mathbf{W}_{k}, \mathbf{T}_{k}} L\left(\mathbf{W}_{k} \odot \mathbf{T}_{k}\right) \quad \text { s.t. } \mathbf{T}_{k}^{(i, j)}=\mathbf{h}_{k}\left(\mathbf{W}_{k}^{(i, j)}\right), \forall(i, j) \in \mathcal{I}
\]
其中 \(L\) 是网络的损失函数, \(h_k\) 是一个判断函数, 满足 \(\mathbf{h}_{k}(w)=1\) 如果在第 \(k\) 层, \(w\) 十分的重要, 否则 \(\mathbf{h}_{k}(w)=0\) . \(\odot\) 是矩阵的元素积的意思,
那么上面的公式应该如何优化呢?
\(T_k\) 矩阵是可以由 \(h_k\) 计算出来的, 那么每一步的 \(W_k\) 矩阵的更新可以使用随机梯度下降和拉格朗日乘子法:
\[\mathbf{W}_{k}^{(i, j)} \leftarrow \mathbf{W}_{k}^{(i, j)}-\beta \frac{\partial}{\partial\left(\mathbf{W}_{k}^{(i, j)} \mathbf{T}_{k}^{(i, j)}\right)} L\left(\mathbf{W}_{k} \odot \mathbf{T}_{k}\right), \forall(i, j) \in \mathcal{I}
\]
其中 \(\beta\) 表示的是学习率, 我们要注意到, 这一步不仅仅是更新 \(W_k\) 其实也是更新了 \(T_k\) .
那么训练的过程(本质是对一个model 的 retrain)是:
- 对于一个已经训练好的模型的矩阵 \(W_k\)
- 插入一个矩阵 \(T_k\) , 然后前向传播
- 然后反向传播, 更新 \(W_k\) 和 \(T_k\),
- 这种方法能够决定某个参数重要的最关键的是函数 \(h_k\) , 这也使得每次会更新矩阵 \(T_k\)
h函数的选择
这个函数的选择至关重要, 那么该如何选择呢? 可以很自然的想到和矩阵 \(W_k\) 的参数的均值与方差有关, 但是文章并没有给出具体的计算方式, 而是给出一个基于阈值的方法, 计算方法如下:
\[\mathbf{h}_{k}\left(\mathbf{W}_{k}^{(i, j)}\right)=\left\{\begin{array}{ll}
0 & \text { if } a_{k}>\left|\mathbf{W}_{k}^{(i, j)}\right| \\
\mathbf{T}_{k}^{(i, j)} & \text { if } a_{k} \leq\left|\mathbf{W}_{k}^{(i, j)}\right|<b_{k} \\
1 & \text { if } b_{k} \leq\left|\mathbf{W}_{k}^{(i, j)}\right|
\end{array}\right.
\]