mygrad.nnet.layers.max_pool#
- mygrad.nnet.layers.max_pool(x: ArrayLike, pool: Tuple[int, ...], stride: int | Tuple[int, ...], *, constant: bool | None = None) Tensor [source]#
Perform max-pooling over the last N dimensions of a data batch.
The data consists of N trailing axes to be pooled over, denoted by
C0, ...
. These can be preceded, optionally, by un-pooled axes, denoted by(N0, ...)
. The dimensions of the window over which pooling is performed is denoted byP0, ...
. The window is placed with stride valuesS0, ...
.Ultimately the pooled channels have a shape
G0, ...
.- Parameters:
- xmygrad.Tensor, shape=([…], C0, …)
The data batch; to be pooled along the trailing axes denoted by
C0, ...
.- poolTuple[Integral, …], (P0, …)
The extent of the pooling window along the
(C0, ...)
axes, respectively. The length of pool determinesN
- the number of trailing dimensions to pool over.- strideUnion[Integral, Tuple[Integral, …]], (S0, …)
The spacing used to place the pooling window, along
(P0, ...)
axes, respectively. If a single value is provided, it is used for allN
pooling axes.- constantOptional[None]
If True, the resulting Tensor is a constant.
- Returns
- ——-
- Tensor, shape=([…], G0, …)
The pooled data batch.
Notes
Only “valid” placements of the pooling window are permitted - the pooling window cannot extend passed the “boundaries” of the data dimensions.
Examples
Simple 2D pooling on a 2D tensor. Tiling a 2x2 max-pool window with stride-1 over a shape-(3, 3) tensor
x
:>>> import mygrad as mg >>> from mygrad.nnet import max_pool >>> x = mg.Tensor([[0., 10., 8.], ... [2., 7., 3.], ... [5., 7., 20.]]) >>> out = max_pool(x, pool=(2, 2), stride=1) >>> out Tensor([[ 10., 10.], [ 7., 20.]]) >>> out.sum().backward() # sum to reduce to scalar for back-prop >>> x.grad # dout/dx array([[0., 2., 0.], [0., 1., 0.], [0., 0., 1.]])
Let’s perform 1D pooling on a 2D tensor. Each row of the tensor will be pooled over independently. Let’s apply a size-2 max-pool window to each row of
x
, using a stride of 1:>>> x = mg.Tensor([[0., 10., 8.], ... [9., 7., 3.], ... [5., 0., 20.]]) >>> max_pool(x, pool=(2,), stride=1) Tensor([[10., 10.], [ 9., 7.], [ 5., 20.]])
Here we perform pooling over the trailing two dimensions of a 4D tensor,
x
. By specifyingpool = (2, 2)
, we instructmax_pool
to tile a 2x2 pooling window along these last two axes. Let’s apply the window every two rows, and for each column; i.e. we specifystride = (2, 1)
:>>> import numpy as np >>> x = mg.Tensor(np.random.rand(10, 3, 12, 12)) >>> pool = (2, 2) # 2x2 pooling over the last axes >>> stride = (2, 1) # Apply 2x1 stride >>> out = max_pool(x, pool, stride) # max-pooled Tensor >>> out.shape (10, 3, 6, 11)
Had we specified, say,
pool = (3, 2, 2)
, then a 3x2x2 pooling window would have been tiled along the last three axes ofx
.