Skip to content

Fix RandomZoom zero-scale validation and missing labels KeyError#22250

Merged
hertschuh merged 1 commit intokeras-team:masterfrom
rstar327:fix-random-zoom-validation
Mar 1, 2026
Merged

Fix RandomZoom zero-scale validation and missing labels KeyError#22250
hertschuh merged 1 commit intokeras-team:masterfrom
rstar327:fix-random-zoom-validation

Conversation

@rstar327
Copy link
Contributor

Summary

Fixes two bugs in RandomZoom:

  1. Zero-scale factor validation: _check_factor_range now rejects -1.0 (changed < to <=), which previously created a zero-scale transformation matrix (1.0 + (-1.0) = 0), leading to singular matrix errors or NaN outputs.

  2. Missing labels KeyError: clip_to_image_size in BoundingBox now treats the labels key as optional using .get(), so bounding box dicts with only boxes no longer crash with KeyError: 'labels'.

Fixes #22247

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @rstar327, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses two critical bugs related to image preprocessing layers. It refines the RandomZoom layer's behavior by enforcing stricter validation on zoom factors, thereby preventing mathematical instabilities. Concurrently, it enhances the robustness of bounding box operations by making the labels field optional during clipping, which improves compatibility with diverse data structures and prevents runtime errors.

Highlights

  • RandomZoom Zero-Scale Validation: The RandomZoom layer now correctly validates zoom factors, rejecting -1.0 to prevent zero-scale transformations that could lead to singular matrix errors or NaN outputs. The validation range for factors has been updated from [-1.0, 1.0] to (-1.0, 1.0].
  • BoundingBox Missing Labels KeyError: The clip_to_image_size method in BoundingBox has been updated to gracefully handle bounding box dictionaries that do not contain a labels key. It now uses .get() to access labels, treating them as optional and avoiding KeyError exceptions.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • keras/src/layers/preprocessing/image_preprocessing/bounding_boxes/bounding_box.py
    • Modified label extraction to safely handle cases where 'labels' key might be missing by using .get() with a default of None.
    • Ensured that area computation and label filtering based on area are only performed if labels are provided.
    • Added a conditional check to assign labels to the result dictionary only if labels are not None.
  • keras/src/layers/preprocessing/image_preprocessing/random_zoom.py
    • Adjusted the error message to indicate that the lower bound for zoom factors is now exclusive (-1.0).
    • Updated the _check_factor_range method to disallow a zoom factor of exactly -1.0, which previously led to zero-scale issues.
Activity
  • No human activity (comments, reviews, etc.) has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces two important bug fixes for RandomZoom and BoundingBox. The change to RandomZoom correctly prevents a zero-scale factor by adjusting the validation range, which avoids potential singular matrix errors. The modification in BoundingBox.clip_to_image_size makes the 'labels' key optional, preventing KeyError when it's not present in the input dictionary. The changes are well-implemented and address the issues described. I've added one suggestion to refactor some duplicated code for better maintainability.

@codecov-commenter
Copy link

codecov-commenter commented Feb 21, 2026

Codecov Report

❌ Patch coverage is 69.23077% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.97%. Comparing base (d1bbce6) to head (f13a2bc).
⚠️ Report is 113 commits behind head on master.

Files with missing lines Patch % Lines
...image_preprocessing/bounding_boxes/bounding_box.py 75.00% 0 Missing and 3 partials ⚠️
...s/preprocessing/image_preprocessing/random_zoom.py 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #22250      +/-   ##
==========================================
- Coverage   82.97%   82.97%   -0.01%     
==========================================
  Files         594      594              
  Lines       64595    64599       +4     
  Branches    10120    10123       +3     
==========================================
+ Hits        53598    53599       +1     
  Misses       8396     8396              
- Partials     2601     2604       +3     
Flag Coverage Δ
keras 82.79% <69.23%> (-0.01%) ⬇️
keras-jax 61.70% <69.23%> (-0.01%) ⬇️
keras-numpy 55.85% <69.23%> (-0.01%) ⬇️
keras-openvino 38.45% <0.00%> (-0.01%) ⬇️
keras-tensorflow 62.96% <69.23%> (-0.01%) ⬇️
keras-torch 61.79% <69.23%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

@amadhan882 amadhan882 left a comment

Choose a reason for hiding this comment

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

Technical Review by Issue Author

Hi @rstar327, thanks for the quick PR to address the issues I reported in #22247!

I've reviewed your changes in random_zoom.py and bounding_box.py. While the core fixes are solid, I noticed some areas in bounding_box.py that could be optimized to prevent redundant operations and code duplication.

Technical Observations:

  1. Redundant Logic in bounding_box.py:
    In the updated clip_to_image_size logic, the area calculation and label filtering (mapping invalid boxes to -1) are repeated within both the xyxy and rel_xyxy blocks.
if labels is not None:
    areas = self._compute_area(boxes)
    areas = ops.numpy.squeeze(areas, axis=-1)
    labels = ops.numpy.where(areas > 0, labels, -1)

Suggestion: Since this filtering logic is independent of the coordinate format (once clipped), it would be much cleaner to move it to a single point at the end of the method, right before creating the result dictionary. This avoids running the same ops twice in different branches.

  1. Factor Range Validation:
    The change in random_zoom.py to input_number <= -1.0 correctly implements the "Fail-Fast" principle for the zero-scale scenario. This is a robust fix for the second part of the reported bug.

  2. KeyError Resolution:
    Using bounding_boxes.get("labels", None) and conditionally adding it back to the result dictionary effectively resolves the KeyError when labels are missing.

Suggested Action:

I recommend refactoring bounding_box.py to consolidate the label-filtering logic to avoid redundancy. Other than that, the fix correctly addresses the stability issues.

Looking forward to seeing this merged!

Copy link
Collaborator

@hertschuh hertschuh left a comment

Choose a reason for hiding this comment

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

Thanks for the fix!

@google-ml-butler google-ml-butler bot added kokoro:force-run ready to pull Ready to be merged into the codebase labels Mar 1, 2026
@hertschuh hertschuh merged commit 975e794 into keras-team:master Mar 1, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready to pull Ready to be merged into the codebase size:S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] RandomZoom crashes with KeyError: 'labels' and lacks validation for zero-scale factor (-1.0)

6 participants