Due to the natural tensor property of numpy, the implementation code with numpy is very concise and has few parameters.
In this version, only a small number of operations are numpy processed, and most operations are for loops, only to understand the algorithm
import numpy as np
def zero_pad(X, pad):
"""
Pad with zeros all images of the dataset X. The padding is applied to the height and width of an image,
as illustrated in Figure 1.
Argument:
X -- python numpy array of shape (m, n_H, n_W, n_C) representing a batch of m images
pad -- integer, amount of padding around each image on vertical and horizontal dimensions
Returns:
X_pad -- padded image of shape (m, n_H + 2*pad, n_W + 2*pad, n_C)
"""
return np.pad(X, ((0, 0), (pad, pad), (pad, pad), (0, 0)), 'constant', constant_values=0)
def conv_single_step(a_slice_prev, W, b):
"""
Apply one filter defined by parameters W on a single slice (a_slice_prev) of the output activation
of the previous layer.
Arguments:
a_slice_prev -- slice of input data of shape (f, f, n_C_prev)
W -- Weight parameters contained in a window - matrix of shape (f, f, n_C_prev)
b -- Bias parameters contained in a window - matrix of shape (1, 1, 1)
Returns:
Z -- a scalar value, result of convolving the sliding window (W, b) on a slice x of the input data
"""
s = np.multiply(a_slice_prev, W) + b
Z = np.sum(s)
return Z
def conv_forward(A_prev, W, b, hparameters):
"""
Implements the forward propagation for a convolution function
Arguments:
A_prev -- output activations of the previous layer, numpy array of shape (m, n_H_prev, n_W_prev, n_C_prev)
W -- Weights, numpy array of shape (f, f, n_C_prev, n_C)
b -- Biases, numpy array of shape (1, 1, 1, n_C)
hparameters -- python dictionary containing "stride" and "pad"
Returns:
Z -- conv output, numpy array of shape (m, n_H, n_W, n_C)
cache -- cache of values needed for the conv_backward() function
"""
# Retrieve dimensions from A_prev's shape
(m, n_H_prev, n_W_prev, n_C_prev) = A_prev.shape
# Retrieve dimensions from W's shape
(f, f, n_C_prev, n_C) = W.shape
# Retrieve information from "hparameters"
stride = hparameters['stride']
pad = hparameters['pad']
# Compute the dimensions of the CONV output volume using the formula given above.
n_H = int((n_H_prev - f + 2 * pad) / stride) + 1
n_W = int((n_W_prev - f + 2 * pad) / stride) + 1
# Initialize the output volume Z with zeros.
Z = np.zeros((m, n_H, n_W, n_C))
# Create A_prev_pad by padding A_prev
A_prev_pad = zero_pad(A_prev, pad)
for i in range(m):
a_prev_pad = A_prev_pad[i]
for h in range(n_H):
for w in range(n_W):
for c in range(n_C):
# Find the corners of the current "slice"
vert_start = h * stride
vert_end = vert_start + f
horiz_start = w * stride
horiz_end = horiz_start + f
# Use the corners to define the (3D) slice of a_prev_pad
a_slice_prev = a_prev_pad[vert_start:vert_end, horiz_start:horiz_end, :]
# Convolve the (3D) slice with the correct filter W and bias b, to get back one output neuron.
Z[i, h, w, c] = conv_single_step(a_slice_prev, W[...,c], b[...,c])
# Making sure your output shape is correct
assert(Z.shape == (m, n_H, n_W, n_C))
# Save information in "cache" for the backprop
cache = (A_prev, W, b, hparameters)
return Z, cache
def relu(Z):
return np.maximum(0, Z)
def pool_forward(A_prev, hparameters, mode = "max"):
"""
Implements the forward pass of the pooling layer
Arguments:
A_prev -- Input data, numpy array of shape (m, n_H_prev, n_W_prev, n_C_prev)
hparameters -- python dictionary containing "f" and "stride"
mode -- the pooling mode you would like to use, defined as a string ("max" or "average")
Returns:
A -- output of the pool layer, a numpy array of shape (m, n_H, n_W, n_C)
cache -- cache used in the backward pass of the pooling layer, contains the input and hparameters
"""
# Retrieve dimensions from the input shape
(m, n_H_prev, n_W_prev, n_C_prev) = A_prev.shape
# Retrieve hyperparameters from "hparameters"
f = hparameters["f"]
stride = hparameters["stride"]
# Define the dimensions of the output
n_H = int(1 + (n_H_prev - f) / stride)
n_W = int(1 + (n_W_prev - f) / stride)
n_C = n_C_prev
# Initialize output matrix A
A = np.zeros((m, n_H, n_W, n_C))
for i in range(m):
for h in range(n_H):
for w in range(n_W):
for c in range (n_C):
vert_start = h * stride
vert_end = vert_start + f
horiz_start = w * stride
horiz_end = horiz_start + f
# Use the corners to define the current slice on the ith training example of A_prev, channel c. (≈1 line)
a_prev_slice = A_prev[i, vert_start:vert_end, horiz_start:horiz_end, c]
# Compute the pooling operation on the slice. Use an if statment to differentiate the modes. Use np.max/np.mean.
if mode == "max":
A[i, h, w, c] = np.max(a_prev_slice)
elif mode == "average":
A[i, h, w, c] = np.mean(a_prev_slice)
# Store the input and hparameters in "cache" for pool_backward()
cache = (A_prev, hparameters)
# Making sure your output shape is correct
assert(A.shape == (m, n_H, n_W, n_C))
return A, cache
def conv_relu_pooling_forward(A_prev, W, b, hparameters_conv, hparameters_pool, mode_pool = "max"):
# Retrieve dimensions from A_prev's shape
(m, n_H_prev, n_W_prev, n_C_prev) = A_prev.shape
# Retrieve dimensions from W's shape
(f, f, n_C_prev, n_C) = W.shape
# Retrieve information from "hparameters"
stride_conv = hparameters_conv['stride']
pad_conv = hparameters_conv['pad']
stride = hparameters_pool['stride']
f = hparameters_pool['f']
# Compute the dimensions of the CONV output volume using the formula given above.
n_H_conv = int((n_H_prev - f + 2 * pad_conv) / stride_conv) + 1
n_W_conv = int((n_W_prev - f + 2 * pad_conv) / stride_conv) + 1
# Initialize the output volume Z with zeros.
Z = np.zeros((m, n_H_conv, n_W_conv, n_C))
# Create A_prev_pad by padding A_prev
A_prev_pad = zero_pad(A_prev, pad_conv)
n_H = int(1 + (n_H_conv - f) / stride)
n_W = int(1 + (n_W_conv - f) / stride)
n_C = n_C_prev
Z_out = np.zeros((m, n_H, n_W, n_C))
for i in range(m):
a_prev_pad = A_prev_pad[i]
for h in range(n_H_conv):
for w in range(n_W_conv):
for c in range(n_C):
# Find the corners of the current "slice"
vert_start = h * stride_conv
vert_end = vert_start + f
horiz_start = w * stride_conv
horiz_end = horiz_start + f
# Use the corners to define the (3D) slice of a_prev_pad
a_slice_prev = a_prev_pad[vert_start:vert_end, horiz_start:horiz_end, :]
# Convolve the (3D) slice with the correct filter W and bias b, to get back one output neuron.
Z[i, h, w, c] = conv_single_step(a_slice_prev, W[...,c], b[...,c])
Z[i, h, w, c] = max(0.0, Z[i, h, w, c])
for h in range(n_H):
for w in range(n_W):
for c in range (n_C):
vert_start = h * stride
vert_end = vert_start + f
horiz_start = w * stride
horiz_end = horiz_start + f
# Use the corners to define the current slice on the ith training example of A_prev, channel c. (≈1 line)
a_prev_slice = Z[i, vert_start:vert_end, horiz_start:horiz_end, c]
# Compute the pooling operation on the slice. Use an if statment to differentiate the modes. Use np.max/np.mean.
if mode_pool == "max":
Z_out[i, h, w, c] = np.max(a_prev_slice)
elif mode_pool == "average":
Z_out[i, h, w, c] = np.mean(a_prev_slice)
# Making sure your output shape is correct
assert(Z_out.shape == (m, n_H, n_W, n_C))
# Save information in "cache" for the backprop
# cache = (A_prev, W, b, hparameters)
return Z
Read More:
- Warning when using numpy: runtimewarning: numpy.dtype size changed, may indicate binary incompatibility
- CNN and other websites encounter error 503
- UserWarning: Failed to initialize NumPy: No module named ‘numpy.core._multiarray_umath‘
- Unable to call numpy in pychar, module notfounderror: no module named ‘numpy’
- Solve the problem of forward parameter req and resp parameter error
- Spring MVC realizes page upload file
- JavaScript realizes the longest substring of non repeated characters
- Numpy adds a new dimension: newaxis
- Mac realizes file interaction (upload and download) between terminal and server
- numpy.random.rand()
- The function of structured shuffleplit() in SK learn realizes the division of data set
- [Python] numpy library array splicing np.concatenate Detailed explanation and examples of official documents
- Ant Design upload listtype = “picture card” realizes multi image upload and click preview image encapsulation
- RuntimeError: Default process group has not been initialized, please make sure to call init_process_
- Dataframe to numpy.ndarray Related issues of
- STOP: c000021a { Fatal System Error } the initial session process or system process terminated …
- C / C + + library function (tower / tower) realizes the conversion of letter case
- Importing the multiarray numpy extension module failed
- Python Numpy.ndarray ValueError:assignment destination is read-only
- No module named numpy error in Python code