Skip to content

simple_neural_network.py: Fewer forward propogations to speed tests - #11013

Closed
cclauss wants to merge 5 commits into
masterfrom
Fewer-forward-propogations-to-speed-tests
Closed

simple_neural_network.py: Fewer forward propogations to speed tests#11013
cclauss wants to merge 5 commits into
masterfrom
Fewer-forward-propogations-to-speed-tests

Conversation

@cclauss

Copy link
Copy Markdown
Member

Closes#9718

Describe your change:

  • Add an algorithm?
  • Fix a bug or typo in an existing algorithm?
  • Add or change doctests? -- Note: Please avoid changing both code and tests in a single pull request.
  • Documentation change?

Checklist:

  • I have read CONTRIBUTING.md.
  • This pull request is all my own work -- I have not plagiarized.
  • I know that pull requests will not be merged if they fail the automated tests.
  • This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
  • All new Python files are placed inside an existing directory.
  • All filenames are in all lowercase characters with no spaces or dashes.
  • All functions and variable names follow Python naming conventions.
  • All function parameters and return values are annotated with Python type hints.
  • All functions have doctests that pass the automated testing.
  • All new algorithms include at least one URL that points to Wikipedia or another similar explanation.
  • If this pull request resolves one or more open issues then the description above includes the issue number(s) with a closing keyword: "Fixes #ISSUE-NUMBER".

@algorithms-keeperalgorithms-keeperBot added enhancement This PR modified some existing files awaiting reviews This PR is ready to be reviewed tests are failing Do not merge until tests pass labels Oct 26, 2023
@tianyizheng02

Copy link
Copy Markdown
Contributor

At one point I tried to decrease the number of iterations like you did, but it didn't work. 100k iterations isn't even enough for the model to converge within 1 of the true value:

=================================== FAILURES ===================================
______ [doctest] neural_network.simple_neural_network.forward_propagation ______
029 Return the value found after the forward propagation training.
030 031 >>> res = forward_propagation(32, 100_000) # Was 10_000_000
032 >>> res > 31 and res < 33
Expected:
True
Got:
False

Like I've been saying, this implementation is really suboptimal and should be rewritten.

@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

@cclauss make 1 million and the tests will pass. I tried to measure the time (not in doctest) and it was 9 - 10 times faster.
res = forward_propagation(32, 1_000_000)

performance code:
"""
Forward propagation explanation:
https://towardsdatascience.com/forward-propagation-in-neural-networks-simplified-math-and-code-version-bbcfef6f9250
"""
import math
import random
# Sigmoid
def sigmoid_function(value: float, deriv: bool = False) -> float:
"""Return the sigmoid function of a float.
>>> sigmoid_function(3.5)
0.9706877692486436
>>> sigmoid_function(3.5, True)
-8.75
"""
if deriv:
return value * (1 - value)
return 1 / (1 + math.exp(-value))
# Initial Value
INITIAL_VALUE = 0.02
def forward_propagation(expected: int, number_propagations: int) -> float:
"""Return the value found after the forward propagation training.
>>> res = forward_propagation(32, 1_000_000)
>>> res > 31 and res < 33
True
>>> res = forward_propagation(32, 1000)
>>> res > 31 and res < 33
False
"""
# Random weight
weight = float(2 * (random.randint(1, 100)) - 1)
for _ in range(number_propagations):
# Forward propagation
layer_1 = sigmoid_function(INITIAL_VALUE * weight)
# How much did we miss?
layer_1_error = (expected / 100) - layer_1
# Error delta
layer_1_delta = layer_1_error * sigmoid_function(layer_1, True)
# Update weight
weight += INITIAL_VALUE * layer_1_delta
return layer_1 * 100
if __name__ == "__main__":
import doctest
doctest.testmod()
import datetime
now = datetime.datetime.now()
forward_propagation(32, 10000000)
old = datetime.datetime.now() - now
print('old_time', old)
now = datetime.datetime.now()
forward_propagation(32, 1000000)
new = datetime.datetime.now() - now
print('new_time', new)
print('old/new', old/new)

Output:

old_time 0:00:07.447717
new_time 0:00:00.735285
old/new 10.129020719856927

@algorithms-keeperalgorithms-keeperBot removed the tests are failing Do not merge until tests pass label Oct 27, 2023
@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

@cclauss I just checked 200_000, it also worked. I apologize for not checking it right away.
But, if you try several times, it happens that the tests fail. I'll try to find the optimal number.

@cclauss

cclauss commented Oct 27, 2023

Copy link
Copy Markdown
MemberAuthor

Thanks, @quant12345 please keep trying to make it faster without becoming a flaky test.

forward_propagation(32, 500_000) # Was 10_000_000 # puts the tests are < 1sec in 4th slowest.

============================= slowest 10 durations =============================
1.32s call web_programming/get_imdbtop.py::web_programming.get_imdbtop.get_imdb_top_movies
1.21s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.search_anime_episode_list
1.00s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.search_scraper
0.90s call neural_network/simple_neural_network.py::neural_network.simple_neural_network.forward_propagation
0.85s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.get_anime_episode
0.83s call dynamic_programming/integer_partition.py::dynamic_programming.integer_partition.partition
0.72s call graphs/bidirectional_a_star.py::graphs.bidirectional_a_star.AStar
0.50s call matrix/count_negative_numbers_in_sorted_matrix.py::matrix.count_negative_numbers_in_sorted_matrix.generate_large_matrix
0.37s call matrix/count_negative_numbers_in_sorted_matrix.py::matrix.count_negative_numbers_in_sorted_matrix.count_negatives_brute_force
0.37s call dynamic_programming/matrix_chain_multiplication.py::dynamic_programming.matrix_chain_multiplication.matrix_chain_order
================== 1749 passed, 1 warning in 72.96s (0:01:12) ==================

@cclauss

cclauss commented Oct 27, 2023

Copy link
Copy Markdown
MemberAuthor

@tianyizheng02 For the web_programming jobs, should we consider replacing requests with the plug-compatible httpx and encouraging contributors to use asyncio for web interactions? I doubt it would speed up the tests but it would continue to push contributors to learn new skills. We currently have 35 files that import requests.

@quant12345

Copy link
Copy Markdown
Contributor

Thanks, @quant12345 please keep trying to make it faster without becoming a flaky test.

forward_propagation(32, 500_000) # Was 10_000_000 # puts the tests are < 1sec in 4th slowest.

Now I tried 400_000 by calling the function 100 times, sometimes the tests fail. At 500_000 I tried 1000, all tests passed(that is, I also think 500_000 is close to the optimal number).

if __name__ == "__main__":
import doctest
doctest.testmod()
for i in range(100):
doctest.run_docstring_examples(forward_propagation, globals())

@cclauss

Copy link
Copy Markdown
MemberAuthor

Nice! Could you please try 450_000 before I merge this?

@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

Nice! Could you please try 450_000 before I merge this?

I run tests 1000 times. It takes some time.

@cclauss

Update: ran it 1000 times with the number 450_000 tests were successful.

@cclauss
cclauss enabled auto-merge (squash) October 27, 2023 21:19
@cclauss

Copy link
Copy Markdown
MemberAuthor

LGTM. @tianyizheng02

@cclausscclauss mentioned this pull request Oct 28, 2023
15 tasks
auto-merge was automatically disabled October 28, 2023 22:47

Pull request was closed

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

Labels

awaiting reviewsThis PR is ready to be reviewedenhancementThis PR modified some existing files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Speedup our eight slowest pytests (one at a time please)

3 participants

@cclauss@tianyizheng02@quant12345
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
simple_neural_network.py: Fewer forward propogations to speed tests by cclauss · Pull Request #11013 · TheAlgorithms/Python · GitHub
Skip to content

simple_neural_network.py: Fewer forward propogations to speed tests - #11013

Closed
cclauss wants to merge 5 commits into
masterfrom
Fewer-forward-propogations-to-speed-tests
Closed

simple_neural_network.py: Fewer forward propogations to speed tests#11013
cclauss wants to merge 5 commits into
masterfrom
Fewer-forward-propogations-to-speed-tests

Conversation

@cclauss

Copy link
Copy Markdown
Member

Closes#9718

Describe your change:

  • Add an algorithm?
  • Fix a bug or typo in an existing algorithm?
  • Add or change doctests? -- Note: Please avoid changing both code and tests in a single pull request.
  • Documentation change?

Checklist:

  • I have read CONTRIBUTING.md.
  • This pull request is all my own work -- I have not plagiarized.
  • I know that pull requests will not be merged if they fail the automated tests.
  • This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
  • All new Python files are placed inside an existing directory.
  • All filenames are in all lowercase characters with no spaces or dashes.
  • All functions and variable names follow Python naming conventions.
  • All function parameters and return values are annotated with Python type hints.
  • All functions have doctests that pass the automated testing.
  • All new algorithms include at least one URL that points to Wikipedia or another similar explanation.
  • If this pull request resolves one or more open issues then the description above includes the issue number(s) with a closing keyword: "Fixes #ISSUE-NUMBER".

@algorithms-keeperalgorithms-keeperBot added enhancement This PR modified some existing files awaiting reviews This PR is ready to be reviewed tests are failing Do not merge until tests pass labels Oct 26, 2023
@tianyizheng02

Copy link
Copy Markdown
Contributor

At one point I tried to decrease the number of iterations like you did, but it didn't work. 100k iterations isn't even enough for the model to converge within 1 of the true value:

=================================== FAILURES ===================================
______ [doctest] neural_network.simple_neural_network.forward_propagation ______
029 Return the value found after the forward propagation training.
030 031 >>> res = forward_propagation(32, 100_000) # Was 10_000_000
032 >>> res > 31 and res < 33
Expected:
True
Got:
False

Like I've been saying, this implementation is really suboptimal and should be rewritten.

@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

@cclauss make 1 million and the tests will pass. I tried to measure the time (not in doctest) and it was 9 - 10 times faster.
res = forward_propagation(32, 1_000_000)

performance code:
"""
Forward propagation explanation:
https://towardsdatascience.com/forward-propagation-in-neural-networks-simplified-math-and-code-version-bbcfef6f9250
"""
import math
import random
# Sigmoid
def sigmoid_function(value: float, deriv: bool = False) -> float:
"""Return the sigmoid function of a float.
>>> sigmoid_function(3.5)
0.9706877692486436
>>> sigmoid_function(3.5, True)
-8.75
"""
if deriv:
return value * (1 - value)
return 1 / (1 + math.exp(-value))
# Initial Value
INITIAL_VALUE = 0.02
def forward_propagation(expected: int, number_propagations: int) -> float:
"""Return the value found after the forward propagation training.
>>> res = forward_propagation(32, 1_000_000)
>>> res > 31 and res < 33
True
>>> res = forward_propagation(32, 1000)
>>> res > 31 and res < 33
False
"""
# Random weight
weight = float(2 * (random.randint(1, 100)) - 1)
for _ in range(number_propagations):
# Forward propagation
layer_1 = sigmoid_function(INITIAL_VALUE * weight)
# How much did we miss?
layer_1_error = (expected / 100) - layer_1
# Error delta
layer_1_delta = layer_1_error * sigmoid_function(layer_1, True)
# Update weight
weight += INITIAL_VALUE * layer_1_delta
return layer_1 * 100
if __name__ == "__main__":
import doctest
doctest.testmod()
import datetime
now = datetime.datetime.now()
forward_propagation(32, 10000000)
old = datetime.datetime.now() - now
print('old_time', old)
now = datetime.datetime.now()
forward_propagation(32, 1000000)
new = datetime.datetime.now() - now
print('new_time', new)
print('old/new', old/new)

Output:

old_time 0:00:07.447717
new_time 0:00:00.735285
old/new 10.129020719856927

@algorithms-keeperalgorithms-keeperBot removed the tests are failing Do not merge until tests pass label Oct 27, 2023
@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

@cclauss I just checked 200_000, it also worked. I apologize for not checking it right away.
But, if you try several times, it happens that the tests fail. I'll try to find the optimal number.

@cclauss

cclauss commented Oct 27, 2023

Copy link
Copy Markdown
MemberAuthor

Thanks, @quant12345 please keep trying to make it faster without becoming a flaky test.

forward_propagation(32, 500_000) # Was 10_000_000 # puts the tests are < 1sec in 4th slowest.

============================= slowest 10 durations =============================
1.32s call web_programming/get_imdbtop.py::web_programming.get_imdbtop.get_imdb_top_movies
1.21s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.search_anime_episode_list
1.00s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.search_scraper
0.90s call neural_network/simple_neural_network.py::neural_network.simple_neural_network.forward_propagation
0.85s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.get_anime_episode
0.83s call dynamic_programming/integer_partition.py::dynamic_programming.integer_partition.partition
0.72s call graphs/bidirectional_a_star.py::graphs.bidirectional_a_star.AStar
0.50s call matrix/count_negative_numbers_in_sorted_matrix.py::matrix.count_negative_numbers_in_sorted_matrix.generate_large_matrix
0.37s call matrix/count_negative_numbers_in_sorted_matrix.py::matrix.count_negative_numbers_in_sorted_matrix.count_negatives_brute_force
0.37s call dynamic_programming/matrix_chain_multiplication.py::dynamic_programming.matrix_chain_multiplication.matrix_chain_order
================== 1749 passed, 1 warning in 72.96s (0:01:12) ==================

@cclauss

