fastmachinelearning / hls4ml

Machine learning on FPGAs using HLS
https://fastmachinelearning.org/hls4ml
Apache License 2.0
1.19k stars 390 forks source link

Fail to convert BatchNormalization with no gamma or beta #720

Closed jicampos closed 1 year ago

jicampos commented 1 year ago

Quick summary

Hls4ml fails to convert a model when initializing batchnormalization layers with no gamma and/or beta. This problem exists for models implemented in both PyTorch and Keras.

Details

Steps to Reproduce

  1. Clone the hls4ml repository
  2. Checkout the master branch, with commit hash: 8523b2b9401b675c53d6b64abe66d84dbf5a079b
  3. Run conversion on the model with
    
    from __future__ import print_function
    from torch import nn
    import hls4ml

hn = 2000 model = nn.Sequential(nn.Linear(hn, int(hn/8)), nn.ReLU(inplace=True), nn.BatchNorm1d(int(hn/8),affine=False), nn.Linear(int(hn/8), 2), nn.ReLU(inplace=True), )

hls_config = hls4ml.utils.config_from_pytorch_model(model) hls_model = hls4ml.converters.convert_from_pytorch_model( model, input_shape=[1, 2000], hls_config=hls_config, output_dir='hls4ml_prj_tmp', part="xczu49dr-ffvf1760-2-e", )

hls_model.compile()


### Actual behavior
Running ```hls4ml.converters.convert_from_pytorch_model``` produces the below error

Traceback (most recent call last): File "/data/jcampos/hls4ml/torch_example.py", line 92, in hls_model = hls4ml.converters.convert_from_pytorch_model( File "/data/jcampos/hls4ml/hls4ml/converters/init.py", line 321, in convert_from_pytorch_model return pytorch_to_hls(config) File "/data/jcampos/hls4ml/hls4ml/converters/pytorch_to_hls.py", line 208, in pytorch_to_hls hls_model = ModelGraph(config, reader, layer_list) File "/data/jcampos/hls4ml/hls4ml/model/graph.py", line 329, in init self._make_graph(layer_list) File "/data/jcampos/hls4ml/hls4ml/model/graph.py", line 347, in _make_graph self.graph[name] = self.make_node(kind, name, layer, inputs, outputs) File "/data/jcampos/hls4ml/hls4ml/model/graph.py", line 433, in make_node node = layer_cls(self, name, attributes, inputs, outputs) File "/data/jcampos/hls4ml/hls4ml/model/layers.py", line 103, in init self.initialize() File "/data/jcampos/hls4ml/hls4ml/model/layers.py", line 803, in initialize gamma = self.model.get_weights_data(self.name, 'gamma') File "/data/jcampos/hls4ml/hls4ml/model/graph.py", line 558, in get_weights_data return self.reader.get_weights_data(layer_name, var_name) File "/data/jcampos/hls4ml/hls4ml/converters/pytorch_to_hls.py", line 60, in get_weights_data data = self.state_dict[layer_name + '.' + var_name].numpy().transpose() #Look at transpose when systhesis produce lousy results. Might need to remove it. KeyError: 'bn.weight'



### Possible fix
If a BatchNormalization layer is instantiated with ```affine=False``` in PyTorch, then gamma and beta are set to default values and are ***not in the state dictionary***. 
This same issue occurs in Keras when ```scale=False``` or ```center=False```. 
I've made a quick fix in a [fork here](https://github.com/jicampos/hls4ml/tree/batchnorm) by changing the batch normalization handlers for Keras and PyTorch.  
jmduarte commented 1 year ago

Thanks for reporting! Can you open a PR from that branch?