Skip to content

BUG: Fix scalar hidden layer sizes - #137

Open
Ashu56376 wants to merge 2 commits into
lanl:mainfrom
Ashu56376:fix-scalar-hidden-layer-sizes
Open

Ashu56376 wants to merge 2 commits into
lanl:mainfrom
Ashu56376:fix-scalar-hidden-layer-sizes

Conversation

@Ashu56376

Copy link
Copy Markdown

This PR fixes handling of scalar hidden_layer_sizes values by converting them to one-dimensional NumPy arrays.

  • Applies the fix to fit() and partial_fit() in both classifier implementations.
  • Adds regression tests for scalar hidden layer sizes.
  • Tested with pytest -q src/gfdl/tests/test_model.py: 5537 passed, 2 xfailed.

Fixes #136

@Ashu56376 Ashu56376 changed the title Fix scalar hidden layer sizesFix scalar hidden_layer_sizes handling Fix scalar hidden layer sizes Oct 17, 2026
@tylerjereddy tylerjereddy added the bug Something isn't working label Oct 18, 2026

@tylerjereddy tylerjereddy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks -- I added some initial review comments. If you used AI/an LLM to prepare any of the work, can you add a brief disclosure to your original PR comment about that, just so we know.

How did you find this project? Do you use RVFL/ELM networks in your work or?

I did confirm that the regression test you added fails before and passes after the source patch. I noted a few small things and of course that the target issue is actually about the regressor. I don't mind if you want to handle the regressor in a separate PR, but let's not consider the target issue fully closed until the testing confirms the regressor is "ok" as well.

predictions = model.predict(X[:5])
assert predictions.shape == (5,)


Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There are some ruff linting failures here and elsewhere. You can find these by running ruff check with ruff version 0.16.8 locally.

"Classifier",
[GFDLClassifier, EnsembleGFDLClassifier],
)
def test_scalar_hidden_layer_sizes(Classifier):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

it is helpful to reference the issue you are writing a test for, i.e., # see gh-136

Comment thread src/gfdl/model.py
if self.reg_alpha is not None and self.reg_alpha < 0.0:
raise ValueError("Negative reg_alpha. Expected range : None or [0.0, inf).")
hidden_layer_sizes = np.asarray(self.hidden_layer_sizes)
hidden_layer_sizes = np.atleast_1d(np.asarray(self.hidden_layer_sizes))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think that, here and elsewhere, you can simplify the call to remove np.asarray() since atleast_1d should call something similar for array coercion under the hood.

)

model = Classifier(hidden_layer_sizes=3, seed=0)
model.fit(X, y)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I suppose if we're being really thorough, we should also test partial_fit()


@pytest.mark.parametrize(
"Classifier",
[GFDLClassifier, EnsembleGFDLClassifier],

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Note that the target issue concerns GFDLRegressor rather than the classifiers. I don't mind if you want to test/fix them separately (regressor tests go in a separate testing module), but let's not consider the target issue fully closed until the GFDLRegressor is tested for the problem scenario in the matching issue.

@tylerjereddy tylerjereddy added this to the 0.3.0 milestone Oct 18, 2026
@tylerjereddy tylerjereddy changed the title Fix scalar hidden layer sizes BUG: Fix scalar hidden layer sizes Oct 18, 2026
@Ashu56376

Copy link
Copy Markdown
Author

Thanks -- I added some initial review comments. If you used AI/an LLM to prepare any of the work, can you add a brief disclosure to your original PR comment about that, just so we know.

How did you find this project? Do you use RVFL/ELM networks in your work or?

I did confirm that the regression test you added fails before and passes after the source patch. I noted a few small things and of course that the target issue is actually about the regressor. I don't mind if you want to handle the regressor in a separate PR, but let's not consider the target issue fully closed until the testing confirms the regressor is "ok" as well.

Thanks for the thorough review and for confirming that the regression test indeed fails before the source patch and passes after it.

I used ChatGPT as an AI assistant for this contribution to get an understanding of the problem and explore potential solutions. I worked on the code changes, ran the tests using Google Colab, and reviewed the implementation.

I came across this project while looking for ML related open-source contributions. I am curious to learn about the RVFL/ELM networks and contribute to the project.

I will look into handling the scalar "hidden_layer_sizes" parameter in "GFDLRegressor", add the relevant regression test, fix the lint issues, and take care of the rest of the feedback.

Thanks for your time and guidance!

@sdtemple

sdtemple commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Thanks for proposing the fix. Somewhere I suggested the same np.atleast_1d solution when opening #136 (probably internally).

I am wondering if we would prefer that one-line fix or use the implementation in sklearn.neural_networks.BaseMultilayerPerceptron.

        hidden_layer_sizes = self.hidden_layer_sizes
        if not hasattr(hidden_layer_sizes, "__iter__"):
            hidden_layer_sizes = [hidden_layer_sizes]
        hidden_layer_sizes = list(hidden_layer_sizes)

Pro: fewer lines of code; Con: sklearn takes another approach that uses base Python only.

In general, is there any reason hidden_layer_sizes needs to be a NumPy array? It appears that it mainly needs to be an iterable object. I'm concerned that we have discussed implementing array API code for the estimators, to a great extent removing np functions, which not all libraries would have. It could be very easy to Ctrl + F for all instances of np, replacing all with xp, and then introduce a bug.

@tylerjereddy

Copy link
Copy Markdown
Collaborator

It could be very easy to Ctrl + F for all instances of np, replacing all with xp, and then introduce a bug.

That shouldn't happen if our array API testing is sufficient.

If hidden_layer_sizes ever gets used in general array ops, then np would probably be better so that it could eventually be translated to xp. If it doesn't, either approach may be "ok," but I'm not sure we should hold this work up for hypothetical array API support issues until testing is in place.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: IndexError when hidden_layer_sizes is a scalar

3 participants