cclauss commented Oct 27, 2023

Copy link
Copy Markdown
MemberAuthor

@tianyizheng02 For the web_programming jobs, should we consider replacing requests with the plug-compatible httpx and encouraging contributors to use asyncio for web interactions? I doubt it would speed up the tests but it would continue to push contributors to learn new skills. We currently have 35 files that import requests.

@quant12345

Copy link
Copy Markdown
Contributor

Thanks, @quant12345 please keep trying to make it faster without becoming a flaky test.

forward_propagation(32, 500_000) # Was 10_000_000 # puts the tests are < 1sec in 4th slowest.

Now I tried 400_000 by calling the function 100 times, sometimes the tests fail. At 500_000 I tried 1000, all tests passed(that is, I also think 500_000 is close to the optimal number).

if __name__ == "__main__":
import doctest
doctest.testmod()
for i in range(100):
doctest.run_docstring_examples(forward_propagation, globals())

@cclauss

Copy link
Copy Markdown
MemberAuthor

Nice! Could you please try 450_000 before I merge this?

@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

Nice! Could you please try 450_000 before I merge this?

I run tests 1000 times. It takes some time.

@cclauss

Update: ran it 1000 times with the number 450_000 tests were successful.

@cclauss
cclauss enabled auto-merge (squash) October 27, 2023 21:19
@cclauss

Copy link
Copy Markdown
MemberAuthor

LGTM. @tianyizheng02

@cclausscclauss mentioned this pull request Oct 28, 2023
15 tasks
auto-merge was automatically disabled October 28, 2023 22:47

Pull request was closed

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

Labels

awaiting reviewsThis PR is ready to be reviewedenhancementThis PR modified some existing files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Speedup our eight slowest pytests (one at a time please)

3 participants

@cclauss@tianyizheng02@quant12345
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' simple_neural_network.py: Fewer forward propogations to speed tests by cclauss · Pull Request #11013 · TheAlgorithms/Python · GitHub
Skip to content

simple_neural_network.py: Fewer forward propogations to speed tests - #11013

Closed
cclauss wants to merge 5 commits into
masterfrom
Fewer-forward-propogations-to-speed-tests
Closed

simple_neural_network.py: Fewer forward propogations to speed tests#11013
cclauss wants to merge 5 commits into
masterfrom
Fewer-forward-propogations-to-speed-tests

Conversation

@cclauss

Copy link
Copy Markdown
Member

Closes#9718

Describe your change:

  • Add an algorithm?
  • Fix a bug or typo in an existing algorithm?
  • Add or change doctests? -- Note: Please avoid changing both code and tests in a single pull request.
  • Documentation change?

Checklist:

  • I have read CONTRIBUTING.md.
  • This pull request is all my own work -- I have not plagiarized.
  • I know that pull requests will not be merged if they fail the automated tests.
  • This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
  • All new Python files are placed inside an existing directory.
  • All filenames are in all lowercase characters with no spaces or dashes.
  • All functions and variable names follow Python naming conventions.
  • All function parameters and return values are annotated with Python type hints.
  • All functions have doctests that pass the automated testing.
  • All new algorithms include at least one URL that points to Wikipedia or another similar explanation.
  • If this pull request resolves one or more open issues then the description above includes the issue number(s) with a closing keyword: "Fixes #ISSUE-NUMBER".

@algorithms-keeperalgorithms-keeperBot added enhancement This PR modified some existing files awaiting reviews This PR is ready to be reviewed tests are failing Do not merge until tests pass labels Oct 26, 2023
@tianyizheng02

Copy link
Copy Markdown
Contributor

At one point I tried to decrease the number of iterations like you did, but it didn't work. 100k iterations isn't even enough for the model to converge within 1 of the true value:

=================================== FAILURES ===================================
______ [doctest] neural_network.simple_neural_network.forward_propagation ______
029 Return the value found after the forward propagation training.
030 031 >>> res = forward_propagation(32, 100_000) # Was 10_000_000
032 >>> res > 31 and res < 33
Expected:
True
Got:
False

Like I've been saying, this implementation is really suboptimal and should be rewritten.

@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

@cclauss make 1 million and the tests will pass. I tried to measure the time (not in doctest) and it was 9 - 10 times faster.
res = forward_propagation(32, 1_000_000)

performance code:
"""
Forward propagation explanation:
https://towardsdatascience.com/forward-propagation-in-neural-networks-simplified-math-and-code-version-bbcfef6f9250
"""
import math
import random
# Sigmoid
def sigmoid_function(value: float, deriv: bool = False) -> float:
"""Return the sigmoid function of a float.
>>> sigmoid_function(3.5)
0.9706877692486436
>>> sigmoid_function(3.5, True)
-8.75
"""
if deriv:
return value * (1 - value)
return 1 / (1 + math.exp(-value))
# Initial Value
INITIAL_VALUE = 0.02
def forward_propagation(expected: int, number_propagations: int) -> float:
"""Return the value found after the forward propagation training.
>>> res = forward_propagation(32, 1_000_000)
>>> res > 31 and res < 33
True
>>> res = forward_propagation(32, 1000)
>>> res > 31 and res < 33
False
"""
# Random weight
weight = float(2 * (random.randint(1, 100)) - 1)
for _ in range(number_propagations):
# Forward propagation
layer_1 = sigmoid_function(INITIAL_VALUE * weight)
# How much did we miss?
layer_1_error = (expected / 100) - layer_1
# Error delta
layer_1_delta = layer_1_error * sigmoid_function(layer_1, True)
# Update weight
weight += INITIAL_VALUE * layer_1_delta
return layer_1 * 100
if __name__ == "__main__":
import doctest
doctest.testmod()
import datetime
now = datetime.datetime.now()
forward_propagation(32, 10000000)
old = datetime.datetime.now() - now
print('old_time', old)
now = datetime.datetime.now()
forward_propagation(32, 1000000)
new = datetime.datetime.now() - now
print('new_time', new)
print('old/new', old/new)

Output:

old_time 0:00:07.447717
new_time 0:00:00.735285
old/new 10.129020719856927

@algorithms-keeperalgorithms-keeperBot removed the tests are failing Do not merge until tests pass label Oct 27, 2023
@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

@cclauss I just checked 200_000, it also worked. I apologize for not checking it right away.
But, if you try several times, it happens that the tests fail. I'll try to find the optimal number.

@cclauss

cclauss commented Oct 27, 2023

Copy link
Copy Markdown
MemberAuthor

Thanks, @quant12345 please keep trying to make it faster without becoming a flaky test.

forward_propagation(32, 500_000) # Was 10_000_000 # puts the tests are < 1sec in 4th slowest.

