Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PERF Discard old layers immediately when making neural net predictions #17661

Merged
merged 1 commit into from Jul 1, 2020

Conversation

alexhenrie
Copy link
Contributor

This function does not need to hold any layer in memory except the current one, and discarding the previous layers immediately after use makes neural net predictions about 3% faster.

Test program:

from sklearn.datasets import load_digits
from sklearn.neural_network import MLPClassifier
from neurtu import delayed, Benchmark

digits = load_digits(return_X_y=True)
X = digits[0][:,:50]
y = digits[0][:,50]

clf = MLPClassifier(solver='lbfgs', alpha=1e-5,
                    hidden_layer_sizes=(50, 20), random_state=1, max_iter=1000)
clf.fit(X, y)

train = delayed(clf).predict([[x for x in range(50)] for y in range(50)])
print(Benchmark(wall_time=True, cpu_time=True, repeat=100)(train))

Before:

      wall_time  cpu_time                                                                                                     
mean   0.000455  0.000454
max    0.000466  0.000467
std    0.000002  0.000002

After:

mean   0.000439  0.000439
max    0.000454  0.000458
std    0.000002  0.000003

@rth
Copy link
Member

rth commented Jun 24, 2020

Yes, it makes sense. My concern is that _predict is essentially _forward_pass but without storing activation. Could you maybe rename it to _forward_pass_fast and put it just after the _forward_pass function?

Let's see what other reviewers think about this improvement in general.

@alexhenrie
Copy link
Contributor Author

That sounds reasonable to me. I have updated the pull request to rename _predict to _forward_pass_fast.

@alexhenrie alexhenrie changed the title PERF Discard old layers immediately in BaseMultilayerPerceptron._predict PERF Discard old layers immediately when making neural net predictions Jun 24, 2020
Copy link
Member

@NicolasHug NicolasHug left a comment

Choose a reason for hiding this comment

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

Thanks @alexhenrie , some minor suggestsions but LGTM

for i in range(self.n_layers_ - 1):
activation = safe_sparse_dot(activation, self.coefs_[i])
activation += self.intercepts_[i]
if i != self.n_layers_ - 2:
Copy link
Member

Choose a reason for hiding this comment

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

Nit but for consistency with the other version:

Suggested change
if i != self.n_layers_ - 2:
if (i + 1) != (self.n_layers_ - 1):

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The original version uses i + 1 several times, but this simplified version only uses i, so it's more clear here to not have the extra addition in the if statement.

@@ -115,6 +115,36 @@ def _forward_pass(self, activations):

return activations

def _forward_pass_fast(self, X):
"""Predict using the trained model
Copy link
Member

Choose a reason for hiding this comment

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

Please add a short description indicating how this differs from _forward_pass e.g.

This is the same as _forward_pass but does not record the activations of all layers and only returns the last layer's activation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have added the text you suggested. Thanks!

@rth
Copy link
Member

rth commented Jun 29, 2020

@alexhenrie There are some linting issues..

@alexhenrie
Copy link
Contributor Author

The linting issues are now fixed.

@rth rth merged commit f4e921e into scikit-learn:master Jul 1, 2020
7 checks passed
@rth
Copy link
Member

rth commented Jul 1, 2020

Thanks @alexhenrie !

@alexhenrie
Copy link
Contributor Author

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants