python - 如何实现神经网络剪枝?

标签 python tensorflow optimization deep-learning inference

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

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

最佳答案

根据评论中的讨论,这里有一种修剪神经网络层(权重矩阵)的方法。该方法本质上所做的是根据它们的范数选择 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)))

虽然上面的方法修剪单个连接(权重),但下面的方法从权重矩阵修剪整个神经元。即,该方法根据欧几里德范数选择k% 最小的神经元(权重矩阵的列),并将它们设置为零。

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

    - The euclidean norm of each column is computed.
    - The indices of smallest k% columns based on their euclidean norms are selected.
    - All elements in the columns that have the matching indices are set to 0.

    Args:
        w: The weight matrix.
        k: The percentage of columns that should be pruned from the matrix.

    Returns:
        The weight pruned weight matrix.

    """
    k = tf.cast(
        tf.round(tf.cast(tf.shape(w)[1], tf.float32) * tf.constant(k)), dtype=tf.int32
    )
    norm = tf.norm(w, axis=0)
    row_indices = tf.tile(tf.range(tf.shape(w)[0]), [k])
    _, col_indices = tf.nn.top_k(tf.negative(norm), k, sorted=True, name=None)
    col_indices = tf.reshape(
        tf.tile(tf.reshape(col_indices, [-1, 1]), [1, tf.shape(w)[0]]), [-1]
    )
    indices = tf.stack([row_indices, col_indices], axis=1)

    return w.assign(
        tf.scatter_nd_update(w, indices, tf.zeros(tf.shape(w)[0] * k, tf.float32))
    )

最后,这个Github repository通过这里解释的修剪方法并在 MNIST 数据集上进行实验。

关于python - 如何实现神经网络剪枝?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56299034/

相关文章:

python-3.x - 输入大小(输入深度)必须可通过形状推断访问,但在尝试将 tf.expand_dims 轴设置为 0 时看到值 None 错误

python - pycrypto-2.6.1(python 2.7.6) ubuntu14.04 LTS 中无法识别“exportKey”函数

python - SQLAlchemy 使用复合外键连接(使用flask-sqlalchemy)

python - 无法使用 Tensorflow 在 Chalice 上部署

javascript - 分析 JavaScript 性能

performance - 在 MATLAB 中展开矩阵的最快方法是什么?

mysql - 为什么我在写入 300KB/sec 时绑定(bind)了 I/O 以写入 MySQL?

python - 语法错误: invalid syntax line 138 unexpected error

Python Pandas : Append Dataframe To Another Dataframe Only If Column Value is Unique

python - 自定义环境的 Tensorflow 2.0 DQN 代理问题