Skip to content
This repository was archived by the owner on Oct 16, 2025. It is now read-only.

Conversation

@prhbrt
Copy link

@prhbrt prhbrt commented Jan 11, 2024

Since the UNET architecture only uses layers that can scale with the image dimensions, the fixed dimensions seem artificial. I've added a zero-padding layer that increases the dimensions to the nearest multiple of 32. The padding is cut off in the end.

Moreover, I've removed the lambda-layer, as it creates marshaling warning, and used ZeroPadding2D's asymmetric padding feature. This removes a warning upon load_model.

I converted the eynollah-models to this architecture, and they should load without warnings now and use the tensorflow.keras API and can be found here.

This might allow you to skip the patching as used in Eynollah and speed up the whole process. Please let me know what you think.

Notes and sanity checks:

  • the enhancement model uses the light version without the last batchnorm and with a sigmoid rather than softmax.
  • the column classifier is a different architecture, I just copied the original model, and hence it's not dimension invariant.
  • Two models weren't in savemodel-format on your website, e.g. the light versions eynollah-main-regions_20220314 and eynollah-textline_light_20210425, so I couldn't convert them.

import tensorflow as tf

resnet50_Weights_path='./pretrained_model/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5'
IMAGE_ORDERING ='channels_last'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be passed as a variable, and ideally use tensorflow's default.

TODO: default to image_data_format from keras' config (~/.keras/keras.json)


resnet50_Weights_path='./pretrained_model/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5'
IMAGE_ORDERING ='channels_last'
MERGE_AXIS=-1
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should follow from data_format, e.g. should always be the channel-axis.

return x

def identity_block(input_tensor, kernel_size, filters, stage, block):
def identity_block(input_tensor, kernel_size, filters, stage, block, data_format='channels_last'):
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added data_format as a parameter everywhere, rather than the global constant IMAGE_FORMAT. Also used the same name as tf does for transparency.


x = ZeroPadding2D((3, 3), data_format=IMAGE_ORDERING)(img_input)
x = Conv2D(64, (7, 7), data_format=IMAGE_ORDERING, strides=(2, 2),kernel_regularizer=l2(weight_decay), name='conv1')(x)
class PadMultiple(Layer):
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pads to a multiple of 32 or whatever is specified in dims.

padded_to_multiple = PadMultiple((32,32))(img_input)

bn_axis = 3 if data_format == 'channels_last' else 1
merge_axis = 3 if data_format == 'channels_last' else 1
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is merge_axis ever something else than the channel dimension?

model=Model( img_input , x ).load_weights(resnet50_Weights_path)
Model(img_input, x).load_weights(resnet50_Weights_path)

if light_version:
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate code complicates code maintenance, so I merged the light version in here.

@cneud
Copy link
Member

cneud commented Jan 12, 2024

Hi @prhbrt, thanks a lot for looking into this and for contributing!

FYI, we are planning to update and refactor this repo and integrate the model training code with https://github.com/qurator-spk/eynollah for future maintenance, so this comes in very handy.

My colleagues @vahidrezanezhad and @michalbubula will be working on this - although due to various reasons, we likely won't be able to get our hands dirty much before March. But we will try our best to review and merge any contributions also beforehand.

Btw the two models that you were missing should be available from our HF:

@prhbrt
Copy link
Author

prhbrt commented Jan 12, 2024

@cneud Understood! Could you in the meantime provide a list of all model-architectures used for eynollah (specifically python code)? I couldn't find python-code for the column classifier in particular, so that one still has fixed dimensions.

Also note that this yolo-version might give slightly different outputs as your patching example, due to boundary conditions.

Thank you in advance!

@vahidrezanezhad
Copy link
Member

@cneud Understood! Could you in the meantime provide a list of all model-architectures used for eynollah (specifically python code)? I couldn't find python-code for the column classifier in particular, so that one still has fixed dimensions.

Also note that this yolo-version might give slightly different outputs as your patching example, due to boundary conditions.

Thank you in advance!

@prhbrt
Sure, I'll try to make classifier code public in the meantime.

@kba
Copy link
Contributor

kba commented Oct 16, 2025

I have tried to port this over to eynollah here: qurator-spk/eynollah#202

If I messed it up, this PR is still around but I am closing so we can archive the repository.

@kba kba closed this Oct 16, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants