gpt4 book ai didi

python - sparsity.PolynomialDecay() TensorFlow 2.0 基于幅度的权重修剪中的 initial_sparsity 参数

转载 作者:行者123 更新时间:2023-12-04 00:01:57 30 4
gpt4 key购买 nike

我正在尝试教程 TensorFlow 2.0 Magnitude-based weight pruning with Keras
并遇到了参数 initial_sparsity

import tensorflow_model_optimization as tfmot
from tensorflow_model_optimization.sparsity import keras as sparsity
import numpy as np

epochs = 12
num_train_samples = x_train.shape[0]
end_step = np.ceil(1.0 * num_train_samples / batch_size).astype(np.int32) * epochs
print('End step: ' + str(end_step))

pruning_params = {
'pruning_schedule': sparsity.PolynomialDecay(initial_sparsity=0.50,
final_sparsity=0.90,
begin_step=2000,
end_step=end_step,
frequency=100)
}

教程说:

The parameter used here means:

Sparsity PolynomialDecay is used across the whole training process. We start at the sparsity level 50% and gradually train the model to reach 90% sparsity. X% sparsity means that X% of the weight tensor is going to be pruned away.



我的问题是,你不应该从 开始吗? initial_sparsity 0% 然后剪掉 90% 的权重?

什么开头 initial_sparsity 50% 是什么意思?这是否意味着先修剪 50% 的权重,然后实现 90% 的稀疏修剪?

另外,对于 tfmot.sparsity.keras.ConstantSparsity ,API如下:
pruning_params_unpruned = {
'pruning_schedule': sparsity.ConstantSparsity(
target_sparsity=0.0, begin_step=0,
end_step = 0, frequency=100
)
}

Initializes a Pruning schedule with constant sparsity.

Sparsity is applied in the interval [begin_step, end_step] every frequency steps. At each applicable step, the sparsity(%) is constant.



这是否意味着如果神经网络模型已经处于 50% 的稀疏级别,但 target_sparsity = 0.5,那么修剪计划是否会执行以下操作:
  • 没有修剪,因为模型已经处于 50% 的修剪水平
  • 它进一步修剪了已经(50% 修剪)模型的 50% 的权重

  • 您可以在 PolynomialDecay 中阅读有关它的信息并在 ConstantSparsity

    谢谢

    最佳答案

    所以我还发现 Tensorflow 上关于权重修剪的文档非常稀少,所以我花了一些时间使用调试器来弄清楚一切是如何工作的。

    修剪计划的工作原理

    在最基本的层面上,修剪时间表只是一个将步骤作为输入并产生稀疏百分比的函数。然后使用该稀疏值生成一个掩码,该掩码用于删除绝对值小于由绝对值权重分布和稀疏百分比给出的 k-1 值的权重。

    多项式衰减

    类定义:Github Link
    上面类定义中包含的注释帮助我了解 PolynomialDecay 调度程序的工作原理。

    Pruning rate grows rapidly in the beginning from initial_sparsity, but then plateaus slowly to the target sparsity.

    The function applied is

    current_sparsity = final_sparsity + (initial_sparsity - final_sparsity) * (1 - (step - begin_step)/(end_step - begin_step)) ^ exponent



    由上式可知,当 step == begin_step然后 current_sparsity = initial_sparsity .因此,权重将被修剪为 initial_sparsitybegin_step 指定的步骤上范围。

    我同意您的评估,因为您通常希望以低于 50% 的稀疏度开始修剪,但我没有任何已发表的研究可以引用来支持这一说法。您可以在 paper 中找到更多信息。引用了 PolynomialDecay 类定义,尽管我自己还没有机会阅读它。

    恒定稀疏度

    类定义: Github Link
    这个调度程序的用途似乎非常有限。对于每个有效的修剪步骤, target_sparsity被退回。因此,多个修剪步骤是非常多余的。此调度程序的用例似乎是在训练期间进行一次修剪。多次使用此调度程序进行修剪的能力是将其与其父抽象类和其他修剪调度程序对齐。

    创建您自己的修剪调度程序

    如果上述两个调度程序没有使您的船漂浮,则抽象类 PruningSchedule公开一个端点,这使得创建自己的修剪调度程序变得非常容易,尽管它可能很复杂。下面是我自己创建的一个例子。
    免责声明:此调度程序是一个 19 岁大学生的想象力的创造,没有任何已发表的文献依据。
    PruningSchedule = tfmot.sparsity.keras.PruningSchedule

    class ExponentialPruning(PruningSchedule):
    def __init__(self, rate=0.01, begin_step=0, frequency=100, max_sparsity=0.9):
    self.rate = rate
    self.begin_step = begin_step
    self.frequency = frequency
    self.max_sparsity = max_sparsity

    # Validation functions provided by the parent class
    # The -1 parameter is for the end_step
    # as this pruning schedule does not have one
    # The last true value is a boolean flag which says it is okay
    # to have no end_step
    self._validate_step(self.begin_step, -1, self.frequency, True)
    self._validate_sparsity(self.max_sparsity, 'Max Sparsity')

    def __call__(self, step):
    # Sparsity calculation endpoint

    # step is a integer tensor

    # The sparsity returned by __call__ must be a tensor
    # of dtype=tf.float32, so tf.math is required.

    # In the logic below, you can assume that a valid
    # pruning step is passed.

    p = tf.math.divide(
    tf.cast(step - self.begin_step, tf.float32),
    tf.constant(self.frequency, dtype=tf.float32)
    )
    sparsity = tf.math.subtract(
    tf.constant(1, dtype=tf.float32),
    tf.math.pow(
    tf.constant(1 - self.rate, dtype=tf.float32),
    p
    )
    )

    sparsity = tf.cond(
    tf.math.greater(sparsity, tf.constant(self.max_sparsity, dtype=tf.float32)),
    lambda: tf.constant(self.max_sparsity, dtype=tf.float32),
    lambda: sparsity
    )

    # This function returns a tuple of length 2
    # The first value determines if pruning should occur on this step
    # I recommend using the parent class function below for this purpose
    # The negative one value denotes no end_step
    # The second value is the sparsity to prune to
    return (self._should_prune_in_step(step, self.begin_step, -1, self.frequency),
    sparsity)

    def get_config(self):
    # A function required by the parent class
    # return the class_name and the input parameters as
    # done below
    return {
    'class_name': self.__class__.__name__,
    'config': {
    'rate': self.rate,
    'begin_step': self.begin_step,
    'frequency': self.frequency,
    'max_sparsity': self.max_sparsity
    }
    }

    使用修剪调度程序

    如果您只想修剪某些层,而不是所有可修剪的层,您可以调用 prune_low_magnitude在您添加到模型的图层上运行。
    prune_low_magnitude = tfmot.sparsity.keras.prune_low_magnitude
    model = keras.models.Sequential()
    ...
    model.add(prune_low_magnitude(keras.layers.Dense(8, activation='relu', kernel_regularizer=keras.regularizers.l1(0.0001)),
    ExponentialPruning(rate=1/8)))

    还要确保通过 UpdatePruningStep训练回调的实例:
    m.fit(train_input, train_labels, epochs=epochs, validation_data=[test_input, test_labels],
    callbacks=[UpdatePruningStep()])

    关于python - sparsity.PolynomialDecay() TensorFlow 2.0 基于幅度的权重修剪中的 initial_sparsity 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60005900/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com