Validates that an input array matches one or more expected shapes.
Dimensions may be integers or -1, where -1 acts as a wildcard.
| Parameters: |
-
array
(Union[ndarray, Tensor])
–
-
expected_shape
(Union[Tuple[int, ...], List[Tuple[int, ...]]])
–
A single expected shape or a list of acceptable shapes.
Use -1 to indicate a wildcard dimension.
|
| Raises: |
-
TypeError
–
If the input is not a NumPy array nor a PyTorch tensor.
-
ValueError
–
If the array shape does not match any of the expected shapes.
|
Examples:
>>> x = np.zeros((4, 8))
>>> check_shape(x, (4, 8)) # exact match
>>> check_shape(x, (-1, 8)) # wildcard batch dimension
>>> check_shape(x, [(-1, 4), (-1, 8)]) # multiple acceptable shapes
Source code in aidevelopementtoolkit/general_utils.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 | def check_shape(
array: Union[np.ndarray, torch.Tensor],
expected_shape: Union[Tuple[int, ...], List[Tuple[int, ...]]]
) -> None:
"""
Validates that an input array matches one or more expected shapes.
Dimensions may be integers or `-1`, where `-1` acts as a wildcard.
Parameters
----------
array : Union[np.ndarray, torch.Tensor]
Input array to validate.
expected_shape : Union[Tuple[int, ...], List[Tuple[int, ...]]]
A single expected shape or a list of acceptable shapes.
Use `-1` to indicate a wildcard dimension.
Raises
------
TypeError
If the input is not a NumPy array nor a PyTorch tensor.
ValueError
If the array shape does not match any of the expected shapes.
Examples
--------
>>> x = np.zeros((4, 8))
>>> check_shape(x, (4, 8)) # exact match
>>> check_shape(x, (-1, 8)) # wildcard batch dimension
>>> check_shape(x, [(-1, 4), (-1, 8)]) # multiple acceptable shapes
"""
# Type check
if not isinstance(array, (np.ndarray, torch.Tensor)):
logger.error(
f"Invalid type: expected `np.ndarray` or `torch.Tensor`, "
f"got `{type(array).__name__}`"
)
raise ValueError()
actual_shape = tuple(array.shape)
if isinstance(expected_shape, tuple):
expected_shapes = [expected_shape]
else:
expected_shapes = expected_shape
# Try all possible shapes
for shape in expected_shapes:
if len(shape) != len(actual_shape):
continue
match = True
for a, e in zip(actual_shape, shape):
if e != -1 and a != e:
match = False
break
# Valid shape found
if match:
return
# If no match found
if isinstance(expected_shape, tuple):
logger.error(
f"Invalid shape: expected `{expected_shape}`, "
f"got `{actual_shape}`"
)
raise ValueError()
else:
logger.error(
f"Invalid shape: expected one of `{expected_shapes}`, "
f"got `{actual_shape}`"
)
raise ValueError()
|