gpt4 book ai didi

tensorflow - 如何卡住/锁定一个 TensorFlow 变量的权重(例如,一层的一个 CNN 内核)

转载 作者:行者123 更新时间:2023-12-02 06:38:26 25 4
gpt4 key购买 nike

我有一个性能良好的 TensorFlow CNN 模型,我们希望在硬件中实现该模型;即 FPGA。这是一个相对较小的网络,但如果它更小一些那就更理想了。出于这个目标,我检查了内核,发现有些内核的权重非常强,而另一些则根本没有做太多事情(内核值都接近于零)。这特别发生在第 2 层,对应于名为“W_conv2”的 tf.Variable()。 W_conv2 的形状为 [3, 3, 32, 32]。我想卡住/锁定 W_conv2[:, :, 29, 13] 的值并将它们设置为零,以便可以训练网络的其余部分进行补偿。将此内核的值设置为零可以有效地从硬件实现中删除/修剪内核,从而实现上述目标。

我发现了类似的问题和建议,这些建议通常围绕两种方法之一;

建议#1:

    tf.Variable(some_initial_value, trainable = False)

实现此建议会卡住整个变量。我只想卡住一个切片,特别是 W_conv2[:, :, 29, 13]。

建议#2:

    Optimizer = tf.train.RMSPropOptimizer(0.001).minimize(loss, var_list)

同样,实现此建议不允许使用切片。例如,如果我尝试与我的既定目标相反的目标(仅优化单个变量的单个内核),如下所示:

    Optimizer = tf.train.RMSPropOptimizer(0.001).minimize(loss, var_list = W_conv2[:,:,0,0]))

我收到以下错误:

    NotImplementedError: ('Trying to optimize unsupported type ', <tf.Tensor 'strided_slice_2228:0' shape=(3, 3) dtype=float32>)

按照我在这里尝试的方式切片 tf.Variables() 是不可能的。我尝试过的唯一接近做我想要的事情是使用 .assign() 但这非常低效、麻烦并且像穴居人一样,因为我按如下方式实现了它(在模型训练之后):

    for _ in range(10000):
# get a new batch of data
# reset the values of W_conv2[:,:,29,13]=0 each time through
for m in range(3):
for n in range(3):
assign_op = W_conv2[m,n,29,13].assign(0)
sess.run(assign_op)
# re-train the rest of the network
_, loss_val = sess.run([optimizer, loss], feed_dict = {
dict_stuff_here
})
print(loss_val)

该模型在 Keras 中启动,然后转移到 TensorFlow,因为 Keras 似乎没有实现预期结果的机制。我开始认为 TensorFlow 不允许修剪,但发现这很难相信;它只需要正确的实现。

最佳答案

一种可能的方法是用零初始化这些特定权重,并修改最小化过程,以便不对它们应用梯度。可以通过将 minimize() 的调用替换为以下内容来完成:

W_conv2_weights = np.ones((3, 3, 32, 32))
W_conv2_weights[:, :, 29, 13] = 0
W_conv2_weights_const = tf.constant(W_conv2_weights)

optimizer = tf.train.RMSPropOptimizer(0.001)

W_conv2_orig_grads = tf.gradients(loss, W_conv2)
W_conv2_grads = tf.multiply(W_conv2_weights_const, W_conv2_orig_grads)
W_conv2_train_op = optimizer.apply_gradients(zip(W_conv2_grads, W_conv2))

rest_grads = tf.gradients(loss, rest_of_vars)
rest_train_op = optimizer.apply_gradients(zip(rest_grads, rest_of_vars))

tf.group([rest_train_op, W_conv2_train_op])

即,

  1. 准备一个常量张量来取消适当的梯度
  2. 仅计算 W_conv2 的梯度,然后按元素与常量 W_conv2_weights 相乘,将适当的梯度归零,然后再应用梯度。
  3. 计算梯度并将其“正常”应用于其余变量。
  4. 将 2 个训练操作分组为一个训练操作。

关于tensorflow - 如何卡住/锁定一个 TensorFlow 变量的权重(例如,一层的一个 CNN 内核),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42517926/

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