============================= slowest 10 durations =============================
1.32s call web_programming/get_imdbtop.py::web_programming.get_imdbtop.get_imdb_top_movies
1.21s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.search_anime_episode_list
1.00s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.search_scraper
0.90s call neural_network/simple_neural_network.py::neural_network.simple_neural_network.forward_propagation
0.85s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.get_anime_episode
0.83s call dynamic_programming/integer_partition.py::dynamic_programming.integer_partition.partition
0.72s call graphs/bidirectional_a_star.py::graphs.bidirectional_a_star.AStar
0.50s call matrix/count_negative_numbers_in_sorted_matrix.py::matrix.count_negative_numbers_in_sorted_matrix.generate_large_matrix
0.37s call matrix/count_negative_numbers_in_sorted_matrix.py::matrix.count_negative_numbers_in_sorted_matrix.count_negatives_brute_force
0.37s call dynamic_programming/matrix_chain_multiplication.py::dynamic_programming.matrix_chain_multiplication.matrix_chain_order
================== 1749 passed, 1 warning in 72.96s (0:01:12) ==================

@cclauss

cclauss commented Oct 27, 2023

Copy link
Copy Markdown
MemberAuthor

@tianyizheng02 For the web_programming jobs, should we consider replacing requests with the plug-compatible httpx and encouraging contributors to use asyncio for web interactions? I doubt it would speed up the tests but it would continue to push contributors to learn new skills. We currently have 35 files that import requests.

@quant12345

Copy link
Copy Markdown
Contributor

Thanks, @quant12345 please keep trying to make it faster without becoming a flaky test.

forward_propagation(32, 500_000) # Was 10_000_000 # puts the tests are < 1sec in 4th slowest.

Now I tried 400_000 by calling the function 100 times, sometimes the tests fail. At 500_000 I tried 1000, all tests passed(that is, I also think 500_000 is close to the optimal number).

if __name__ == "__main__":
import doctest
doctest.testmod()
for i in range(100):
doctest.run_docstring_examples(forward_propagation, globals())

@cclauss

Copy link
Copy Markdown
MemberAuthor

Nice! Could you please try 450_000 before I merge this?

@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

Nice! Could you please try 450_000 before I merge this?

I run tests 1000 times. It takes some time.

@cclauss

Update: ran it 1000 times with the number 450_000 tests were successful.

@cclauss
cclauss enabled auto-merge (squash) October 27, 2023 21:19
@cclauss

Copy link
Copy Markdown
MemberAuthor

LGTM. @tianyizheng02

@cclausscclauss mentioned this pull request Oct 28, 2023
15 tasks
auto-merge was automatically disabled October 28, 2023 22:47

Pull request was closed

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

Labels

awaiting reviewsThis PR is ready to be reviewedenhancementThis PR modified some existing files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Speedup our eight slowest pytests (one at a time please)

3 participants

@cclauss@tianyizheng02@quant12345
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' simple_neural_network.py: Fewer forward propogations to speed tests by cclauss · Pull Request #11013 · TheAlgorithms/Python · GitHub
Skip to content

simple_neural_network.py: Fewer forward propogations to speed tests - #11013

Closed
cclauss wants to merge 5 commits into
masterfrom
Fewer-forward-propogations-to-speed-tests
Closed

simple_neural_network.py: Fewer forward propogations to speed tests#11013
cclauss wants to merge 5 commits into
masterfrom
Fewer-forward-propogations-to-speed-tests

Conversation

@cclauss

Copy link
Copy Markdown
Member

Closes#9718

Describe your change:

  • Add an algorithm?
  • Fix a bug or typo in an existing algorithm?
  • Add or change doctests? -- Note: Please avoid changing both code and tests in a single pull request.
  • Documentation change?

Checklist:

  • I have read CONTRIBUTING.md.
  • This pull request is all my own work -- I have not plagiarized.
  • I know that pull requests will not be merged if they fail the automated tests.
  • This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
  • All new Python files are placed inside an existing directory.
  • All filenames are in all lowercase characters with no spaces or dashes.
  • All functions and variable names follow Python naming conventions.
  • All function parameters and return values are annotated with Python type hints.
  • All functions have doctests that pass the automated testing.
  • All new algorithms include at least one URL that points to Wikipedia or another similar explanation.
  • If this pull request resolves one or more open issues then the description above includes the issue number(s) with a closing keyword: "Fixes #ISSUE-NUMBER".

@algorithms-keeperalgorithms-keeperBot added enhancement This PR modified some existing files awaiting reviews This PR is ready to be reviewed tests are failing Do not merge until tests pass labels Oct 26, 2023
@tianyizheng02

Copy link
Copy Markdown
Contributor

At one point I tried to decrease the number of iterations like you did, but it didn't work. 100k iterations isn't even enough for the model to converge within 1 of the true value:

=================================== FAILURES ===================================
______ [doctest] neural_network.simple_neural_network.forward_propagation ______
029 Return the value found after the forward propagation training.
030 031 >>> res = forward_propagation(32, 100_000) # Was 10_000_000
032 >>> res > 31 and res < 33
Expected:
True
Got:
False

Like I've been saying, this implementation is really suboptimal and should be rewritten.

@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

@cclauss make 1 million and the tests will pass. I tried to measure the time (not in doctest) and it was 9 - 10 times faster.
res = forward_propagation(32, 1_000_000)

performance code:
"""
Forward propagation explanation:
https://towardsdatascience.com/forward-propagation-in-neural-networks-simplified-math-and-code-version-bbcfef6f9250
"""
import math
import random
# Sigmoid
def sigmoid_function(value: float, deriv: bool = False) -> float:
"""Return the sigmoid function of a float.
>>> sigmoid_function(3.5)
0.9706877692486436
>>> sigmoid_function(3.5, True)
-8.75
"""
if deriv:
return value * (1 - value)
return 1 / (1 + math.exp(-value))
# Initial Value
INITIAL_VALUE = 0.02
def forward_propagation(expected: int, number_propagations: int) -> float:
"""Return the value found after the forward propagation training.
>>> res = forward_propagation(32, 1_000_000)
>>> res > 31 and res < 33
True
>>> res = forward_propagation(32, 1000)
>>> res > 31 and res < 33
False
"""
# Random weight
weight = float(2 * (random.randint(1, 100)) - 1)
for _ in range(number_propagations):
# Forward propagation
layer_1 = sigmoid_function(INITIAL_VALUE * weight)
# How much did we miss?
layer_1_error = (expected / 100) - layer_1
# Error delta
layer_1_delta = layer_1_error * sigmoid_function(layer_1, True)
# Update weight
weight += INITIAL_VALUE * layer_1_delta
return layer_1 * 100
if __name__ == "__main__":
import doctest
doctest.testmod()
import datetime
now = datetime.datetime.now()
forward_propagation(32, 10000000)
old = datetime.datetime.now() - now
print('old_time', old)
now = datetime.datetime.now()
forward_propagation(32, 1000000)
new = datetime.datetime.now() - now
print('new_time', new)
print('old/new', old/new)

