feat(hybridz): add affine and structural operators#90
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #90 +/- ##
==========================================
- Coverage 73.62% 73.48% -0.15%
==========================================
Files 92 92
Lines 18993 19585 +592
==========================================
+ Hits 13984 14392 +408
- Misses 5009 5193 +184
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
1d01c55 to
fa20113
Compare
| self._input_ids: Optional[torch.Tensor] = None | ||
| self._input_box: Optional[tuple] = None | ||
|
|
||
| def _input_box_matches(self, bounds: Bounds) -> bool: |
There was a problem hiding this comment.
I believe our bounds have been already settled in the model and spec synthesis phase, why we still need this flattening?
There was a problem hiding this comment.
Agreed, this was not recomputing bounds, only a guard for reusing input generator ids so correlations such as x - x can remain exact. But comparing bounds is not clean when ACT already has stable variable ids via Layer.in_vars/out_vars. I switched to seeding col_ids directly from those ids (INPUT -> out_vars, input-reading root -> in_vars), with a disjoint id block per batch item and a negative id namespace for fresh auxiliary generators. _input_box_matches is removed.
| ) | ||
|
|
||
|
|
||
| def _spatial_op_generators(G, op_fn, B, C, H, W, n_out_per_sample): |
There was a problem hiding this comment.
can you leverage the math expression here with what is spatial operation?
There was a problem hiding this comment.
“spatial operation” means a linear BCHW operator S, e.g. AvgPool2D or ConvTranspose2D without bias. For y = S(x)+b and x = c+G·ξ, HybridZ propagates c' = S(c)+b and G'[:,j] = vec(S(unvec(G[:,j]))) (the bias affects only the center). The helper applies S to each generator column by reshaping columns into BCHW tensors, so it avoids materializing the large matrix for S. I added a short docstring with this math.
| return torch.ones(int(hz.Ac.shape[0]), dtype=torch.bool, device=hz.Ac.device) | ||
|
|
||
|
|
||
| def _shared_constraint_prefix( |
There was a problem hiding this comment.
This is hard to understand the usability. Can you leave some comment within/ above your code?
There was a problem hiding this comment.
These helpers implement shared-generator algebra for Add/Sub, and the same generator-alignment idea is used for Concat: matching col_ids denote the same latent factor, so correlated terms can combine exactly instead of being duplicated as independent Minkowski terms (x - x = 0, not [-2r, 2r]). If ids are unavailable, we back to the sound Minkowski construction. I added short docstrings to hz_from_bounds, _align, _scatter_cols, _shared_constraint_prefix, and hz_sgm_add.
fa20113 to
d964759
Compare
| bcol_ids: Optional[torch.Tensor] = None | ||
|
|
||
|
|
||
| _NEXT_COL_ID = [-1] |
There was a problem hiding this comment.
This is the counter for new HZ generator ids.
These ids are used when merge or align HZ generator cols, e.g. in Add/Sub/Concat. If two cols have the same id, they represent the same latent factor and should be combined; if the ids differ, they are independent factors.
Now the original input generators use ACT's variable ids from Layer.in_vars/out_vars, which are non-negative. Later, when HZ creates extra generators, e.g. for ReLU/Sigmoid/slack encodings, those new generators also need ids. If we start fresh ids from 0, they may collide with ACT input variable ids and be incorrectly merged.
So fresh internal ids are allocated on negative: -1, -2, -3, ...
They are only symbolic labels for matching generator cols, not tensor indices or ACT variable ids.
PR2 Summary by file: