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

Added Global average pooling #9863

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 57 additions & 21 deletions computer_vision/pooling_functions.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
# Source : https://computersciencewiki.org/index.php/Max-pooling_/_Pooling
# Importing the libraries
"""
Sources :
Max Pooling: https://computersciencewiki.org/index.php/Max-pooling_/_Pooling
Average Pooling: https://computersciencewiki.org/index.php/Average_pooling
Global Average Pooling: https://paperswithcode.com/method/global-average-pooling
"""

import numpy as np
from PIL import Image


# Maxpooling Function
def maxpooling(arr: np.ndarray, size: int, stride: int) -> np.ndarray:
# Max pooling Function
def max_pooling(arr: np.ndarray, size: int, stride: int) -> np.ndarray:
"""
This function is used to perform maxpooling on the input array of 2D matrix(image)
Comment on lines +12 to 15
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Max pooling Function
def max_pooling(arr: np.ndarray, size: int, stride: int) -> np.ndarray:
"""
This function is used to perform maxpooling on the input array of 2D matrix(image)
def max_pooling(arr: np.ndarray, size: int, stride: int) -> np.ndarray:
"""
Performs max pooling on the input image matrix

The comment at the top of the function is unnecessary because we already have the docstring to explain what the algorithm does

Args:
Expand All @@ -15,10 +20,10 @@ def maxpooling(arr: np.ndarray, size: int, stride: int) -> np.ndarray:
Returns:
numpy array of maxpooled matrix
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
numpy array of maxpooled matrix
The max pooled matrix

Sample Input Output:
>>> maxpooling([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]], 2, 2)
>>> max_pooling(np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]), 2, 2)
array([[ 6., 8.],
[14., 16.]])
>>> maxpooling([[147, 180, 122],[241, 76, 32],[126, 13, 157]], 2, 1)
>>> max_pooling(np.array([[147, 180, 122],[241, 76, 32],[126, 13, 157]]), 2, 1)
array([[241., 180.],
[241., 157.]])
"""
Expand All @@ -31,9 +36,9 @@ def maxpooling(arr: np.ndarray, size: int, stride: int) -> np.ndarray:
mat_j = 0

# compute the shape of the output matrix
maxpool_shape = (arr.shape[0] - size) // stride + 1
max_pool_shape = (arr.shape[0] - size) // stride + 1
# initialize the output matrix with zeros of shape maxpool_shape
updated_arr = np.zeros((maxpool_shape, maxpool_shape))
updated_arr = np.zeros((max_pool_shape, max_pool_shape))

while i < arr.shape[0]:
if i + size > arr.shape[0]:
Expand All @@ -60,8 +65,8 @@ def maxpooling(arr: np.ndarray, size: int, stride: int) -> np.ndarray:
return updated_arr


# Averagepooling Function
def avgpooling(arr: np.ndarray, size: int, stride: int) -> np.ndarray:
# Average pooling Function
def avg_pooling(arr: np.ndarray, size: int, stride: int) -> np.ndarray:
"""
This function is used to perform avgpooling on the input array of 2D matrix(image)
Comment on lines +68 to 71
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Average pooling Function
def avg_pooling(arr: np.ndarray, size: int, stride: int) -> np.ndarray:
"""
This function is used to perform avgpooling on the input array of 2D matrix(image)
def avg_pooling(arr: np.ndarray, size: int, stride: int) -> np.ndarray:
"""
Perform average pooling on the input image matrix

Args:
Expand All @@ -71,10 +76,10 @@ def avgpooling(arr: np.ndarray, size: int, stride: int) -> np.ndarray:
Returns:
numpy array of avgpooled matrix
Comment on lines 76 to 77
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Returns:
numpy array of avgpooled matrix
Returns:
The average pooled matrix

Sample Input Output:
>>> avgpooling([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]], 2, 2)
>>> avg_pooling(np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]), 2, 2)
array([[ 3., 5.],
[11., 13.]])
>>> avgpooling([[147, 180, 122],[241, 76, 32],[126, 13, 157]], 2, 1)
>>> avg_pooling(np.array([[147, 180, 122],[241, 76, 32],[126, 13, 157]]), 2, 1)
array([[161., 102.],
[114., 69.]])
"""
Expand All @@ -87,9 +92,9 @@ def avgpooling(arr: np.ndarray, size: int, stride: int) -> np.ndarray:
mat_j = 0