Output:

old_time 0:00:07.447717
new_time 0:00:00.735285
old/new 10.129020719856927

@algorithms-keeperalgorithms-keeperBot removed the tests are failing Do not merge until tests pass label Oct 27, 2023
@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

@cclauss I just checked 200_000, it also worked. I apologize for not checking it right away.
But, if you try several times, it happens that the tests fail. I'll try to find the optimal number.

@cclauss

cclauss commented Oct 27, 2023

Copy link
Copy Markdown
MemberAuthor

Thanks, @quant12345 please keep trying to make it faster without becoming a flaky test.

forward_propagation(32, 500_000) # Was 10_000_000 # puts the tests are < 1sec in 4th slowest.

============================= slowest 10 durations =============================
1.32s call web_programming/get_imdbtop.py::web_programming.get_imdbtop.get_imdb_top_movies
1.21s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.search_anime_episode_list
1.00s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.search_scraper
0.90s call neural_network/simple_neural_network.py::neural_network.simple_neural_network.forward_propagation
0.85s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.get_anime_episode
0.83s call dynamic_programming/integer_partition.py::dynamic_programming.integer_partition.partition
0.72s call graphs/bidirectional_a_star.py::graphs.bidirectional_a_star.AStar
0.50s call matrix/count_negative_numbers_in_sorted_matrix.py::matrix.count_negative_numbers_in_sorted_matrix.generate_large_matrix
0.37s call matrix/count_negative_numbers_in_sorted_matrix.py::matrix.count_negative_numbers_in_sorted_matrix.count_negatives_brute_force
0.37s call dynamic_programming/matrix_chain_multiplication.py::dynamic_programming.matrix_chain_multiplication.matrix_chain_order
================== 1749 passed, 1 warning in 72.96s (0:01:12) ==================

@cclauss

cclauss commented Oct 27, 2023

Copy link
Copy Markdown
MemberAuthor

@tianyizheng02 For the web_programming jobs, should we consider replacing requests with the plug-compatible httpx and encouraging contributors to use asyncio for web interactions? I doubt it would speed up the tests but it would continue to push contributors to learn new skills. We currently have 35 files that import requests.

@quant12345

Copy link
Copy Markdown
Contributor

Thanks, @quant12345 please keep trying to make it faster without becoming a flaky test.

forward_propagation(32, 500_000) # Was 10_000_000 # puts the tests are < 1sec in 4th slowest.

Now I tried 400_000 by calling the function 100 times, sometimes the tests fail. At 500_000 I tried 1000, all tests passed(that is, I also think 500_000 is close to the optimal number).

if __name__ == "__main__":
import doctest
doctest.testmod()
for i in range(100):
doctest.run_docstring_examples(forward_propagation, globals())

@cclauss

Copy link
Copy Markdown
MemberAuthor

Nice! Could you please try 450_000 before I merge this?

@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

Nice! Could you please try 450_000 before I merge this?

I run tests 1000 times. It takes some time.

@cclauss

Update: ran it 1000 times with the number 450_000 tests were successful.

@cclauss
cclauss enabled auto-merge (squash) October 27, 2023 21:19
@cclauss

Copy link
Copy Markdown
MemberAuthor

LGTM. @tianyizheng02

@cclausscclauss mentioned this pull request Oct 28, 2023
15 tasks
auto-merge was automatically disabled October 28, 2023 22:47

Pull request was closed

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

Labels

awaiting reviewsThis PR is ready to be reviewedenhancementThis PR modified some existing files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Speedup our eight slowest pytests (one at a time please)

3 participants

@cclauss@tianyizheng02@quant12345
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' simple_neural_network.py: Fewer forward propogations to speed tests by cclauss · Pull Request #11013 · TheAlgorithms/Python · GitHub
Skip to content

simple_neural_network.py: Fewer forward propogations to speed tests - #11013

Closed
cclauss wants to merge 5 commits into
masterfrom
Fewer-forward-propogations-to-speed-tests
Closed

simple_neural_network.py: Fewer forward propogations to speed tests#11013
cclauss wants to merge 5 commits into
masterfrom
Fewer-forward-propogations-to-speed-tests

Conversation

@cclauss

Copy link
Copy Markdown
Member

Closes#9718

Describe your change:

  • Add an algorithm?
  • Fix a bug or typo in an existing algorithm?
  • Add or change doctests? -- Note: Please avoid changing both code and tests in a single pull request.
  • Documentation change?

Checklist:

  • I have read CONTRIBUTING.md.
  • This pull request is all my own work -- I have not plagiarized.
  • I know that pull requests will not be merged if they fail the automated tests.
  • This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
  • All new Python files are placed inside an existing directory.
  • All filenames are in all lowercase characters with no spaces or dashes.
  • All functions and variable names follow Python naming conventions.
  • All function parameters and return values are annotated with Python type hints.
  • All functions have doctests that pass the automated testing.
  • All new algorithms include at least one URL that points to Wikipedia or another similar explanation.
  • If this pull request resolves one or more open issues then the description above includes the issue number(s) with a closing keyword: "Fixes #ISSUE-NUMBER".

@algorithms-keeperalgorithms-keeperBot added enhancement This PR modified some existing files awaiting reviews This PR is ready to be reviewed tests are failing Do not merge until tests pass labels Oct 26, 2023
@tianyizheng02

Copy link
Copy Markdown
Contributor

At one point I tried to decrease the number of iterations like you did, but it didn't work. 100k iterations isn't even enough for the model to converge within 1 of the true value:

=================================== FAILURES ===================================
______ [doctest] neural_network.simple_neural_network.forward_propagation ______
029 Return the value found after the forward propagation training.
030 031 >>> res = forward_propagation(32, 100_000) # Was 10_000_000
032 >>> res > 31 and res < 33
Expected:
True
Got:
False

Like I've been saying, this implementation is really suboptimal and should be rewritten.

@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

@cclauss make 1 million and the tests will pass. I tried to measure the time (not in doctest) and it was 9 - 10 times faster.
res = forward_propagation(32, 1_000_000)

