1

目前,我正在使用 Tf-Slim 库中的预训练 VGG 模型。我的动机是为这个网络的给定图像生成对抗性示例。任务总结如下:

x= tf.placeholder(shape=(None, 32, 32,3), dtype=tf.float32)
for i in range(2):
    logits= vgg.vgg_16(x, is_training=False, spatial_squeeze=False, fc_conv_padding='SAME')
    x =  x + learning_rate*cal_gradient_of_logits_wrt_x(logits)

但是,一旦我们进入第二次迭代并开始运行 logits= vgg.vgg16(....) 我们就会收到以下错误:

Variable vgg_16/conv1/conv1_1/weights already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope?

很明显,这个错误是由于第二次迭代中的图形复制而发生的。由于 tf-slim 模型不在reuse=True作用域中使用,它会引发此错误(因为在第二次迭代中,我们再次要求它在图中添加 vgg 层,这些层已经存在)。

是否有可能以某种方式避免此错误?应该可以为 VGG 模型创建一次图,并在需要计算 logits 时使用它。

这应该是可能的原因是来自 keras 的示例。在 keras 中,我们可以简单地定义一次模型,

model= vgg.VGG16(*args, *kwargs)

稍后,我们可以为不同的张量添加计算 logits,

logits_1= model(x1)
logits_2= model(x2)

现在在这两个计算中,将使用相同的模型参数,即不会出现这样的错误。有没有办法使用 tensorflow 模型实现相同的功能。

4

2 回答 2

1

在 tfslim/models/research/slim/nets/vgg.py 中:

在 vgg16 或 vgg19 定义中添加重用参数

def vgg_16(inputs,
           num_classes=1000,
           is_training=True,
           dropout_keep_prob=0.5,
           spatial_squeeze=True,
           scope='vgg_16',
           fc_conv_padding='VALID',
           global_pool=False,
           reuse=None):

...然后设置变量范围以在需要时重用 arg_scope

with tf.variable_scope(scope, 'vgg_16', [inputs], reuse=reuse) as sc:

...

然后,当您调用该函数时,将参数传递为reuse=tf.AUTO_REUSE

vgg.vgg_16(images, num_classes=dataset.num_classes,
           is_training=True, reuse=tf.AUTO_REUSE)
于 2018-08-02T22:15:12.127 回答
0

您可以使用 tf.make_template(func) 来执行此操作。

x= tf.placeholder(shape=(None, 32, 32,3), dtype=tf.float32)

vgg_model = tf.make_template(vgg.vgg_16, is_training=False, spatial_squeeze=False, fc_conv_padding='SAME')

for i in range(2):
  logits = vgg_model(x)
  x += learning_rate*cal_gradient_of_logits_wrt_x(logits)
于 2018-07-13T03:58:35.240 回答