# compute the shape of the output matrix
avgpool_shape = (arr.shape[0] - size) // stride + 1
avg_pool_shape = (arr.shape[0] - size) // stride + 1
# initialize the output matrix with zeros of shape avgpool_shape
updated_arr = np.zeros((avgpool_shape, avgpool_shape))
updated_arr = np.zeros((avg_pool_shape, avg_pool_shape))

while i < arr.shape[0]:
# if the end of the matrix is reached, break
Expand All @@ -115,21 +120,52 @@ def avgpooling(arr: np.ndarray, size: int, stride: int) -> np.ndarray:
return updated_arr


# Main Function
# Global Average pooling Function
def global_average_pooling(arr: np.ndarray) -> np.ndarray:
"""
This function performs global average pooling on the input 2D matrix (image).
Args:
arr: numpy array
The input 2D matrix.
Returns:
numpy array of the global average pooled matrix.
Comment on lines +123 to +131
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Global Average pooling Function
def global_average_pooling(arr: np.ndarray) -> np.ndarray:
"""
This function performs global average pooling on the input 2D matrix (image).
Args:
arr: numpy array
The input 2D matrix.
Returns:
numpy array of the global average pooled matrix.
def global_avg_pooling(arr: np.ndarray) -> np.ndarray:
"""
Performs global average pooling on the input image matrix.
Args:
arr: the input 2D matrix.
Returns:
The global average pooled matrix

Changed name from "...average..." to "...avg..." for consistency with avg_pooling


>>> global_average_pooling(np.array([[1,2,3],[5,6,7],[9,10,11],[13,14,15]]))
array([[8.]])
>>> global_average_pooling(np.array([[147, 180, 122],[241, 76, 32],[126, 13, 157]]))
array([[121.55555556]])
"""
arr = np.array(arr)

Comment on lines +138 to +139
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
arr = np.array(arr)

This is unnecessary regardless of whether arr is a numpy array

# Calculate the average of the entire input matrix
average_value = np.mean(arr)

# Create a matrix with a single element, which is the average value
global_avg_pooled_matrix = np.array([[average_value]])

return global_avg_pooled_matrix
Comment on lines +143 to +146
Copy link
Contributor

Choose a reason for hiding this comment

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

Please just have your function return the value as a float rather than returning it in a numpy array



# Test with Images
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Test with Images

if __name__ == "__main__":
from doctest import testmod

testmod(name="avgpooling", verbose=True)
testmod(name="average_pooling", verbose=True)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
testmod(name="average_pooling", verbose=True)
testmod(name="pooling_functions", verbose=True)


# Loading the image
image = Image.open("path_to_image")
image = Image.open("/path_to_image")

# Converting the image to numpy array and max_pooling, displaying the result
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Converting the image to numpy array and max_pooling, displaying the result
# Converting the image to numpy array and max pooling, displaying the result

# Ensure that the image is a square matrix

Image.fromarray(max_pooling(np.array(image), size=3, stride=2)).show()

# Converting the image to numpy array and maxpooling, displaying the result
# Converting the image to numpy array and average_pooling, displaying the result
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Converting the image to numpy array and average_pooling, displaying the result
# Converting the image to numpy array and average pooling, displaying the result

# Ensure that the image is a square matrix

Image.fromarray(maxpooling(np.array(image), size=3, stride=2)).show()
Image.fromarray(avg_pooling(np.array(image), size=3, stride=2)).show()

# Converting the image to numpy array and averagepooling, displaying the result
# Converting the image to numpy array and average_pooling, displaying the result
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Converting the image to numpy array and average_pooling, displaying the result
# Converting the image to numpy array and global average pooling, displaying the result

# Ensure that the image is a square matrix

Image.fromarray(avgpooling(np.array(image), size=3, stride=2)).show()
Image.fromarray(global_average_pooling(np.array(image))).show()