performance code:
"""
Forward propagation explanation:
https://towardsdatascience.com/forward-propagation-in-neural-networks-simplified-math-and-code-version-bbcfef6f9250
"""
import math
import random
# Sigmoid
def sigmoid_function(value: float, deriv: bool = False) -> float:
"""Return the sigmoid function of a float.
>>> sigmoid_function(3.5)
0.9706877692486436
>>> sigmoid_function(3.5, True)
-8.75
"""
if deriv:
return value * (1 - value)
return 1 / (1 + math.exp(-value))
# Initial Value
INITIAL_VALUE = 0.02
def forward_propagation(expected: int, number_propagations: int) -> float:
"""Return the value found after the forward propagation training.
>>> res = forward_propagation(32, 1_000_000)
>>> res > 31 and res < 33
True
>>> res = forward_propagation(32, 1000)
>>> res > 31 and res < 33
False
"""
# Random weight
weight = float(2 * (random.randint(1, 100)) - 1)
for _ in range(number_propagations):
# Forward propagation
layer_1 = sigmoid_function(INITIAL_VALUE * weight)
# How much did we miss?
layer_1_error = (expected / 100) - layer_1
# Error delta
layer_1_delta = layer_1_error * sigmoid_function(layer_1, True)
# Update weight
weight += INITIAL_VALUE * layer_1_delta
return layer_1 * 100
if __name__ == "__main__":
import doctest
doctest.testmod()
import datetime
now = datetime.datetime.now()
forward_propagation(32, 10000000)
old = datetime.datetime.now() - now
print('old_time', old)
now = datetime.datetime.now()
forward_propagation(32, 1000000)
new = datetime.datetime.now() - now
print('new_time', new)
print('old/new', old/new)

Output:

old_time 0:00:07.447717
new_time 0:00:00.735285
old/new 10.129020719856927

@algorithms-keeperalgorithms-keeperBot removed the tests are failing Do not merge until tests pass label Oct 27, 2023
@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

@cclauss I just checked 200_000, it also worked. I apologize for not checking it right away.
But, if you try several times, it happens that the tests fail. I'll try to find the optimal number.

@cclauss

cclauss commented Oct 27, 2023

Copy link
Copy Markdown
MemberAuthor

Thanks, @quant12345 please keep trying to make it faster without becoming a flaky test.

forward_propagation(32, 500_000) # Was 10_000_000 # puts the tests are < 1sec in 4th slowest.

============================= slowest 10 durations =============================
1.32s call web_programming/get_imdbtop.py::web_programming.get_imdbtop.get_imdb_top_movies
1.21s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.search_anime_episode_list
1.00s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.search_scraper
0.90s call neural_network/simple_neural_network.py::neural_network.simple_neural_network.forward_propagation
0.85s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.get_anime_episode
0.83s call dynamic_programming/integer_partition.py::dynamic_programming.integer_partition.partition
0.72s call graphs/bidirectional_a_star.py::graphs.bidirectional_a_star.AStar
0.50s call matrix/count_negative_numbers_in_sorted_matrix.py::matrix.count_negative_numbers_in_sorted_matrix.generate_large_matrix
0.37s call matrix/count_negative_numbers_in_sorted_matrix.py::matrix.count_negative_numbers_in_sorted_matrix.count_negatives_brute_force
0.37s call dynamic_programming/matrix_chain_multiplication.py::dynamic_programming.matrix_chain_multiplication.matrix_chain_order
================== 1749 passed, 1 warning in 72.96s (0:01:12) ==================

@cclauss

cclauss commented Oct 27, 2023

Copy link
Copy Markdown
MemberAuthor

@tianyizheng02 For the web_programming jobs, should we consider replacing requests with the plug-compatible httpx and encouraging contributors to use asyncio for web interactions? I doubt it would speed up the tests but it would continue to push contributors to learn new skills. We currently have 35 files that import requests.

@quant12345

Copy link
Copy Markdown
Contributor

Thanks, @quant12345 please keep trying to make it faster without becoming a flaky test.

forward_propagation(32, 500_000) # Was 10_000_000 # puts the tests are < 1sec in 4th slowest.

Now I tried 400_000 by calling the function 100 times, sometimes the tests fail. At 500_000 I tried 1000, all tests passed(that is, I also think 500_000 is close to the optimal number).

if __name__ == "__main__":
import doctest
doctest.testmod()
for i in range(100):
doctest.run_docstring_examples(forward_propagation, globals())

@cclauss

Copy link
Copy Markdown
MemberAuthor

Nice! Could you please try 450_000 before I merge this?

@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

Nice! Could you please try 450_000 before I merge this?

I run tests 1000 times. It takes some time.

@cclauss

Update: ran it 1000 times with the number 450_000 tests were successful.

@cclauss
cclauss enabled auto-merge (squash) October 27, 2023 21:19
@cclauss

Copy link
Copy Markdown
MemberAuthor

LGTM. @tianyizheng02

@cclausscclauss mentioned this pull request Oct 28, 2023
15 tasks
auto-merge was automatically disabled October 28, 2023 22:47

Pull request was closed

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

Labels

awaiting reviewsThis PR is ready to be reviewedenhancementThis PR modified some existing files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Speedup our eight slowest pytests (one at a time please)

3 participants

@cclauss@tianyizheng02@quant12345
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' simple_neural_network.py: Fewer forward propogations to speed tests by cclauss · Pull Request #11013 · TheAlgorithms/Python · GitHub
Skip to content

simple_neural_network.py: Fewer forward propogations to speed tests - #11013

Closed
cclauss wants to merge 5 commits into
masterfrom
Fewer-forward-propogations-to-speed-tests
Closed

simple_neural_network.py: Fewer forward propogations to speed tests#11013
cclauss wants to merge 5 commits into
masterfrom
Fewer-forward-propogations-to-speed-tests

Conversation

@cclauss

Copy link
Copy Markdown
Member

Closes#9718

Describe your change:

  • Add an algorithm?
  • Fix a bug or typo in an existing algorithm?
  • Add or change doctests? -- Note: Please avoid changing both code and tests in a single pull request.
  • Documentation change?

Checklist:

  • I have read CONTRIBUTING.md.
  • This pull request is all my own work -- I have not plagiarized.
  • I know that pull requests will not be merged if they fail the automated tests.
  • This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
  • All new Python files are placed inside an existing directory.
  • All filenames are in all lowercase characters with no spaces or dashes.
  • All functions and variable names follow Python naming conventions.
  • All function parameters and return values are annotated with Python type hints.
  • All functions have doctests that pass the automated testing.
  • All new algorithms include at least one URL that points to Wikipedia or another similar explanation.
  • If this pull request resolves one or more open issues then the description above includes the issue number(s) with a closing keyword: "Fixes #ISSUE-NUMBER".

@algorithms-keeperalgorithms-keeperBot added enhancement This PR modified some existing files awaiting reviews This PR is ready to be reviewed tests are failing Do not merge until tests pass labels Oct 26, 2023
@tianyizheng02

Copy link
Copy Markdown
Contributor

At one point I tried to decrease the number of iterations like you did, but it didn't work. 100k iterations isn't even enough for the model to converge within 1 of the true value:

=================================== FAILURES ===================================
______ [doctest] neural_network.simple_neural_network.forward_propagation ______
029 Return the value found after the forward propagation training.
030 031 >>> res = forward_propagation(32, 100_000) # Was 10_000_000
032 >>> res > 31 and res < 33
Expected:
True
Got:
False

Like I've been saying, this implementation is really suboptimal and should be rewritten.

@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

@cclauss make 1 million and the tests will pass. I tried to measure the time (not in doctest) and it was 9 - 10 times faster.
res = forward_propagation(32, 1_000_000)

performance code:
"""
Forward propagation explanation:
https://towardsdatascience.com/forward-propagation-in-neural-networks-simplified-math-and-code-version-bbcfef6f9250
"""
import math
import random
# Sigmoid
def sigmoid_function(value: float, deriv: bool = False) -> float:
"""Return the sigmoid function of a float.
>>> sigmoid_function(3.5)
0.9706877692486436
>>> sigmoid_function(3.5, True)
-8.75
"""
if deriv:
return value * (1 - value)
return 1 / (1 + math.exp(-value))
# Initial Value
INITIAL_VALUE = 0.02
def forward_propagation(expected: int, number_propagations: int) -> float:
"""Return the value found after the forward propagation training.
>>> res = forward_propagation(32, 1_000_000)
>>> res > 31 and res < 33
True
>>> res = forward_propagation(32, 1000)
>>> res > 31 and res < 33
False
"""
# Random weight
weight = float(2 * (random.randint(1, 100)) - 1)
for _ in range(number_propagations):
# Forward propagation
layer_1 = sigmoid_function(INITIAL_VALUE * weight)
# How much did we miss?
layer_1_error = (expected / 100) - layer_1
# Error delta
layer_1_delta = layer_1_error * sigmoid_function(layer_1, True)
# Update weight
weight += INITIAL_VALUE * layer_1_delta
return layer_1 * 100
if __name__ == "__main__":
import doctest
doctest.testmod()
import datetime
now = datetime.datetime.now()
forward_propagation(32, 10000000)
old = datetime.datetime.now() - now
print('old_time', old)
now = datetime.datetime.now()
forward_propagation(32, 1000000)
new = datetime.datetime.now() - now
print('new_time', new)
print('old/new', old/new)

Output:

old_time 0:00:07.447717
new_time 0:00:00.735285
old/new 10.129020719856927

@algorithms-keeperalgorithms-keeperBot removed the tests are failing Do not merge until tests pass label Oct 27, 2023
@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

@cclauss I just checked 200_000, it also worked. I apologize for not checking it right away.
But, if you try several times, it happens that the tests fail. I'll try to find the optimal number.

@cclauss

cclauss commented Oct 27, 2023

Copy link
Copy Markdown
MemberAuthor

Thanks, @quant12345 please keep trying to make it faster without becoming a flaky test.

forward_propagation(32, 500_000) # Was 10_000_000 # puts the tests are < 1sec in 4th slowest.

============================= slowest 10 durations =============================
1.32s call web_programming/get_imdbtop.py::web_programming.get_imdbtop.get_imdb_top_movies
1.21s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.search_anime_episode_list
1.00s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.search_scraper
0.90s call neural_network/simple_neural_network.py::neural_network.simple_neural_network.forward_propagation
0.85s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.get_anime_episode
0.83s call dynamic_programming/integer_partition.py::dynamic_programming.integer_partition.partition
0.72s call graphs/bidirectional_a_star.py::graphs.bidirectional_a_star.AStar
0.50s call matrix/count_negative_numbers_in_sorted_matrix.py::matrix.count_negative_numbers_in_sorted_matrix.generate_large_matrix
0.37s call matrix/count_negative_numbers_in_sorted_matrix.py::matrix.count_negative_numbers_in_sorted_matrix.count_negatives_brute_force
0.37s call dynamic_programming/matrix_chain_multiplication.py::dynamic_programming.matrix_chain_multiplication.matrix_chain_order
================== 1749 passed, 1 warning in 72.96s (0:01:12) ==================

@cclauss

cclauss commented Oct 27, 2023

Copy link
Copy Markdown
MemberAuthor

@tianyizheng02 For the web_programming jobs, should we consider replacing requests with the plug-compatible httpx and encouraging contributors to use asyncio for web interactions? I doubt it would speed up the tests but it would continue to push contributors to learn new skills. We currently have 35 files that import requests.

@quant12345

Copy link
Copy Markdown
Contributor

Thanks, @quant12345 please keep trying to make it faster without becoming a flaky test.

forward_propagation(32, 500_000) # Was 10_000_000 # puts the tests are < 1sec in 4th slowest.

Now I tried 400_000 by calling the function 100 times, sometimes the tests fail. At 500_000 I tried 1000, all tests passed(that is, I also think 500_000 is close to the optimal number).

if __name__ == "__main__":
import doctest
doctest.testmod()
for i in range(100):
doctest.run_docstring_examples(forward_propagation, globals())

@cclauss

Copy link
Copy Markdown
MemberAuthor

Nice! Could you please try 450_000 before I merge this?

@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

Nice! Could you please try 450_000 before I merge this?

I run tests 1000 times. It takes some time.

@cclauss

Update: ran it 1000 times with the number 450_000 tests were successful.

@cclauss
cclauss enabled auto-merge (squash) October 27, 2023 21:19
@cclauss

Copy link
Copy Markdown
MemberAuthor

LGTM. @tianyizheng02

@cclausscclauss mentioned this pull request Oct 28, 2023
15 tasks
auto-merge was automatically disabled October 28, 2023 22:47

Pull request was closed

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

Labels

awaiting reviewsThis PR is ready to be reviewedenhancementThis PR modified some existing files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Speedup our eight slowest pytests (one at a time please)

3 participants

@cclauss@tianyizheng02@quant12345
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); simple_neural_network.py: Fewer forward propogations to speed tests by cclauss · Pull Request #11013 · TheAlgorithms/Python · GitHub
Skip to content

simple_neural_network.py: Fewer forward propogations to speed tests - #11013

Closed
cclauss wants to merge 5 commits into
masterfrom
Fewer-forward-propogations-to-speed-tests
Closed

simple_neural_network.py: Fewer forward propogations to speed tests#11013
cclauss wants to merge 5 commits into
masterfrom
Fewer-forward-propogations-to-speed-tests

Conversation

@cclauss

Copy link
Copy Markdown
Member

Closes#9718

Describe your change:

  • Add an algorithm?
  • Fix a bug or typo in an existing algorithm?
  • Add or change doctests? -- Note: Please avoid changing both code and tests in a single pull request.
  • Documentation change?

Checklist:

  • I have read CONTRIBUTING.md.
  • This pull request is all my own work -- I have not plagiarized.
  • I know that pull requests will not be merged if they fail the automated tests.
  • This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
  • All new Python files are placed inside an existing directory.
  • All filenames are in all lowercase characters with no spaces or dashes.
  • All functions and variable names follow Python naming conventions.
  • All function parameters and return values are annotated with Python type hints.
  • All functions have doctests that pass the automated testing.
  • All new algorithms include at least one URL that points to Wikipedia or another similar explanation.
  • If this pull request resolves one or more open issues then the description above includes the issue number(s) with a closing keyword: "Fixes #ISSUE-NUMBER".

@algorithms-keeperalgorithms-keeperBot added enhancement This PR modified some existing files awaiting reviews This PR is ready to be reviewed tests are failing Do not merge until tests pass labels Oct 26, 2023
@tianyizheng02

Copy link
Copy Markdown
Contributor

At one point I tried to decrease the number of iterations like you did, but it didn't work. 100k iterations isn't even enough for the model to converge within 1 of the true value:

=================================== FAILURES ===================================
______ [doctest] neural_network.simple_neural_network.forward_propagation ______
029 Return the value found after the forward propagation training.
030 031 >>> res = forward_propagation(32, 100_000) # Was 10_000_000
032 >>> res > 31 and res < 33
Expected:
True
Got:
False

Like I've been saying, this implementation is really suboptimal and should be rewritten.

@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

@cclauss make 1 million and the tests will pass. I tried to measure the time (not in doctest) and it was 9 - 10 times faster.
res = forward_propagation(32, 1_000_000)

performance code:
"""
Forward propagation explanation:
https://towardsdatascience.com/forward-propagation-in-neural-networks-simplified-math-and-code-version-bbcfef6f9250
"""
import math
import random
# Sigmoid
def sigmoid_function(value: float, deriv: bool = False) -> float:
"""Return the sigmoid function of a float.
>>> sigmoid_function(3.5)
0.9706877692486436
>>> sigmoid_function(3.5, True)
-8.75
"""
if deriv:
return value * (1 - value)
return 1 / (1 + math.exp(-value))
# Initial Value
INITIAL_VALUE = 0.02
def forward_propagation(expected: int, number_propagations: int) -> float:
"""Return the value found after the forward propagation training.
>>> res = forward_propagation(32, 1_000_000)
>>> res > 31 and res < 33
True
>>> res = forward_propagation(32, 1000)
>>> res > 31 and res < 33
False
"""
# Random weight
weight = float(2 * (random.randint(1, 100)) - 1)
for _ in range(number_propagations):
# Forward propagation
layer_1 = sigmoid_function(INITIAL_VALUE * weight)
# How much did we miss?
layer_1_error = (expected / 100) - layer_1
# Error delta
layer_1_delta = layer_1_error * sigmoid_function(layer_1, True)
# Update weight
weight += INITIAL_VALUE * layer_1_delta
return layer_1 * 100
if __name__ == "__main__":
import doctest
doctest.testmod()
import datetime
now = datetime.datetime.now()
forward_propagation(32, 10000000)
old = datetime.datetime.now() - now
print('old_time', old)
now = datetime.datetime.now()
forward_propagation(32, 1000000)
new = datetime.datetime.now() - now
print('new_time', new)
print('old/new', old/new)

Output:

old_time 0:00:07.447717
new_time 0:00:00.735285
old/new 10.129020719856927

@algorithms-keeperalgorithms-keeperBot removed the tests are failing Do not merge until tests pass label Oct 27, 2023
@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

@cclauss I just checked 200_000, it also worked. I apologize for not checking it right away.
But, if you try several times, it happens that the tests fail. I'll try to find the optimal number.

@cclauss

cclauss commented Oct 27, 2023

Copy link
Copy Markdown
MemberAuthor

Thanks, @quant12345 please keep trying to make it faster without becoming a flaky test.

forward_propagation(32, 500_000) # Was 10_000_000 # puts the tests are < 1sec in 4th slowest.

============================= slowest 10 durations =============================
1.32s call web_programming/get_imdbtop.py::web_programming.get_imdbtop.get_imdb_top_movies
1.21s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.search_anime_episode_list
1.00s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.search_scraper
0.90s call neural_network/simple_neural_network.py::neural_network.simple_neural_network.forward_propagation
0.85s call web_programming/fetch_anime_and_play.py::web_programming.fetch_anime_and_play.get_anime_episode
0.83s call dynamic_programming/integer_partition.py::dynamic_programming.integer_partition.partition
0.72s call graphs/bidirectional_a_star.py::graphs.bidirectional_a_star.AStar
0.50s call matrix/count_negative_numbers_in_sorted_matrix.py::matrix.count_negative_numbers_in_sorted_matrix.generate_large_matrix
0.37s call matrix/count_negative_numbers_in_sorted_matrix.py::matrix.count_negative_numbers_in_sorted_matrix.count_negatives_brute_force
0.37s call dynamic_programming/matrix_chain_multiplication.py::dynamic_programming.matrix_chain_multiplication.matrix_chain_order
================== 1749 passed, 1 warning in 72.96s (0:01:12) ==================

@cclauss

cclauss commented Oct 27, 2023

Copy link
Copy Markdown
MemberAuthor

@tianyizheng02 For the web_programming jobs, should we consider replacing requests with the plug-compatible httpx and encouraging contributors to use asyncio for web interactions? I doubt it would speed up the tests but it would continue to push contributors to learn new skills. We currently have 35 files that import requests.

@quant12345

Copy link
Copy Markdown
Contributor

Thanks, @quant12345 please keep trying to make it faster without becoming a flaky test.

forward_propagation(32, 500_000) # Was 10_000_000 # puts the tests are < 1sec in 4th slowest.

Now I tried 400_000 by calling the function 100 times, sometimes the tests fail. At 500_000 I tried 1000, all tests passed(that is, I also think 500_000 is close to the optimal number).

if __name__ == "__main__":
import doctest
doctest.testmod()
for i in range(100):
doctest.run_docstring_examples(forward_propagation, globals())

@cclauss

Copy link
Copy Markdown
MemberAuthor

Nice! Could you please try 450_000 before I merge this?

@quant12345

quant12345 commented Oct 27, 2023

Copy link
Copy Markdown
Contributor

Nice! Could you please try 450_000 before I merge this?

I run tests 1000 times. It takes some time.

@cclauss

Update: ran it 1000 times with the number 450_000 tests were successful.

@cclauss
cclauss enabled auto-merge (squash) October 27, 2023 21:19
@cclauss

Copy link
Copy Markdown
MemberAuthor

LGTM. @tianyizheng02

@cclausscclauss mentioned this pull request Oct 28, 2023
15 tasks
auto-merge was automatically disabled October 28, 2023 22:47

Pull request was closed

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

Labels

awaiting reviewsThis PR is ready to be reviewedenhancementThis PR modified some existing files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Speedup our eight slowest pytests (one at a time please)

3 participants

@cclauss@tianyizheng02@quant12345