1313- `thermometer_encoding(model, num_bins=10)`: Thermometer Encoding defense.
1414- `adversarial_logit_pairing(model, paired_model)`: Adversarial Logit Pairing defense.
1515- `spatial_smoothing(model, kernel_size=3)`: Spatial Smoothing defense.
16+ - `jpeg_compression(model, quality=75)`: JPEG Compression defense.
1617"""
1718
1819import numpy as np
@@ -118,18 +119,16 @@ def input_transformation(model, transformation_function=None):
118119 Returns:
119120 defended_model (tensorflow.keras.Model): The model with input transformation defense.
120121 """
121- defended_model = tf .keras .models .clone_model (model )
122- defended_model .set_weights (model .get_weights ())
123-
124122 def transformed_input (x ):
125123 if transformation_function is not None :
126124 return transformation_function (x )
127125 else :
128126 return x
129127
130- defended_model .layers [0 ].input = tf .keras .Input (shape = model .input_shape [1 :])
131- defended_model .layers [0 ].input = transformed_input (defended_model .layers [0 ].input )
132- return defended_model
128+ input_layer = tf .keras .Input (shape = model .input_shape [1 :])
129+ x = transformed_input (input_layer )
130+ predictions = model (x )
131+ return tf .keras .Model (inputs = input_layer , outputs = predictions )
133132
134133def defensive_distillation (model , teacher_model , temperature = 2 ):
135134 """
@@ -170,16 +169,14 @@ def randomized_smoothing(model, noise_level=0.1):
170169 Returns:
171170 defended_model (tensorflow.keras.Model): The model with randomized smoothing defense.
172171 """
173- defended_model = tf .keras .models .clone_model (model )
174- defended_model .set_weights (model .get_weights ())
175-
176172 def add_noise (x ):
177173 noise = tf .random .normal (shape = tf .shape (x ), mean = 0.0 , stddev = noise_level , dtype = tf .float32 )
178174 return x + noise
179175
180- defended_model .layers [0 ].input = tf .keras .Input (shape = model .input_shape [1 :])
181- defended_model .layers [0 ].input = add_noise (defended_model .layers [0 ].input )
182- return defended_model
176+ input_layer = tf .keras .Input (shape = model .input_shape [1 :])
177+ x = add_noise (input_layer )
178+ predictions = model (x )
179+ return tf .keras .Model (inputs = input_layer , outputs = predictions )
183180
184181def feature_denoising (model ):
185182 """
@@ -193,15 +190,13 @@ def feature_denoising(model):
193190 Returns:
194191 defended_model (tensorflow.keras.Model): The model with feature denoising defense.
195192 """
196- defended_model = tf .keras .models .clone_model (model )
197- defended_model .set_weights (model .get_weights ())
198-
199193 def denoise (x ):
200194 return tf .image .total_variation (x )
201195
202- defended_model .layers [0 ].input = tf .keras .Input (shape = model .input_shape [1 :])
203- defended_model .layers [0 ].input = denoise (defended_model .layers [0 ].input )
204- return defended_model
196+ input_layer = tf .keras .Input (shape = model .input_shape [1 :])
197+ x = denoise (input_layer )
198+ predictions = model (x )
199+ return tf .keras .Model (inputs = input_layer , outputs = predictions )
205200
206201def thermometer_encoding (model , num_bins = 10 ):
207202 """
@@ -217,17 +212,15 @@ def thermometer_encoding(model, num_bins=10):
217212 Returns:
218213 defended_model (tensorflow.keras.Model): The model with thermometer encoding defense.
219214 """
220- defended_model = tf .keras .models .clone_model (model )
221- defended_model .set_weights (model .get_weights ())
222-
223215 def encode (x ):
224216 x = tf .clip_by_value (x , 0 , 1 )
225217 x = tf .floor (x * num_bins ) / num_bins
226218 return x
227219
228- defended_model .layers [0 ].input = tf .keras .Input (shape = model .input_shape [1 :])
229- defended_model .layers [0 ].input = encode (defended_model .layers [0 ].input )
230- return defended_model
220+ input_layer = tf .keras .Input (shape = model .input_shape [1 :])
221+ x = encode (input_layer )
222+ predictions = model (x )
223+ return tf .keras .Model (inputs = input_layer , outputs = predictions )
231224
232225def adversarial_logit_pairing (model , paired_model ):
233226 """
@@ -266,12 +259,33 @@ def spatial_smoothing(model, kernel_size=3):
266259 Returns:
267260 defended_model (tensorflow.keras.Model): The model with spatial smoothing defense.
268261 """
269- defended_model = tf .keras .models .clone_model (model )
270- defended_model .set_weights (model .get_weights ())
271-
272262 def smooth (x ):
273263 return tf .nn .avg_pool2d (x , ksize = kernel_size , strides = 1 , padding = 'SAME' )
274264
275- defended_model .layers [0 ].input = tf .keras .Input (shape = model .input_shape [1 :])
276- defended_model .layers [0 ].input = smooth (defended_model .layers [0 ].input )
277- return defended_model
265+ input_layer = tf .keras .Input (shape = model .input_shape [1 :])
266+ x = smooth (input_layer )
267+ predictions = model (x )
268+ return tf .keras .Model (inputs = input_layer , outputs = predictions )
269+
270+
271+ def jpeg_compression (model , quality = 75 ):
272+ """
273+ JPEG Compression defense.
274+
275+ This defense compresses the input image using JPEG, which can remove high-frequency
276+ adversarial perturbations.
277+
278+ Parameters:
279+ model (tensorflow.keras.Model): The model to defend.
280+ quality (int): The JPEG compression quality (0-100), default is 75.
281+
282+ Returns:
283+ defended_model (tensorflow.keras.Model): The model with JPEG compression defense.
284+ """
285+ def compress (x ):
286+ return tf .map_fn (lambda img : tf .cast (tf .image .decode_jpeg (tf .image .encode_jpeg (tf .cast (img * 255 , tf .uint8 ), quality = quality ), channels = 3 ), tf .float32 ) / 255.0 , x )
287+
288+ input_layer = tf .keras .Input (shape = model .input_shape [1 :])
289+ x = compress (input_layer )
290+ predictions = model (x )
291+ return tf .keras .Model (inputs = input_layer , outputs = predictions )
0 commit comments