如何在推理期间修改权重

问题描述 投票:1回答:1

我正在努力在存在故障的情况下模拟神经网络操作。我想在推理期间访问权重数据以破坏权重中的位,并且我希望在每次新激活时以不同方式破坏它们,因此无法脱机完成。在推理期间如何访问和写入权重?

我正在使用models repo中的vgg16模型,该模型是使用TF-Slim API(https://github.com/tensorflow/models/blob/master/research/slim/nets/vgg.py)编写的,我在这里复制了一个片段:

with tf.variable_scope(scope, 'vgg_a', [inputs]) as sc:
    end_points_collection = sc.original_name_scope + '_end_points'
    # Collect outputs for conv2d, fully_connected and max_pool2d.
    with slim.arg_scope([slim.conv2d, slim.max_pool2d], 
                        outputs_collections=end_points_collection):
        net = slim.repeat(inputs, 1, slim.conv2d, 64, [3, 3], scope='conv1')
        net = slim.max_pool2d(net, [2, 2], scope='pool1')

例如,我想通过访问可训练和不可训练的变量,对其值进行一些修改并将其写回来在slim.conv2d层中注入错误。

如何在处理输入之前访问conv2d图层的实例?

我可以阅读layer.variables,修改它们,然后将新值设置回layer.variables吗?

或者是正确的方法来继承slim.conv2d并添加允许我写入layer.variables属性的访问器?

tensorflow
1个回答
0
投票

我想通过访问可训练和不可训练的变量来注入错误,对它们的值进行一些修改,然后将它们写回来。

看一下名为tf.get_variabledocumentation的这个函数

tf.get_variable获取具有指定参数的现有变量或创建一个新变量。


首先,在Tensorflow中使用变量时,命名很重要。在范围内声明变量时,如示例中的代码:

with tf.variable_scope(scope, 'vgg_a', [inputs]) as sc:
    [...]

变量的名称取决于范围vgg_a

例如:

def conv_relu(input, kernel_shape, bias_shape):
    # Create variable named "weights".
    weights = tf.get_variable("weights", kernel_shape,
        initializer=tf.random_normal_initializer())
    # Create variable named "biases".
    biases = tf.get_variable("biases", bias_shape,
        initializer=tf.constant_initializer(0.0))
    conv = tf.nn.conv2d(input, weights,
        strides=[1, 1, 1, 1], padding='SAME')
    return tf.nn.relu(conv + biases)

如果我有一个辅助方法正在创建类似上面代码的变量,并在范围层次结构中调用此方法,如下所示:

def my_image_filter(input_images):
    with tf.variable_scope("conv1"):
        relu1 = conv_relu(input_images, [5, 5, 32, 32], [32])

这里创建的变量将命名为conv1/weightsconv1/biases

    with tf.variable_scope("conv2"):
        return conv_relu(relu1, [5, 5, 32, 32], [32])

这里创建的变量将命名为conv2/weightsconv2/biases


考虑到这一点,让我们深入了解Tensorflow中的变量:

import numpy as np
import tensorflow as tf

with tf.variable_scope("foo", reuse=tf.AUTO_REUSE):
    a = tf.get_variable(name='a', shape=[1, 10], initializer=tf.constant_initializer(5))

print(a)

with tf.variable_scope("foo", reuse=True):
    b = tf.get_variable(name='a', shape=[1, 10])

print(b)

这打印以下行:

<tf.Variable 'foo/a:0' shape=(1, 10) dtype=float32_ref>
<tf.Variable 'foo/a:0' shape=(1, 10) dtype=float32_ref>

嗯,有趣。两个变量都具有相同的名称。

现在让我们试着看看它们包含什么:

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    val_a = sess.run(a)
    val_b = sess.run(b)

print("val_a:", val_a)
print("val_b:", val_b)

我们得到以下输出:

val_a: [[5. 5. 5. 5. 5. 5. 5. 5. 5. 5.]]
val_b: [[5. 5. 5. 5. 5. 5. 5. 5. 5. 5.]]

太好了!当我们为tf.get_variable(name='a', shape=[1, 10])调用b时,我们没有指定任何初始化器,但是我们得到的值与a相同。

现在,只是要仔细检查ab引用相同的变量,让我们添加以下代码:

new_val = np.array([[2., 2., 2., 2., 2., 2., 2., 2., 2., 2.]])
assign_op = b.assign(new_val)

with tf.Session() as sess:
    sess.run(assign_op)
    val_a = sess.run(a)
    val_b = sess.run(b)

print("val_a:", val_a)
print("val_b:", val_b)

打印:

val_a: [[2. 2. 2. 2. 2. 2. 2. 2. 2. 2.]]
val_b: [[2. 2. 2. 2. 2. 2. 2. 2. 2. 2.]]

大!我们现在知道如何使用其范围和名称来查找变量,就像您按目录和文件名查找文件一样。然后我们可以使用任一变量来操纵值。


同样,对于您的问题,您可以检索已初始化的变量并根据需要进行更改。只需确保在您的范围内设置reuse=True或致电scope.reuse_variables()

Here是一个关于在Tensorflow中使用变量的好教程。

© www.soinside.com 2019 - 2024. All rights reserved.