-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix scaling of RGBs for tensorflow/keras #183
Conversation
Hi all, Wishing you both a wonderful week! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thanks for taking a look @fel-thomas! 🙏🏼 You too have a great rest of the week :) |
Thanks a lot for handling this @candemircan! 🙏🏼 Much appreciated! |
@martinhebart could you make sure that this PR gets into a state where I can confidently merge it into |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm no expert with Keras, but looks good to me! The test does speak for itself too, good job 👍
Cleaned up a bit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I cleaned up a bit and have one minor comment. Overall this looks good. Great work!
] | ||
# Try each pattern | ||
for pattern, preprocess_value in patterns: | ||
if re.match(pattern, model_name): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why re.match(pattern, string)
and not re.search(pattern, string)
? re.match
searches for the pattern only at the beginning of a string, whereas re.search
searches through the entire string. I am seeing that you specify start and end positions using ^
and $
although you use re.match
. Why is that? I think we could just drop all ^
and $
and it would work equally well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, if you're confident that it'll be identical in behaviour then go ahead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't omitting $
cause unwanted matches (e.g. "MobileNet" would match "MobileNetV3" too)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@candemircan This was just feedback :) I am trying to understand whether there is a specific reason for re.match
in combination with the regular expressions you used :)
@andropar I guess it depends on re.match
vs re.search
. re.match
searches for the pattern only at the beginning of a string. Thus, ^
is baked into the function and $
is omitted. I don't think we ever need ^
(definitely not for re.match
) but $
is needed for one of the two (or maybe even for both the more I think about it? 🤔)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no specific reason on my side. it was the first thing I wrote that worked correctly, and I left it as is because I don't know regexp very well. If there is a better way to do this, go ahead and change it please :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, thanks for the clarification! I changed it from re.match
to re.search
because ^
is redundant with re.match
. It's baked into the function. I left the patterns as you specified them to be as explicit as possible ($
is indeed necessary; I just tested it). Thank you for helping with this! I will accept the PR now and merge it into main
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
coolio, thanks Lukas! all the best
fixed typo
changed `match` to `search`
Hi,
This pull request fixes the following:
Harmonizer (and Generic
tf
) ModelsThe default
tf
preprocessing now rescales the RGBs between 0, and 1. As you can see here, now we get identical results fromthingsvision
and when using the harmonized models directly.Note that this also applies the same scaling to any
tf
model that is manually turned into an extractor, and anytf
model that does not specify a preprocessing function.tf.keras
pretrained model fixesBefore these commits, always the same preprocessing was applied to the pretrained
tf.keras.applications
models. This yielded silent but catastrophic errors, as unfortunately, the pretrained models differ in their preprocessing in non-systematic ways. This is now fixed. Again, using models viathingsvision
and directly yielded the same results here.Getting the correct preprocessing function is a bit tricky, as it is done via different modules and functions and not through arguments (e.g.,
tf.keras.applications.efficientnet_v2.preprocess_input
). Additionally, the preprocessing module names differ from the model names in subtle ways. I tried to resolve this using regular expressions, and it seems to work for the current models. If there is no regexp match, currently we raise a warning saying no preprocessing function could be found and that the user should be careful, and we revert to default preprocessing described in the previous section. If new pretrained models get added, its name needs to be added to the function. This is not ideal, but I couldn't find a better, more generic way.Additionally, different keras models have different input sizes, and this needs to be accounted for. Now it should be sorted.
testing
I did all the testing in a separate repo here, where I'd also reproduced some of these issues. I know you have a
tests
folder here. I couldn't quite wrap my head around how to do some of the simple tests I did there. For example, I see that you have acreate_test_images
function that you call, but I don't see where these images actually get used in the tests. Instead, I think some manually created values are being passed through the models? Either way, it should be straightforward to add the tests I did into your test suite for someone who understands the structure.Sorry for closing and reopening an issue. Had to create a new branch and delete the old one.