Beispiel #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)
Beispiel #2
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)
Beispiel #3
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])
def train_and_save(model, x_train, y_train, x_test, y_test):
    model.compile(
        loss="categorical_crossentropy",
        optimizer="adam",
        metrics=["accuracy"])

    # Print the model summary.
    model.summary()

    # Add a pruning step callback to peg the pruning step to the optimizer's
    # step. Also add a callback to add pruning summaries to tensorboard
    callbacks = [
        pruning_callbacks.UpdatePruningStep(),
        #pruning_callbacks.PruningSummaries(log_dir=tempfile.mkdtemp())
        pruning_callbacks.PruningSummaries(log_dir="/tmp/mnist_prune")
    ]

    model.fit(
        x_train,
        y_train,
        batch_size=batch_size,
        epochs=epochs,
        verbose=1,
        callbacks=callbacks,
        validation_data=(x_test, y_test))
    score = model.evaluate(x_test, y_test, verbose=0)
    print("Test loss:", score[0])
    print("Test accuracy:", score[1])

    print_model_sparsity(model)

    # Export and import the model. Check that accuracy persists.
    _, keras_file = tempfile.mkstemp(".h5")
    print("Saving model to: ", keras_file)
    save_model(model, keras_file)
    
    print("Reloading model")
    with prune.prune_scope():
        loaded_model = load_qmodel(keras_file)
    score = loaded_model.evaluate(x_test, y_test, verbose=0)
    print("Test loss:", score[0])
    print("Test accuracy:", score[1])
Beispiel #5
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)
Beispiel #6
0
# -*- coding: utf-8 -*-
import numpy as np
from keras.models import load_model
from qkeras.utils import load_qmodel
from QKeras_Model import preproc
import hls4ml
from subprocess import check_output

modelname = "QKeras_Model_60_50_30_40_15"
outrootname = "QKeras_Model_60_50_30_40_15_HLS_noreuse"

#Preprocessing data
X_test, Y_test = preproc(True)

#Loading QKeras model from disk
model = load_qmodel(modelname + '/' + modelname + '.h5')

#Creating configuration dictionary
config = hls4ml.utils.config_from_keras_model(model,
                                              granularity='name',
                                              default_reuse_factor=1)

#Activating tracing (i.e. saving also the results passed between hidden layers)
for layer in config['LayerName'].keys():
    config['LayerName'][layer]['Trace'] = True

#Creating HLS_model from the QKeras one using the config dict
hls_model = hls4ml.converters.convert_from_keras_model(
    model,
    hls_config=config,
    output_dir=modelname + '/' + outrootname + '/HLS_Project',
Beispiel #7
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)
    json_file.close()
    model = quantized_model_from_json(loaded_model_json)
    model.load_weights(model_name + '.h5')

    return model


# In[3]:

model = load_model_quantized(
    'models/qkeras_models/qkeras_model_2_4_2020_3layers_vol100')
model.summary()

# In[4]:

model_2 = load_qmodel(
    'models/qkeras_models/qkeras_model_2_4_2020_3layers_vol100_h5file.h5')
model_2.summary()

# In[7]:

# didn't use this always (for making sure input and output are compatible with the board)
lays = model_2.layers

n_input_features = lays[0].input_shape[0][1]
inputs = Input(shape=(
    1,
    1,
    n_input_features,
))
hidden_layers = Reshape((n_input_features, ), name='reshaped_hidden')(inputs)