Skip to content

Fix pooling layers when padding is applied from the left/top

Javier Duarte requested to merge github/fork/JanFSchulte/poolingFix into main

Created by: JanFSchulte

When padding is applied from the left (or top and left in the 2D case), the indices to the entries of the data array currently point to the wrong elements when the pools are filled because the shift in indices due to the padding is not taken into account. In Keras this only happens when the pool_size is set above 2 so that the padding in the case of same padding is not only applied to the right but also to the left side of the input.

This PR has a simple fix by correctly shifting the indices to take into account the offset. Is transparent in case there is no padding from the left/top required.

Additionally, when the zero padding is removed from the result in case of AveragePooling, this was not done correctly because the division of 2 integers always resulted in an integer result, so that the result was always rescaled with a factor of 1. This has been fixed by casting the numerator to data_T.

Type of change

For a new feature or function, please create an issue first to discuss it with us before submitting a pull request.

Note: Please delete options that are not relevant.

  • Bug fix (non-breaking change that fixes an issue)

Tests

Problem can be reproduced and fix verified with this small script:

import math
from pathlib import Path

import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import MaxPooling1D

import hls4ml

input_shape = (124, 5)
X_input = np.random.rand(100, *input_shape)

keras_model = tf.keras.models.Sequential()
keras_model.add(MaxPooling1D(pool_size = 3, padding="same", input_shape=input_shape))
keras_model.compile()

hls_cfg = hls4ml.utils.config_from_keras_model(keras_model)
output_dir = "test_keras"

hls_model = hls4ml.converters.convert_from_keras_model(
    keras_model, hls_config=hls_cfg, output_dir=output_dir, backend="Vivado"
)
hls_model.compile()

# Verify accuracy
keras_prediction = keras_model.predict(X_input)
hls_prediction = hls_model.predict(X_input).reshape(keras_prediction.shape)

np.testing.assert_allclose(hls_prediction, keras_prediction, rtol=0, atol=3e-2)

A test was added in test/pytest/test_pooling.h to verify the fixes.

Checklist

  • I have read the guidelines for contributing.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have made corresponding changes to the documentation.
  • My changes generate no new warnings.
  • I have installed and run pre-commit on the files I edited or added.
  • I have added tests that prove my fix is effective or that my feature works.

Merge request reports

Loading