Exemple #1
0
def test_q_average_pooling(pooling, input_size, pool_size, strides, padding,
                           data_format, average_quantizer,
                           activation_quantizer, y):
    """q_average_pooling test utility."""

    np.random.seed(33)

    x = Input(input_size)
    xin = x
    if pooling == 'QAveragePooling2D':
        x = QAveragePooling2D(pool_size=pool_size,
                              strides=strides,
                              padding=padding,
                              data_format=data_format,
                              average_quantizer=average_quantizer,
                              activation=activation_quantizer,
                              name='qpooling')(x)
    else:
        x = QGlobalAveragePooling2D(data_format=data_format,
                                    average_quantizer=average_quantizer,
                                    activation=activation_quantizer,
                                    name='qpooling')(x)
    model = Model(inputs=xin, outputs=x)

    # Prints qstats to make sure it works with Conv1D layer
    print_qstats(model)

    size = (2, ) + input_size
    inputs = np.random.rand(size[0], size[1], size[2], size[3])

    if data_format == 'channels_first':
        assert_raises(tf.errors.InvalidArgumentError, model.predict, inputs)
    else:
        p = model.predict(inputs).astype(np.float16)
        assert_allclose(p, y, rtol=1e-4)

        # Reloads the model to ensure saving/loading works
        json_string = model.to_json()
        clear_session()
        reload_model = quantized_model_from_json(json_string)
        p = reload_model.predict(inputs).astype(np.float16)
        assert_allclose(p, y, rtol=1e-4)

        # Saves the model as an h5 file using Keras's model.save()
        fd, fname = tempfile.mkstemp(".h5")
        model.save(fname)
        del model  # Delete the existing model

        # Returns a compiled model identical to the previous one
        loaded_model = load_qmodel(fname)

        # Cleans the created h5 file after loading the model
        os.close(fd)
        os.remove(fname)

        # Applys quantizer to weights
        model_save_quantized_weights(loaded_model)
        p = loaded_model.predict(inputs).astype(np.float16)
        assert_allclose(p, y, rtol=1e-4)
def load_model_quantized(model_name):
    json_file = open(model_name + '.json', 'r')
    loaded_model_json = json_file.read()
    json_file.close()
    model = quantized_model_from_json(loaded_model_json)
    model.load_weights(model_name + '.h5')

    return model
