Apply ToTensor Transform
Problem Statement
Apply the ToTensor transform to convert a NumPy array (simulating an image) into a PyTorch tensor.
Background
ToTensor from torchvision.transforms converts image data (PIL Image or NumPy array) into a normalized FloatTensor. It handles both the type conversion and value scaling automatically.
Your Task
Write a function apply_to_tensor(numpy_array) that applies the ToTensor transform and returns a dictionary describing the resulting tensor's shape, dtype, and value range.
Output Format
Return a dictionary with keys: "shape" (list), "dtype" (string), "min_val" (float, 2 decimals), "max_val" (float, 2 decimals).
Example:
numpy array of shape (2, 2, 3) with values 0-255
{"shape": [3, 2, 2], "dtype": "torch.float32", "min_val": 0.0, "max_val": 1.0}ToTensor converts (H,W,C) to (C,H,W) and scales values to [0,1]
Constraints:
- Use torchvision.transforms.ToTensor
- Input will be a NumPy array with shape (H, W, C) and dtype uint8
- Values are in range [0, 255]
- Round min_val and max_val to 2 decimal places
1. Background Knowledge
PyTorch Tensors are multi-dimensional arrays central to deep learning, supporting GPU acceleration and automatic differentiation. Images are typically represented as NumPy arrays with shape (H, W, C) (height Γ width Γ channels) and uint8 dtype [0, 255] range.
ToTensor() from torchvision.transforms performs two critical operations:
- Type conversion: uint8 β torch.float32
- Normalization: Pixel values β [0, 255] β [0.0, 1.0] via division by 255
- Dimension permutation: (H, W, C) β (C, H, W) (PyTorch convention)
Mathematical transformation:
tensor = numpy_array.astype(float) / 255.0
tensor = tensor.permute(2, 0, 1) # CHW format
This normalization is essential because neural networks converge faster with inputs in [0, 1] or standardized ranges.
Prerequisites:
import torch
import torchvision.transforms as transforms
import numpy as np
2. Algorithm Approach
The solution uses a single transform pipeline:
- ToTensor() handles conversion + normalization + permutation automatically
- Tensor properties extraction using PyTorch tensor methods:
- tensor.shape β list conversion
- tensor.dtype β string representation
- tensor.min().item(), tensor.max().item() β scalar extraction
- Dictionary construction with rounded min/max values
Core insight: ToTensor() is a composable transform designed specifically for this exact use caseβno manual math required.
3. Step-by-Step Strategy
def apply_to_tensor(numpy_array):
# Step 1: Apply ToTensor transform
transform = transforms.ToTensor()
tensor = transform(numpy_array)
# Step 2: Extract required properties
shape = list(tensor.shape) # Convert tuple to list
dtype = str(tensor.dtype) # "torch.float32"
min_val = round(float(tensor.min()), 2) # Round to 2 decimals
max_val = round(float(tensor.max()), 2) # Round to 2 decimals
# Step 3: Return dictionary
return {
"shape": shape,
"dtype": dtype,
"min_val": min_val,
"max_val": max_val
}
Verification with sample:
- Input: (2, 2, 3) uint8 array [0-255]
- Output: (3, 2, 2) float32 tensor [0.0-1.0]
- β Matches expected {"shape": [3, 2, 2], "dtype": "torch.float32", "min_val": 0.0, "max_val": 1.0}
4. Common Pitfalls
| Mistake | Why It Fails | Fix |
|---|---|---|
| Manual division by 255 | Forgets channel permutation (HWCβCHW) | Use ToTensor() |
| tensor.shape as tuple | Output expects list | list(tensor.shape) |
| tensor.dtype as object | Output expects string | str(tensor.dtype) |
| tensor.min() without .item() | Returns tensor, not float | tensor.min().item() |
| No rounding | min_val may be 0.00392157 | round(..., 2) |
| Wrong import | torch.ToTensor doesn't exist | torchvision.transforms.ToTensor |
Shape transformation visualization:
Input: np.array(shape=(H=2, W=2, C=3)) # HWC
[[[...], [...]], # H
[[...], [...]]] # H
Output: tensor(shape=(C=3, H=2, W=2)) # CHW
[ # C
[[..,..], # H
[..,..]], # H
...
]
5. Time & Space Complexity
Time Complexity: O(HΓWΓC)
- Single pass through all pixels for conversion + normalization
- Min/max computation: O(HWC) linear scan
- Shape/dtype extraction: O(1)
Space Complexity: O(HΓWΓC)
- Input NumPy: O(HWC) bytes (uint8)
- Output tensor: O(4HWC) bytes (float32 = 4Γ larger)
- Net increase: O(3HWC) due to type promotion
- Temporary transform objects: O(1)
For typical images (e.g., 224Γ224Γ3):
- Time: ~150K operations (negligible)
- Space: ~0.6MB (float32 tensor dominates)
This transform is memory-bound for large images/batches, but PyTorch optimizes memory layout for GPU transfer.