如何实现神经网络修剪?

时间:2019-05-24 20:15:57

标签: python tensorflow optimization deep-learning inference

我在keras中训练了一个模型,并且正在考虑修剪我的全连接网络。我对如何修剪图层有些迷惑。

“有效学习权重和连接方法”一书的作者 神经网络公司说,他们为图层的阈值权重添加了一个掩码。我可以尝试做同样的事情,并微调训练好的模型。但是,它如何减少模型大小和计算数量?

2 个答案:

答案 0 :(得分:6)

根据评论中的讨论,这里提供了一种修剪神经网络层(权重矩阵)的方法。该方法的基本作用是根据范数选择k%最小权重(矩阵的元素),并将其设置为零。这样,可以将相应的矩阵视为稀疏矩阵,以便我们可以执行密集稀疏矩阵乘法,如果修剪了足够的权重,该乘法会更快。

def weight_pruning(w: tf.Variable, k: float) -> tf.Variable:
    """Performs pruning on a weight matrix w in the following way:

    - The absolute value of all elements in the weight matrix are computed.
    - The indices of the smallest k% elements based on their absolute values are selected.
    - All elements with the matching indices are set to 0.

    Args:
        w: The weight matrix.
        k: The percentage of values (units) that should be pruned from the matrix.

    Returns:
        The unit pruned weight matrix.

    """
    k = tf.cast(tf.round(tf.size(w, out_type=tf.float32) * tf.constant(k)), dtype=tf.int32)
    w_reshaped = tf.reshape(w, [-1])
    _, indices = tf.nn.top_k(tf.negative(tf.abs(w_reshaped)), k, sorted=True, name=None)
    mask = tf.scatter_nd_update(tf.Variable(tf.ones_like(w_reshaped, dtype=tf.float32), name="mask", trainable=False), tf.reshape(indices, [-1, 1]),tf.zeros([k], tf.float32))

    return w.assign(tf.reshape(w_reshaped * mask, tf.shape(w)))

答案 1 :(得分:0)

如果添加蒙版,则只有一部分权重将有助于计算,因此将修剪模型。例如,自回归模型使用掩码来屏蔽引用未来数据的权重,以便时间步长t的输出仅取决于时间步长0, 1, ..., t-1

在您的情况下,由于您具有简单的完全连接的层,因此最好使用dropout。它在每个迭代步骤中随机关闭一些神经元,因此降低了计算复杂度。但是,发明辍学的主要原因是解决过度拟合问题:通过随机关闭某些神经元,可以减少神经元的相互依赖性,即避免某些神经元依赖其他神经元。此外,在每次迭代中,您的模型将是不同的(活动神经元的数量不同,它们之间的连接不同),因此最终模型可以解释为几种不同模型的一个加注(集合),每种模型在我们看来都是专门的(我们希望)了解输入空间的特定子集。