Exemple #3
0
def test_qbidirectional(rnn, all_weights_signature, expected_output):
    K.set_learning_phase(0)
    np.random.seed(22)
    tf.random.set_seed(22)

    x = x_in = Input((2, 4), name='input')
    x = QBidirectional(
        rnn(16,
            activation="quantized_po2(8)",
            kernel_quantizer="quantized_po2(8)",
            recurrent_quantizer="quantized_po2(8)",
            bias_quantizer="quantized_po2(8)",
            name='qbirnn_0'))(x)
    x = QDense(4,
               kernel_quantizer=quantized_bits(8, 2, 1, alpha=1.0),
               bias_quantizer=quantized_bits(8, 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)

    # Save the model as an h5 file using Keras's model.save()
    fd, fname = tempfile.mkstemp('.h5')
    model.save(fname)
    del model  # Delete the existing model

    # Return a compiled model identical to the previous one
    model = load_qmodel(fname)

    # Clean the created h5 file after loading the model
    os.close(fd)
    os.remove(fname)

    # 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)

    assert all_weights.size == all_weights_signature.size
    assert np.all(all_weights == all_weights_signature)

    # test forward:
    inputs = 2 * np.random.rand(10, 2, 4)
    actual_output = model.predict(inputs).astype(np.float16)
    assert_allclose(actual_output, expected_output, rtol=1e-4)
Exemple #4
0
def test_loading():
    """Test to load model using different approahches."""

    loss_fn = tf.keras.losses.MeanSquaredError()
    loss_metric = metrics.Mean()
    optimizer = tf.keras.optimizers.SGD(learning_rate=1e-3)
    x_shape = (2, 2, 1)

    custom_objects = {}
    qkeras_utils._add_supported_quantized_objects(custom_objects)

    train_ds = generate_dataset(train_size=1,
                                batch_size=1,
                                input_shape=x_shape,
                                num_class=2)

    model_fold = get_qconv2d_batchnorm_model(input_shape=x_shape,
                                             kernel_size=(2, 2),
                                             folding_mode="ema_stats_folding")
    model_fold.compile(loss=loss_fn, optimizer=optimizer, metrics="acc")

    run_training(model_fold,
                 10,
                 loss_fn,
                 loss_metric,
                 optimizer,
                 train_ds,
                 do_print=False)

    # test load model from json to ensure saving/loading model architecture works
    json_string = model_fold.to_json()
    clear_session()
    model_from_json = qkeras_utils.quantized_model_from_json(json_string)
    assert json_string == model_from_json.to_json()

    # test reload model from hdf5 files to ensure saving/loading works
    _, fname = tempfile.mkstemp(".h5")
    model_fold.save(fname)
    model_loaded = qkeras_utils.load_qmodel(fname)
    weight1 = model_fold.layers[1].get_folded_quantized_weight()
    weight2 = model_loaded.layers[1].get_folded_quantized_weight()
    assert_equal(weight1[0], weight2[0])
    assert_equal(weight1[1], weight2[1])

    # test convert a folded model to a normal model for zpm
    # the kernel/bias weight in the normal model should be the same as the folded
    # kernel/bias in the folded model
    normal_model = bn_folding_utils.convert_folded_model_to_normal(model_fold)
    weight2 = normal_model.layers[1].get_weights()

    assert_equal(weight1[0], weight2[0])
    assert_equal(weight1[1], weight2[1])
Exemple #5
0
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)
Exemple #6
0
def test_qconv1d():
  np.random.seed(33)
  x = Input((4, 4,))
  y = QConv1D(
      2, 1,
      kernel_quantizer=quantized_bits(6, 2, 1),
      bias_quantizer=quantized_bits(4, 0, 1),
      name='qconv1d')(
          x)
  model = Model(inputs=x, outputs=y)

  #Extract model operations
  model_ops = extract_model_operations(model)

  # Assertion about the number of operations for this Conv1D layer
  assert model_ops['qconv1d']["number_of_operations"] == 32

  # Print qstats to make sure it works with Conv1D layer
  print_qstats(model) 

  # reload the model to ensure saving/loading works
  json_string = model.to_json()
  clear_session()
  model = quantized_model_from_json(json_string)

  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 = 10 * 10
      shape = weights.shape
      assert input_size > 0, 'input size for {} {}'.format(layer.name, i)
      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)
    
  # Save the model as an h5 file using Keras's model.save()
  fd, fname = tempfile.mkstemp('.h5')
  model.save(fname)
  del model  # Delete the existing model

  # Returns a compiled model identical to the previous one
  model = load_qmodel(fname)

  #Clean the created h5 file after loading the model
  os.close(fd)
  os.remove(fname)

  # apply quantizer to weights
  model_save_quantized_weights(model)

  inputs = np.random.rand(2, 4, 4)
  p = model.predict(inputs).astype(np.float16)
  '''
  y = np.array([[[0.1309, -1.229], [-0.4165, -2.639], [-0.08105, -2.299],
                 [1.981, -2.195]],
                [[-0.3174, -3.94], [-0.3352, -2.316], [0.105, -0.833],
                 [0.2115, -2.89]]]).astype(np.float16)
  '''
  y = np.array([[[-2.441, 3.816], [-3.807, -1.426], [-2.684, -1.317],
                 [-1.659, 0.9834]],
                [[-4.99, 1.139], [-2.559, -1.216], [-2.285, 1.905],
                 [-2.652, -0.467]]]).astype(np.float16)
  assert np.all(p == y)