Table of Contents

Class AveragePoolingLayer<T>

Namespace
AiDotNet.NeuralNetworks.Layers
Assembly
AiDotNet.dll

Implements an average pooling layer for neural networks, which reduces the spatial dimensions of the input by taking the average value in each pooling window.

public class AveragePoolingLayer<T> : LayerBase<T>, ILayer<T>, IJitCompilable<T>, IDiagnosticsProvider, IWeightLoadable<T>, IDisposable

Type Parameters

T

The numeric type used for computations (typically float or double).

Inheritance
AveragePoolingLayer<T>
Implements
Inherited Members

Remarks

For Beginners: An average pooling layer helps reduce the size of data flowing through a neural network while preserving overall characteristics. It works by dividing the input into small windows (determined by the pool size) and computing the average of all values in each window.

Think of it like creating a lower-resolution summary: instead of keeping every detail, you average all the values in each area to get a representative value.

This helps the network:

  1. Preserve background information and overall context
  2. Reduce computation needs
  3. Smooth out noisy features

Average pooling is often used in the final layers of a network or when you want to preserve more spatial information compared to max pooling.

Constructors

AveragePoolingLayer(int[], int, int)

Creates a new average pooling layer with the specified parameters.

public AveragePoolingLayer(int[] inputShape, int poolSize, int strides)

Parameters

inputShape int[]

The shape of the input data (channels, height, width).

poolSize int

The size of the pooling window.

strides int

The step size when moving the pooling window.

Remarks

For Beginners: This constructor sets up the average pooling layer with your chosen settings. It calculates what the output shape will be based on your input shape, pool size, and strides.

Properties

PoolSize

Gets the size of the pooling window.

public int PoolSize { get; }

Property Value

int

Remarks

For Beginners: This determines how large of an area we look at when computing the average value. For example, a pool size of 2 means we look at 2×2 squares of the input.

Strides

Gets the step size when moving the pooling window across the input.

public int Strides { get; }

Property Value

int

Remarks

For Beginners: This controls how much we move our window each time. For example, a stride of 2 means we move the window 2 pixels at a time, which reduces the output size to half of the input size (assuming pool size is also 2).

SupportsGpuExecution

Indicates that this layer supports GPU-accelerated execution.

protected override bool SupportsGpuExecution { get; }

Property Value

bool

SupportsJitCompilation

Gets whether this average pooling layer supports JIT compilation.

public override bool SupportsJitCompilation { get; }

Property Value

bool

True if the layer is properly configured.

Remarks

This property indicates whether the layer can be JIT compiled. The layer supports JIT if: - Input shape is configured

For Beginners: This tells you if this layer can use JIT compilation for faster inference.

The layer can be JIT compiled if:

  • The layer has been initialized with valid input shape

Average pooling has no trainable parameters, so it can be JIT compiled immediately after initialization. It's a purely computational operation that:

  • Averages values in sliding windows
  • Reduces spatial dimensions
  • Provides translation invariance

JIT compilation optimizes:

  • Window sliding and boundary handling
  • Parallel averaging across channels
  • Memory access patterns for cache efficiency

Once initialized, JIT compilation can provide significant speedup (5-10x) especially for large feature maps in CNNs.

SupportsTraining

Indicates whether this layer supports training operations.

public override bool SupportsTraining { get; }

Property Value

bool

Remarks

For Beginners: This property tells the neural network system whether this layer can be trained (adjusted) during the learning process. Average pooling layers don't have parameters to train, but they do support the training process by allowing gradients to flow backward through them.

Methods

Backward(Tensor<T>)

Performs the backward pass of the average pooling operation.

public override Tensor<T> Backward(Tensor<T> outputGradient)

Parameters

outputGradient Tensor<T>

The gradient flowing back from the next layer.

Returns

Tensor<T>

The gradient to pass to the previous layer.

Remarks

For Beginners: During training, neural networks need to adjust their parameters based on how much error they made. This adjustment flows backward through the network.

In average pooling, all values in each window contributed equally to the output average. So during the backward pass, the gradient is distributed equally to all positions in the window. Each position receives (output gradient) / (pool size × pool size).

This is different from max pooling, where only the maximum value gets the gradient.

Exceptions

ArgumentException

Thrown when the output gradient tensor doesn't have 3 dimensions.

BackwardGpu(IGpuTensor<T>)

Performs GPU-resident backward pass of average pooling.

public override IGpuTensor<T> BackwardGpu(IGpuTensor<T> outputGradient)

Parameters

outputGradient IGpuTensor<T>

The gradient of the output on GPU.

Returns

IGpuTensor<T>

The gradient with respect to input as a GPU-resident tensor.

Deserialize(BinaryReader)

Loads the layer's configuration from a binary stream.

public override void Deserialize(BinaryReader reader)

Parameters

reader BinaryReader

The binary reader to read the data from.

Remarks

For Beginners: This method loads previously saved settings for the layer. It's the counterpart to Serialize - if Serialize is like saving your game, Deserialize is like loading that saved game.

ExportComputationGraph(List<ComputationNode<T>>)

