-
Notifications
You must be signed in to change notification settings - Fork 53
Add comprehensive image normalization documentation for wandb.Image DOCS-1016 #1559
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
Closed
Closed
Changes from 24 commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
fe9cfe7
Add comprehensive image normalization documentation
mdlinville 0f05c59
Fix broken relref links in Japanese and Korean media guides
mdlinville f988610
docs: address review feedback - use sentence case, avoid 'we', improv…
mdlinville 5e1e10c
docs: address additional review feedback - use sentence case for head…
mdlinville 437e947
Artifacts: When to use save() vs .log() (#1557)
ngrayluna a9f6290
Updated new view for lineage and dataset mismatch in keras tutorials …
knisar 6093944
test: temporarily use mock preview URL for testing path matching
mdlinville fc5abb0
revert: remove mock URL test changes
mdlinville 48196ce
docs(weave): fix broken relref links in Japanese and Korean media guides
mdlinville 585403f
docs: address review feedback - move detailed normalization content t…
mdlinville fdebb34
feat: add image normalization demo notebook for testing and user exam…
mdlinville 71f1092
refactor: move detailed normalization docs to dedicated guide and sim…
mdlinville eb9f9a5
docs: add visual contrast effects and guidance on when to use differe…
mdlinville bf500a7
docs: add improved image normalization demo notebook with detailed ex…
mdlinville 6804a5c
docs: update notebook with detailed explanations for all examples
mdlinville 6c5b58b
docs: use --quiet --upgrade flags for pip install to reduce output noise
mdlinville 3bb8f89
docs: add reassuring note about import cell success
mdlinville 6b42746
docs: add explanation about expected deprecation warning in Example 2
mdlinville 59d90c7
docs: add reassuring note about import cell success
mdlinville c0bab04
docs: restore --quiet --upgrade flags to pip install command
mdlinville c1f8928
docs: remove --upgrade flag from pip install to avoid dependency conf…
mdlinville 6b14efa
docs: remove notebook (moved to examples repo PR #609)
mdlinville 394761f
fix: correct GITHUB_TOKEN parameter name in calibreapp image actions …
mdlinville b0eed78
Merge branch 'main' into DOCS-1016
mdlinville 7508402
docs: address reviewer feedback - combine sections, fix terminology, …
mdlinville f6c3a69
docs: remove # characters from headings in reference documentation
mdlinville f5cfa3f
Apply suggestions from code review
mdlinville 7b3b451
docs: remove remaining # characters from reference documentation head…
mdlinville dbd68d4
docs: remove # characters from English reference documentation headings
mdlinville 4a45f33
docs: improve normalization table with matrix format for better clarity
mdlinville 0bca154
docs: convert numbered normalization algorithm steps to bullet points…
mdlinville 90d2d1d
docs: remove accidentally committed test notebook
mdlinville File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
139 changes: 139 additions & 0 deletions
139
content/en/guides/models/track/log/image-normalization.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,139 @@ | ||
| --- | ||
| title: "Image Normalization Guide" | ||
| description: "Learn how wandb.Image handles normalization for different input types and how to control this behavior" | ||
| --- | ||
|
|
||
| # Image Normalization Guide | ||
|
|
||
| When you pass PyTorch tensors or NumPy arrays to `wandb.Image`, the pixel values are automatically normalized to the range [0, 255] unless you set `normalize=False`. This guide explains how normalization works and how to control it. | ||
|
mdlinville marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## When normalization is applied | ||
|
|
||
| Normalization is applied to: | ||
| - **PyTorch tensors** (format: `(channel, height, width)`) | ||
| - **NumPy arrays** (format: `(height, width, channel)`) | ||
|
|
||
| Normalization is **NOT** applied to: | ||
| - **PIL Images** (passed as-is) | ||
| - **File paths** (loaded as-is) | ||
|
mdlinville marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## Normalization algorithm | ||
|
|
||
| The normalization algorithm automatically detects the input range and applies the appropriate transformation: | ||
|
|
||
| 1. **If data is in range [0, 1]**: Values are multiplied by 255 and converted to uint8 | ||
| ```python | ||
| normalized_data = (data * 255).astype(np.uint8) | ||
| ``` | ||
|
|
||
| 2. **If data is in range [-1, 1]**: Values are rescaled to [0, 255] using: | ||
| ```python | ||
| normalized_data = (255 * 0.5 * (data + 1)).astype(np.uint8) | ||
| ``` | ||
|
|
||
| 3. **For any other range**: Values are clipped to [0, 255] and converted to uint8 | ||
| ```python | ||
| normalized_data = data.clip(0, 255).astype(np.uint8) | ||
| ``` | ||
|
mdlinville marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## Examples of normalization effects | ||
|
|
||
| ### Example 1: [0, 1] range data | ||
|
|
||
| ```python | ||
| import torch | ||
| import wandb | ||
|
|
||
| # Create tensor with values in [0, 1] range | ||
| tensor_0_1 = torch.rand(3, 64, 64) # Random values between 0 and 1 | ||
|
|
||
| # This will multiply all values by 255 | ||
| image = wandb.Image(tensor_0_1, caption="Normalized from [0,1] range") | ||
| ``` | ||
|
|
||
| ### Example 2: [-1, 1] range data | ||
|
|
||
| ```python | ||
| import torch | ||
| import wandb | ||
|
|
||
| # Create tensor with values in [-1, 1] range | ||
| tensor_neg1_1 = torch.rand(3, 64, 64) * 2 - 1 # Random values between -1 and 1 | ||
|
|
||
| # This will rescale: -1 → 0, 0 → 127.5, 1 → 255 | ||
| image = wandb.Image(tensor_neg1_1, caption="Normalized from [-1,1] range") | ||
| ``` | ||
|
|
||
| **Note on visual contrast**: The [-1, 1] normalization creates higher visual contrast compared to [0, 1] normalization. This is because: | ||
| - Negative values (like -0.8) become very dark (around 25) | ||
| - Positive values (like 0.8) become very bright (around 230) | ||
| - Values near 0 become mid-gray (127.5) | ||
|
|
||
| This "stretches" the visual range, making differences between pixel values more pronounced. This is particularly useful for highlighting subtle patterns in machine learning data, but if you want less contrast, consider preprocessing your data to a [0, 1] range before logging. | ||
|
|
||
| ### Example 3: Avoiding normalization with PIL Images | ||
|
mdlinville marked this conversation as resolved.
Outdated
|
||
|
|
||
|
mdlinville marked this conversation as resolved.
|
||
| ```python | ||
| import torch | ||
| from PIL import Image as PILImage | ||
| import wandb | ||
|
|
||
| # Create tensor with values in [0, 1] range | ||
| tensor_0_1 = torch.rand(3, 64, 64) | ||
|
|
||
| # Convert to PIL Image to avoid normalization | ||
| pil_image = PILImage.fromarray((tensor_0_1.permute(1, 2, 0).numpy() * 255).astype('uint8')) | ||
| image = wandb.Image(pil_image, caption="No normalization applied") | ||
| ``` | ||
|
|
||
| ### Example 4: Using normalize=False | ||
|
|
||
|
mdlinville marked this conversation as resolved.
|
||
| ```python | ||
| import torch | ||
| import wandb | ||
|
|
||
| # Create tensor with values in [0, 1] range | ||
| tensor_0_1 = torch.rand(3, 64, 64) | ||
|
|
||
| # Disable normalization - values will be clipped to [0, 255] | ||
| image = wandb.Image(tensor_0_1, normalize=False, caption="Normalization disabled") | ||
| ``` | ||
|
|
||
| ## When to use different approaches | ||
|
|
||
| ### Use PIL conversion when: | ||
| - You want complete control over pixel values | ||
| - You need custom preprocessing (filters, brightness adjustments, etc.) | ||
| - You want to use PIL's image processing capabilities | ||
| - You're debugging and want to see exact values being logged | ||
|
|
||
| ### Use normalize=False when: | ||
| - You want to see raw tensor values as they are | ||
| - Your data is already in the correct range (like [0, 255] integers) | ||
| - You're debugging normalization issues | ||
| - Quick testing without additional processing steps | ||
|
|
||
| ### Use automatic normalization when: | ||
| - You want consistent behavior across different input types | ||
| - Your data is in standard ranges ([0, 1] or [-1, 1]) | ||
| - You want the system to handle the conversion automatically | ||
|
|
||
| ## Best practices | ||
|
mdlinville marked this conversation as resolved.
Outdated
|
||
|
|
||
| 1. **For consistent results**: Pre-process your data to the expected [0, 255] range before logging | ||
| 2. **To avoid normalization**: Convert tensors to PIL Images using `PILImage.fromarray()` | ||
| 3. **For debugging**: Use `normalize=False` to see the raw values (they will be clipped to [0, 255]) | ||
| 4. **For precise control**: Use PIL Images when you need exact pixel values | ||
| 5. **For highlighting subtle patterns**: Use [-1, 1] normalization to increase visual contrast | ||
| 6. **For natural-looking images**: Use [0, 1] normalization or preprocess to [0, 255] range | ||
| 7. **For custom processing**: Use PIL conversion when you need to apply filters or adjustments | ||
|
|
||
| ## Common issues | ||
|
|
||
| - **Unexpected brightness**: If your tensor values are in [0, 1] range, they will be multiplied by 255, making the image much brighter | ||
| - **Data loss**: Values outside the [0, 255] range will be clipped, potentially losing information | ||
| - **Inconsistent behavior**: Different input types (tensor vs PIL vs file path) may produce different results | ||
|
|
||
| ## Testing your code | ||
|
|
||
| You can test the normalization behavior using our [Image Normalization Demo Notebook](https://github.com/wandb/wandb/blob/main/wandb_image_normalization_demo.ipynb) which demonstrates all the examples above with visual output. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,7 +49,7 @@ for batch_idx, (data, target) in enumerate(train_loader): | |
|
|
||
| ## 画像とメディアのログ | ||
|
|
||
| 画像データを持つ PyTorch `Tensors` を [`wandb.Image`]({{< relref path="/ref/python/data-types/image.md" lang="ja" >}}) に渡すことができ、[`torchvision`](https://pytorch.org/vision/stable/index.html) のユーティリティが自動的に画像に変換します。 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggest undoing changes to JA and KO docs. They will get overwritten. Also, keeps the PR cleaner for review. |
||
| 画像データを持つ PyTorch `Tensors` を [`wandb.Image`]({{< relref "/ref/python/data-types/image.md" >}}) に渡すことができ、[`torchvision`](https://pytorch.org/vision/stable/index.html) のユーティリティが自動的に画像に変換します。 | ||
|
|
||
| ```python | ||
| images_t = ... # PyTorch Tensors として画像を生成またはロードする | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.