This notebook covers how to use low quantized neural networks on Pynq. It shows an example of CIFAR-10 image recognition with different precision neural network inspired at VGG-16, featuring 6 convolutional layers, 3 max pool layers and 3 fully connected layers. There are 3 different precision available:
All of them can be performed in pure software or hardware accelerated environment.
In [1]:
import bnn
In [2]:
from PIL import Image
import numpy as np
img = Image.open('/home/xilinx/jupyter_notebooks/bnn/pictures/deer.jpg')
img
Out[2]:
The inference can be performed with different precision for weights and activation. Creating a specific Classifier will automatically download the correct bitstream onto PL and load the weights and thresholds trained on the specific dataset. Passing a runtime attribute will allow to choose between hardware accelerated or pure software inference.
Instantiate the classifier:
In [3]:
hw_classifier = bnn.CnvClassifier(bnn.NETWORK_CNVW1A1,'cifar10',bnn.RUNTIME_HW)
Inference can be performed by using classify_image
for single and classify_images
for multiple images. The image(s) will automatically be processed to match Cifar-10 format that can be taken by CNV network. For Cifar-10 preformatted pictures classify_cifar
and classify_cifars
are available (see notebook CNV-QNN_Cifar10_TestSet).
In [4]:
inferred_class = hw_classifier.classify_image(img)
hw_timeW1A1 = hw_classifier.usecPerImage
print("Class number: {0}".format(inferred_class))
print("Class name: {0}".format(hw_classifier.class_name(inferred_class)))
It is also possible to get the rankings of each class using classify_image_details
for single and classify_images_details
for multiple images:
In [5]:
rankingsW1A1 = hw_classifier.classify_image_details(img)
print("\n{: >10}{: >13}".format("[CLASS]","[RANKING]"))
for i in range(len(rankingsW1A1)):
print("{: >10}{: >10}".format(hw_classifier.classes[i],rankingsW1A1[i]))
As expected deer is the highest ranked class.
In [6]:
hw_classifier = bnn.CnvClassifier(bnn.NETWORK_CNVW1A2,'cifar10',bnn.RUNTIME_HW)
In [7]:
inferred_class = hw_classifier.classify_image(img)
hw_timeW1A2 = hw_classifier.usecPerImage
print("Class number: {0}".format(inferred_class))
print("Class name: {0}".format(hw_classifier.class_name(inferred_class)))
and now with rankings:
In [8]:
rankingsW1A2 = hw_classifier.classify_image_details(img)
print("\n{: >10}{: >13}".format("[CLASS]","[RANKING]"))
for i in range(len(rankingsW1A2)):
print("{: >10}{: >10}".format(hw_classifier.classes[i],rankingsW1A2[i]))
In [9]:
hw_classifier = bnn.CnvClassifier(bnn.NETWORK_CNVW2A2,'cifar10',bnn.RUNTIME_HW)
In [10]:
inferred_class = hw_classifier.classify_image(img)
hw_timeW2A2 = hw_classifier.usecPerImage
print("Class number: {0}".format(inferred_class))
print("Class name: {0}".format(hw_classifier.class_name(inferred_class)))
In [11]:
rankingsW2A2 = hw_classifier.classify_image_details(img)
print("\n{: >10}{: >13}".format("[CLASS]","[RANKING]"))
for i in range(len(rankingsW2A2)):
print("{: >10}{: >10}".format(hw_classifier.classes[i],rankingsW2A2[i]))
In [12]:
sw_W1A1 = bnn.CnvClassifier(bnn.NETWORK_CNVW1A1,'cifar10',bnn.RUNTIME_SW)
sw_W1A2 = bnn.CnvClassifier(bnn.NETWORK_CNVW1A2,'cifar10',bnn.RUNTIME_SW)
sw_W2A2 = bnn.CnvClassifier(bnn.NETWORK_CNVW2A2,'cifar10',bnn.RUNTIME_SW)
In [13]:
print("-- Software inference CNVW1A1 --")
out=sw_W1A1.classify_image(img)
sw_timeW1A1=sw_W1A1.usecPerImage
print("Class number: {0}".format(out))
print("\n-- Software inference CNVW1A2 --")
out=sw_W1A2.classify_image(img)
sw_timeW1A2=sw_W1A2.usecPerImage
print("Class number: {0}".format(out))
print("\n-- Software inference CNVW2A2 --")
out=sw_W2A2.classify_image(img)
sw_timeW2A2=sw_W2A2.usecPerImage
print("Class number: {0}".format(out))
In [14]:
%matplotlib inline
import matplotlib.pyplot as plt
hw_bars = [hw_timeW1A1, hw_timeW1A2, hw_timeW2A2]
sw_bars = [sw_timeW1A1, sw_timeW1A2, sw_timeW2A2]
x_pos = np.arange(3)
fig, ax = plt.subplots()
ax.bar(x_pos - 0.25, hw_bars, 0.25)
ax.bar(x_pos + 0.25, sw_bars, 0.25)
ax.set_xticklabels(["W1A1","W1A2","W2A2"], rotation='vertical')
ax.set_xticks(x_pos)
plt.legend(["hardware","software"])
plt.semilogy()
plt.show()
In [15]:
%matplotlib inline
import matplotlib.pyplot as plt
x_pos = np.arange(len(rankingsW1A1))
fig, ax = plt.subplots()
ax.bar(x_pos, (rankingsW1A1/200), 0.7)
ax.set_xticklabels(hw_classifier.classes, rotation='vertical')
ax.set_xticks(x_pos)
ax.set
plt.show()
In [16]:
x_pos = np.arange(len(rankingsW1A2))
fig, ax = plt.subplots()
ax.bar(x_pos, rankingsW1A2, 0.7)
ax.set_xticklabels(hw_classifier.classes, rotation='vertical')
ax.set_xticks(x_pos)
ax.set
plt.show()
In [17]:
x_pos = np.arange(len(rankingsW2A2))
fig, ax = plt.subplots()
ax.bar(x_pos, rankingsW2A2, 0.7)
ax.set_xticklabels(hw_classifier.classes, rotation='vertical')
ax.set_xticks(x_pos)
ax.set
plt.show()
In [18]:
from pynq import Xlnk
xlnk = Xlnk()
xlnk.xlnk_reset()