Skip to content

Shonali lux layer - #13

Merged
espottesmith merged 7 commits into
CoReACTER:mainfrom
shonalidixit:shonali-lux-layer
Jul 31, 2026
Merged

Shonali lux layer#13
espottesmith merged 7 commits into
CoReACTER:mainfrom
shonalidixit:shonali-lux-layer

Conversation

@shonalidixit

Copy link
Copy Markdown
Contributor

Description

This PR introduces an initial Lux-based implementation for directed hypergraph neural networks.

Summary of changes

  • Added a new layers/ directory to organise neural network layers.
  • Implemented a reusable DirectedHypergraphLayer using Lux.jl.
  • Added an initial DirectedHypergraphRegression model built on top of the directed hypergraph layer.
  • Integrated the new layers into the package.
  • Added basic tests for layer initialisation and the forward pass.

This PR is intended as an initial implementation for review and discussion before further development.

Create layers directory, add reusable DirectedHypergraphLayer, regression model, and initial tests.
@espottesmith
espottesmith self-requested a review July 20, 2026 12:08
Comment thread src/layers/DirectedHypergraphLayer.jl Outdated
Comment on lines +4 to +19
"""
safe_column_normalise(M)

Normalise each column of `M` by its column sum.

Columns with a sum of zero use a denominator of one, preventing division by
zero while leaving those columns unchanged.
"""

function safe_column_normalise(M::AbstractMatrix)
col_sums = sum(M, dims = 1)
safe_sums = similar(col_sums)

for i in eachindex(col_sums)
safe_sums[i] = col_sums[i] == 0 ? one(eltype(col_sums)) : col_sums[i]
end

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why not combine this with safe_row_normalize and just have the dimension be an input parameter?

Comment thread src/layers/DirectedHypergraphLayer.jl Outdated
Comment on lines +23 to +42
"""
safe_row_normalise(M)

Normalise each row of `M` by its row sum.

Rows with a sum of zero use a denominator of one, preventing division by
zero while leaving those rows unchanged.
"""


function safe_row_normalise(M::AbstractMatrix)
row_sums = sum(M, dims = 2)
safe_sums = similar(row_sums)

for i in eachindex(row_sums)
safe_sums[i] = row_sums[i] == 0 ? one(eltype(row_sums)) : row_sums[i]
end

return M ./ safe_sums
end

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See above.

Comment thread src/layers/DirectedHypergraphLayer.jl Outdated

A Lux-compatible message-passing layer for directed hypergraphs.

The layer accepts a species-feature matrix together with source and target

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

"species" is specific to CRNs. Remember that HyperGraphNeuralNetworks.jl is a generic hypergraph ML library.

Comment thread src/layers/DirectedHypergraphLayer.jl Outdated
Comment on lines +52 to +57
1. A learnable transformation of species features.
2. Separate aggregation of source and target species into reaction embeddings.
3. A learnable transformation of reaction embeddings.
4. Propagation of reaction messages back to participating species.
5. A learnable update of the species embeddings.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See above. The layers that you develop should be general to any (di)hypergraph.

Comment thread src/layers/DirectedHypergraphLayer.jl Outdated

# Arguments

- `species_in_dim`: Number of input features associated with each species.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should be something like vertex_in_dim. You should also have a hyperedge_in_dim, I would think.

Comment on lines +6 to +12

struct DirectedHypergraphRegression{H, R} <:
Lux.AbstractLuxContainerLayer{(:hypergraph_layer, :regression_head)}

hypergraph_layer::H
regression_head::R
end

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Again, think about your end user. Is this something that an average end user will want, or will they be designing their own network architectures? I think likely the latter. HyperGraphNeuralNetworks.jl should (mainly) be general-purpose features that could be used for HGNNs. We shouldn't be pigeon-holing folks into one particular architecture.

- `hidden_dim`: Size of the hidden embeddings.
- `activation`: Activation function used in the hypergraph layer.
"""
function DirectedHypergraphRegression(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here, you're assuming a single message-passing layer, we we discussed. At very least, you should have a variable number of layers.

@@ -0,0 +1,47 @@
using Test

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Personal style, but unless your tests are massive, I prefer to have one test file with multiple @testsets

ps,
st
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You're testing that the dimensions are what you expect and that you don't get any exploding infinite numbers. Is that all you need?

Comment thread test/runtests.jl
using SimpleHypergraphs
using SimpleDirectedHypergraphs
using HyperGraphNeuralNetworks
include("layers/DirectedHypergraphLayer.jl")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If you're exporting properly, you shouldn't need to do this.

@espottesmith

Copy link
Copy Markdown
Member

Solid improvement on the test. Unless I missed it, you're still not testing gradients/differentiation (which is important for backpropagation and ML). Take a look at how GraphNeuralNetworks.jl runs their tests, e.g., https://github.com/JuliaGraphs/GraphNeuralNetworks.jl/blob/f80bc29ba47a987cbc69b4563e5109b0c17ad18d/GNNLux/test/test_module.jl

The DirectedHypergraphLayer should be renamed (there will presumably be a number of directed hypergraph layers). Will take another close look later.

Also, for the final PR, please remove your sandbox files (i.e., all of your numbered files, like examples/shonali_prototypes/12_formose_crn_case_study.jl). These shouldn't be part of the main codebase.

@codecov-commenter

codecov-commenter commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.72%. Comparing base (a963eda) to head (9ef5ef3).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #13      +/-   ##
==========================================
+ Coverage   92.19%   92.72%   +0.52%     
==========================================
  Files           8       10       +2     
  Lines        1960     2102     +142     
==========================================
+ Hits         1807     1949     +142     
  Misses        153      153              

☔ View full report in Codecov by Harness.
📢 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.

Added additional unit tests for DirectedHypergraphLayer, including constructor validation, parameter/state initialization, forward-pass behaviour, and invalid input handling. All project tests pass successfully.
## Summary

This PR introduces a new `DirectedHypergraphAttentionLayer` for Lux-compatible directed hypergraph neural networks.

### Features

- Added a directed hypergraph attention layer supporting:
  - source and target attention mechanisms
  - optional hyperedge features
  - optional return of attention weights
- Added helper functions for masked attention computation and safe normalization.
- Added comprehensive unit tests covering:
  - constructor validation
  - parameter initialization
  - forward passes with and without hyperedge features
  - attention weight behaviour
  - deterministic zero-parameter behaviour
  - input validation and error handling

All tests pass successfully.
@espottesmith
espottesmith merged commit 4d9264e into CoReACTER:main Jul 31, 2026
3 checks passed
@espottesmith espottesmith mentioned this pull request Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants