예제 #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)
예제 #2
0
def save_model(model_save_name, model):
    with open(model_save_name + '.json', 'w') as file:
        file.write(model.to_json())

    model.save_weights(model_save_name + '.h5')
    model_save_quantized_weights(
        model, model_save_name + '_quantized_weights' + '.h5')
    model.save(model_save_name + '_h5file.h5')
예제 #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)
예제 #4
0
def qbn_model_inference():

    x = x_in = keras.layers.Input((23, 23, 1), name="input")
    x = QConv2D(4,
                2,
                23,
                kernel_quantizer=quantizers.quantized_bits(4, 0, 1, alpha=1.0),
                bias_quantizer=quantizers.quantized_bits(4, 0, 1, alpha=1.0),
                use_bias=False,
                name="qconv2d_1")(x)
    x = QBatchNormalization(mean_quantizer=quantizers.quantized_bits(6, 0, 1),
                            gamma_quantizer=None,
                            variance_quantizer=None,
                            beta_quantizer=quantizers.quantized_bits(6, 0, 1),
                            inverse_quantizer=quantizers.quantized_bits(
                                16, 0, 1),
                            scale=False,
                            center=False,
                            gamma_range=8,
                            beta_range=4,
                            name="qbn_2")(x)

    x = QConv2D(2,
                1,
                1,
                kernel_quantizer=quantizers.quantized_bits(3, 0),
                bias_quantizer=quantizers.quantized_bits(3, 2),
                name="qconv2d_3")(x)

    model = keras.Model(inputs=[x_in], outputs=[x])
    hw_weight_dict = model_save_quantized_weights(model)

    return (hw_weight_dict, model)
예제 #5
0
        for i, weights in enumerate(layer.get_weights()):
            weights = K.eval(layer.get_quantizers()[i](K.constant(weights)))
            print(" ({: 8.4f} {: 8.4f})".format(np.min(weights),
                                                np.max(weights)),
                  end="")
            print("")

    p_test = mo.predict(x_test)
    p_test.tofile("p_test.bin")

    score = model.evaluate(x_test, y_test, verbose=VERBOSE)
    print("Test score:", score[0])
    print("Test accuracy:", score[1])

    all_weights = []
    model_save_quantized_weights(model)

    for layer in model.layers:
        for w, weights in enumerate(layer.get_weights()):
            print(layer.name, w)
            all_weights.append(weights.flatten())

    all_weights = np.concatenate(all_weights).astype(np.float32)
    print(all_weights.size)

for layer in model.layers:
    for w, weight in enumerate(layer.get_weights()):
        print(layer.name, w, weight.shape)

print_qstats(model)
예제 #6
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)
예제 #7
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)
예제 #8
0
def test_qconv1d(layer_cls):
    np.random.seed(33)
    if layer_cls == "QConv1D":
        x = Input((
            4,
            4,
        ))
        y = QConv1D(2,
                    1,
                    kernel_quantizer=quantized_bits(6, 2, 1, alpha=1.0),
                    bias_quantizer=quantized_bits(4, 0, 1),
                    name='qconv1d')(x)
        model = Model(inputs=x, outputs=y)
    else:
        x = Input((
            4,
            4,
        ))
        y = QSeparableConv1D(2,
                             2,
                             depthwise_quantizer=quantized_bits(6,
                                                                2,
                                                                1,
                                                                alpha=1.0),
                             pointwise_quantizer=quantized_bits(4,
                                                                0,
                                                                1,
                                                                alpha=1.0),
                             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)

    # Check the input layer model operation was found correctly
    assert model_ops['qconv1d']['type'][0] != 'null'

    # Assertion about the number of operations for this (Separable)Conv1D layer
    if layer_cls == "QConv1D":
        assert model_ops['qconv1d']['number_of_operations'] == 32
    else:
        assert model_ops['qconv1d']['number_of_operations'] == 30

    # 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

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

    inputs = np.random.rand(2, 4, 4)
    p = model.predict(inputs).astype(np.float16)
    if layer_cls == "QConv1D":
        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)
    else:
        y = np.array([[[-2.275, -3.178], [-0.4358, -3.262], [1.987, 0.3987]],
                      [[-0.01251, -0.376], [0.3928, -1.328],
                       [-1.243, -2.43]]]).astype(np.float16)
    assert_allclose(p, y, rtol=1e-4)
예제 #9
0
def SaveQuantizedWeights(qmodel, qmodelfile):
    model_save_quantized_weights(qmodel, qmodelfile)
    return