Skip to content

Commit

Permalink
add qkeras example
Browse files Browse the repository at this point in the history
  • Loading branch information
calad0i committed Nov 27, 2023
1 parent f8f27fd commit 8e8798c
Showing 1 changed file with 249 additions and 0 deletions.
249 changes: 249 additions & 0 deletions examples/qkeras.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"os.environ['CUDA_VISIBLE_DEVICES'] = '-1'\n",
"\n",
"from HGQ import shutup\n",
"import numpy as np\n",
"import keras\n",
"import qkeras\n",
"from HGQ import to_proxy_model\n",
"\n",
"with shutup:\n",
" from hls4ml.converters import convert_from_keras_model"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"qkeras_model = keras.models.Sequential([\n",
" qkeras.QActivation('quantized_bits(8, 0, 0, False, alpha=1)'), # This layer can NOT be removed\n",
" keras.layers.Reshape((28, 28, 1)),\n",
" qkeras.QConv2D(4,\n",
" (3, 3),\n",
" kernel_quantizer='quantized_bits(8, 3, alpha=1)',\n",
" bias_quantizer='quantized_bits(8, 3, alpha=1)',\n",
" activation='quantized_relu(8, 4)'\n",
" ),\n",
" keras.layers.MaxPooling2D(pool_size=(2, 2)),\n",
" qkeras.QConv2D(4,\n",
" (3, 3),\n",
" kernel_quantizer='quantized_bits(8, 3, alpha=1)',\n",
" bias_quantizer='quantized_bits(8, 3, alpha=1)',\n",
" activation='quantized_relu(8, 4)'\n",
" ),\n",
" keras.layers.MaxPooling2D(pool_size=(2, 2)),\n",
" keras.layers.Flatten(),\n",
" qkeras.QDense(32,\n",
" kernel_quantizer='quantized_bits(8, 3, alpha=1)',\n",
" bias_quantizer='quantized_bits(8, 3, alpha=1)',\n",
" activation='quantized_relu(8, 4)'\n",
" ),\n",
" qkeras.QDense(10,\n",
" kernel_quantizer='quantized_bits(8, 3, alpha=1)',\n",
" bias_quantizer='quantized_bits(8, 3, alpha=1)',\n",
" activation='quantized_bits(8, 4, alpha=1)'\n",
" )\n",
"])\n",
"\n",
"qkeras_model.build((None, 28, 28, 1))"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()\n",
"x_train = x_train / np.float32(256.0)\n",
"x_test = x_test / np.float32(256.0)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"opt = keras.optimizers.Adam(0.003)\n",
"loss = keras.losses.SparseCategoricalCrossentropy(from_logits=True)\n",
"qkeras_model.compile(optimizer=opt, loss=loss, metrics=['accuracy'])"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/3\n",
"469/469 [==============================] - 8s 13ms/step - loss: 0.4635 - accuracy: 0.8571 - val_loss: 0.1471 - val_accuracy: 0.9543\n",
"Epoch 2/3\n",
"469/469 [==============================] - 5s 10ms/step - loss: 0.1513 - accuracy: 0.9535 - val_loss: 0.1258 - val_accuracy: 0.9597\n",
"Epoch 3/3\n",
"469/469 [==============================] - 5s 10ms/step - loss: 0.1190 - accuracy: 0.9641 - val_loss: 0.1071 - val_accuracy: 0.9667\n"
]
},
{
"data": {
"text/plain": [
"<keras.src.callbacks.History at 0x7f406f845f50>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"qkeras_model.fit(x_train, y_train, epochs=3, batch_size=128, verbose=1, validation_data=(x_test, y_test))"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"proxy = to_proxy_model(qkeras_model, aggressive=False)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"r_qkeras = qkeras_model(x_test).numpy()\n",
"r_proxy = proxy(x_test).numpy()\n",
"\n",
"assert np.all(r_qkeras == r_proxy)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Interpreting Model\n",
"Topology:\n",
"Layer name: input_1, layer type: InputLayer, input shapes: [[None, 28, 28, 1]], output shape: [None, 28, 28, 1]\n",
"Layer name: fixed_point_quantizer, layer type: FixedPointQuantizer, input shapes: [[None, 28, 28, 1]], output shape: [None, 28, 28, 1]\n",
"Layer name: reshape, layer type: Reshape, input shapes: [[None, 28, 28, 1]], output shape: [None, 28, 28, 1]\n",
"Layer name: q_conv2d, layer type: Conv2D, input shapes: [[None, 28, 28, 1]], output shape: [None, 26, 26, 4]\n",
"Layer name: fixed_point_quantizer_1, layer type: FixedPointQuantizer, input shapes: [[None, 26, 26, 4]], output shape: [None, 26, 26, 4]\n",
"Layer name: activation, layer type: Activation, input shapes: [[None, 26, 26, 4]], output shape: [None, 26, 26, 4]\n",
"Layer name: fixed_point_quantizer_2, layer type: FixedPointQuantizer, input shapes: [[None, 26, 26, 4]], output shape: [None, 26, 26, 4]\n",
"Layer name: max_pooling2d, layer type: MaxPooling2D, input shapes: [[None, 26, 26, 4]], output shape: [None, 13, 13, 4]\n",
"Layer name: q_conv2d_1, layer type: Conv2D, input shapes: [[None, 13, 13, 4]], output shape: [None, 11, 11, 4]\n",
"Layer name: fixed_point_quantizer_3, layer type: FixedPointQuantizer, input shapes: [[None, 11, 11, 4]], output shape: [None, 11, 11, 4]\n",
"Layer name: activation_1, layer type: Activation, input shapes: [[None, 11, 11, 4]], output shape: [None, 11, 11, 4]\n",
"Layer name: fixed_point_quantizer_4, layer type: FixedPointQuantizer, input shapes: [[None, 11, 11, 4]], output shape: [None, 11, 11, 4]\n",
"Layer name: max_pooling2d_1, layer type: MaxPooling2D, input shapes: [[None, 11, 11, 4]], output shape: [None, 5, 5, 4]\n",
"Layer name: flatten, layer type: Reshape, input shapes: [[None, 5, 5, 4]], output shape: [None, 100]\n",
"Layer name: q_dense, layer type: Dense, input shapes: [[None, 100]], output shape: [None, 32]\n",
"Layer name: fixed_point_quantizer_5, layer type: FixedPointQuantizer, input shapes: [[None, 32]], output shape: [None, 32]\n",
"Layer name: activation_2, layer type: Activation, input shapes: [[None, 32]], output shape: [None, 32]\n",
"Layer name: fixed_point_quantizer_6, layer type: FixedPointQuantizer, input shapes: [[None, 32]], output shape: [None, 32]\n",
"Layer name: q_dense_1, layer type: Dense, input shapes: [[None, 32]], output shape: [None, 10]\n",
"Layer name: fixed_point_quantizer_7, layer type: FixedPointQuantizer, input shapes: [[None, 10]], output shape: [None, 10]\n",
"Creating HLS model\n",
"WARNING: Layer q_conv2d requires \"dataflow\" pipeline style. Switching to \"dataflow\" pipeline style.\n"
]
}
],
"source": [
"hls_conf = {'model': {'Precision': 'fixed<1,0>', 'ReuseFactor': 1}}\n",
"hls_model = convert_from_keras_model(proxy, output_dir='/tmp/qkeras_mnist', io_type='io_stream', hls_config=hls_conf)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Writing HLS project\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/calad/mambaforge/envs/HGQ/lib/python3.11/site-packages/keras/src/engine/training.py:3000: UserWarning: You are saving your model as an HDF5 file via `model.save()`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')`.\n",
" saving_api.save_model(\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done\n"
]
}
],
"source": [
"hls_model.compile()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"r_hls = hls_model.predict(x_test)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"assert np.all(r_qkeras == r_hls.reshape(r_qkeras.shape))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "HGQ",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit 8e8798c

Please sign in to comment.