we identify the neuron with the maximum $\operatorname*{popcount}$ value (i.e. the $\operatorname{argmax}$ of the last layer neurons), which gives the output of the neural network. The whole inference process of a conventional BNN is described with vectorized notations in Algorithm \[alg:algorithm1\].

The performance of BNNs is quite impressive. [ A fully-connected BNN with two hidden layers of 1024 neurons, and the use of dropout during training [@srivastava2014dropout] obtains a $1.8\%$ error rate on the test dataset of the canonical MNIST handwritten digits task [@lecun1998gradient], with 300 epochs. In comparison, a conventional neural network with no binarization and $\tanh$ activation function, and the same architecture and number of neurons, obtains a $1.5\%$ test error rate after 300 epochs.]{} Similarly, on more complex datasets such as CIFAR-10 or ImageNet, near-equivalent performed is obtained by BNNs and conventional neural networks [@courbariaux2016binarized; @rastegari2016xnor; @lin2017towards]. The low memory requirements of BNNs (one bit by synapse), as well as the fact that they do not require any multiplication, makes them extremely adapted for inference hardware [@nurvitadhi2016accelerating; @sun2018xnor; @tang2017binary; @yu2018neuro].

The training process of BNNs is reminded in Appendix \[sec:appendix\_training\]. Unlike inference, the training process requires real valued weights and real arithmetic: [training BNNs is not easier 