You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
3.3 KiB
107 lines
3.3 KiB
from __future__ import absolute_import
|
|
|
|
import numpy as np
|
|
import paddle.v2 as paddle
|
|
import paddle.v2.fluid as fluid
|
|
from paddle.v2.fluid.framework import program_guard
|
|
|
|
from .base import Model
|
|
|
|
class PaddleModel(Model):
|
|
"""
|
|
Create a PaddleModel instance.
|
|
When you need to generate a adversarial sample, you should construct an instance of PaddleModel.
|
|
|
|
Args:
|
|
program(paddle.v2.fluid.framework.Program): The program of the model which generate the adversarial sample.
|
|
input_name(string): The name of the input.
|
|
logits_name(string): The name of the logits.
|
|
predict_name(string): The name of the predict.
|
|
cost_name(string): The name of the loss in the program.
|
|
"""
|
|
|
|
def __init__(self,
|
|
program,
|
|
input_name,
|
|
logits_name,
|
|
predict_name,
|
|
cost_name,
|
|
bounds,
|
|
channel_axis=3,
|
|
preprocess=None):
|
|
super(PaddleModel, self).__init__(
|
|
bounds=bounds,
|
|
channel_axis=channel_axis,
|
|
preprocess=preprocess)
|
|
|
|
if preprocess is None:
|
|
preprocess = (0, 1)
|
|
|
|
self._program = program
|
|
self._place = fluid.CPUPlace()
|
|
self._exe = fluid.Executor(self._place)
|
|
|
|
self._input_name = input_name
|
|
self._logits_name = logits_name
|
|
self._predict_name = predict_name
|
|
self._cost_name = cost_name
|
|
|
|
# gradient
|
|
loss = self._program.block(0).var(self._cost_name)
|
|
param_grads = fluid.backward.append_backward(loss, parameter_list=[self._input_name])
|
|
self._gradient = param_grads[0][1]
|
|
|
|
def predict(self, image_batch):
|
|
"""
|
|
Predict the label of the image_batch.
|
|
|
|
Args:
|
|
image_batch(list): The image and label tuple list.
|
|
Return:
|
|
numpy.ndarray: predictions of the images with shape (batch_size, num_of_classes).
|
|
"""
|
|
feeder = fluid.DataFeeder(
|
|
feed_list=[self._input_name, self._logits_name],
|
|
place=self._place,
|
|
program=self._program
|
|
)
|
|
predict_var = self._program.block(0).var(self._predict_name)
|
|
predict = self._exe.run(
|
|
self._program,
|
|
feed=feeder.feed(image_batch),
|
|
fetch_list=[predict_var]
|
|
)
|
|
return predict
|
|
|
|
def num_classes(self):
|
|
"""
|
|
Calculate the number of classes of the output label.
|
|
|
|
Return:
|
|
int: the number of classes
|
|
"""
|
|
predict_var = self._program.block(0).var(self._predict_name)
|
|
assert len(predict_var.shape) == 2
|
|
return predict_var.shape[1]
|
|
|
|
def gradient(self, image_batch):
|
|
"""
|
|
Calculate the gradient of the loss w.r.t the input.
|
|
|
|
Args:
|
|
image_batch(list): The image and label tuple list.
|
|
Return:
|
|
list: The list of the gradient of the image.
|
|
"""
|
|
feeder = fluid.DataFeeder(
|
|
feed_list=[self._input_name, self._logits_name],
|
|
place=self._place,
|
|
program=self._program
|
|
)
|
|
|
|
grad, = self._exe.run(
|
|
self._program,
|
|
feed=feeder.feed(image_batch),
|
|
fetch_list=[self._gradient])
|
|
return grad
|