def test_qnetwork(): x = x_in = Input((28, 28, 1), name='input') x = QSeparableConv2D( 32, (2, 2), strides=(2, 2), depthwise_quantizer="binary", pointwise_quantizer=quantized_bits(4, 0, 1), depthwise_activation=quantized_bits(6, 2, 1), bias_quantizer=quantized_bits(4, 0, 1), name='conv2d_0_m')( x) x = QActivation('quantized_relu(6,2,1)', name='act0_m')(x) x = QConv2D( 64, (3, 3), strides=(2, 2), kernel_quantizer="ternary", bias_quantizer=quantized_bits(4, 0, 1), name='conv2d_1_m', activation=quantized_relu(6, 3, 1))( x) x = QConv2D( 64, (2, 2), strides=(2, 2), kernel_quantizer=quantized_bits(6, 2, 1), bias_quantizer=quantized_bits(4, 0, 1), name='conv2d_2_m')( x) x = QActivation('quantized_relu(6,4,1)', name='act2_m')(x) x = Flatten(name='flatten')(x) x = QDense( 10, kernel_quantizer=quantized_bits(6, 2, 1), bias_quantizer=quantized_bits(4, 0, 1), name='dense')( x) x = Activation('softmax', name='softmax')(x) model = Model(inputs=[x_in], outputs=[x]) # reload the model to ensure saving/loading works json_string = model.to_json() clear_session() model = quantized_model_from_json(json_string) # generate same output for weights np.random.seed(42) for layer in model.layers: all_weights = [] for i, weights in enumerate(layer.get_weights()): input_size = np.prod(layer.input.shape.as_list()[1:]) if input_size is None: input_size = 576 * 10 # to avoid learning sizes shape = weights.shape assert input_size > 0, 'input size for {} {}'.format(layer.name, i) # he normal initialization with a scale factor of 2.0 all_weights.append( 10.0 * np.random.normal(0.0, np.sqrt(2.0 / input_size), shape)) if all_weights: layer.set_weights(all_weights) # apply quantizer to weights model_save_quantized_weights(model) all_weights = [] for layer in model.layers: for i, weights in enumerate(layer.get_weights()): w = np.sum(weights) all_weights.append(w) all_weights = np.array(all_weights) # test_qnetwork_weight_quantization all_weights_signature = np.array( [2., -6.75, -0.625, -2., -0.25, -56., 1.125, -1.625, -1.125]) assert all_weights.size == all_weights_signature.size assert np.all(all_weights == all_weights_signature) # test_qnetwork_forward: expected_output = np.array([[0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 1.e+00, 0.e+00, 0.e+00, 0.e+00], [0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 1.e+00, 0.e+00, 0.e+00, 0.e+00], [0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 6.e-08, 1.e+00], [0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 1.e+00, 0.e+00, 0.e+00, 0.e+00], [0.e+00 ,0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 1.e+00, 0.e+00, 0.e+00, 0.e+00], [0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 5.e-07, 1.e+00], [0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00 ,1.e+00, 0.e+00, 0.e+00, 0.e+00], [0.e+00, 1.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00 ,0.e+00, 0.e+00, 0.e+00, 0.e+00], [0.e+00, 0.e+00, 0.e+00, 0.e+00, 1.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00], [0.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00, 1.e+00, 0.e+00, 0.e+00, 0.e+00, 0.e+00]]).astype(np.float16) inputs = 2 * np.random.rand(10, 28, 28, 1) actual_output = model.predict(inputs).astype(np.float16) assert_allclose(actual_output, expected_output, rtol=1e-4)
def test_qnetwork(): x = x_in = Input((28, 28, 1), name='input') x = QSeparableConv2D(32, (2, 2), strides=(2, 2), depthwise_quantizer=binary(), pointwise_quantizer=quantized_bits(4, 0, 1), depthwise_activation=quantized_bits(6, 2, 1), bias_quantizer=quantized_bits(4, 0, 1), name='conv2d_0_m')(x) x = QActivation('quantized_relu(6,2,1)', name='act0_m')(x) x = QConv2D(64, (3, 3), strides=(2, 2), kernel_quantizer=ternary(), bias_quantizer=quantized_bits(4, 0, 1), name='conv2d_1_m')(x) x = QActivation('quantized_relu(6, 3, 1)', name='act1_m')(x) x = QConv2D(64, (2, 2), strides=(2, 2), kernel_quantizer=quantized_bits(6, 2, 1), bias_quantizer=quantized_bits(4, 0, 1), name='conv2d_2_m')(x) x = QActivation('quantized_relu(6,4,1)', name='act2_m')(x) x = Flatten(name='flatten')(x) x = QDense(10, kernel_quantizer=quantized_bits(6, 2, 1), bias_quantizer=quantized_bits(4, 0, 1), name='dense')(x) x = Activation('softmax', name='softmax')(x) model = Model(inputs=[x_in], outputs=[x]) # generate same output for weights np.random.seed(42) for layer in model.layers: all_weights = [] for i, weights in enumerate(layer.get_weights()): input_size = np.prod(layer.input.shape.as_list()[1:]) if input_size is None: input_size = 576 * 10 # hack to avoid learning sizes shape = weights.shape assert input_size > 0, 'input size for {} {}'.format(layer.name, i) # he normal initialization with a scale factor of 2.0 all_weights.append( 10.0 * np.random.normal(0.0, np.sqrt(2.0 / input_size), shape)) if all_weights: layer.set_weights(all_weights) # apply quantizer to weights model_save_quantized_weights(model) all_weights = [] for layer in model.layers: for i, weights in enumerate(layer.get_weights()): w = np.sum(weights) all_weights.append(w) all_weights = np.array(all_weights) # test_qnetwork_weight_quantization all_weights_signature = np.array( [2.0, -6.75, -0.625, -2.0, -0.25, -56.0, 1.125, -2.625, -0.75]) assert all_weights.size == all_weights_signature.size assert np.all(all_weights == all_weights_signature) # test_qnetwork_forward: y = np.array([[ 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 5.341e-02, 9.468e-01, 0.000e+00, 0.000e+00, 0.000e+00 ], [ 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 5.960e-08, 0.000e+00, 1.919e-01, 0.000e+00, 0.000e+00, 8.081e-01 ], [ 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 2.378e-04, 0.000e+00, 0.000e+00, 0.000e+00, 2.843e-05, 9.995e-01 ], [ 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 1.000e+00, 0.000e+00, 0.000e+00, 0.000e+00 ], [ 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 1.000e+00, 0.000e+00, 2.623e-06, 0.000e+00 ], [ 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 7.749e-07, 0.000e+00, 0.000e+00, 1.634e-04, 1.000e+00 ], [ 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 1.000e+00, 0.000e+00, 0.000e+00, 0.000e+00 ], [ 0.000e+00, 1.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 6.557e-07, 0.000e+00, 0.000e+00, 0.000e+00 ], [ 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 1.000e+00, 0.000e+00, 5.960e-08, 0.000e+00, 0.000e+00, 0.000e+00 ], [ 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 9.125e-03, 9.907e-01, 9.418e-06, 0.000e+00, 5.597e-05, 0.000e+00 ]]).astype(np.float16) inputs = 2 * np.random.rand(10, 28, 28, 1) p = model.predict(inputs).astype(np.float16) assert np.all(p == y)