def apply_conv1d(self, wrapper, w, b, padding, stride):
        mapped_centres = tf.nn.conv1d(self.nominal,
                                      w,
                                      padding=padding,
                                      stride=stride)
        if self.vertices.shape.ndims == 3:
            # `self.vertices` has no batch dimension; its shape is
            # (num_vertices, input_length, embedding_channels).
            mapped_vertices = tf.nn.conv1d(self.vertices,
                                           w,
                                           padding=padding,
                                           stride=stride)
        elif self.vertices.shape.ndims == 4:
            # `self.vertices` has shape
            # (batch_size, num_vertices, input_length, embedding_channels).
            # Vertices are different for each example in the batch,
            # e.g. for word perturbations.
            mapped_vertices = snt.BatchApply(
                lambda x: tf.nn.conv1d(x, w, padding=padding, stride=stride))(
                    self.vertices)
        else:
            raise ValueError('"vertices" must have either 3 or 4 dimensions.')

        lb, ub = _simplex_bounds(mapped_vertices, mapped_centres, self.r, -3)

        nominal_out = tf.nn.conv1d(self.nominal,
                                   w,
                                   padding=padding,
                                   stride=stride)
        if b is not None:
            nominal_out += b

        return relative_bounds.RelativeIntervalBounds(lb, ub, nominal_out)
    def apply_conv2d(self, wrapper, w, b, padding, strides):
        mapped_centres = tf.nn.convolution(self.nominal,
                                           w,
                                           padding=padding,
                                           strides=strides)
        if self.vertices.shape.ndims == 4:
            # `self.vertices` has no batch dimension; its shape is
            # (num_vertices, input_height, input_width, input_channels).
            mapped_vertices = tf.nn.convolution(self.vertices,
                                                w,
                                                padding=padding,
                                                strides=strides)
        elif self.vertices.shape.ndims == 5:
            # `self.vertices` has shape
            # (batch_size, num_vertices, input_height, input_width, input_channels).
            # Vertices are different for each example in the batch.
            mapped_vertices = snt.BatchApply(lambda x: tf.nn.convolution(
                x, w, padding=padding, strides=strides))(self.vertices)
        else:
            raise ValueError('"vertices" must have either 4 or 5 dimensions.')

        lb, ub = _simplex_bounds(mapped_vertices, mapped_centres, self.r, -4)

        nominal_out = tf.nn.convolution(self.nominal,
                                        w,
                                        padding=padding,
                                        strides=strides)
        if b is not None:
            nominal_out += b

        return relative_bounds.RelativeIntervalBounds(lb, ub, nominal_out)
    def apply_linear(self, wrapper, w, b):
        mapped_centres = tf.matmul(self.nominal, w)
        mapped_vertices = tf.tensordot(self.vertices, w, axes=1)

        lb, ub = _simplex_bounds(mapped_vertices, mapped_centres, self.r, -2)

        nominal_out = tf.matmul(self.nominal, w)
        if b is not None:
            nominal_out += b

        return relative_bounds.RelativeIntervalBounds(lb, ub, nominal_out)
Пример #4
0
  def concretize(self):
    """Returns lower and upper interval bounds."""
    if self._concretized is None:
      # Construct once and cache.
      lb_offset, ub_offset = self._concretize_bounds(self.lower, self.upper)

      # Apply intersections with prior runs.
      if self._prior_bounds is not None:
        lb_offset = tf.maximum(lb_offset, self._prior_bounds.lower_offset)
        ub_offset = tf.minimum(ub_offset, self._prior_bounds.upper_offset)
      self._concretized = relative_bounds.RelativeIntervalBounds(
          lb_offset, ub_offset, self._nominal)

    return self._concretized
Пример #5
0
  def convert(cls, bounds):
    if isinstance(bounds, cls):
      return bounds

    if isinstance(bounds, tf.Tensor):
      bounds = relative_bounds.RelativeIntervalBounds(
          tf.zeros_like(bounds), tf.zeros_like(bounds), bounds)
    bounds = bounds.concretize()
    if not isinstance(bounds, relative_bounds.RelativeIntervalBounds):
      raise ValueError(
          'Cannot convert "{}" to "RelativeSymbolicBounds"'.format(bounds))

    lower, upper = cls._initial_symbolic_bounds(bounds.lower_offset,
                                                bounds.upper_offset)
    return cls(lower, upper, bounds.nominal)