Exports the average pooling layer as a computation graph for JIT compilation.

public override ComputationNode<T> ExportComputationGraph(List<ComputationNode<T>> inputNodes)

Parameters

inputNodes List<ComputationNode<T>>

List to which the input node will be added.

Returns

ComputationNode<T>

The output computation node representing the average pooling operation.

Remarks

This method creates a symbolic computation graph for JIT compilation: 1. Creates a symbolic input node with shape [batch=1, channels, height, width] 2. Applies the AvgPool2D operation with specified pool size and strides 3. No learnable parameters needed (average pooling is parameter-free)

For Beginners: This method builds a symbolic representation of average pooling for JIT.

JIT compilation converts the average pooling operation into optimized native code. Average pooling:

  • Reduces spatial dimensions by averaging values in each pooling window
  • Slides a window across the input with specified stride
  • Provides smoother downsampling compared to max pooling
  • Has no trainable parameters (purely computational)

The symbolic graph allows the JIT compiler to:

  • Optimize the sliding window computation
  • Generate SIMD-optimized code for parallel averaging
  • Fuse operations with adjacent layers

Average pooling is commonly used in CNNs for downsampling and global pooling. JIT compilation provides 5-10x speedup by optimizing the window operations.

Exceptions

ArgumentNullException

Thrown when inputNodes is null.

InvalidOperationException

Thrown when layer shape is not configured.

Forward(Tensor<T>)

Performs the forward pass of the average pooling operation.

public override Tensor<T> Forward(Tensor<T> input)

Parameters

input Tensor<T>

The input tensor to apply average pooling to.

Returns

Tensor<T>

The output tensor after average pooling.

Remarks

For Beginners: This is where the actual average pooling happens. For each small window in the input:

  1. We look at all values in that window
  2. We calculate the average of those values
  3. We put that average value in the output

The method processes the input channel by channel, sliding the pooling window across the height and width dimensions.

Exceptions

ArgumentException

Thrown when the input tensor doesn't have 3 dimensions.

ForwardGpu(params IGpuTensor<T>[])

Performs GPU-resident forward pass of average pooling, keeping all data on GPU.

public override IGpuTensor<T> ForwardGpu(params IGpuTensor<T>[] inputs)

Parameters

inputs IGpuTensor<T>[]

The input tensors on GPU (uses first input).

Returns

IGpuTensor<T>

The pooled output as a GPU-resident tensor.

GetActivationTypes()

Returns the activation functions used by this layer.

public override IEnumerable<ActivationFunction> GetActivationTypes()

Returns

IEnumerable<ActivationFunction>

An empty collection since average pooling layers don't use activation functions.

Remarks

For Beginners: Activation functions are mathematical operations that determine the output of a neural network node. They introduce non-linearity, which helps neural networks learn complex patterns.

However, average pooling layers don't use activation functions - they simply compute the average of values in each window. That's why this method returns an empty collection.

GetParameters()

Gets all trainable parameters of the layer.

public override Vector<T> GetParameters()

Returns

Vector<T>

An empty vector since average pooling layers have no trainable parameters.

Remarks

For Beginners: This method returns all the values that can be adjusted during training.

Many neural network layers have weights and biases that get updated as the network learns. However, average pooling layers simply compute the average of values in each window - there are no weights or biases to adjust.

This is why the method returns an empty vector (essentially a list with no elements).

GetPoolSize()

Gets the pool size as a 2D array (height, width).

public int[] GetPoolSize()

Returns

int[]

An array containing [poolSize, poolSize].

Remarks

This method is used by the JIT compiler to extract pooling parameters.

GetStride()

Gets the stride as a 2D array (height stride, width stride).

public int[] GetStride()

Returns

int[]

An array containing [strides, strides].

Remarks

This method is used by the JIT compiler to extract pooling parameters.

ResetState()

Resets the internal state of the layer.

public override void ResetState()

Remarks

For Beginners: This method clears any information the layer has stored from previous calculations.

During the forward pass, the average pooling layer stores the input for use in the backward pass.

Resetting the state clears this memory, which is useful when:

  1. Starting a new training session
  2. Processing a new batch of data
  3. Switching from training to evaluation mode

It's like wiping a whiteboard clean before starting a new calculation.

Serialize(BinaryWriter)

Saves the layer's configuration to a binary stream.

public override void Serialize(BinaryWriter writer)

Parameters

writer BinaryWriter

The binary writer to write the data to.

Remarks

For Beginners: This method saves the layer's settings (pool size and stride) so that you can reload the exact same layer later. It's like saving your game progress so you can continue from where you left off.

UpdateParameters(T)

Updates the layer's parameters during training.

public override void UpdateParameters(T learningRate)

Parameters

learningRate T

The learning rate that controls how much parameters change.

Remarks

For Beginners: This method is part of the neural network training process.

During training, most layers need to update their internal values (parameters) to learn from data. However, average pooling layers don't have any trainable parameters - they just compute the average of values in each window.

Think of it like a simple rule that doesn't need to be adjusted: "Always compute the average." Since this rule never changes, there's nothing to update in this method.