def test_conv1d_simplex_bounds_shape(self, dtype): num_vertices = 41 batch_size = 11 input_length = 13 kernel_length = 5 input_channels = 3 output_channels = 2 padding = 'VALID' strides = (2, ) # Expected output dimensions, based on convolution settings. output_length = 5 w = tf.placeholder(dtype=dtype, shape=(kernel_length, input_channels, output_channels)) b = tf.placeholder(dtype=dtype, shape=(output_channels, )) vertices = tf.placeholder(dtype=dtype, shape=(batch_size, num_vertices, input_length, input_channels)) centres = tf.placeholder(dtype=dtype, shape=(batch_size, input_length, input_channels)) r = .2 bounds_in = ibp.SimplexBounds(vertices, centres, r) bounds_out = bounds_in.apply_conv1d(None, w, b, padding, strides) lb_out, ub_out = bounds_out.lower, bounds_out.upper self.assertEqual(dtype, lb_out.dtype) self.assertEqual(dtype, ub_out.dtype) self.assertEqual((batch_size, output_length, output_channels), lb_out.shape) self.assertEqual((batch_size, output_length, output_channels), ub_out.shape)
def add_verifiable_objective(self, minibatch, vocab_table, perturbation, stop_gradient=False): # pylint: disable=g-missing-docstring data_batch = self.embed_dataset(minibatch, vocab_table) _, vertices = self.compute_mask_vertices(data_batch, perturbation) def classifier(embedded_inputs): representation = self.sentence_representer(embedded_inputs, data_batch.length) return self.linear_classifier(representation) # Verification graph. network = ibp.VerifiableModelWrapper(classifier) network(data_batch.embedded_inputs) input_bounds = ibp.SimplexBounds( vertices=vertices, nominal=data_batch.embedded_inputs, r=(self.delta if not stop_gradient else self.config['delta'])) network.propagate_bounds(input_bounds) # Calculate the verifiable objective. verifiable_obj = verifiable_objective(network, data_batch.sentiment, margin=1.) return verifiable_obj
def test_linear_simplex_bounds_shape(self, dtype): vocab_size = 103 batch_size = 11 input_size = 7 output_size = 5 w = tf.placeholder(dtype=dtype, shape=(input_size, output_size)) b = tf.placeholder(dtype=dtype, shape=(output_size, )) embedding = tf.placeholder(dtype=dtype, shape=(vocab_size, input_size)) centres = tf.placeholder(dtype=dtype, shape=(batch_size, input_size)) r = .2 bounds_in = ibp.SimplexBounds(embedding, centres, r) bounds_out = bounds_in.apply_linear(None, w, b) lb_out, ub_out = bounds_out.lower, bounds_out.upper self.assertEqual(dtype, lb_out.dtype) self.assertEqual(dtype, ub_out.dtype) self.assertEqual((batch_size, output_size), lb_out.shape) self.assertEqual((batch_size, output_size), ub_out.shape)
def test_linear_bounds_on_embedding_layer(self, dtype, tol): w = tf.constant([[1.0, 2.0, 3.0], [4.0, -5.0, 6.0]], dtype=dtype) b = tf.constant([0.01, -0.02, 0.03], dtype=dtype) embedding = tf.constant([[0.0, 0.0], [10.0, 10.0], [0.0, -20.0]], dtype=dtype) centres = tf.constant([[7.0, 6.0]], dtype=dtype) r = .1 # Simplex vertices: [6.3, 5.4], [7.3, 6.4], and [6.3, 3.4]. # They map to: [27.91, -14.42, 51.33], [32.91, -17.42, 60.33], # and [19.91, -4.42, 39.33]. bounds_in = ibp.SimplexBounds(embedding, centres, r) bounds_out = bounds_in.apply_linear(None, w, b) lb_out, ub_out = bounds_out.lower, bounds_out.upper lb_out_exp = np.array([[19.91, -17.42, 39.33]]) ub_out_exp = np.array([[32.91, -4.42, 60.33]]) with self.test_session() as session: lb_out_act, ub_out_act = session.run((lb_out, ub_out)) self.assertAllClose(lb_out_exp, lb_out_act, atol=tol, rtol=tol) self.assertAllClose(ub_out_exp, ub_out_act, atol=tol, rtol=tol)
def test_conv1d_simplex_bounds(self, dtype, tol): num_vertices = 37 batch_size = 53 input_length = 17 kernel_length = 7 input_channels = 3 output_channels = 2 padding = 'VALID' strides = (2, ) w = tf.random_normal(dtype=dtype, shape=(kernel_length, input_channels, output_channels)) b = tf.random_normal(dtype=dtype, shape=(output_channels, )) vertices = tf.random_normal(dtype=dtype, shape=(batch_size, num_vertices, input_length, input_channels)) centres = tf.random_normal(dtype=dtype, shape=(batch_size, input_length, input_channels)) r = .2 bounds_in = ibp.SimplexBounds(vertices, centres, r) bounds_out = bounds_in.apply_conv1d(None, w, b, padding, strides[0]) lb_out, ub_out = bounds_out.lower, bounds_out.upper # Compare against equivalent linear layer. bounds_out_lin = _materialised_conv_simplex_bounds( w, b, padding, strides, bounds_in) lb_out_lin, ub_out_lin = bounds_out_lin.lower, bounds_out_lin.upper with self.test_session() as session: (lb_out_val, ub_out_val, lb_out_lin_val, ub_out_lin_val) = session.run( (lb_out, ub_out, lb_out_lin, ub_out_lin)) self.assertAllClose(lb_out_val, lb_out_lin_val, atol=tol, rtol=tol) self.assertAllClose(ub_out_val, ub_out_lin_val, atol=tol, rtol=tol)