结合使用GradientTape和SavedModel对输入进行梯度下降

时间:2019-12-12 11:55:50

标签: tensorflow autodiff

我正在尝试对使用SavedModel API加载的模型进行对抗性攻击。我要针对给定目标的模型损失对输入进行梯度下降。该代码有点长,但这只是说明问题的最低要求。

from __future__ import absolute_import, division, print_function, unicode_literals

from tensorflow import keras
from tensorflow.keras import layers, models
import tensorflow as tf
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

# creating the dataset
X, y = make_classification(n_samples=10000, n_informative=10)
X, X_test, y, y_test = train_test_split(X, y)

# training the model
model = models.Sequential()
model.add(layers.Dense(10, activation='relu'))
model.add(layers.Dense(2, activation='softmax', name="output"))

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(X, y, 
          epochs=10,
          batch_size=32,
          verbose=0)

print(f"final accuracy is {model.evaluate(X_test, y_test, verbose=0)[1]}")

# saving and loading it
tf.saved_model.save(model, "/content/demo")
loaded_model = tf.saved_model.load("/content/demo")

inference_func = loaded_model.signatures["serving_default"]

# making the adversarial example
x = tf.random.normal([1, 20])
x = tf.Variable(x)

target = tf.convert_to_tensor([0, 1], dtype=tf.float32)
cce = tf.keras.losses.CategoricalCrossentropy()

with tf.GradientTape() as t:
    t.watch(x)
    y = inference_func(x)["output"]
    loss = cce(target, y)
dl_dx = t.gradient(loss, x)
x.assign_sub(learning_rate * dl_dx)

print(x.numpy())

然后出现以下错误:

final accuracy is 0.8899999856948853
INFO:tensorflow:Assets written to: /content/demo/assets
---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
<ipython-input-31-1b61c316b9dc> in <module>()
     40 with tf.GradientTape() as t:
     41     t.watch(x)
---> 42     y = inference_func(x)["output"]
     43     loss = cce(target, y)
     44 dl_dx = t.gradient(loss, x)

6 frames
/usr/local/lib/python3.6/dist-packages/six.py in raise_from(value, from_value)

InvalidArgumentError: cannot compute __forward_signature_wrapper_147414 as input #0(zero-based) was expected to be a float tensor but is a resource tensor [Op:__forward_signature_wrapper_147414]

我对低级张量流非常陌生,我还不太了解它是如何工作的。我认为问题与我的推断函数(不是真正的@tf.function)有关,因为它的类型为tensorflow.python.saved_model.load._WrapperFunction。但是我该如何检索实函数呢?

1 个答案:

答案 0 :(得分:0)

我知道了!所以我要寻找的功能在loaded_model.__call__中。我不知道为什么tensorflow文档没有清楚地解释这一点。