29
29
from tensorflow .keras .backend import clear_session
30
30
from tensorflow .keras .utils import to_categorical
31
31
from tensorflow .keras import metrics
32
+ import pytest
32
33
33
34
from qkeras import QConv2DBatchnorm
34
35
from qkeras import QConv2D
36
+ from qkeras import QDenseBatchnorm
35
37
from qkeras import QDense
36
38
from qkeras import QActivation
37
39
from qkeras import QDepthwiseConv2D
@@ -110,7 +112,7 @@ def get_qconv2d_batchnorm_model(input_shape, kernel_size, folding_mode,
110
112
return model
111
113
112
114
113
- def get_models_with_one_layer (kernel_quantizer , folding_mode , ema_freeze_delay ):
115
+ def get_conv2d_models_with_one_layer (kernel_quantizer , folding_mode , ema_freeze_delay ):
114
116
115
117
x_shape = (2 , 2 , 1 )
116
118
loss_fn = tf .keras .losses .MeanSquaredError ()
@@ -164,6 +166,60 @@ def get_models_with_one_layer(kernel_quantizer, folding_mode, ema_freeze_delay):
164
166
return (unfold_model , fold_model )
165
167
166
168
169
+ def get_dense_models_with_one_layer (kernel_quantizer , folding_mode , ema_freeze_delay ):
170
+
171
+ x_shape = (4 ,)
172
+ loss_fn = tf .keras .losses .MeanSquaredError ()
173
+ optimizer = get_sgd_optimizer (learning_rate = 1e-3 )
174
+
175
+ # define a model with seperate conv2d and bn layers
176
+ x = x_in = layers .Input (x_shape , name = "input" )
177
+ x = QDense (
178
+ 2 ,
179
+ kernel_initializer = "ones" ,
180
+ bias_initializer = "zeros" , use_bias = False ,
181
+ kernel_quantizer = kernel_quantizer , bias_quantizer = None ,
182
+ name = "conv2d" )(x )
183
+ x = layers .BatchNormalization (
184
+ axis = - 1 ,
185
+ momentum = 0.99 ,
186
+ epsilon = 0.001 ,
187
+ center = True ,
188
+ scale = True ,
189
+ beta_initializer = "zeros" ,
190
+ gamma_initializer = "ones" ,
191
+ moving_mean_initializer = "zeros" ,
192
+ moving_variance_initializer = "ones" ,
193
+ beta_regularizer = None ,
194
+ gamma_regularizer = None ,
195
+ beta_constraint = None ,
196
+ gamma_constraint = None ,
197
+ renorm = False ,
198
+ renorm_clipping = None ,
199
+ renorm_momentum = 0.99 ,
200
+ fused = None ,
201
+ trainable = True ,
202
+ virtual_batch_size = None ,
203
+ adjustment = None ,
204
+ name = "bn" )(x )
205
+ unfold_model = Model (inputs = [x_in ], outputs = [x ])
206
+ unfold_model .compile (loss = loss_fn , optimizer = optimizer , metrics = "acc" )
207
+
208
+ x = x_in = layers .Input (x_shape , name = "input" )
209
+ x = QDenseBatchnorm (
210
+ 2 ,
211
+ kernel_initializer = "ones" , bias_initializer = "zeros" , use_bias = False ,
212
+ kernel_quantizer = kernel_quantizer , beta_initializer = "zeros" ,
213
+ gamma_initializer = "ones" , moving_mean_initializer = "zeros" ,
214
+ moving_variance_initializer = "ones" , folding_mode = folding_mode ,
215
+ ema_freeze_delay = ema_freeze_delay ,
216
+ name = "foldconv2d" )(x )
217
+ fold_model = Model (inputs = [x_in ], outputs = [x ])
218
+ fold_model .compile (loss = loss_fn , optimizer = optimizer , metrics = "acc" )
219
+
220
+ return (unfold_model , fold_model )
221
+
222
+
167
223
def get_debug_model (model ):
168
224
layer_output_list = []
169
225
for layer in model .layers :
@@ -181,10 +237,7 @@ def generate_dataset(train_size=10,
181
237
output_shape = None ):
182
238
"""create tf.data.Dataset with shape: (N,) + input_shape."""
183
239
184
- x_train = np .random .randint (
185
- 4 , size = (train_size , input_shape [0 ], input_shape [1 ], input_shape [2 ]))
186
- x_train = np .random .rand (
187
- train_size , input_shape [0 ], input_shape [1 ], input_shape [2 ])
240
+ x_train = np .random .rand (* (train_size ,) + input_shape )
188
241
189
242
if output_shape :
190
243
y_train = np .random .random_sample ((train_size ,) + output_shape )
@@ -397,31 +450,48 @@ def test_loading():
397
450
assert_equal (weight1 [1 ], weight2 [1 ])
398
451
399
452
400
- def test_same_training_and_prediction ():
453
+ @pytest .mark .parametrize ("model_name" , ["conv2d" , "dense" ])
454
+ def test_same_training_and_prediction (model_name ):
401
455
"""test if fold/unfold layer has the same training and prediction output."""
402
456
403
457
epochs = 5
404
458
loss_fn = tf .keras .losses .MeanSquaredError ()
405
459
loss_metric = metrics .Mean ()
406
460
optimizer = get_sgd_optimizer (learning_rate = 1e-3 )
407
461
408
- x_shape = (2 , 2 , 1 )
409
- kernel = np .array ([[[[1. , 1. ]], [[1. , 0. ]]], [[[1. , 1. ]], [[0. , 1. ]]]])
410
- gamma = np .array ([2. , 1. ])
411
- beta = np .array ([0. , 1. ])
412
- moving_mean = np .array ([1. , 1. ])
413
- moving_variance = np .array ([1. , 2. ])
462
+ if model_name == "conv2d" :
463
+ x_shape = (2 , 2 , 1 )
464
+ kernel = np .array ([[[[1. , 1. ]], [[1. , 0. ]]], [[[1. , 1. ]], [[0. , 1. ]]]])
465
+ gamma = np .array ([2. , 1. ])
466
+ beta = np .array ([0. , 1. ])
467
+ moving_mean = np .array ([1. , 1. ])
468
+ moving_variance = np .array ([1. , 2. ])
469
+ elif model_name == "dense" :
470
+ x_shape = (4 ,)
471
+ kernel = np .array ([[1. , 1. ], [1. , 0. ], [1. , 1. ], [0. , 1. ]])
472
+ gamma = np .array ([2. , 1. ])
473
+ beta = np .array ([0. , 1. ])
474
+ moving_mean = np .array ([1. , 1. ])
475
+ moving_variance = np .array ([1. , 2. ])
414
476
iteration = np .array (- 1 )
415
477
416
478
train_ds = generate_dataset (train_size = 10 , batch_size = 10 , input_shape = x_shape ,
417
479
num_class = 2 )
418
480
419
- (unfold_model , fold_model_batch ) = get_models_with_one_layer (
420
- kernel_quantizer = None , folding_mode = "batch_stats_folding" ,
421
- ema_freeze_delay = 10 )
422
- (_ , fold_model_ema ) = get_models_with_one_layer (
423
- kernel_quantizer = None , folding_mode = "ema_stats_folding" ,
424
- ema_freeze_delay = 10 )
481
+ if model_name == "conv2d" :
482
+ (unfold_model , fold_model_batch ) = get_conv2d_models_with_one_layer (
483
+ kernel_quantizer = None , folding_mode = "batch_stats_folding" ,
484
+ ema_freeze_delay = 10 )
485
+ (_ , fold_model_ema ) = get_conv2d_models_with_one_layer (
486
+ kernel_quantizer = None , folding_mode = "ema_stats_folding" ,
487
+ ema_freeze_delay = 10 )
488
+ elif model_name == "dense" :
489
+ (unfold_model , fold_model_batch ) = get_dense_models_with_one_layer (
490
+ kernel_quantizer = None , folding_mode = "batch_stats_folding" ,
491
+ ema_freeze_delay = 10 )
492
+ (_ , fold_model_ema ) = get_dense_models_with_one_layer (
493
+ kernel_quantizer = None , folding_mode = "ema_stats_folding" ,
494
+ ema_freeze_delay = 10 )
425
495
426
496
unfold_model .layers [1 ].set_weights ([kernel ])
427
497
unfold_model .layers [2 ].set_weights (
@@ -455,12 +525,20 @@ def test_same_training_and_prediction():
455
525
# models should be different, but the two folding modes should be the same
456
526
epochs = 5
457
527
iteration = np .array (8 )
458
- (unfold_model , fold_model_batch ) = get_models_with_one_layer (
459
- kernel_quantizer = None , folding_mode = "batch_stats_folding" ,
460
- ema_freeze_delay = 10 )
461
- (_ , fold_model_ema ) = get_models_with_one_layer (
462
- kernel_quantizer = None , folding_mode = "ema_stats_folding" ,
463
- ema_freeze_delay = 10 )
528
+ if model_name == "conv2d" :
529
+ (unfold_model , fold_model_batch ) = get_conv2d_models_with_one_layer (
530
+ kernel_quantizer = None , folding_mode = "batch_stats_folding" ,
531
+ ema_freeze_delay = 10 )
532
+ (_ , fold_model_ema ) = get_conv2d_models_with_one_layer (
533
+ kernel_quantizer = None , folding_mode = "ema_stats_folding" ,
534
+ ema_freeze_delay = 10 )
535
+ elif model_name == "dense" :
536
+ (unfold_model , fold_model_batch ) = get_dense_models_with_one_layer (
537
+ kernel_quantizer = None , folding_mode = "batch_stats_folding" ,
538
+ ema_freeze_delay = 10 )
539
+ (_ , fold_model_ema ) = get_dense_models_with_one_layer (
540
+ kernel_quantizer = None , folding_mode = "ema_stats_folding" ,
541
+ ema_freeze_delay = 10 )
464
542
unfold_model .layers [1 ].set_weights ([kernel ])
465
543
unfold_model .layers [2 ].set_weights (
466
544
[gamma , beta , moving_mean , moving_variance ])
0 commit comments