class_docstr: Create a PaddleModel instance.
  When you need to generate a adversarial sample, you should construct an
  instance of PaddleModel.
  Args:
      program(paddle.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.
class_docstr_tok: ["Create","a","PaddleModel","instance",".","When","you","need","to","generate","a","adversarial","sample",",","you","should","construct","an","instance","of","PaddleModel",".","Args",":","program","(","paddle.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","."]
code: def __init__(
      self,
      program,
      input_name,
      logits_name,
      predict_name,
      cost_name,
      bounds,
      channel_axis=3,
      preprocess=None,
  ):
      if preprocess is None:
          preprocess = (0, 1)
  
      super(PaddleModel, self).__init__(
          bounds=bounds,
          channel_axis=channel_axis,
          preprocess=preprocess,
      )
  
      # 用于计算梯度
      self._program = program
      # 仅用于预测
      self._predict_program = program.clone(for_test=True)
      self._place = fluid.CUDAPlace(0) if with_gpu else 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
  
      # change all `is_test` attributes to True 使_program只计算梯度 不自动更新参数 单纯clone后不计算梯度的
      import six
  
      """
          for i in six.moves.range(self._program.desc.num_blocks()):
              block = self._program.desc.block(i)
              for j in six.moves.range(block.op_size()):
                  op = block.op(j)
                  if op.has_attr('is_test') and op.type != 'batch_norm_grad':
                      # 兼容旧版本 paddle
                      if hasattr(op, 'set_attr'):
                          op.set_attr('is_test', True)
                      else:
                          op._set_attr('is_test', True)
          """
      for op in self._program.block(0).ops:
          # print("op type is {}".format(op.type))
          if op.type in ["batch_norm"]:
              # 兼容旧版本 paddle
              if hasattr(op, "set_attr"):
                  op.set_attr("is_test", False)
                  op.set_attr("use_global_stats", True)
              else:
                  op._set_attr("is_test", False)
                  op._set_attr("use_global_stats", True)
                  op.desc.check_attrs()
  
      # gradient
      loss = self._program.block(0).var(self._cost_name)
      param_grads = fluid.backward.append_backward(
          loss, parameter_list=[self._input_name]
      )
      # self._gradient = filter(lambda p: p[0].name == self._input_name,
      #                        param_grads)[0][1]
      self._gradient = param_grads[0][1]
  
file_path: AdvBox/adversarialbox/models/paddle.py
imports: from __future__ import absolute_import
  import numpy
  import os
  import paddle.fluid
  from .base import Model
label_desc: Use image node_id 1 to create a new PaddleModel object from inherited base classes: Model with example: obj = PaddleModel(program, input_name, logits_name, predict_name, cost_name, bounds, channel_axis, preprocess)